NoRedInk/noredink-ui/23.1.0

NOTE: the latest version is 35.9.3

Nri.Ui.Highlightable.V1

A Highlightable represents a span of text, typically a word, and its state.

Highlightable is the unit by which text-wrapping happens. Depending on how the Highlighter is initialized, it's very possible for a Highlightable to consist of just a single whitespace.

Patch changes

  • move asFragmentTuples, usedMarkers, and text to the Highlightable module

Types

type alias Highlightable marker =
{ text : String
, uiState : UIState
, customAttributes : List Attribute
, marked : Maybe (MarkerModel marker)
, groupIndex : Int
, type_ : Type
}

A Highlightable comes in two flavors:

  • Highlightable | Interactive piece of text.

  • Static | Non-interactive piece of text. Gets highlighted grudgingly if the UI is going to get unintuitive otherwise. i.e. does not get highlighted when hovered etc.

    Data for a Highlightable:

  • text: String to display.

  • uiState: How the user is currently interacting with the Highlightable.

  • customAttributes: User-supplied attributes that do not change once a Highlightable is initialized.

  • marked: Current highlight.

  • groupIndex: Index that identifies the fragment this Highlightable belongs to.

type Type
= Interactive
| Static
type UIState
= Hovered
| Hinted
| None

UIState connects user-behavior to the highlightable.

State transitions:

  • None → (mouse over) → Hovered
  • None → (click & drag over highlightables) → Hinted
  • Hovered → (mouse out) → None
  • Hovered → (mouse down) → Hinted
  • Hinted → (mouse out) → None
  • Hinted → (mouse up while on a different Highlightable) → None
  • Hinted → (mouse up while on me) → Hovered
= Class String
| Data String String

Custom attributes that do not change after initialization.

  • Class: add a class to the highlight
  • Data: add a data-X to the highlight (you don't need to prepend data- to this name.)

Initializers

-> Maybe (MarkerModel marker)
-> Int
-> ( List Attribute, String )
-> Highlightable marker
Maybe (MarkerModel marker)
-> Int
-> List ( List Attribute, String )
-> List (Highlightable marker)

Split a multi-word string into multiple single-word highlights. This is to deal with the highlighter not doing line breaks within a highlight group, which can look funny if a highlight contains longer text.

initFragments : Maybe (MarkerModel marker) -> String -> List (Highlightable marker)

Similar to initFragment but each word is treated as a fragment, instead of treating the whole string as a fragment.

Note that we're transforming all whitespace to spaces, so newlines are not preserved as me move to and from fragments

fromMarkdown : String -> List (Highlightable ())

How do we know which elements should be marked, if all we have is a markdown string?

We do some funky parsing to interpret empty anchor tags and tagged spans as highlighted!

fromMarkdown "for example, [this phrase]() will show as highlighted"

will result in a list of highlightables where "this phrase" is marked with the default marker.

Transformations

splitHighlightableOnWords : Highlightable marker -> List (Highlightable marker)

Split a highlightable into one highlightable per word.

splitWords : String -> List String

Create list of words intersperse with spaces.

blur : Highlightable marker -> Highlightable marker
clearHint : Highlightable marker -> Highlightable marker
hint : Highlightable marker -> Highlightable marker
hover : Highlightable marker -> Highlightable marker
set :
Maybe (MarkerModel marker)
-> Highlightable marker
-> Highlightable marker
toggle : MarkerModel marker -> Highlightable marker -> Highlightable marker

A Sorter for Attributes

Getters

asFragmentTuples : List (Highlightable marker) -> List ( Maybe marker, String )

Get a list of fragment texts and whether or not they are marked. Useful for encoding answers.

usedMarkers : Sorter marker -> List (Highlightable marker) -> Set marker

Get unique markers that have been used.

text : List (Highlightable marker) -> String

Fetch the text from a series of highlightables.

Modules