0 | module Text.HTML.Class
  1 |
  2 | import Derive.Prelude
  3 | import public Text.CSS.Class
  4 | import Text.HTML
  5 | import Text.HTML.Select
  6 | import Text.HTML.DomID
  7 |
  8 | %default total
  9 | %language ElabReflection
 10 |
 11 | --------------------------------------------------------------------------------
 12 | --          Utility Classes
 13 | --------------------------------------------------------------------------------
 14 |
 15 | ||| A UI widget (typically, an interactive element such as a button
 16 | ||| or text input field)
 17 | export
 18 | Widget : SnocList Class
 19 | Widget = [<"widget"]
 20 |
 21 | ||| A clickable button with some text.
 22 | export
 23 | Btn : SnocList Class
 24 | Btn = Widget :< "button"
 25 |
 26 | ||| A larger UI component
 27 | export
 28 | Comp : SnocList Class
 29 | Comp = [<"comp"]
 30 |
 31 | ||| A cell in a table
 32 | export
 33 | Cell : SnocList Class
 34 | Cell = [<"cell"]
 35 |
 36 | ||| A clickable icon
 37 | export
 38 | Icon : SnocList Class
 39 | Icon = [<"icon"]
 40 |
 41 | ||| A text input field
 42 | export
 43 | Inp : SnocList Class
 44 | Inp = Widget :< "input"
 45 |
 46 | ||| A select element
 47 | export
 48 | Sel : SnocList Class
 49 | Sel = Widget :< "select"
 50 |
 51 | ||| A text typically linked to some input element
 52 | export
 53 | Lbl : SnocList Class
 54 | Lbl = [<"label"]
 55 |
 56 | ||| A larger view displaying a list of values
 57 | export
 58 | Lst : SnocList Class
 59 | Lst = [<"list"]
 60 |
 61 | ||| A single row in a list of values
 62 | export
 63 | Row : SnocList Class
 64 | Row = [<"row"]
 65 |
 66 | ||| A title in a UI component
 67 | export
 68 | Title : SnocList Class
 69 | Title = [<"title"]
 70 |
 71 | ||| A collapsed UI element (hiding some details)
 72 | export
 73 | collapsed : Class
 74 | collapsed = "collapsed"
 75 |
 76 | ||| An expanded UI element
 77 | export
 78 | expanded : Class
 79 | expanded = "expanded"
 80 |
 81 | --------------------------------------------------------------------------------
 82 | --          UI Elements
 83 | --------------------------------------------------------------------------------
 84 |
 85 | export
 86 | cls : SnocList Class -> Class -> Attribute t e
 87 | cls sv v = classes $ sv <>> [v]
 88 |
 89 | export %inline
 90 | cls1 : Class -> Attribute t e
 91 | cls1 = cls [<]
 92 |
 93 | ||| Creates a text label for a probably editable field
 94 | |||
 95 | ||| @ uid   : ID used in "for" attribute
 96 | ||| @ class : CSS class to use
 97 | ||| @ txt   : actual textual content
 98 | export
 99 | lbl : Cast i DomID => Class -> i -> String -> Node e
100 | lbl c vi txt = label [cls Lbl c, forID vi] [Text txt]
101 |
102 | ||| A cell in a table
103 | export %inline
104 | cell : Class -> List (Attribute Div e) -> List (Node e) -> Node e
105 | cell v as = div (cls Cell v :: as)
106 |
107 | ||| A list of elements.
108 | export %inline
109 | list : Class -> List (Attribute Ul e) -> List (Node e) -> Node e
110 | list v as = ul (cls Lst v :: as)
111 |
112 | ||| A single row in a list of elements.
113 | export %inline
114 | row : Class -> List (Attribute Div e) -> List (Node e) -> Node e
115 | row v as = div (cls Row v :: as)
116 |
117 | ||| A clickable button in the UI firing the given event on a left click.
118 | export %inline
119 | btn : Class -> e -> String -> List (Attribute Tag.Button e) -> Node e
120 | btn v ev txt as = button (cls Btn v :: onClick ev :: as) [Text txt]
121 |
122 | ||| A clickable icon in the UI firing the given event on a left click.
123 | export %inline
124 | icon : Class -> e -> List (Attribute Tag.Button e) -> Node e
125 | icon v ev as = button (cls Icon v :: onClick ev :: as) []
126 |
127 | ||| A clickable icon with predefined class.
128 | |||
129 | ||| This takes a `DomID` as additional argument since we want
130 | ||| to be able to disable it in case of invalid input.
131 | export %inline
132 | iok : Cast i DomID => i -> e -> Node e
133 | iok u ev = icon "ok" ev [ref u]
134 |
135 | ||| A clickable icon with predefined class.
136 | export %inline
137 | iadd : e -> Node e
138 | iadd v = icon "add" v []
139 |
140 | ||| A clickable icon with predefined class.
141 | export %inline
142 | icancel : e -> Node e
143 | icancel v = icon "cancel" v []
144 |
145 | ||| A clickable icon with predefined class.
146 | export %inline
147 | idelete : e -> Node e
148 | idelete v = icon "delete" v []
149 |
150 | --------------------------------------------------------------------------------
151 | --          Editing
152 | --------------------------------------------------------------------------------
153 |
154 | ||| An `<input>` element of the given class.
155 | export %inline
156 | inp : Class -> (String -> e) -> List (Attribute Tag.Input e) -> Node e
157 | inp v f as = input (cls Inp v :: onInput f :: as) []
158 |
159 | ||| A select element displaying the values of type `v`
160 | ||| shown in the given list.
161 | |||
162 | ||| It fires events of type `t`, and uses two functions, one for
163 | ||| converting elements to events and one for displaying elements.
164 | export %inline
165 | sel : Eq t => (v -> t) -> (v -> String) -> List v -> Class -> Maybe t -> Node t
166 | sel f g vs c i = selectFromListBy vs ((i ==) . Just . f) g f [cls Sel c]
167 |