NoRedInk/noredink-ui/23.3.0

NOTE: the latest version is 35.9.3

Nri.Ui.Highlightable.V2

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.

Changes from V1

  • move asFragmentTuples, usedMarkers, and text to the Highlightable module
  • remove initFragment, splitHighlightableOnWords, splitWords
  • remove toggle, which is not used
  • rename groupIndex -> index
  • ensure that fromMarkdown indexes the fragments correctly
  • support multiple kinds of mark
  • move joinAdjacentInteractiveHighlights to the Highlightable module
  • adds byId

Types

type alias Highlightable marker =
{ text : String
, uiState : UIState
, customAttributes : List Attribute
, marked : List (MarkerModel marker)
, index : 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 highlights, if any.

  • index: Index that identifies the fragment this Highlightable belongs to. Must be unique in the list of highlightables.

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

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

Initialize highlightables from a string.

Note that we're transforming all whitespace to spaces, so newlines are not preserved as me move to and from fragments. Spaces will be treated as static elements. Words will be interactive.

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.

UIState and marker

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
joinAdjacentInteractiveHighlights : List (Highlightable m) -> List (Highlightable m)

A Sorter for Attributes

Getters

asFragmentTuples : List (Highlightable marker) -> List ( List 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. Note: ignores marks on whitespace.

text : List (Highlightable marker) -> String

Fetch the text from a series of highlightables.

byId : Int -> List (Highlightable kind) -> Maybe (Highlightable kind)

Get the highlightable matching the passed-in ID, if any.

Modules