module ModalGroup exposing (..) {-| A ModalGroup is a collection of items, zero or one of which can be active at a time. It is intended for modelling the behaviour of modal dialog boxes, where at most one dialog box can be open at a time. -} import Dict exposing (Dict) type ModalGroup k comparable a = Group { active : Maybe k , group : Dict comparable a , keyFn : k -> comparable } {-| Empty grouping. Map the key type of the group with a function, so that non-comparable keys can be used. -} empty : (k -> comparableKey) -> ModalGroup k comparableKey a empty keyFn = Group { active = Nothing, group = Dict.empty, keyFn = keyFn } {-| Clears any active item. -} reset : ModalGroup k comparableKey a -> ModalGroup k comparableKey a reset (Group record) = Group { record | active = Nothing } {-| Adds a new item to the group by its key. -} add : k -> a -> ModalGroup k comparableKey a -> ModalGroup k comparableKey a add key value (Group record) = let compKey = record.keyFn key newGroup = Dict.insert compKey value record.group in Group { record | group = newGroup } {-| Sets the active item in the group. If no matching item can be found any active item will be cleared. -} active : k -> ModalGroup k comparableKey a -> ( ModalGroup k comparableKey a, Maybe a ) active key (Group record) = let compKey = record.keyFn key maybeValue = Dict.get compKey record.group newActive = maybeValue |> Maybe.map (always key) newRecord = Group { record | active = newActive } in ( newRecord, maybeValue )