rip-lang 3.13.93 → 3.13.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/docs/dist/rip.js +142 -38
- package/docs/dist/rip.min.js +174 -174
- package/docs/dist/rip.min.js.br +0 -0
- package/package.json +1 -1
- package/src/ui.rip +65 -0
- package/docs/ui/accordion.rip +0 -113
- package/docs/ui/alert-dialog.rip +0 -96
- package/docs/ui/autocomplete.rip +0 -141
- package/docs/ui/avatar.rip +0 -37
- package/docs/ui/badge.rip +0 -15
- package/docs/ui/breadcrumb.rip +0 -46
- package/docs/ui/button-group.rip +0 -26
- package/docs/ui/button.rip +0 -23
- package/docs/ui/card.rip +0 -25
- package/docs/ui/carousel.rip +0 -110
- package/docs/ui/checkbox-group.rip +0 -65
- package/docs/ui/checkbox.rip +0 -33
- package/docs/ui/collapsible.rip +0 -50
- package/docs/ui/combobox.rip +0 -155
- package/docs/ui/context-menu.rip +0 -105
- package/docs/ui/date-picker.rip +0 -214
- package/docs/ui/dialog.rip +0 -107
- package/docs/ui/drawer.rip +0 -79
- package/docs/ui/editable-value.rip +0 -80
- package/docs/ui/field.rip +0 -53
- package/docs/ui/fieldset.rip +0 -22
- package/docs/ui/form.rip +0 -39
- package/docs/ui/grid.rip +0 -901
- package/docs/ui/hljs-rip.js +0 -209
- package/docs/ui/index.css +0 -1772
- package/docs/ui/index.html +0 -2433
- package/docs/ui/input-group.rip +0 -28
- package/docs/ui/input.rip +0 -36
- package/docs/ui/label.rip +0 -16
- package/docs/ui/menu.rip +0 -162
- package/docs/ui/menubar.rip +0 -155
- package/docs/ui/meter.rip +0 -36
- package/docs/ui/multi-select.rip +0 -158
- package/docs/ui/native-select.rip +0 -32
- package/docs/ui/nav-menu.rip +0 -129
- package/docs/ui/number-field.rip +0 -162
- package/docs/ui/otp-field.rip +0 -89
- package/docs/ui/pagination.rip +0 -123
- package/docs/ui/popover.rip +0 -143
- package/docs/ui/preview-card.rip +0 -73
- package/docs/ui/progress.rip +0 -25
- package/docs/ui/radio-group.rip +0 -67
- package/docs/ui/resizable.rip +0 -123
- package/docs/ui/scroll-area.rip +0 -145
- package/docs/ui/select.rip +0 -184
- package/docs/ui/separator.rip +0 -17
- package/docs/ui/skeleton.rip +0 -22
- package/docs/ui/slider.rip +0 -165
- package/docs/ui/spinner.rip +0 -17
- package/docs/ui/table.rip +0 -27
- package/docs/ui/tabs.rip +0 -124
- package/docs/ui/textarea.rip +0 -48
- package/docs/ui/toast.rip +0 -87
- package/docs/ui/toggle-group.rip +0 -78
- package/docs/ui/toggle.rip +0 -24
- package/docs/ui/toolbar.rip +0 -46
- package/docs/ui/tooltip.rip +0 -115
package/docs/ui/index.html
DELETED
|
@@ -1,2433 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Rip UI</title>
|
|
7
|
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
10
|
-
<link rel="stylesheet" href="index.css">
|
|
11
|
-
<style>body { opacity: 0; } body.ready { opacity: 1; transition: opacity 200ms ease-in; }</style>
|
|
12
|
-
<script defer src="../dist/rip.min.js" data-src="
|
|
13
|
-
otp-field.rip
|
|
14
|
-
multi-select.rip
|
|
15
|
-
editable-value.rip
|
|
16
|
-
date-picker.rip
|
|
17
|
-
field.rip
|
|
18
|
-
fieldset.rip
|
|
19
|
-
form.rip
|
|
20
|
-
preview-card.rip
|
|
21
|
-
menubar.rip
|
|
22
|
-
nav-menu.rip
|
|
23
|
-
toggle-group.rip
|
|
24
|
-
radio-group.rip
|
|
25
|
-
checkbox-group.rip
|
|
26
|
-
avatar.rip
|
|
27
|
-
context-menu.rip
|
|
28
|
-
toolbar.rip
|
|
29
|
-
drawer.rip
|
|
30
|
-
autocomplete.rip
|
|
31
|
-
scroll-area.rip
|
|
32
|
-
number-field.rip
|
|
33
|
-
slider.rip
|
|
34
|
-
separator.rip
|
|
35
|
-
button.rip
|
|
36
|
-
input.rip
|
|
37
|
-
toggle.rip
|
|
38
|
-
progress.rip
|
|
39
|
-
meter.rip
|
|
40
|
-
checkbox.rip
|
|
41
|
-
toast.rip
|
|
42
|
-
dialog.rip
|
|
43
|
-
select.rip
|
|
44
|
-
combobox.rip
|
|
45
|
-
tooltip.rip
|
|
46
|
-
tabs.rip
|
|
47
|
-
menu.rip
|
|
48
|
-
popover.rip
|
|
49
|
-
accordion.rip
|
|
50
|
-
grid.rip
|
|
51
|
-
badge.rip
|
|
52
|
-
skeleton.rip
|
|
53
|
-
spinner.rip
|
|
54
|
-
card.rip
|
|
55
|
-
label.rip
|
|
56
|
-
textarea.rip
|
|
57
|
-
native-select.rip
|
|
58
|
-
input-group.rip
|
|
59
|
-
button-group.rip
|
|
60
|
-
alert-dialog.rip
|
|
61
|
-
breadcrumb.rip
|
|
62
|
-
table.rip
|
|
63
|
-
collapsible.rip
|
|
64
|
-
pagination.rip
|
|
65
|
-
carousel.rip
|
|
66
|
-
resizable.rip
|
|
67
|
-
" data-mount="WidgetGallery">
|
|
68
|
-
</script>
|
|
69
|
-
</head>
|
|
70
|
-
<body>
|
|
71
|
-
|
|
72
|
-
<script type="text/rip">
|
|
73
|
-
do ->
|
|
74
|
-
orig = HTMLElement::focus
|
|
75
|
-
HTMLElement::focus = (o) -> orig.call this, { preventScroll: true, ...o }
|
|
76
|
-
|
|
77
|
-
export SectionHead = component
|
|
78
|
-
accept _gallery
|
|
79
|
-
@tag := ''
|
|
80
|
-
@name := ''
|
|
81
|
-
@lines := 0
|
|
82
|
-
|
|
83
|
-
render
|
|
84
|
-
.section-title
|
|
85
|
-
= @name
|
|
86
|
-
if @lines > 0
|
|
87
|
-
span.badge @click: (=> _gallery._viewSource(@tag)), "#{@lines} lines ❐"
|
|
88
|
-
else
|
|
89
|
-
span.badge "pattern"
|
|
90
|
-
.section-nav
|
|
91
|
-
a @click: (=> _gallery._navSection(@tag, 'prev')), "‹"
|
|
92
|
-
a @click: (=> _gallery._navSection(@tag, 'home')), "⌂"
|
|
93
|
-
a @click: (=> _gallery._navSection(@tag, 'next')), "›"
|
|
94
|
-
|
|
95
|
-
export WidgetGallery = component
|
|
96
|
-
offer _gallery := this
|
|
97
|
-
|
|
98
|
-
# ---- State ----
|
|
99
|
-
check1 := false
|
|
100
|
-
check2 := true
|
|
101
|
-
switch1 := false
|
|
102
|
-
toasts := []
|
|
103
|
-
showDialog := false
|
|
104
|
-
fruit := null
|
|
105
|
-
role := null
|
|
106
|
-
searchQuery := ''
|
|
107
|
-
allFruits := ['Apple', 'Apricot', 'Avocado', 'Banana', 'Blueberry', 'Cherry', 'Cranberry', 'Date', 'Fig', 'Grape', 'Kiwi', 'Lemon', 'Lime', 'Mango', 'Orange', 'Papaya', 'Peach', 'Pear', 'Plum', 'Raspberry', 'Strawberry']
|
|
108
|
-
filteredFruits := allFruits
|
|
109
|
-
currentTab := 'overview'
|
|
110
|
-
isBold := false
|
|
111
|
-
isItalic := false
|
|
112
|
-
userName := ''
|
|
113
|
-
progressVal := 0.65
|
|
114
|
-
meterVal := 72
|
|
115
|
-
sliderVal := 40
|
|
116
|
-
rangeVal := [20, 70]
|
|
117
|
-
showDrawer := false
|
|
118
|
-
citySearch := ''
|
|
119
|
-
cities := ['Albuquerque', 'Anchorage', 'Arlington', 'Atlanta', 'Aurora', 'Austin', 'Anaheim', 'Asheville', 'Baltimore', 'Baton Rouge', 'Birmingham', 'Boise', 'Boston', 'Buffalo', 'Bakersfield', 'Bridgeport', 'Charlotte', 'Chicago', 'Dallas', 'Denver', 'Detroit', 'El Paso', 'Houston', 'Miami', 'New York', 'Phoenix', 'Portland', 'San Diego', 'San Francisco', 'Seattle']
|
|
120
|
-
quantity := 1
|
|
121
|
-
price := 9.99
|
|
122
|
-
alignment := 'left'
|
|
123
|
-
fontSize := 'md'
|
|
124
|
-
toppings := ['Cheese']
|
|
125
|
-
cbToppings := ['Cheese']
|
|
126
|
-
fieldEmail := ''
|
|
127
|
-
fieldError := ''
|
|
128
|
-
otpCode := ''
|
|
129
|
-
selectedColors := ['Red']
|
|
130
|
-
editName := 'John Doe'
|
|
131
|
-
pickedDate := null
|
|
132
|
-
dateRange := null
|
|
133
|
-
darkMode := false
|
|
134
|
-
showAlertDialog := false
|
|
135
|
-
textareaVal := ''
|
|
136
|
-
nativeSelectVal := ''
|
|
137
|
-
collapsibleOpen := false
|
|
138
|
-
currentPage := 1
|
|
139
|
-
sourceCode := null
|
|
140
|
-
sourceName := ''
|
|
141
|
-
sourceLines := 0
|
|
142
|
-
tocActive := null
|
|
143
|
-
tocFilter := ''
|
|
144
|
-
tocGroups := [
|
|
145
|
-
{ label: 'Selection', ids: ['select', 'combobox', 'multi-select', 'autocomplete'] }
|
|
146
|
-
{ label: 'Toggle', ids: ['checkbox', 'toggle', 'toggle-group', 'radio-group', 'checkbox-group'] }
|
|
147
|
-
{ label: 'Input', ids: ['input', 'textarea', 'native-select', 'number-field', 'slider', 'otp-field', 'date-picker', 'editable-value', 'input-group'] }
|
|
148
|
-
{ label: 'Navigation', ids: ['tabs', 'menu', 'context-menu', 'menubar', 'nav-menu', 'toolbar', 'breadcrumb'] }
|
|
149
|
-
{ label: 'Overlay', ids: ['dialog', 'alert-dialog', 'drawer', 'popover', 'tooltip', 'preview-card', 'toast'] }
|
|
150
|
-
{ label: 'Display', ids: ['button', 'badge', 'card', 'separator', 'progress', 'meter', 'spinner', 'skeleton', 'avatar', 'label', 'scroll-area'] }
|
|
151
|
-
{ label: 'Form', ids: ['field', 'fieldset', 'form', 'button-group'] }
|
|
152
|
-
{ label: 'Data', ids: ['grid', 'accordion', 'table', 'collapsible'] }
|
|
153
|
-
{ label: 'Interactive', ids: ['pagination', 'carousel', 'resizable'] }
|
|
154
|
-
]
|
|
155
|
-
_nameFor: (id) -> (tocData.find((c) -> c.id is id))?.name or id
|
|
156
|
-
_viewSource: (id) ->
|
|
157
|
-
entry = tocData.find((c) -> c.id is id)
|
|
158
|
-
return unless entry
|
|
159
|
-
sourceName = entry.name
|
|
160
|
-
sourceLines = entry.lines
|
|
161
|
-
resp = fetch! "#{id}.rip"
|
|
162
|
-
sourceCode = resp.text!
|
|
163
|
-
_closeSource: -> sourceCode = null
|
|
164
|
-
_ensureHljs: (cb) ->
|
|
165
|
-
if window.hljs then return cb()
|
|
166
|
-
link = document.createElement('link')
|
|
167
|
-
link.rel = 'stylesheet'
|
|
168
|
-
link.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css'
|
|
169
|
-
document.head.appendChild(link)
|
|
170
|
-
script = document.createElement('script')
|
|
171
|
-
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js'
|
|
172
|
-
script.onload = =>
|
|
173
|
-
fetch('hljs-rip.js').then((r) -> r.text()).then (src) =>
|
|
174
|
-
fn = new Function('return ' + src.replace(/[\s\S]*export default /, ''))()
|
|
175
|
-
hljs.registerLanguage 'rip', fn
|
|
176
|
-
cb()
|
|
177
|
-
document.head.appendChild(script)
|
|
178
|
-
_onFilter: (e) -> tocFilter = e.target.value
|
|
179
|
-
_getVisibleLinks: -> Array.from(document.querySelectorAll('.toc-nav .toc-group a:not([data-hidden])') or [])
|
|
180
|
-
|
|
181
|
-
_onFilterKey: (e) ->
|
|
182
|
-
if e.key is '/'
|
|
183
|
-
e.preventDefault()
|
|
184
|
-
@_navSection('', 'home')
|
|
185
|
-
tocFilter = ''
|
|
186
|
-
e.target.value = ''
|
|
187
|
-
document.addEventListener 'keyup', (=> e.target.focus()), { once: true }
|
|
188
|
-
return
|
|
189
|
-
if e.key is 'Escape'
|
|
190
|
-
tocFilter = ''
|
|
191
|
-
e.target.value = ''
|
|
192
|
-
else if e.key is 'Enter'
|
|
193
|
-
links = @_getVisibleLinks()
|
|
194
|
-
if links.length is 1
|
|
195
|
-
e.preventDefault()
|
|
196
|
-
tocActive = links[0].getAttribute('href')?.slice(1)
|
|
197
|
-
@_fadeTo(document.getElementById(tocActive))
|
|
198
|
-
tocFilter = ''
|
|
199
|
-
e.target.value = ''
|
|
200
|
-
else if e.key is 'Tab' and not e.shiftKey
|
|
201
|
-
links = @_getVisibleLinks()
|
|
202
|
-
if links.length
|
|
203
|
-
e.preventDefault()
|
|
204
|
-
tocActive = links[0].getAttribute('href')?.slice(1)
|
|
205
|
-
links[0].focus()
|
|
206
|
-
|
|
207
|
-
_getTocGrid: ->
|
|
208
|
-
groups = Array.from(document.querySelectorAll('.toc-nav .toc-group') or [])
|
|
209
|
-
grid = []
|
|
210
|
-
for grp in groups
|
|
211
|
-
col = Array.from(grp.querySelectorAll('a:not([data-hidden])') or [])
|
|
212
|
-
grid.push(col) if col.length
|
|
213
|
-
grid
|
|
214
|
-
|
|
215
|
-
_focusTocLink: (link) ->
|
|
216
|
-
tocActive = link.getAttribute('href')?.slice(1)
|
|
217
|
-
link.focus()
|
|
218
|
-
|
|
219
|
-
_onTocKeydown: (e) ->
|
|
220
|
-
grid = @_getTocGrid()
|
|
221
|
-
return unless grid.length
|
|
222
|
-
focused = document.activeElement
|
|
223
|
-
col = -1
|
|
224
|
-
row = -1
|
|
225
|
-
for c, ci in grid
|
|
226
|
-
ri = c.indexOf(focused)
|
|
227
|
-
if ri >= 0
|
|
228
|
-
col = ci
|
|
229
|
-
row = ri
|
|
230
|
-
break
|
|
231
|
-
return if col < 0
|
|
232
|
-
switch e.key
|
|
233
|
-
when 'ArrowDown'
|
|
234
|
-
e.preventDefault()
|
|
235
|
-
if row < grid[col].length - 1
|
|
236
|
-
@_focusTocLink(grid[col][row + 1])
|
|
237
|
-
else if col < grid.length - 1
|
|
238
|
-
@_focusTocLink(grid[col + 1][0])
|
|
239
|
-
when 'ArrowUp'
|
|
240
|
-
e.preventDefault()
|
|
241
|
-
if row > 0
|
|
242
|
-
@_focusTocLink(grid[col][row - 1])
|
|
243
|
-
else if col > 0
|
|
244
|
-
prev = grid[col - 1]
|
|
245
|
-
@_focusTocLink(prev[prev.length - 1])
|
|
246
|
-
else
|
|
247
|
-
@_root?.querySelector('.toc-search')?.focus()
|
|
248
|
-
when 'ArrowRight'
|
|
249
|
-
e.preventDefault()
|
|
250
|
-
if col < grid.length - 1
|
|
251
|
-
target = grid[col + 1]
|
|
252
|
-
@_focusTocLink(target[Math.min(row, target.length - 1)])
|
|
253
|
-
when 'ArrowLeft'
|
|
254
|
-
e.preventDefault()
|
|
255
|
-
if col > 0
|
|
256
|
-
target = grid[col - 1]
|
|
257
|
-
@_focusTocLink(target[Math.min(row, target.length - 1)])
|
|
258
|
-
when 'Home'
|
|
259
|
-
e.preventDefault()
|
|
260
|
-
@_focusTocLink(grid[0][0])
|
|
261
|
-
when 'End'
|
|
262
|
-
e.preventDefault()
|
|
263
|
-
last = grid[grid.length - 1]
|
|
264
|
-
@_focusTocLink(last[last.length - 1])
|
|
265
|
-
when 'Enter', ' '
|
|
266
|
-
e.preventDefault()
|
|
267
|
-
@_fadeTo(document.getElementById(tocActive))
|
|
268
|
-
when 'Escape'
|
|
269
|
-
@_root?.querySelector('.toc-search')?.focus()
|
|
270
|
-
|
|
271
|
-
~>
|
|
272
|
-
q = tocFilter.toLowerCase()
|
|
273
|
-
visible = []
|
|
274
|
-
for el in Array.from(document.querySelectorAll('.toc-nav a') or [])
|
|
275
|
-
if q and not el.textContent.toLowerCase().includes(q)
|
|
276
|
-
el.setAttribute('data-hidden', '')
|
|
277
|
-
else
|
|
278
|
-
el.removeAttribute('data-hidden')
|
|
279
|
-
visible.push(el) if q
|
|
280
|
-
if visible.length is 1
|
|
281
|
-
tocActive = visible[0].getAttribute('href')?.slice(1)
|
|
282
|
-
tocData := [
|
|
283
|
-
{ id: 'select', name: 'Select', lines: 147, desc: 'Dropdown with typeahead, keyboard nav, ARIA listbox.', props: ['@value', '@placeholder', '@disabled'], events: ['change'], keys: ['↕', 'Enter', 'Space', 'Esc', 'Home', 'End', 'type-ahead'], attrs: ['$open', '$placeholder', '$disabled', '$value', '$highlighted', '$selected'] }
|
|
284
|
-
{ id: 'combobox', name: 'Combobox', lines: 124, desc: 'Filterable input + listbox for search-as-you-type.', props: ['@query', '@items', '@placeholder', '@disabled', '@autoHighlight'], events: ['filter', 'select'], keys: ['↕', 'Enter', 'Esc', 'Tab'], attrs: ['$open', '$disabled', '$clear', '$value', '$highlighted', '$empty'] }
|
|
285
|
-
{ id: 'multi-select', name: 'MultiSelect', lines: 130, desc: 'Multi-select with chips, filtering, and keyboard nav.', props: ['@value', '@items', '@placeholder', '@disabled'], events: ['change'], keys: ['↕', 'Enter', 'Esc', 'Backspace', 'Tab'], attrs: ['$open', '$disabled', '$chips', '$chip', '$remove', '$clear', '$highlighted', '$selected'] }
|
|
286
|
-
{ id: 'autocomplete', name: 'Autocomplete', lines: 115, desc: 'Suggestion input — type to filter, select to fill.', props: ['@value', '@items', '@placeholder', '@disabled'], events: ['select'], keys: ['↕', 'Enter', 'Esc', 'Tab'], attrs: ['$open', '$disabled', '$clear'] }
|
|
287
|
-
{ id: 'checkbox', name: 'Checkbox', lines: 18, desc: 'Toggle with checkbox or switch semantics.', props: ['@checked', '@disabled', '@indeterminate', '@switch'], events: ['change'], keys: [], attrs: ['$checked', '$indeterminate', '$disabled'] }
|
|
288
|
-
{ id: 'toggle', name: 'Toggle', lines: 13, desc: 'Two-state toggle button with pressed state.', props: ['@pressed', '@disabled'], events: ['change'], keys: [], attrs: ['$pressed', '$disabled'] }
|
|
289
|
-
{ id: 'toggle-group', name: 'ToggleGroup', lines: 59, desc: 'Single or multi-select toggle buttons.', props: ['@value', '@disabled', '@multiple', '@orientation'], events: ['change'], keys: ['← →', '↕', 'Home', 'End'], attrs: ['$orientation', '$disabled', '$pressed', '$value'] }
|
|
290
|
-
{ id: 'radio-group', name: 'RadioGroup', lines: 50, desc: 'Exactly one option selected with arrow key nav.', props: ['@value', '@disabled', '@orientation', '@name'], events: ['change'], keys: ['← →', '↕', 'Home', 'End'], attrs: ['$orientation', '$disabled', '$checked', '$value'] }
|
|
291
|
-
{ id: 'checkbox-group', name: 'CheckboxGroup', lines: 46, desc: 'Multiple options checked independently.', props: ['@value', '@disabled', '@orientation', '@label'], events: ['change'], keys: ['← →', '↕'], attrs: ['$orientation', '$disabled', '$checked', '$value'] }
|
|
292
|
-
{ id: 'input', name: 'Input', lines: 24, desc: 'Headless input tracking focus, touch, and validation.', props: ['@value', '@placeholder', '@type', '@disabled', '@required'], events: [], keys: [], attrs: ['$disabled', '$focused', '$touched'] }
|
|
293
|
-
{ id: 'number-field', name: 'NumberField', lines: 132, desc: 'Number input with stepper buttons and hold-to-repeat.', props: ['@value', '@min', '@max', '@step', '@disabled', '@readOnly'], events: ['input', 'change'], keys: ['↕', 'PgUp', 'PgDn', 'Home', 'End'], attrs: ['$disabled', '$readonly', '$decrement', '$increment'] }
|
|
294
|
-
{ id: 'slider', name: 'Slider', lines: 130, desc: 'Draggable range input with pointer capture and keyboard.', props: ['@value', '@min', '@max', '@step', '@orientation', '@disabled'], events: ['input', 'change'], keys: ['← →', '↕', 'PgUp', 'PgDn', 'Home', 'End'], attrs: ['$orientation', '$disabled', '$dragging', '$track', '$indicator', '$thumb', '$active'] }
|
|
295
|
-
{ id: 'otp-field', name: 'OTPField', lines: 72, desc: 'Multi-digit code input with auto-advance and paste.', props: ['@length', '@value', '@disabled', '@mask'], events: ['input', 'complete'], keys: ['← →', 'Backspace', 'Home', 'End', 'paste'], attrs: ['$disabled', '$complete', '$filled'] }
|
|
296
|
-
{ id: 'date-picker', name: 'DatePicker', lines: 172, desc: 'Calendar dropdown for single date or range selection.', props: ['@value', '@placeholder', '@disabled', '@range', '@firstDayOfWeek'], events: ['change'], keys: ['Esc', 'Enter', 'Space'], attrs: ['$open', '$disabled', '$range', '$calendar', '$selected', '$today', '$in-range'] }
|
|
297
|
-
{ id: 'editable-value', name: 'EditableValue', lines: 58, desc: 'Click-to-edit inline value with popover form.', props: ['@disabled'], events: ['save'], keys: ['Esc', 'Enter'], attrs: ['$editing', '$disabled', '$saving', '$edit-trigger'] }
|
|
298
|
-
{ id: 'tabs', name: 'Tabs', lines: 91, desc: 'Tab panel with roving tabindex and arrow key nav.', props: ['@active', '@orientation', '@activation'], events: ['change'], keys: ['← →', '↕', 'Home', 'End', 'Enter', 'Space'], attrs: ['$tab', '$panel', '$active', '$disabled'] }
|
|
299
|
-
{ id: 'menu', name: 'Menu', lines: 133, desc: 'Dropdown action menu with keyboard navigation.', props: ['@disabled'], events: ['select'], keys: ['↕', 'Home', 'End', 'Enter', 'Space', 'Esc', 'Tab', 'type-ahead'], attrs: ['$open', '$disabled', '$highlighted', '$value'] }
|
|
300
|
-
{ id: 'context-menu', name: 'ContextMenu', lines: 80, desc: 'Right-click context menu with keyboard navigation.', props: ['@disabled'], events: ['select'], keys: ['↕', 'Home', 'End', 'Enter', 'Space', 'Esc', 'Tab'], attrs: ['$open', '$highlighted', '$disabled', '$value'] }
|
|
301
|
-
{ id: 'menubar', name: 'Menubar', lines: 125, desc: 'Horizontal menu bar with dropdown menus.', props: ['@disabled'], events: ['select'], keys: ['← →', '↕', 'Enter', 'Space', 'Esc', 'Tab'], attrs: ['$disabled', '$open', '$highlighted', '$value'] }
|
|
302
|
-
{ id: 'nav-menu', name: 'NavMenu', lines: 99, desc: 'Site navigation with hover/click dropdown panels.', props: ['@orientation', '@hoverDelay', '@hoverCloseDelay'], events: [], keys: ['← →', '↓', 'Esc'], attrs: ['$orientation', '$open'] }
|
|
303
|
-
{ id: 'toolbar', name: 'Toolbar', lines: 31, desc: 'Groups controls with roving tabindex keyboard nav.', props: ['@orientation', '@label'], events: [], keys: ['← →', '↕', 'Home', 'End'], attrs: ['$orientation'] }
|
|
304
|
-
{ id: 'dialog', name: 'Dialog', lines: 83, desc: 'Modal with focus trap, scroll lock, escape dismiss.', props: ['@open', '@dismissable', '@initialFocus'], events: ['close'], keys: ['Esc', 'Tab'], attrs: ['$open'] }
|
|
305
|
-
{ id: 'drawer', name: 'Drawer', lines: 60, desc: 'Slide-out panel with focus trap and scroll lock.', props: ['@open', '@side', '@dismissable'], events: ['close'], keys: ['Esc', 'Tab'], attrs: ['$open', '$side'] }
|
|
306
|
-
{ id: 'popover', name: 'Popover', lines: 117, desc: 'Anchored floating content with flip/shift positioning.', props: ['@placement', '@offset', '@disabled', '@openOnHover', '@hoverDelay', '@hoverCloseDelay'], events: [], keys: ['Esc', 'Enter', 'Space', '↓'], attrs: ['$open', '$placement'] }
|
|
307
|
-
{ id: 'tooltip', name: 'Tooltip', lines: 92, desc: 'Hover/focus tooltip with delay and positioning.', props: ['@text', '@placement', '@delay', '@offset', '@hoverable'], events: [], keys: [], attrs: ['$open', '$entering', '$exiting', '$placement'] }
|
|
308
|
-
{ id: 'preview-card', name: 'PreviewCard', lines: 56, desc: 'Hover/focus preview card with delay.', props: ['@delay', '@closeDelay'], events: [], keys: [], attrs: ['$open'] }
|
|
309
|
-
{ id: 'toast', name: 'Toast', lines: 56, desc: 'Auto-dismiss notification with ARIA live region.', props: ['@toasts', '@toast', '@placement'], events: ['dismiss'], keys: [], attrs: ['$placement', '$type', '$leaving'] }
|
|
310
|
-
{ id: 'button', name: 'Button', lines: 10, desc: 'Accessible button with disabled-but-focusable pattern.', props: ['@disabled'], events: ['press'], keys: [], attrs: ['$disabled'] }
|
|
311
|
-
{ id: 'separator', name: 'Separator', lines: 7, desc: 'Decorative or semantic divider between sections.', props: ['@orientation', '@decorative'], events: [], keys: [], attrs: ['$orientation'] }
|
|
312
|
-
{ id: 'progress', name: 'Progress', lines: 14, desc: 'Progress bar with CSS custom property for value.', props: ['@value', '@max', '@label'], events: [], keys: [], attrs: ['$complete'] }
|
|
313
|
-
{ id: 'meter', name: 'Meter', lines: 23, desc: 'Gauge for known-range measurements with thresholds.', props: ['@value', '@min', '@max', '@low', '@high', '@optimum', '@label'], events: [], keys: [], attrs: ['$level'] }
|
|
314
|
-
{ id: 'avatar', name: 'Avatar', lines: 23, desc: 'Image with fallback to initials or placeholder.', props: ['@src', '@alt', '@fallback'], events: [], keys: [], attrs: ['$status', '$initials', '$placeholder'] }
|
|
315
|
-
{ id: 'scroll-area', name: 'ScrollArea', lines: 115, desc: 'Custom scrollbar with draggable thumb and auto-hide.', props: ['@orientation'], events: [], keys: [], attrs: ['$orientation', '$hovering', '$scrolling', '$dragging', '$viewport', '$scrollbar', '$thumb'] }
|
|
316
|
-
{ id: 'field', name: 'Field', lines: 39, desc: 'Form field wrapper with label, description, and error.', props: ['@label', '@description', '@error', '@disabled', '@required'], events: [], keys: [], attrs: ['$disabled', '$invalid', '$label', '$required', '$description', '$error'] }
|
|
317
|
-
{ id: 'fieldset', name: 'Fieldset', lines: 9, desc: 'Grouped fields with legend and cascading disable.', props: ['@legend', '@disabled'], events: [], keys: [], attrs: ['$disabled', '$legend'] }
|
|
318
|
-
{ id: 'form', name: 'Form', lines: 21, desc: 'Form wrapper with submit handling and validation state.', props: ['@disabled'], events: ['submit'], keys: [], attrs: ['$disabled', '$submitting', '$submitted'] }
|
|
319
|
-
{ id: 'grid', name: 'Grid', lines: 799, desc: 'Virtual-scrolling data grid — 100K+ rows at 60fps.', props: ['@data', '@columns', '@rowHeight', '@overscan', '@striped', '@beforeEdit', '@afterEdit'], events: [], keys: ['Arrows', 'Tab', 'Enter', 'F2', 'Esc', 'Home', 'End', 'PgUp', 'PgDn', 'Ctrl+A', 'Ctrl+C', 'Ctrl+V', 'Ctrl+X'], attrs: ['$editing', '$selecting', '$sorted'] }
|
|
320
|
-
{ id: 'accordion', name: 'Accordion', lines: 86, desc: 'Expand/collapse sections, single or multiple mode.', props: ['@multiple'], events: ['change'], keys: ['Enter', 'Space', '↕', 'Home', 'End'], attrs: ['$item', '$trigger', '$content', '$open', '$disabled'] }
|
|
321
|
-
{ id: 'badge', name: 'Badge', lines: 5, desc: 'Inline label with variant (solid/outline/subtle).', props: ['@variant'], events: [], keys: [], attrs: ['$variant'] }
|
|
322
|
-
{ id: 'skeleton', name: 'Skeleton', lines: 10, desc: 'Loading placeholder with shimmer animation.', props: ['@width', '@height', '@circle', '@label'], events: [], keys: [], attrs: ['$circle'] }
|
|
323
|
-
{ id: 'spinner', name: 'Spinner', lines: 6, desc: 'Loading indicator with accessible status.', props: ['@label', '@size'], events: [], keys: [], attrs: [] }
|
|
324
|
-
{ id: 'card', name: 'Card', lines: 6, desc: 'Structured container with header/content/footer.', props: ['@interactive'], events: [], keys: [], attrs: ['$interactive'] }
|
|
325
|
-
{ id: 'label', name: 'Label', lines: 6, desc: 'Standalone accessible form label.', props: ['@for', '@required'], events: [], keys: [], attrs: ['$required'] }
|
|
326
|
-
{ id: 'textarea', name: 'Textarea', lines: 33, desc: 'Auto-resizing text area with focus and validation tracking.', props: ['@value', '@placeholder', '@disabled', '@required', '@rows', '@autoResize'], events: [], keys: [], attrs: ['$disabled', '$focused', '$touched'] }
|
|
327
|
-
{ id: 'native-select', name: 'NativeSelect', lines: 18, desc: 'Styled native select element with state tracking.', props: ['@value', '@disabled', '@required'], events: ['change'], keys: [], attrs: ['$disabled', '$focused'] }
|
|
328
|
-
{ id: 'input-group', name: 'InputGroup', lines: 11, desc: 'Input with prefix/suffix addon elements.', props: ['@disabled'], events: [], keys: [], attrs: ['$disabled', '$focused'] }
|
|
329
|
-
{ id: 'button-group', name: 'ButtonGroup', lines: 11, desc: 'Grouped buttons with ARIA group semantics.', props: ['@orientation', '@disabled', '@label'], events: [], keys: [], attrs: ['$orientation', '$disabled'] }
|
|
330
|
-
{ id: 'alert-dialog', name: 'AlertDialog', lines: 74, desc: 'Non-dismissable modal requiring explicit user action.', props: ['@open', '@initialFocus'], events: ['close'], keys: ['Tab'], attrs: ['$open'] }
|
|
331
|
-
{ id: 'breadcrumb', name: 'Breadcrumb', lines: 25, desc: 'Navigation trail with separator and current page.', props: ['@separator', '@label'], events: [], keys: [], attrs: ['$current'] }
|
|
332
|
-
{ id: 'table', name: 'Table', lines: 9, desc: 'Semantic table wrapper with optional caption and striped rows.', props: ['@caption', '@striped'], events: [], keys: [], attrs: ['$striped'] }
|
|
333
|
-
{ id: 'collapsible', name: 'Collapsible', lines: 33, desc: 'Single open/close section with animated expand.', props: ['@open', '@disabled'], events: ['change'], keys: ['Enter', 'Space'], attrs: ['$open', '$disabled'] }
|
|
334
|
-
{ id: 'pagination', name: 'Pagination', lines: 96, desc: 'Page navigation with prev/next and ellipsis gaps.', props: ['@page', '@total', '@perPage', '@siblingCount'], events: ['change'], keys: ['← →', 'Home', 'End'], attrs: ['$active', '$disabled', '$ellipsis'] }
|
|
335
|
-
{ id: 'carousel', name: 'Carousel', lines: 78, desc: 'Slide carousel with autoplay, loop, and keyboard nav.', props: ['@orientation', '@loop', '@autoplay', '@interval', '@label'], events: ['change'], keys: ['← →', '↕', 'Home', 'End'], attrs: ['$orientation', '$active', '$prev', '$next'] }
|
|
336
|
-
{ id: 'resizable', name: 'Resizable', lines: 89, desc: 'Draggable resize handles between panels.', props: ['@orientation', '@minSize', '@maxSize'], events: ['resize'], keys: ['← →', '↕'], attrs: ['$orientation', '$dragging'] }
|
|
337
|
-
]
|
|
338
|
-
_infoName := ''
|
|
339
|
-
_infoDesc := ''
|
|
340
|
-
_infoLines := 0
|
|
341
|
-
_infoProps := []
|
|
342
|
-
_infoEvents := []
|
|
343
|
-
_infoKeys := []
|
|
344
|
-
_infoAttrs := []
|
|
345
|
-
|
|
346
|
-
~>
|
|
347
|
-
info = tocData.find (c) -> c.id is tocActive
|
|
348
|
-
if info
|
|
349
|
-
_infoName = info.name
|
|
350
|
-
_infoDesc = info.desc
|
|
351
|
-
_infoLines = info.lines
|
|
352
|
-
_infoProps = info.props
|
|
353
|
-
_infoEvents = info.events
|
|
354
|
-
_infoKeys = info.keys
|
|
355
|
-
_infoAttrs = info.attrs
|
|
356
|
-
|
|
357
|
-
~>
|
|
358
|
-
raw = sourceCode
|
|
359
|
-
return unless raw
|
|
360
|
-
setTimeout =>
|
|
361
|
-
codeEl = document.querySelector('.source-code')
|
|
362
|
-
gutterEl = document.querySelector('.source-gutter')
|
|
363
|
-
return unless codeEl
|
|
364
|
-
text = raw.replace(/^\n+/, '').replace(/\n+$/, '')
|
|
365
|
-
lines = text.split('\n')
|
|
366
|
-
gutterEl.textContent = lines.map((_, i) -> String(i + 1)).join('\n') if gutterEl
|
|
367
|
-
codeEl.textContent = text
|
|
368
|
-
codeEl.className = 'source-code language-rip'
|
|
369
|
-
@_ensureHljs =>
|
|
370
|
-
hljs.highlightElement(codeEl) if window.hljs
|
|
371
|
-
, 0
|
|
372
|
-
|
|
373
|
-
~>
|
|
374
|
-
if sourceCode
|
|
375
|
-
onKey = (e) => @_closeSource() if e.key is 'Escape'
|
|
376
|
-
document.addEventListener 'keydown', onKey
|
|
377
|
-
return -> document.removeEventListener 'keydown', onKey
|
|
378
|
-
|
|
379
|
-
_toggleDark: ->
|
|
380
|
-
darkMode = not darkMode
|
|
381
|
-
document.documentElement.classList.add('no-transition')
|
|
382
|
-
document.documentElement.dataset.theme = if darkMode then 'dark' else ''
|
|
383
|
-
localStorage.setItem('rip-ui-theme', if darkMode then 'dark' else 'light')
|
|
384
|
-
requestAnimationFrame -> requestAnimationFrame -> document.documentElement.classList.remove('no-transition')
|
|
385
|
-
|
|
386
|
-
mounted: ->
|
|
387
|
-
if localStorage.getItem('rip-ui-theme') is 'dark'
|
|
388
|
-
darkMode = true
|
|
389
|
-
document.documentElement.dataset.theme = 'dark'
|
|
390
|
-
document.addEventListener 'keydown', (e) =>
|
|
391
|
-
if e.key is '/' and not (e.target.tagName in ['INPUT', 'TEXTAREA', 'SELECT']) and not e.target.isContentEditable
|
|
392
|
-
e.preventDefault()
|
|
393
|
-
@_navSection('', 'home')
|
|
394
|
-
tocFilter = ''
|
|
395
|
-
document.addEventListener 'keyup', (=>
|
|
396
|
-
@_root?.querySelector('.toc-search')?.focus()
|
|
397
|
-
), { once: true }
|
|
398
|
-
gc = document.querySelector('.grid-container')
|
|
399
|
-
if gc
|
|
400
|
-
gc.addEventListener 'mousedown', => setTimeout (=> @_updateGridRef()), 0
|
|
401
|
-
gc.addEventListener 'keyup', => setTimeout (=> @_updateGridRef()), 0
|
|
402
|
-
hash = location.hash.slice(1)
|
|
403
|
-
if hash and document.getElementById(hash)
|
|
404
|
-
tocActive = hash
|
|
405
|
-
setTimeout =>
|
|
406
|
-
document.getElementById(hash)?.scrollIntoView({ behavior: 'instant', block: 'start' })
|
|
407
|
-
document.body.classList.add('ready')
|
|
408
|
-
, 50
|
|
409
|
-
else
|
|
410
|
-
document.body.classList.add('ready')
|
|
411
|
-
|
|
412
|
-
gridCellRef := ''
|
|
413
|
-
|
|
414
|
-
_updateGridRef: ->
|
|
415
|
-
cell = document.querySelector('.grid-container td[data-active]')
|
|
416
|
-
if cell
|
|
417
|
-
tr = cell.parentElement
|
|
418
|
-
rowNum = tr?.firstElementChild?.textContent?.trim()
|
|
419
|
-
ci = Array.from(tr.children).indexOf(cell)
|
|
420
|
-
gridCellRef = if rowNum then "R#{rowNum}:C#{ci + 1}" else ''
|
|
421
|
-
else
|
|
422
|
-
gridCellRef = ''
|
|
423
|
-
|
|
424
|
-
_loadGridRows: (n) ->
|
|
425
|
-
firstNames = ['Alice', 'Bob', 'Carol', 'Dan', 'Eve', 'Frank', 'Grace', 'Hank', 'Iris', 'Jack', 'Karen', 'Leo', 'Mia', 'Nora', 'Omar', 'Pia', 'Quinn', 'Rosa', 'Sam', 'Tina']
|
|
426
|
-
lastNames = ['Chen', 'Park', 'Singh', 'Nakamura', 'Torres', 'Liu', 'Kim', 'Patel', 'Wang', 'Brown', 'Lee', 'Martin', 'Garcia', 'Davis', 'Lopez', 'Clark', 'Hall', 'Young', 'King', 'Wright']
|
|
427
|
-
roles = ['Engineer', 'Designer', 'Manager', 'Director', 'Analyst', 'Lead', 'Intern']
|
|
428
|
-
cityList = ['Seattle', 'Portland', 'Denver', 'Austin', 'Chicago', 'Boston', 'Miami', 'Phoenix', 'Dallas', 'Atlanta']
|
|
429
|
-
gc = document.querySelector('.grid-container')
|
|
430
|
-
gc?.scrollTop = 0
|
|
431
|
-
gridData = Array.from { length: n }, (_, idx) ->
|
|
432
|
-
fn = firstNames[idx %% firstNames.length]
|
|
433
|
-
ln = lastNames[Math.floor(Math.random() * lastNames.length)]
|
|
434
|
-
{ _row: idx + 1, name: "#{fn} #{ln}", role: roles[idx %% roles.length], age: 22 + (idx %% 40), city: cityList[idx %% cityList.length] }
|
|
435
|
-
gridCellRef = ''
|
|
436
|
-
|
|
437
|
-
gridColumns := [
|
|
438
|
-
{ key: '_row', title: '#', width: 60, align: 'right' },
|
|
439
|
-
{ key: 'name', title: 'Name', width: 180 },
|
|
440
|
-
{ key: 'role', title: 'Role', width: 140 },
|
|
441
|
-
{ key: 'age', title: 'Age', width: 80, align: 'right' },
|
|
442
|
-
{ key: 'city', title: 'City', width: 140 },
|
|
443
|
-
]
|
|
444
|
-
gridData := [
|
|
445
|
-
{ _row: 1, name: 'Alice Chen', role: 'Engineer', age: 28, city: 'Seattle' },
|
|
446
|
-
{ _row: 2, name: 'Bob Park', role: 'Designer', age: 34, city: 'Portland' },
|
|
447
|
-
{ _row: 3, name: 'Carol Singh', role: 'Manager', age: 41, city: 'Denver' },
|
|
448
|
-
{ _row: 4, name: 'Dan Nakamura', role: 'Engineer', age: 26, city: 'Austin' },
|
|
449
|
-
{ _row: 5, name: 'Eve Torres', role: 'Director', age: 45, city: 'Chicago' },
|
|
450
|
-
{ _row: 6, name: 'Frank Liu', role: 'Designer', age: 31, city: 'Boston' },
|
|
451
|
-
{ _row: 7, name: 'Grace Kim', role: 'Engineer', age: 29, city: 'Seattle' },
|
|
452
|
-
{ _row: 8, name: 'Hank Patel', role: 'Manager', age: 38, city: 'Denver' },
|
|
453
|
-
{ _row: 9, name: 'Iris Wang', role: 'Engineer', age: 33, city: 'Austin' },
|
|
454
|
-
{ _row: 10, name: 'Jack Brown', role: 'Designer', age: 27, city: 'Portland' },
|
|
455
|
-
{ _row: 11, name: 'Karen Lee', role: 'Director', age: 52, city: 'Chicago' },
|
|
456
|
-
{ _row: 12, name: 'Leo Martin', role: 'Engineer', age: 24, city: 'Boston' },
|
|
457
|
-
]
|
|
458
|
-
|
|
459
|
-
sectionIds =! ['select', 'combobox', 'multi-select', 'autocomplete', 'checkbox', 'toggle', 'toggle-group', 'radio-group', 'checkbox-group', 'input', 'textarea', 'native-select', 'number-field', 'slider', 'otp-field', 'date-picker', 'editable-value', 'input-group', 'tabs', 'menu', 'context-menu', 'menubar', 'nav-menu', 'toolbar', 'breadcrumb', 'dialog', 'alert-dialog', 'drawer', 'popover', 'tooltip', 'preview-card', 'toast', 'button', 'badge', 'card', 'separator', 'progress', 'meter', 'spinner', 'skeleton', 'avatar', 'label', 'scroll-area', 'field', 'form', 'button-group', 'grid', 'accordion', 'table', 'collapsible', 'pagination', 'carousel', 'resizable']
|
|
460
|
-
|
|
461
|
-
_fadeTo: (el) ->
|
|
462
|
-
return unless el
|
|
463
|
-
gallery = document.querySelector('.gallery')
|
|
464
|
-
gallery.style.transition = 'opacity 80ms ease-out'
|
|
465
|
-
gallery.style.opacity = '0'
|
|
466
|
-
setTimeout =>
|
|
467
|
-
el.scrollIntoView({ behavior: 'instant', block: 'start' })
|
|
468
|
-
history.replaceState(null, '', '#' + el.id) if el.id
|
|
469
|
-
gallery.style.transition = 'opacity 120ms ease-in'
|
|
470
|
-
gallery.style.opacity = '1'
|
|
471
|
-
, 80
|
|
472
|
-
|
|
473
|
-
_jumpTo: (e) ->
|
|
474
|
-
e.preventDefault()
|
|
475
|
-
@_fadeTo(document.getElementById(tocActive))
|
|
476
|
-
|
|
477
|
-
_navSection: (currentId, dir) ->
|
|
478
|
-
if dir is 'home'
|
|
479
|
-
gallery = document.querySelector('.gallery')
|
|
480
|
-
gallery.style.transition = 'opacity 80ms ease-out'
|
|
481
|
-
gallery.style.opacity = '0'
|
|
482
|
-
setTimeout =>
|
|
483
|
-
window.scrollTo({ top: 0, behavior: 'instant' })
|
|
484
|
-
history.replaceState(null, '', location.pathname)
|
|
485
|
-
gallery.style.transition = 'opacity 120ms ease-in'
|
|
486
|
-
gallery.style.opacity = '1'
|
|
487
|
-
, 80
|
|
488
|
-
return
|
|
489
|
-
idx = sectionIds.indexOf(currentId)
|
|
490
|
-
return if idx < 0
|
|
491
|
-
nextId = sectionIds[if dir is 'prev' then idx - 1 else idx + 1]
|
|
492
|
-
@_fadeTo(document.getElementById(nextId)) if nextId
|
|
493
|
-
|
|
494
|
-
render
|
|
495
|
-
.gallery
|
|
496
|
-
|
|
497
|
-
.gallery-header
|
|
498
|
-
.
|
|
499
|
-
h1 "Rip UI"
|
|
500
|
-
button.theme-toggle @click: (=> @_toggleDark())
|
|
501
|
-
if darkMode then "☀" else "☾"
|
|
502
|
-
p "54 headless, accessible components. Zero CSS, zero dependencies."
|
|
503
|
-
|
|
504
|
-
.toc
|
|
505
|
-
.toc-nav @keydown: @_onTocKeydown
|
|
506
|
-
input.toc-search type: "text", placeholder: "Filter components...", @input: @_onFilter, @keydown: @_onFilterKey
|
|
507
|
-
.toc-group
|
|
508
|
-
.toc-label "Selection"
|
|
509
|
-
a @mouseenter: (=> tocActive = 'select'), @click: (=> tocActive = 'select'), href: "#select", $active: (tocActive is 'select')?!, "Select"
|
|
510
|
-
a @mouseenter: (=> tocActive = 'combobox'), @click: (=> tocActive = 'combobox'), href: "#combobox", $active: (tocActive is 'combobox')?!, "Combobox"
|
|
511
|
-
a @mouseenter: (=> tocActive = 'multi-select'), @click: (=> tocActive = 'multi-select'), href: "#multi-select", $active: (tocActive is 'multi-select')?!, "MultiSelect"
|
|
512
|
-
a @mouseenter: (=> tocActive = 'autocomplete'), @click: (=> tocActive = 'autocomplete'), href: "#autocomplete", $active: (tocActive is 'autocomplete')?!, "Autocomplete"
|
|
513
|
-
.toc-group
|
|
514
|
-
.toc-label "Toggle"
|
|
515
|
-
a @mouseenter: (=> tocActive = 'checkbox'), @click: (=> tocActive = 'checkbox'), href: "#checkbox", $active: (tocActive is 'checkbox')?!, "Checkbox"
|
|
516
|
-
a @mouseenter: (=> tocActive = 'toggle'), @click: (=> tocActive = 'toggle'), href: "#toggle", $active: (tocActive is 'toggle')?!, "Toggle"
|
|
517
|
-
a @mouseenter: (=> tocActive = 'toggle-group'), @click: (=> tocActive = 'toggle-group'), href: "#toggle-group", $active: (tocActive is 'toggle-group')?!, "ToggleGroup"
|
|
518
|
-
a @mouseenter: (=> tocActive = 'radio-group'), @click: (=> tocActive = 'radio-group'), href: "#radio-group", $active: (tocActive is 'radio-group')?!, "RadioGroup"
|
|
519
|
-
a @mouseenter: (=> tocActive = 'checkbox-group'), @click: (=> tocActive = 'checkbox-group'), href: "#checkbox-group", $active: (tocActive is 'checkbox-group')?!, "CheckboxGroup"
|
|
520
|
-
.toc-group
|
|
521
|
-
.toc-label "Input"
|
|
522
|
-
a @mouseenter: (=> tocActive = 'input'), @click: (=> tocActive = 'input'), href: "#input", $active: (tocActive is 'input')?!, "Input"
|
|
523
|
-
a @mouseenter: (=> tocActive = 'textarea'), @click: (=> tocActive = 'textarea'), href: "#textarea", $active: (tocActive is 'textarea')?!, "Textarea"
|
|
524
|
-
a @mouseenter: (=> tocActive = 'native-select'), @click: (=> tocActive = 'native-select'), href: "#native-select", $active: (tocActive is 'native-select')?!, "NativeSelect"
|
|
525
|
-
a @mouseenter: (=> tocActive = 'number-field'), @click: (=> tocActive = 'number-field'), href: "#number-field", $active: (tocActive is 'number-field')?!, "NumberField"
|
|
526
|
-
a @mouseenter: (=> tocActive = 'slider'), @click: (=> tocActive = 'slider'), href: "#slider", $active: (tocActive is 'slider')?!, "Slider"
|
|
527
|
-
a @mouseenter: (=> tocActive = 'otp-field'), @click: (=> tocActive = 'otp-field'), href: "#otp-field", $active: (tocActive is 'otp-field')?!, "OTPField"
|
|
528
|
-
a @mouseenter: (=> tocActive = 'date-picker'), @click: (=> tocActive = 'date-picker'), href: "#date-picker", $active: (tocActive is 'date-picker')?!, "DatePicker"
|
|
529
|
-
a @mouseenter: (=> tocActive = 'editable-value'), @click: (=> tocActive = 'editable-value'), href: "#editable-value", $active: (tocActive is 'editable-value')?!, "EditableValue"
|
|
530
|
-
a @mouseenter: (=> tocActive = 'input-group'), @click: (=> tocActive = 'input-group'), href: "#input-group", $active: (tocActive is 'input-group')?!, "InputGroup"
|
|
531
|
-
.toc-group
|
|
532
|
-
.toc-label "Navigation"
|
|
533
|
-
a @mouseenter: (=> tocActive = 'tabs'), @click: (=> tocActive = 'tabs'), href: "#tabs", $active: (tocActive is 'tabs')?!, "Tabs"
|
|
534
|
-
a @mouseenter: (=> tocActive = 'menu'), @click: (=> tocActive = 'menu'), href: "#menu", $active: (tocActive is 'menu')?!, "Menu"
|
|
535
|
-
a @mouseenter: (=> tocActive = 'context-menu'), @click: (=> tocActive = 'context-menu'), href: "#context-menu", $active: (tocActive is 'context-menu')?!, "ContextMenu"
|
|
536
|
-
a @mouseenter: (=> tocActive = 'menubar'), @click: (=> tocActive = 'menubar'), href: "#menubar", $active: (tocActive is 'menubar')?!, "Menubar"
|
|
537
|
-
a @mouseenter: (=> tocActive = 'nav-menu'), @click: (=> tocActive = 'nav-menu'), href: "#nav-menu", $active: (tocActive is 'nav-menu')?!, "NavMenu"
|
|
538
|
-
a @mouseenter: (=> tocActive = 'toolbar'), @click: (=> tocActive = 'toolbar'), href: "#toolbar", $active: (tocActive is 'toolbar')?!, "Toolbar"
|
|
539
|
-
a @mouseenter: (=> tocActive = 'breadcrumb'), @click: (=> tocActive = 'breadcrumb'), href: "#breadcrumb", $active: (tocActive is 'breadcrumb')?!, "Breadcrumb"
|
|
540
|
-
.toc-group
|
|
541
|
-
.toc-label "Overlay"
|
|
542
|
-
a @mouseenter: (=> tocActive = 'dialog'), @click: (=> tocActive = 'dialog'), href: "#dialog", $active: (tocActive is 'dialog')?!, "Dialog"
|
|
543
|
-
a @mouseenter: (=> tocActive = 'alert-dialog'), @click: (=> tocActive = 'alert-dialog'), href: "#alert-dialog", $active: (tocActive is 'alert-dialog')?!, "AlertDialog"
|
|
544
|
-
a @mouseenter: (=> tocActive = 'drawer'), @click: (=> tocActive = 'drawer'), href: "#drawer", $active: (tocActive is 'drawer')?!, "Drawer"
|
|
545
|
-
a @mouseenter: (=> tocActive = 'popover'), @click: (=> tocActive = 'popover'), href: "#popover", $active: (tocActive is 'popover')?!, "Popover"
|
|
546
|
-
a @mouseenter: (=> tocActive = 'tooltip'), @click: (=> tocActive = 'tooltip'), href: "#tooltip", $active: (tocActive is 'tooltip')?!, "Tooltip"
|
|
547
|
-
a @mouseenter: (=> tocActive = 'preview-card'), @click: (=> tocActive = 'preview-card'), href: "#preview-card", $active: (tocActive is 'preview-card')?!, "PreviewCard"
|
|
548
|
-
a @mouseenter: (=> tocActive = 'toast'), @click: (=> tocActive = 'toast'), href: "#toast", $active: (tocActive is 'toast')?!, "Toast"
|
|
549
|
-
.toc-group
|
|
550
|
-
.toc-label "Display"
|
|
551
|
-
a @mouseenter: (=> tocActive = 'button'), @click: (=> tocActive = 'button'), href: "#button", $active: (tocActive is 'button')?!, "Button"
|
|
552
|
-
a @mouseenter: (=> tocActive = 'badge'), @click: (=> tocActive = 'badge'), href: "#badge", $active: (tocActive is 'badge')?!, "Badge"
|
|
553
|
-
a @mouseenter: (=> tocActive = 'card'), @click: (=> tocActive = 'card'), href: "#card", $active: (tocActive is 'card')?!, "Card"
|
|
554
|
-
a @mouseenter: (=> tocActive = 'separator'), @click: (=> tocActive = 'separator'), href: "#separator", $active: (tocActive is 'separator')?!, "Separator"
|
|
555
|
-
a @mouseenter: (=> tocActive = 'progress'), @click: (=> tocActive = 'progress'), href: "#progress", $active: (tocActive is 'progress')?!, "Progress"
|
|
556
|
-
a @mouseenter: (=> tocActive = 'meter'), @click: (=> tocActive = 'meter'), href: "#meter", $active: (tocActive is 'meter')?!, "Meter"
|
|
557
|
-
a @mouseenter: (=> tocActive = 'spinner'), @click: (=> tocActive = 'spinner'), href: "#spinner", $active: (tocActive is 'spinner')?!, "Spinner"
|
|
558
|
-
a @mouseenter: (=> tocActive = 'skeleton'), @click: (=> tocActive = 'skeleton'), href: "#skeleton", $active: (tocActive is 'skeleton')?!, "Skeleton"
|
|
559
|
-
a @mouseenter: (=> tocActive = 'avatar'), @click: (=> tocActive = 'avatar'), href: "#avatar", $active: (tocActive is 'avatar')?!, "Avatar"
|
|
560
|
-
a @mouseenter: (=> tocActive = 'label'), @click: (=> tocActive = 'label'), href: "#label", $active: (tocActive is 'label')?!, "Label"
|
|
561
|
-
a @mouseenter: (=> tocActive = 'scroll-area'), @click: (=> tocActive = 'scroll-area'), href: "#scroll-area", $active: (tocActive is 'scroll-area')?!, "ScrollArea"
|
|
562
|
-
.toc-group
|
|
563
|
-
.toc-label "Form"
|
|
564
|
-
a @mouseenter: (=> tocActive = 'field'), @click: (=> tocActive = 'field'), href: "#field", $active: (tocActive is 'field')?!, "Field"
|
|
565
|
-
a @mouseenter: (=> tocActive = 'fieldset'), @click: (=> tocActive = 'fieldset'), href: "#fieldset", $active: (tocActive is 'fieldset')?!, "Fieldset"
|
|
566
|
-
a @mouseenter: (=> tocActive = 'form'), @click: (=> tocActive = 'form'), href: "#form", $active: (tocActive is 'form')?!, "Form"
|
|
567
|
-
a @mouseenter: (=> tocActive = 'button-group'), @click: (=> tocActive = 'button-group'), href: "#button-group", $active: (tocActive is 'button-group')?!, "ButtonGroup"
|
|
568
|
-
.toc-group
|
|
569
|
-
.toc-label "Data"
|
|
570
|
-
a @mouseenter: (=> tocActive = 'grid'), @click: (=> tocActive = 'grid'), href: "#grid", $active: (tocActive is 'grid')?!, "Grid"
|
|
571
|
-
a @mouseenter: (=> tocActive = 'accordion'), @click: (=> tocActive = 'accordion'), href: "#accordion", $active: (tocActive is 'accordion')?!, "Accordion"
|
|
572
|
-
a @mouseenter: (=> tocActive = 'table'), @click: (=> tocActive = 'table'), href: "#table", $active: (tocActive is 'table')?!, "Table"
|
|
573
|
-
a @mouseenter: (=> tocActive = 'collapsible'), @click: (=> tocActive = 'collapsible'), href: "#collapsible", $active: (tocActive is 'collapsible')?!, "Collapsible"
|
|
574
|
-
.toc-group
|
|
575
|
-
.toc-label "Interactive"
|
|
576
|
-
a @mouseenter: (=> tocActive = 'pagination'), @click: (=> tocActive = 'pagination'), href: "#pagination", $active: (tocActive is 'pagination')?!, "Pagination"
|
|
577
|
-
a @mouseenter: (=> tocActive = 'carousel'), @click: (=> tocActive = 'carousel'), href: "#carousel", $active: (tocActive is 'carousel')?!, "Carousel"
|
|
578
|
-
a @mouseenter: (=> tocActive = 'resizable'), @click: (=> tocActive = 'resizable'), href: "#resizable", $active: (tocActive is 'resizable')?!, "Resizable"
|
|
579
|
-
.toc-detail
|
|
580
|
-
if tocActive
|
|
581
|
-
.
|
|
582
|
-
h3
|
|
583
|
-
_infoName
|
|
584
|
-
span.badge @click: (=> @_viewSource(tocActive)), "#{_infoLines} lines ❐"
|
|
585
|
-
p.toc-desc _infoDesc
|
|
586
|
-
.api
|
|
587
|
-
dl
|
|
588
|
-
dt "Props"
|
|
589
|
-
dd
|
|
590
|
-
for item in _infoProps
|
|
591
|
-
code item
|
|
592
|
-
if _infoEvents.length
|
|
593
|
-
dt "Events"
|
|
594
|
-
dd
|
|
595
|
-
for item in _infoEvents
|
|
596
|
-
code item
|
|
597
|
-
if _infoKeys.length
|
|
598
|
-
dt "Keyboard"
|
|
599
|
-
dd
|
|
600
|
-
for item in _infoKeys
|
|
601
|
-
kbd item
|
|
602
|
-
dt "Data"
|
|
603
|
-
dd
|
|
604
|
-
for item in _infoAttrs
|
|
605
|
-
code item
|
|
606
|
-
a.jump href: "##{tocActive}", @click: ((e) => @_jumpTo(e))
|
|
607
|
-
"Jump to demo ↓"
|
|
608
|
-
else
|
|
609
|
-
.toc-empty "← Hover a component to see its API"
|
|
610
|
-
|
|
611
|
-
# ========================================================================
|
|
612
|
-
# SELECT
|
|
613
|
-
# ========================================================================
|
|
614
|
-
.section id: "select"
|
|
615
|
-
SectionHead tag: "select", name: "Select", lines: 147
|
|
616
|
-
.section-desc "Dropdown with typeahead, keyboard nav, ARIA listbox."
|
|
617
|
-
.demo-row
|
|
618
|
-
.demo-label "Basic select"
|
|
619
|
-
Select value <=> fruit, @change: (=> null)
|
|
620
|
-
for f in allFruits
|
|
621
|
-
option value: f.toLowerCase(), f
|
|
622
|
-
.status "selected: #{fruit ?? 'none'}"
|
|
623
|
-
.demo-row
|
|
624
|
-
.demo-label "With placeholder"
|
|
625
|
-
Select value <=> role, placeholder: "Choose a role..."
|
|
626
|
-
option value: "eng", "Engineer"
|
|
627
|
-
option value: "des", "Designer"
|
|
628
|
-
option value: "mgr", "Manager"
|
|
629
|
-
option value: "dir", "Director"
|
|
630
|
-
.status "selected: #{role ?? 'none'}"
|
|
631
|
-
.api
|
|
632
|
-
dl
|
|
633
|
-
dt "Props"
|
|
634
|
-
dd
|
|
635
|
-
code "@value"
|
|
636
|
-
code "@placeholder"
|
|
637
|
-
code "@disabled"
|
|
638
|
-
dt "Events"
|
|
639
|
-
dd
|
|
640
|
-
code "change"
|
|
641
|
-
dt "Keyboard"
|
|
642
|
-
dd
|
|
643
|
-
kbd "↕"
|
|
644
|
-
kbd "Enter"
|
|
645
|
-
kbd "Space"
|
|
646
|
-
kbd "Esc"
|
|
647
|
-
kbd "Home"
|
|
648
|
-
kbd "End"
|
|
649
|
-
kbd "type-ahead"
|
|
650
|
-
dt "Data"
|
|
651
|
-
dd
|
|
652
|
-
code "$open"
|
|
653
|
-
code "$placeholder"
|
|
654
|
-
code "$disabled"
|
|
655
|
-
code "$value"
|
|
656
|
-
code "$highlighted"
|
|
657
|
-
code "$selected"
|
|
658
|
-
|
|
659
|
-
# ========================================================================
|
|
660
|
-
# COMBOBOX
|
|
661
|
-
# ========================================================================
|
|
662
|
-
.section id: "combobox"
|
|
663
|
-
SectionHead tag: "combobox", name: "Combobox", lines: 124
|
|
664
|
-
.section-desc "Filterable input + listbox for search-as-you-type."
|
|
665
|
-
.demo-row
|
|
666
|
-
.demo-label "Search fruits"
|
|
667
|
-
Combobox query <=> searchQuery, items: filteredFruits, placeholder: "Type to search..."
|
|
668
|
-
@select: (e) => (searchQuery = e.detail if e.detail?; filteredFruits = allFruits)
|
|
669
|
-
@filter: (=> filteredFruits = allFruits.filter (f) -> f.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
670
|
-
.status "query: '#{searchQuery}'"
|
|
671
|
-
.api
|
|
672
|
-
dl
|
|
673
|
-
dt "Props"
|
|
674
|
-
dd
|
|
675
|
-
code "@query"
|
|
676
|
-
code "@items"
|
|
677
|
-
code "@placeholder"
|
|
678
|
-
code "@disabled"
|
|
679
|
-
code "@autoHighlight"
|
|
680
|
-
dt "Events"
|
|
681
|
-
dd
|
|
682
|
-
code "filter"
|
|
683
|
-
code "select"
|
|
684
|
-
dt "Keyboard"
|
|
685
|
-
dd
|
|
686
|
-
kbd "↕"
|
|
687
|
-
kbd "Enter"
|
|
688
|
-
kbd "Esc"
|
|
689
|
-
kbd "Tab"
|
|
690
|
-
dt "Data"
|
|
691
|
-
dd
|
|
692
|
-
code "$open"
|
|
693
|
-
code "$disabled"
|
|
694
|
-
code "$clear"
|
|
695
|
-
code "$value"
|
|
696
|
-
code "$highlighted"
|
|
697
|
-
code "$empty"
|
|
698
|
-
|
|
699
|
-
# ========================================================================
|
|
700
|
-
# MULTI-SELECT
|
|
701
|
-
# ========================================================================
|
|
702
|
-
.section id: "multi-select"
|
|
703
|
-
SectionHead tag: "multi-select", name: "MultiSelect", lines: 130
|
|
704
|
-
.section-desc "Multi-select with chips, filtering, and keyboard navigation."
|
|
705
|
-
.demo-row
|
|
706
|
-
.demo-label "Pick colors"
|
|
707
|
-
MultiSelect value <=> selectedColors, items: ['Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet'], placeholder: "Choose colors..."
|
|
708
|
-
.status "selected: #{selectedColors.join(', ')}"
|
|
709
|
-
.api
|
|
710
|
-
dl
|
|
711
|
-
dt "Props"
|
|
712
|
-
dd
|
|
713
|
-
code "@value"
|
|
714
|
-
code "@items"
|
|
715
|
-
code "@placeholder"
|
|
716
|
-
code "@disabled"
|
|
717
|
-
dt "Events"
|
|
718
|
-
dd
|
|
719
|
-
code "change"
|
|
720
|
-
dt "Keyboard"
|
|
721
|
-
dd
|
|
722
|
-
kbd "↕"
|
|
723
|
-
kbd "Enter"
|
|
724
|
-
kbd "Esc"
|
|
725
|
-
kbd "Backspace"
|
|
726
|
-
kbd "Tab"
|
|
727
|
-
dt "Data"
|
|
728
|
-
dd
|
|
729
|
-
code "$open"
|
|
730
|
-
code "$disabled"
|
|
731
|
-
code "$chips"
|
|
732
|
-
code "$chip"
|
|
733
|
-
code "$remove"
|
|
734
|
-
code "$clear"
|
|
735
|
-
code "$highlighted"
|
|
736
|
-
code "$selected"
|
|
737
|
-
|
|
738
|
-
# ========================================================================
|
|
739
|
-
# AUTOCOMPLETE
|
|
740
|
-
# ========================================================================
|
|
741
|
-
.section id: "autocomplete"
|
|
742
|
-
SectionHead tag: "autocomplete", name: "Autocomplete", lines: 115
|
|
743
|
-
.section-desc "Suggestion input — type to filter, select to fill."
|
|
744
|
-
.demo-row
|
|
745
|
-
.demo-label "Search cities"
|
|
746
|
-
Autocomplete value <=> citySearch, items: cities
|
|
747
|
-
.status "value: #{citySearch}"
|
|
748
|
-
.api
|
|
749
|
-
dl
|
|
750
|
-
dt "Props"
|
|
751
|
-
dd
|
|
752
|
-
code "@value"
|
|
753
|
-
code "@items"
|
|
754
|
-
code "@placeholder"
|
|
755
|
-
code "@disabled"
|
|
756
|
-
dt "Events"
|
|
757
|
-
dd
|
|
758
|
-
code "select"
|
|
759
|
-
dt "Keyboard"
|
|
760
|
-
dd
|
|
761
|
-
kbd "↕"
|
|
762
|
-
kbd "Enter"
|
|
763
|
-
kbd "Esc"
|
|
764
|
-
kbd "Tab"
|
|
765
|
-
dt "Data"
|
|
766
|
-
dd
|
|
767
|
-
code "$open"
|
|
768
|
-
code "$disabled"
|
|
769
|
-
code "$clear"
|
|
770
|
-
|
|
771
|
-
# ========================================================================
|
|
772
|
-
# CHECKBOX
|
|
773
|
-
# ========================================================================
|
|
774
|
-
.section id: "checkbox"
|
|
775
|
-
SectionHead tag: "checkbox", name: "Checkbox", lines: 18
|
|
776
|
-
.section-desc "Toggle with checkbox or switch semantics. Supports indeterminate."
|
|
777
|
-
.demo-row
|
|
778
|
-
.demo-label "Checkbox (unchecked)"
|
|
779
|
-
Checkbox checked <=> check1, @change: (=> p "Clicked!")
|
|
780
|
-
"Enable notifications"
|
|
781
|
-
.status "checked: #{check1}"
|
|
782
|
-
.demo-row
|
|
783
|
-
.demo-label "Checkbox (pre-checked)"
|
|
784
|
-
Checkbox checked <=> check2
|
|
785
|
-
"Accept terms"
|
|
786
|
-
.status "checked: #{check2}"
|
|
787
|
-
.demo-row
|
|
788
|
-
.demo-label "Switch variant"
|
|
789
|
-
Checkbox checked <=> switch1, switch: true
|
|
790
|
-
"Dark mode"
|
|
791
|
-
.status "on: #{switch1}"
|
|
792
|
-
.api
|
|
793
|
-
dl
|
|
794
|
-
dt "Props"
|
|
795
|
-
dd
|
|
796
|
-
code "@checked"
|
|
797
|
-
code "@disabled"
|
|
798
|
-
code "@indeterminate"
|
|
799
|
-
code "@switch"
|
|
800
|
-
dt "Events"
|
|
801
|
-
dd
|
|
802
|
-
code "change"
|
|
803
|
-
dt "Data"
|
|
804
|
-
dd
|
|
805
|
-
code "$checked"
|
|
806
|
-
code "$indeterminate"
|
|
807
|
-
code "$disabled"
|
|
808
|
-
|
|
809
|
-
# ========================================================================
|
|
810
|
-
# TOGGLE
|
|
811
|
-
# ========================================================================
|
|
812
|
-
.section id: "toggle"
|
|
813
|
-
SectionHead tag: "toggle", name: "Toggle", lines: 13
|
|
814
|
-
.section-desc "Stateful toggle button with pressed state."
|
|
815
|
-
.demo-row
|
|
816
|
-
.demo-label "Tap to toggle"
|
|
817
|
-
.toggle-heart
|
|
818
|
-
Toggle pressed <=> isBold
|
|
819
|
-
span.heart (if isBold then "♥" else "♡")
|
|
820
|
-
.api
|
|
821
|
-
dl
|
|
822
|
-
dt "Props"
|
|
823
|
-
dd
|
|
824
|
-
code "@pressed"
|
|
825
|
-
code "@disabled"
|
|
826
|
-
dt "Events"
|
|
827
|
-
dd
|
|
828
|
-
code "change"
|
|
829
|
-
dt "Data"
|
|
830
|
-
dd
|
|
831
|
-
code "$pressed"
|
|
832
|
-
code "$disabled"
|
|
833
|
-
|
|
834
|
-
# ========================================================================
|
|
835
|
-
# TOGGLE GROUP
|
|
836
|
-
# ========================================================================
|
|
837
|
-
.section id: "toggle-group"
|
|
838
|
-
SectionHead tag: "toggle-group", name: "ToggleGroup", lines: 59
|
|
839
|
-
.section-desc "Single or multi-select toggle buttons."
|
|
840
|
-
.demo-row
|
|
841
|
-
.demo-label "Text alignment"
|
|
842
|
-
ToggleGroup value <=> alignment
|
|
843
|
-
div $value: "left", "Left"
|
|
844
|
-
div $value: "center", "Center"
|
|
845
|
-
div $value: "right", "Right"
|
|
846
|
-
.status "alignment: #{alignment ?? 'none'}"
|
|
847
|
-
.demo-row
|
|
848
|
-
.demo-label "Multi-select"
|
|
849
|
-
ToggleGroup value <=> toppings, multiple: true
|
|
850
|
-
div $value: "Cheese", "Cheese"
|
|
851
|
-
div $value: "Bacon", "Bacon"
|
|
852
|
-
div $value: "Lettuce", "Lettuce"
|
|
853
|
-
.status "toppings: #{toppings.join(', ')}"
|
|
854
|
-
.api
|
|
855
|
-
dl
|
|
856
|
-
dt "Props"
|
|
857
|
-
dd
|
|
858
|
-
code "@value"
|
|
859
|
-
code "@disabled"
|
|
860
|
-
code "@multiple"
|
|
861
|
-
code "@orientation"
|
|
862
|
-
dt "Events"
|
|
863
|
-
dd
|
|
864
|
-
code "change"
|
|
865
|
-
dt "Keyboard"
|
|
866
|
-
dd
|
|
867
|
-
kbd "← →"
|
|
868
|
-
kbd "↕"
|
|
869
|
-
kbd "Home"
|
|
870
|
-
kbd "End"
|
|
871
|
-
dt "Data"
|
|
872
|
-
dd
|
|
873
|
-
code "$orientation"
|
|
874
|
-
code "$disabled"
|
|
875
|
-
code "$pressed"
|
|
876
|
-
code "$value"
|
|
877
|
-
|
|
878
|
-
# ========================================================================
|
|
879
|
-
# RADIO GROUP
|
|
880
|
-
# ========================================================================
|
|
881
|
-
.section id: "radio-group"
|
|
882
|
-
SectionHead tag: "radio-group", name: "RadioGroup", lines: 50
|
|
883
|
-
.section-desc "Exactly one option selected. Arrow keys move focus and selection."
|
|
884
|
-
.demo-row
|
|
885
|
-
.demo-label "Font size"
|
|
886
|
-
RadioGroup value <=> fontSize
|
|
887
|
-
div $value: "sm", "Small"
|
|
888
|
-
div $value: "md", "Medium"
|
|
889
|
-
div $value: "lg", "Large"
|
|
890
|
-
.status "fontSize: #{fontSize ?? 'none'}"
|
|
891
|
-
.api
|
|
892
|
-
dl
|
|
893
|
-
dt "Props"
|
|
894
|
-
dd
|
|
895
|
-
code "@value"
|
|
896
|
-
code "@disabled"
|
|
897
|
-
code "@orientation"
|
|
898
|
-
code "@name"
|
|
899
|
-
dt "Events"
|
|
900
|
-
dd
|
|
901
|
-
code "change"
|
|
902
|
-
dt "Keyboard"
|
|
903
|
-
dd
|
|
904
|
-
kbd "← →"
|
|
905
|
-
kbd "↕"
|
|
906
|
-
kbd "Home"
|
|
907
|
-
kbd "End"
|
|
908
|
-
dt "Data"
|
|
909
|
-
dd
|
|
910
|
-
code "$orientation"
|
|
911
|
-
code "$disabled"
|
|
912
|
-
code "$checked"
|
|
913
|
-
code "$value"
|
|
914
|
-
|
|
915
|
-
# ========================================================================
|
|
916
|
-
# CHECKBOX GROUP
|
|
917
|
-
# ========================================================================
|
|
918
|
-
.section id: "checkbox-group"
|
|
919
|
-
SectionHead tag: "checkbox-group", name: "CheckboxGroup", lines: 46
|
|
920
|
-
.section-desc "Multiple options checked independently."
|
|
921
|
-
.demo-row
|
|
922
|
-
.demo-label "Toppings"
|
|
923
|
-
CheckboxGroup value <=> cbToppings, label: "Pizza toppings"
|
|
924
|
-
div $value: "Cheese", "Cheese"
|
|
925
|
-
div $value: "Bacon", "Bacon"
|
|
926
|
-
div $value: "Lettuce", "Lettuce"
|
|
927
|
-
div $value: "Tomato", "Tomato"
|
|
928
|
-
.status "selected: #{cbToppings.join(', ')}"
|
|
929
|
-
.api
|
|
930
|
-
dl
|
|
931
|
-
dt "Props"
|
|
932
|
-
dd
|
|
933
|
-
code "@value"
|
|
934
|
-
code "@disabled"
|
|
935
|
-
code "@orientation"
|
|
936
|
-
code "@label"
|
|
937
|
-
dt "Events"
|
|
938
|
-
dd
|
|
939
|
-
code "change"
|
|
940
|
-
dt "Keyboard"
|
|
941
|
-
dd
|
|
942
|
-
kbd "← →"
|
|
943
|
-
kbd "↕"
|
|
944
|
-
dt "Data"
|
|
945
|
-
dd
|
|
946
|
-
code "$orientation"
|
|
947
|
-
code "$disabled"
|
|
948
|
-
code "$checked"
|
|
949
|
-
code "$value"
|
|
950
|
-
|
|
951
|
-
# ========================================================================
|
|
952
|
-
# INPUT
|
|
953
|
-
# ========================================================================
|
|
954
|
-
.section id: "input"
|
|
955
|
-
SectionHead tag: "input", name: "Input", lines: 24
|
|
956
|
-
.section-desc "Headless input tracking focus, touch, and validation state."
|
|
957
|
-
.demo-row
|
|
958
|
-
.demo-label "Text input"
|
|
959
|
-
Input value <=> userName, placeholder: "Enter your name"
|
|
960
|
-
.status "value: #{userName}"
|
|
961
|
-
.api
|
|
962
|
-
dl
|
|
963
|
-
dt "Props"
|
|
964
|
-
dd
|
|
965
|
-
code "@value"
|
|
966
|
-
code "@placeholder"
|
|
967
|
-
code "@type"
|
|
968
|
-
code "@disabled"
|
|
969
|
-
code "@required"
|
|
970
|
-
dt "Data"
|
|
971
|
-
dd
|
|
972
|
-
code "$disabled"
|
|
973
|
-
code "$focused"
|
|
974
|
-
code "$touched"
|
|
975
|
-
|
|
976
|
-
# ========================================================================
|
|
977
|
-
# NUMBER FIELD
|
|
978
|
-
# ========================================================================
|
|
979
|
-
.section id: "number-field"
|
|
980
|
-
SectionHead tag: "number-field", name: "NumberField", lines: 132
|
|
981
|
-
.section-desc "Number input with increment/decrement buttons, hold-to-repeat, and keyboard stepping."
|
|
982
|
-
.demo-row
|
|
983
|
-
.demo-label "Quantity (1-99)"
|
|
984
|
-
.nf-wrap
|
|
985
|
-
NumberField value <=> quantity, min: 1, max: 99
|
|
986
|
-
.status "quantity: #{quantity}"
|
|
987
|
-
.demo-row
|
|
988
|
-
.demo-label "Price (step: 0.01)"
|
|
989
|
-
.nf-wrap
|
|
990
|
-
NumberField value <=> price, min: 0, max: 999.99, step: 0.01
|
|
991
|
-
.status "price: #{price}"
|
|
992
|
-
.api
|
|
993
|
-
dl
|
|
994
|
-
dt "Props"
|
|
995
|
-
dd
|
|
996
|
-
code "@value"
|
|
997
|
-
code "@min"
|
|
998
|
-
code "@max"
|
|
999
|
-
code "@step"
|
|
1000
|
-
code "@disabled"
|
|
1001
|
-
code "@readOnly"
|
|
1002
|
-
dt "Events"
|
|
1003
|
-
dd
|
|
1004
|
-
code "input"
|
|
1005
|
-
code "change"
|
|
1006
|
-
dt "Keyboard"
|
|
1007
|
-
dd
|
|
1008
|
-
kbd "↕"
|
|
1009
|
-
kbd "PgUp"
|
|
1010
|
-
kbd "PgDn"
|
|
1011
|
-
kbd "Home"
|
|
1012
|
-
kbd "End"
|
|
1013
|
-
dt "Data"
|
|
1014
|
-
dd
|
|
1015
|
-
code "$disabled"
|
|
1016
|
-
code "$readonly"
|
|
1017
|
-
code "$decrement"
|
|
1018
|
-
code "$increment"
|
|
1019
|
-
|
|
1020
|
-
# ========================================================================
|
|
1021
|
-
# SLIDER
|
|
1022
|
-
# ========================================================================
|
|
1023
|
-
.section id: "slider"
|
|
1024
|
-
SectionHead tag: "slider", name: "Slider", lines: 130
|
|
1025
|
-
.section-desc "Draggable range input with pointer capture and keyboard stepping."
|
|
1026
|
-
.demo-row
|
|
1027
|
-
.demo-label "Single thumb"
|
|
1028
|
-
.slider-wrap
|
|
1029
|
-
Slider value <=> sliderVal
|
|
1030
|
-
.status "value: #{sliderVal}"
|
|
1031
|
-
.demo-row
|
|
1032
|
-
.demo-label "Range (two thumbs)"
|
|
1033
|
-
.slider-wrap
|
|
1034
|
-
Slider value <=> rangeVal
|
|
1035
|
-
.status "range: #{rangeVal}"
|
|
1036
|
-
.api
|
|
1037
|
-
dl
|
|
1038
|
-
dt "Props"
|
|
1039
|
-
dd
|
|
1040
|
-
code "@value"
|
|
1041
|
-
code "@min"
|
|
1042
|
-
code "@max"
|
|
1043
|
-
code "@step"
|
|
1044
|
-
code "@orientation"
|
|
1045
|
-
code "@disabled"
|
|
1046
|
-
dt "Events"
|
|
1047
|
-
dd
|
|
1048
|
-
code "input"
|
|
1049
|
-
code "change"
|
|
1050
|
-
dt "Keyboard"
|
|
1051
|
-
dd
|
|
1052
|
-
kbd "← →"
|
|
1053
|
-
kbd "↕"
|
|
1054
|
-
kbd "PgUp"
|
|
1055
|
-
kbd "PgDn"
|
|
1056
|
-
kbd "Home"
|
|
1057
|
-
kbd "End"
|
|
1058
|
-
dt "Data"
|
|
1059
|
-
dd
|
|
1060
|
-
code "$orientation"
|
|
1061
|
-
code "$disabled"
|
|
1062
|
-
code "$dragging"
|
|
1063
|
-
code "$track"
|
|
1064
|
-
code "$indicator"
|
|
1065
|
-
code "$thumb"
|
|
1066
|
-
code "$active"
|
|
1067
|
-
|
|
1068
|
-
# ========================================================================
|
|
1069
|
-
# OTP FIELD
|
|
1070
|
-
# ========================================================================
|
|
1071
|
-
.section id: "otp-field"
|
|
1072
|
-
SectionHead tag: "otp-field", name: "OTPField", lines: 72
|
|
1073
|
-
.section-desc "Multi-digit code input with auto-advance, backspace nav, and paste."
|
|
1074
|
-
.demo-row
|
|
1075
|
-
.demo-label "6-digit code"
|
|
1076
|
-
OTPField length: 6, value <=> otpCode
|
|
1077
|
-
.status "code: '#{otpCode}'"
|
|
1078
|
-
.demo-row
|
|
1079
|
-
.demo-label "4-digit masked"
|
|
1080
|
-
OTPField length: 4, mask: true
|
|
1081
|
-
.api
|
|
1082
|
-
dl
|
|
1083
|
-
dt "Props"
|
|
1084
|
-
dd
|
|
1085
|
-
code "@length"
|
|
1086
|
-
code "@value"
|
|
1087
|
-
code "@disabled"
|
|
1088
|
-
code "@mask"
|
|
1089
|
-
dt "Events"
|
|
1090
|
-
dd
|
|
1091
|
-
code "input"
|
|
1092
|
-
code "complete"
|
|
1093
|
-
dt "Keyboard"
|
|
1094
|
-
dd
|
|
1095
|
-
kbd "← →"
|
|
1096
|
-
kbd "Backspace"
|
|
1097
|
-
kbd "Home"
|
|
1098
|
-
kbd "End"
|
|
1099
|
-
kbd "paste"
|
|
1100
|
-
dt "Data"
|
|
1101
|
-
dd
|
|
1102
|
-
code "$disabled"
|
|
1103
|
-
code "$complete"
|
|
1104
|
-
code "$filled"
|
|
1105
|
-
|
|
1106
|
-
# ========================================================================
|
|
1107
|
-
# DATE PICKER
|
|
1108
|
-
# ========================================================================
|
|
1109
|
-
.section id: "date-picker"
|
|
1110
|
-
SectionHead tag: "date-picker", name: "DatePicker", lines: 172
|
|
1111
|
-
.section-desc "Calendar dropdown for single date or range selection."
|
|
1112
|
-
.demo-row
|
|
1113
|
-
.demo-label "Single date"
|
|
1114
|
-
DatePicker value <=> pickedDate
|
|
1115
|
-
.status "date: #{if pickedDate then pickedDate.toLocaleDateString() else 'none'}"
|
|
1116
|
-
.demo-row
|
|
1117
|
-
.demo-label "Date range"
|
|
1118
|
-
DatePicker value <=> dateRange, range: true
|
|
1119
|
-
.status "range: #{if dateRange and dateRange[0] then dateRange[0].toLocaleDateString() else 'none'} – #{if dateRange and dateRange[1] then dateRange[1].toLocaleDateString() else '...'}"
|
|
1120
|
-
.api
|
|
1121
|
-
dl
|
|
1122
|
-
dt "Props"
|
|
1123
|
-
dd
|
|
1124
|
-
code "@value"
|
|
1125
|
-
code "@placeholder"
|
|
1126
|
-
code "@disabled"
|
|
1127
|
-
code "@range"
|
|
1128
|
-
code "@firstDayOfWeek"
|
|
1129
|
-
dt "Events"
|
|
1130
|
-
dd
|
|
1131
|
-
code "change"
|
|
1132
|
-
dt "Keyboard"
|
|
1133
|
-
dd
|
|
1134
|
-
kbd "Esc"
|
|
1135
|
-
kbd "Enter"
|
|
1136
|
-
kbd "Space"
|
|
1137
|
-
dt "Data"
|
|
1138
|
-
dd
|
|
1139
|
-
code "$open"
|
|
1140
|
-
code "$disabled"
|
|
1141
|
-
code "$range"
|
|
1142
|
-
code "$calendar"
|
|
1143
|
-
code "$selected"
|
|
1144
|
-
code "$today"
|
|
1145
|
-
code "$in-range"
|
|
1146
|
-
|
|
1147
|
-
# ========================================================================
|
|
1148
|
-
# EDITABLE VALUE
|
|
1149
|
-
# ========================================================================
|
|
1150
|
-
.section id: "editable-value"
|
|
1151
|
-
SectionHead tag: "editable-value", name: "EditableValue", lines: 58
|
|
1152
|
-
.section-desc "Click the edit icon to modify the value inline."
|
|
1153
|
-
.demo-row
|
|
1154
|
-
EditableValue @save: (=> editName = editName)
|
|
1155
|
-
span $display: true
|
|
1156
|
-
editName
|
|
1157
|
-
div $editor: true, hidden: true
|
|
1158
|
-
input type: "text", value: editName
|
|
1159
|
-
@input: (e) => editName = e.target.value
|
|
1160
|
-
.api
|
|
1161
|
-
dl
|
|
1162
|
-
dt "Props"
|
|
1163
|
-
dd
|
|
1164
|
-
code "@disabled"
|
|
1165
|
-
dt "Events"
|
|
1166
|
-
dd
|
|
1167
|
-
code "save"
|
|
1168
|
-
dt "Keyboard"
|
|
1169
|
-
dd
|
|
1170
|
-
kbd "Esc"
|
|
1171
|
-
kbd "Enter"
|
|
1172
|
-
dt "Data"
|
|
1173
|
-
dd
|
|
1174
|
-
code "$editing"
|
|
1175
|
-
code "$disabled"
|
|
1176
|
-
code "$saving"
|
|
1177
|
-
code "$edit-trigger"
|
|
1178
|
-
|
|
1179
|
-
# ========================================================================
|
|
1180
|
-
# TEXTAREA
|
|
1181
|
-
# ========================================================================
|
|
1182
|
-
.section id: "textarea"
|
|
1183
|
-
SectionHead tag: "textarea", name: "Textarea", lines: 33
|
|
1184
|
-
.section-desc "Auto-resizing text area with focus and validation tracking."
|
|
1185
|
-
.demo-row
|
|
1186
|
-
.demo-label "Auto-resize textarea"
|
|
1187
|
-
Textarea value <=> textareaVal, placeholder: "Type something...", autoResize: true
|
|
1188
|
-
.status "length: #{textareaVal.length}"
|
|
1189
|
-
.api
|
|
1190
|
-
dl
|
|
1191
|
-
dt "Props"
|
|
1192
|
-
dd
|
|
1193
|
-
code "@value"
|
|
1194
|
-
code "@placeholder"
|
|
1195
|
-
code "@disabled"
|
|
1196
|
-
code "@required"
|
|
1197
|
-
code "@rows"
|
|
1198
|
-
code "@autoResize"
|
|
1199
|
-
dt "Data"
|
|
1200
|
-
dd
|
|
1201
|
-
code "$disabled"
|
|
1202
|
-
code "$focused"
|
|
1203
|
-
code "$touched"
|
|
1204
|
-
|
|
1205
|
-
# ========================================================================
|
|
1206
|
-
# NATIVE SELECT
|
|
1207
|
-
# ========================================================================
|
|
1208
|
-
.section id: "native-select"
|
|
1209
|
-
SectionHead tag: "native-select", name: "NativeSelect", lines: 18
|
|
1210
|
-
.section-desc "Native browser select element with state tracking."
|
|
1211
|
-
.demo-row.native-select-demo
|
|
1212
|
-
.demo-label "Choose a color"
|
|
1213
|
-
NativeSelect value <=> nativeSelectVal
|
|
1214
|
-
option value: "", "Pick one..."
|
|
1215
|
-
option value: "red", "Red"
|
|
1216
|
-
option value: "green", "Green"
|
|
1217
|
-
option value: "blue", "Blue"
|
|
1218
|
-
.status "value: '#{nativeSelectVal}'"
|
|
1219
|
-
.api
|
|
1220
|
-
dl
|
|
1221
|
-
dt "Props"
|
|
1222
|
-
dd
|
|
1223
|
-
code "@value"
|
|
1224
|
-
code "@disabled"
|
|
1225
|
-
code "@required"
|
|
1226
|
-
dt "Events"
|
|
1227
|
-
dd
|
|
1228
|
-
code "change"
|
|
1229
|
-
dt "Data"
|
|
1230
|
-
dd
|
|
1231
|
-
code "$disabled"
|
|
1232
|
-
code "$focused"
|
|
1233
|
-
|
|
1234
|
-
# ========================================================================
|
|
1235
|
-
# INPUT GROUP
|
|
1236
|
-
# ========================================================================
|
|
1237
|
-
.section id: "input-group"
|
|
1238
|
-
SectionHead tag: "input-group", name: "InputGroup", lines: 11
|
|
1239
|
-
.section-desc "Input with prefix/suffix addon elements."
|
|
1240
|
-
.demo-row.input-group-demo
|
|
1241
|
-
.demo-label "With prefix"
|
|
1242
|
-
InputGroup
|
|
1243
|
-
span $prefix: true, "$"
|
|
1244
|
-
input type: "text", placeholder: "Amount"
|
|
1245
|
-
.demo-row.input-group-demo
|
|
1246
|
-
.demo-label "With suffix"
|
|
1247
|
-
InputGroup
|
|
1248
|
-
input type: "text", placeholder: "Search..."
|
|
1249
|
-
button $suffix: true, "Go"
|
|
1250
|
-
.api
|
|
1251
|
-
dl
|
|
1252
|
-
dt "Props"
|
|
1253
|
-
dd
|
|
1254
|
-
code "@disabled"
|
|
1255
|
-
dt "Data"
|
|
1256
|
-
dd
|
|
1257
|
-
code "$disabled"
|
|
1258
|
-
code "$focused"
|
|
1259
|
-
|
|
1260
|
-
# ========================================================================
|
|
1261
|
-
# TABS
|
|
1262
|
-
# ========================================================================
|
|
1263
|
-
.section id: "tabs"
|
|
1264
|
-
SectionHead tag: "tabs", name: "Tabs", lines: 91
|
|
1265
|
-
.section-desc "Tab panel with roving tabindex and arrow key navigation."
|
|
1266
|
-
.demo-row
|
|
1267
|
-
.demo-label "Basic tabs"
|
|
1268
|
-
Tabs active <=> currentTab
|
|
1269
|
-
div data-tab: "overview", "Overview"
|
|
1270
|
-
div data-tab: "details", "Details"
|
|
1271
|
-
div data-tab: "settings", "Settings"
|
|
1272
|
-
div data-panel: "overview"
|
|
1273
|
-
p "This is the overview panel."
|
|
1274
|
-
div data-panel: "details"
|
|
1275
|
-
p "These are the details."
|
|
1276
|
-
div data-panel: "settings"
|
|
1277
|
-
p "Settings go here."
|
|
1278
|
-
.status "active: #{currentTab}"
|
|
1279
|
-
.api
|
|
1280
|
-
dl
|
|
1281
|
-
dt "Props"
|
|
1282
|
-
dd
|
|
1283
|
-
code "@active"
|
|
1284
|
-
code "@orientation"
|
|
1285
|
-
code "@activation"
|
|
1286
|
-
dt "Events"
|
|
1287
|
-
dd
|
|
1288
|
-
code "change"
|
|
1289
|
-
dt "Keyboard"
|
|
1290
|
-
dd
|
|
1291
|
-
kbd "← →"
|
|
1292
|
-
kbd "↕"
|
|
1293
|
-
kbd "Home"
|
|
1294
|
-
kbd "End"
|
|
1295
|
-
kbd "Enter"
|
|
1296
|
-
kbd "Space"
|
|
1297
|
-
dt "Data"
|
|
1298
|
-
dd
|
|
1299
|
-
code "$tab"
|
|
1300
|
-
code "$panel"
|
|
1301
|
-
code "$active"
|
|
1302
|
-
code "$disabled"
|
|
1303
|
-
|
|
1304
|
-
# ========================================================================
|
|
1305
|
-
# MENU
|
|
1306
|
-
# ========================================================================
|
|
1307
|
-
.section id: "menu"
|
|
1308
|
-
SectionHead tag: "menu", name: "Menu", lines: 133
|
|
1309
|
-
.section-desc "Dropdown action menu with keyboard navigation."
|
|
1310
|
-
.demo-row
|
|
1311
|
-
.demo-label "Click to open menu"
|
|
1312
|
-
Menu
|
|
1313
|
-
@select: (e) => console.log("Selected: #{e.detail}")
|
|
1314
|
-
span "Actions"
|
|
1315
|
-
div data-item: "edit", "Edit"
|
|
1316
|
-
div data-item: "duplicate", "Duplicate"
|
|
1317
|
-
div data-item: "archive", "Archive"
|
|
1318
|
-
div data-item: "delete", "Delete"
|
|
1319
|
-
.api
|
|
1320
|
-
dl
|
|
1321
|
-
dt "Props"
|
|
1322
|
-
dd
|
|
1323
|
-
code "@disabled"
|
|
1324
|
-
dt "Events"
|
|
1325
|
-
dd
|
|
1326
|
-
code "select"
|
|
1327
|
-
dt "Keyboard"
|
|
1328
|
-
dd
|
|
1329
|
-
kbd "↕"
|
|
1330
|
-
kbd "Home"
|
|
1331
|
-
kbd "End"
|
|
1332
|
-
kbd "Enter"
|
|
1333
|
-
kbd "Space"
|
|
1334
|
-
kbd "Esc"
|
|
1335
|
-
kbd "Tab"
|
|
1336
|
-
kbd "type-ahead"
|
|
1337
|
-
dt "Data"
|
|
1338
|
-
dd
|
|
1339
|
-
code "$open"
|
|
1340
|
-
code "$disabled"
|
|
1341
|
-
code "$highlighted"
|
|
1342
|
-
code "$value"
|
|
1343
|
-
|
|
1344
|
-
# ========================================================================
|
|
1345
|
-
# CONTEXT MENU
|
|
1346
|
-
# ========================================================================
|
|
1347
|
-
.section id: "context-menu"
|
|
1348
|
-
SectionHead tag: "context-menu", name: "ContextMenu", lines: 80
|
|
1349
|
-
.section-desc "Right-click the dashed area to open a context menu."
|
|
1350
|
-
ContextMenu
|
|
1351
|
-
div $trigger: true
|
|
1352
|
-
.context-zone
|
|
1353
|
-
"Right-click here"
|
|
1354
|
-
div $item: "cut", "Cut"
|
|
1355
|
-
div $item: "copy", "Copy"
|
|
1356
|
-
div $item: "paste", "Paste"
|
|
1357
|
-
.api
|
|
1358
|
-
dl
|
|
1359
|
-
dt "Props"
|
|
1360
|
-
dd
|
|
1361
|
-
code "@disabled"
|
|
1362
|
-
dt "Events"
|
|
1363
|
-
dd
|
|
1364
|
-
code "select"
|
|
1365
|
-
dt "Keyboard"
|
|
1366
|
-
dd
|
|
1367
|
-
kbd "↕"
|
|
1368
|
-
kbd "Home"
|
|
1369
|
-
kbd "End"
|
|
1370
|
-
kbd "Enter"
|
|
1371
|
-
kbd "Space"
|
|
1372
|
-
kbd "Esc"
|
|
1373
|
-
kbd "Tab"
|
|
1374
|
-
dt "Data"
|
|
1375
|
-
dd
|
|
1376
|
-
code "$open"
|
|
1377
|
-
code "$highlighted"
|
|
1378
|
-
code "$disabled"
|
|
1379
|
-
code "$value"
|
|
1380
|
-
|
|
1381
|
-
# ========================================================================
|
|
1382
|
-
# MENUBAR
|
|
1383
|
-
# ========================================================================
|
|
1384
|
-
.section id: "menubar"
|
|
1385
|
-
SectionHead tag: "menubar", name: "Menubar", lines: 125
|
|
1386
|
-
.section-desc "Horizontal menu bar with dropdown menus."
|
|
1387
|
-
.demo-row
|
|
1388
|
-
Menubar
|
|
1389
|
-
div $menu: "File"
|
|
1390
|
-
div $item: "new", "New"
|
|
1391
|
-
div $item: "open", "Open"
|
|
1392
|
-
div $item: "save", "Save"
|
|
1393
|
-
div $menu: "Edit"
|
|
1394
|
-
div $item: "undo", "Undo"
|
|
1395
|
-
div $item: "redo", "Redo"
|
|
1396
|
-
div $item: "cut", "Cut"
|
|
1397
|
-
div $menu: "View"
|
|
1398
|
-
div $item: "zoom-in", "Zoom In"
|
|
1399
|
-
div $item: "zoom-out", "Zoom Out"
|
|
1400
|
-
.api
|
|
1401
|
-
dl
|
|
1402
|
-
dt "Props"
|
|
1403
|
-
dd
|
|
1404
|
-
code "@disabled"
|
|
1405
|
-
dt "Events"
|
|
1406
|
-
dd
|
|
1407
|
-
code "select"
|
|
1408
|
-
dt "Keyboard"
|
|
1409
|
-
dd
|
|
1410
|
-
kbd "← →"
|
|
1411
|
-
kbd "↕"
|
|
1412
|
-
kbd "Enter"
|
|
1413
|
-
kbd "Space"
|
|
1414
|
-
kbd "Esc"
|
|
1415
|
-
kbd "Tab"
|
|
1416
|
-
dt "Data"
|
|
1417
|
-
dd
|
|
1418
|
-
code "$disabled"
|
|
1419
|
-
code "$open"
|
|
1420
|
-
code "$highlighted"
|
|
1421
|
-
code "$value"
|
|
1422
|
-
|
|
1423
|
-
# ========================================================================
|
|
1424
|
-
# NAVIGATION MENU
|
|
1425
|
-
# ========================================================================
|
|
1426
|
-
.section id: "nav-menu"
|
|
1427
|
-
SectionHead tag: "nav-menu", name: "NavigationMenu", lines: 99
|
|
1428
|
-
.section-desc "Site navigation with dropdown panels."
|
|
1429
|
-
.demo-row
|
|
1430
|
-
NavigationMenu
|
|
1431
|
-
a $link: true, href: "javascript:void(0)"
|
|
1432
|
-
"Home"
|
|
1433
|
-
div $trigger: "Products"
|
|
1434
|
-
div $panel: true
|
|
1435
|
-
a href: "javascript:void(0)", "Components"
|
|
1436
|
-
a href: "javascript:void(0)", "Templates"
|
|
1437
|
-
a href: "javascript:void(0)", "Playground"
|
|
1438
|
-
div $trigger: "Learn"
|
|
1439
|
-
div $panel: true
|
|
1440
|
-
a href: "javascript:void(0)", "Documentation"
|
|
1441
|
-
a href: "javascript:void(0)", "Blog"
|
|
1442
|
-
a href: "javascript:void(0)", "Changelog"
|
|
1443
|
-
a $link: true, href: "javascript:void(0)"
|
|
1444
|
-
"GitHub"
|
|
1445
|
-
.api
|
|
1446
|
-
dl
|
|
1447
|
-
dt "Props"
|
|
1448
|
-
dd
|
|
1449
|
-
code "@orientation"
|
|
1450
|
-
code "@hoverDelay"
|
|
1451
|
-
code "@hoverCloseDelay"
|
|
1452
|
-
dt "Keyboard"
|
|
1453
|
-
dd
|
|
1454
|
-
kbd "← →"
|
|
1455
|
-
kbd "↓"
|
|
1456
|
-
kbd "Esc"
|
|
1457
|
-
dt "Data"
|
|
1458
|
-
dd
|
|
1459
|
-
code "$orientation"
|
|
1460
|
-
code "$open"
|
|
1461
|
-
|
|
1462
|
-
# ========================================================================
|
|
1463
|
-
# TOOLBAR
|
|
1464
|
-
# ========================================================================
|
|
1465
|
-
.section id: "toolbar"
|
|
1466
|
-
SectionHead tag: "toolbar", name: "Toolbar", lines: 31
|
|
1467
|
-
.section-desc "Groups controls with roving tabindex keyboard navigation."
|
|
1468
|
-
.demo-row
|
|
1469
|
-
.demo-label "Text"
|
|
1470
|
-
Toolbar label: "Formatting"
|
|
1471
|
-
Button
|
|
1472
|
-
"Save"
|
|
1473
|
-
Button
|
|
1474
|
-
"Undo"
|
|
1475
|
-
Separator orientation: "vertical"
|
|
1476
|
-
Toggle pressed <=> isBold
|
|
1477
|
-
"Bold"
|
|
1478
|
-
Toggle pressed <=> isItalic
|
|
1479
|
-
"Italic"
|
|
1480
|
-
.demo-row
|
|
1481
|
-
.demo-label "Icons + Text"
|
|
1482
|
-
Toolbar label: "Formatting"
|
|
1483
|
-
Button
|
|
1484
|
-
"💾 Save"
|
|
1485
|
-
Button
|
|
1486
|
-
"↩ Undo"
|
|
1487
|
-
Separator orientation: "vertical"
|
|
1488
|
-
Toggle pressed <=> isBold
|
|
1489
|
-
"𝐁 Bold"
|
|
1490
|
-
Toggle pressed <=> isItalic
|
|
1491
|
-
"𝐼 Italic"
|
|
1492
|
-
.demo-row
|
|
1493
|
-
.demo-label "Icons Only"
|
|
1494
|
-
Toolbar label: "Formatting"
|
|
1495
|
-
Button aria-label: "Save"
|
|
1496
|
-
"💾"
|
|
1497
|
-
Button aria-label: "Undo"
|
|
1498
|
-
"↩"
|
|
1499
|
-
Separator orientation: "vertical"
|
|
1500
|
-
Toggle pressed <=> isBold, aria-label: "Bold"
|
|
1501
|
-
"𝐁"
|
|
1502
|
-
Toggle pressed <=> isItalic, aria-label: "Italic"
|
|
1503
|
-
"𝐼"
|
|
1504
|
-
.api
|
|
1505
|
-
dl
|
|
1506
|
-
dt "Props"
|
|
1507
|
-
dd
|
|
1508
|
-
code "@orientation"
|
|
1509
|
-
code "@label"
|
|
1510
|
-
dt "Keyboard"
|
|
1511
|
-
dd
|
|
1512
|
-
kbd "← →"
|
|
1513
|
-
kbd "↕"
|
|
1514
|
-
kbd "Home"
|
|
1515
|
-
kbd "End"
|
|
1516
|
-
dt "Data"
|
|
1517
|
-
dd
|
|
1518
|
-
code "$orientation"
|
|
1519
|
-
|
|
1520
|
-
# ========================================================================
|
|
1521
|
-
# BREADCRUMB
|
|
1522
|
-
# ========================================================================
|
|
1523
|
-
.section id: "breadcrumb"
|
|
1524
|
-
SectionHead tag: "breadcrumb", name: "Breadcrumb", lines: 25
|
|
1525
|
-
.section-desc "Navigation trail with separator and current page."
|
|
1526
|
-
.demo-row
|
|
1527
|
-
.demo-label "Basic breadcrumb"
|
|
1528
|
-
Breadcrumb
|
|
1529
|
-
a $item: true, href: "#breadcrumb", "Home"
|
|
1530
|
-
a $item: true, href: "#breadcrumb", "Products"
|
|
1531
|
-
a $item: true, href: "#breadcrumb", "Widgets"
|
|
1532
|
-
span $item: true, "Widget Pro"
|
|
1533
|
-
.api
|
|
1534
|
-
dl
|
|
1535
|
-
dt "Props"
|
|
1536
|
-
dd
|
|
1537
|
-
code "@separator"
|
|
1538
|
-
code "@label"
|
|
1539
|
-
dt "Data"
|
|
1540
|
-
dd
|
|
1541
|
-
code "$current"
|
|
1542
|
-
|
|
1543
|
-
# ========================================================================
|
|
1544
|
-
# DIALOG
|
|
1545
|
-
# ========================================================================
|
|
1546
|
-
.section id: "dialog"
|
|
1547
|
-
SectionHead tag: "dialog", name: "Dialog", lines: 83
|
|
1548
|
-
.section-desc "Modal with focus trap and scroll lock. Press Escape or click outside to dismiss."
|
|
1549
|
-
.demo-row
|
|
1550
|
-
.demo-label "Click to open"
|
|
1551
|
-
button.demo-btn @click: (=> showDialog = true)
|
|
1552
|
-
"Open Dialog"
|
|
1553
|
-
.status "open: #{showDialog}"
|
|
1554
|
-
Dialog open <=> showDialog, @close: (=> showDialog = false)
|
|
1555
|
-
.dialog-panel
|
|
1556
|
-
h2 style: "font-size:18px;font-weight:600;margin-bottom:8px", "Confirm Action"
|
|
1557
|
-
p.dialog-desc "Are you sure you want to proceed?"
|
|
1558
|
-
. style: "display:flex;gap:8px;justify-content:flex-end"
|
|
1559
|
-
button.demo-btn @click: (=> showDialog = false)
|
|
1560
|
-
"Cancel"
|
|
1561
|
-
button style: "padding:6px 16px;border:none;border-radius:6px;background:#1d4ed8;color:white;font-weight:600", @click: (=> showDialog = false)
|
|
1562
|
-
"Confirm"
|
|
1563
|
-
.api
|
|
1564
|
-
dl
|
|
1565
|
-
dt "Props"
|
|
1566
|
-
dd
|
|
1567
|
-
code "@open"
|
|
1568
|
-
code "@dismissable"
|
|
1569
|
-
code "@initialFocus"
|
|
1570
|
-
dt "Events"
|
|
1571
|
-
dd
|
|
1572
|
-
code "close"
|
|
1573
|
-
dt "Keyboard"
|
|
1574
|
-
dd
|
|
1575
|
-
kbd "Esc"
|
|
1576
|
-
kbd "Tab"
|
|
1577
|
-
dt "Data"
|
|
1578
|
-
dd
|
|
1579
|
-
code "$open"
|
|
1580
|
-
|
|
1581
|
-
# ========================================================================
|
|
1582
|
-
# ALERT DIALOG
|
|
1583
|
-
# ========================================================================
|
|
1584
|
-
.section id: "alert-dialog"
|
|
1585
|
-
SectionHead tag: "alert-dialog", name: "AlertDialog", lines: 74
|
|
1586
|
-
.section-desc "Non-dismissable modal — Escape and click-outside are blocked. User must choose an action."
|
|
1587
|
-
.demo-row
|
|
1588
|
-
.demo-label "Requires explicit action"
|
|
1589
|
-
button.demo-btn @click: (=> showAlertDialog = true)
|
|
1590
|
-
"Delete Account"
|
|
1591
|
-
.status "open: #{showAlertDialog}"
|
|
1592
|
-
AlertDialog open <=> showAlertDialog
|
|
1593
|
-
.dialog-panel
|
|
1594
|
-
h2 style: "font-size:18px;font-weight:600;margin-bottom:8px", "Delete Account?"
|
|
1595
|
-
p.dialog-desc "This action is permanent and cannot be undone."
|
|
1596
|
-
. style: "display:flex;gap:8px;justify-content:flex-end"
|
|
1597
|
-
button.demo-btn @click: (=> showAlertDialog = false)
|
|
1598
|
-
"Cancel"
|
|
1599
|
-
button style: "padding:6px 16px;border:none;border-radius:6px;background:#dc2626;color:white;font-weight:600", @click: (=> showAlertDialog = false)
|
|
1600
|
-
"Delete"
|
|
1601
|
-
.api
|
|
1602
|
-
dl
|
|
1603
|
-
dt "Props"
|
|
1604
|
-
dd
|
|
1605
|
-
code "@open"
|
|
1606
|
-
code "@initialFocus"
|
|
1607
|
-
dt "Events"
|
|
1608
|
-
dd
|
|
1609
|
-
code "close"
|
|
1610
|
-
dt "Keyboard"
|
|
1611
|
-
dd
|
|
1612
|
-
kbd "Tab"
|
|
1613
|
-
dt "Data"
|
|
1614
|
-
dd
|
|
1615
|
-
code "$open"
|
|
1616
|
-
|
|
1617
|
-
# ========================================================================
|
|
1618
|
-
# DRAWER
|
|
1619
|
-
# ========================================================================
|
|
1620
|
-
.section id: "drawer"
|
|
1621
|
-
SectionHead tag: "drawer", name: "Drawer", lines: 60
|
|
1622
|
-
.section-desc "Slide-out panel from edge of screen with focus trap and scroll lock."
|
|
1623
|
-
.demo-row
|
|
1624
|
-
.demo-label "Open from right"
|
|
1625
|
-
.btn-demo
|
|
1626
|
-
.btn-row
|
|
1627
|
-
button @click: (=> showDrawer = true)
|
|
1628
|
-
"Open Drawer"
|
|
1629
|
-
Drawer open <=> showDrawer, side: "right"
|
|
1630
|
-
.drawer-panel
|
|
1631
|
-
h2 "Settings"
|
|
1632
|
-
p "This is a drawer panel that slides in from the right."
|
|
1633
|
-
p "Press Escape or click outside to close."
|
|
1634
|
-
button @click: (=> showDrawer = false)
|
|
1635
|
-
"Close"
|
|
1636
|
-
.api
|
|
1637
|
-
dl
|
|
1638
|
-
dt "Props"
|
|
1639
|
-
dd
|
|
1640
|
-
code "@open"
|
|
1641
|
-
code "@side"
|
|
1642
|
-
code "@dismissable"
|
|
1643
|
-
dt "Events"
|
|
1644
|
-
dd
|
|
1645
|
-
code "close"
|
|
1646
|
-
dt "Keyboard"
|
|
1647
|
-
dd
|
|
1648
|
-
kbd "Esc"
|
|
1649
|
-
kbd "Tab"
|
|
1650
|
-
dt "Data"
|
|
1651
|
-
dd
|
|
1652
|
-
code "$open"
|
|
1653
|
-
code "$side"
|
|
1654
|
-
|
|
1655
|
-
# ========================================================================
|
|
1656
|
-
# POPOVER
|
|
1657
|
-
# ========================================================================
|
|
1658
|
-
.section id: "popover"
|
|
1659
|
-
SectionHead tag: "popover", name: "Popover", lines: 117
|
|
1660
|
-
.section-desc "Anchored floating content with flip/shift positioning."
|
|
1661
|
-
.demo-row
|
|
1662
|
-
.demo-label "Click to toggle"
|
|
1663
|
-
Popover placement: "bottom-start"
|
|
1664
|
-
button.demo-btn data-trigger: true
|
|
1665
|
-
"Open Popover"
|
|
1666
|
-
div.floating-panel data-content: true
|
|
1667
|
-
p.floating-title "Popover content"
|
|
1668
|
-
p.floating-desc "Click outside or press Escape to close."
|
|
1669
|
-
.api
|
|
1670
|
-
dl
|
|
1671
|
-
dt "Props"
|
|
1672
|
-
dd
|
|
1673
|
-
code "@placement"
|
|
1674
|
-
code "@offset"
|
|
1675
|
-
code "@disabled"
|
|
1676
|
-
code "@openOnHover"
|
|
1677
|
-
code "@hoverDelay"
|
|
1678
|
-
code "@hoverCloseDelay"
|
|
1679
|
-
dt "Keyboard"
|
|
1680
|
-
dd
|
|
1681
|
-
kbd "Esc"
|
|
1682
|
-
kbd "Enter"
|
|
1683
|
-
kbd "Space"
|
|
1684
|
-
kbd "↓"
|
|
1685
|
-
dt "Data"
|
|
1686
|
-
dd
|
|
1687
|
-
code "$open"
|
|
1688
|
-
code "$placement"
|
|
1689
|
-
|
|
1690
|
-
# ========================================================================
|
|
1691
|
-
# TOOLTIP
|
|
1692
|
-
# ========================================================================
|
|
1693
|
-
.section id: "tooltip"
|
|
1694
|
-
SectionHead tag: "tooltip", name: "Tooltip", lines: 92
|
|
1695
|
-
.section-desc "Hover/focus tooltip with delay and positioning."
|
|
1696
|
-
.demo-row
|
|
1697
|
-
.demo-label "Hover the buttons"
|
|
1698
|
-
. style: "display:flex;gap:12px"
|
|
1699
|
-
Tooltip text: "Save your changes", placement: "top"
|
|
1700
|
-
button.demo-btn
|
|
1701
|
-
"Save (top)"
|
|
1702
|
-
Tooltip text: "Delete this item", placement: "bottom"
|
|
1703
|
-
button.demo-btn
|
|
1704
|
-
"Delete (bottom)"
|
|
1705
|
-
.api
|
|
1706
|
-
dl
|
|
1707
|
-
dt "Props"
|
|
1708
|
-
dd
|
|
1709
|
-
code "@text"
|
|
1710
|
-
code "@placement"
|
|
1711
|
-
code "@delay"
|
|
1712
|
-
code "@offset"
|
|
1713
|
-
code "@hoverable"
|
|
1714
|
-
dt "Data"
|
|
1715
|
-
dd
|
|
1716
|
-
code "$open"
|
|
1717
|
-
code "$entering"
|
|
1718
|
-
code "$exiting"
|
|
1719
|
-
code "$placement"
|
|
1720
|
-
|
|
1721
|
-
# ========================================================================
|
|
1722
|
-
# PREVIEW CARD
|
|
1723
|
-
# ========================================================================
|
|
1724
|
-
.section id: "preview-card"
|
|
1725
|
-
SectionHead tag: "preview-card", name: "PreviewCard", lines: 56
|
|
1726
|
-
.section-desc "Hover or focus the link to see a preview card."
|
|
1727
|
-
.demo-row
|
|
1728
|
-
PreviewCard delay: 300
|
|
1729
|
-
a $trigger: true, href: "#preview-card", @click: ((e) => e.preventDefault())
|
|
1730
|
-
"Hover me for preview"
|
|
1731
|
-
div $content: true, hidden: true
|
|
1732
|
-
.floating-panel style: "width:240px"
|
|
1733
|
-
p.floating-title "Preview Card"
|
|
1734
|
-
p.floating-desc "This content appears on hover or focus. Useful for link previews."
|
|
1735
|
-
.api
|
|
1736
|
-
dl
|
|
1737
|
-
dt "Props"
|
|
1738
|
-
dd
|
|
1739
|
-
code "@delay"
|
|
1740
|
-
code "@closeDelay"
|
|
1741
|
-
dt "Data"
|
|
1742
|
-
dd
|
|
1743
|
-
code "$open"
|
|
1744
|
-
|
|
1745
|
-
# ========================================================================
|
|
1746
|
-
# TOAST
|
|
1747
|
-
# ========================================================================
|
|
1748
|
-
.section id: "toast"
|
|
1749
|
-
SectionHead tag: "toast", name: "Toast", lines: 56
|
|
1750
|
-
.section-desc "Auto-dismiss notification with ARIA live region."
|
|
1751
|
-
.demo-row
|
|
1752
|
-
.demo-label "Click to show toasts"
|
|
1753
|
-
button.demo-btn @click: (=> toasts = [...toasts, { message: 'Hello!', type: 'info' }])
|
|
1754
|
-
"Info Toast"
|
|
1755
|
-
button.demo-btn style: "margin-left:8px", @click: (=> toasts = [...toasts, { message: 'Saved!', type: 'success' }])
|
|
1756
|
-
"Success Toast"
|
|
1757
|
-
.toast-wrap
|
|
1758
|
-
ToastViewport toasts <=> toasts
|
|
1759
|
-
.api
|
|
1760
|
-
dl
|
|
1761
|
-
dt "Props"
|
|
1762
|
-
dd
|
|
1763
|
-
code "@toasts"
|
|
1764
|
-
code "@toast"
|
|
1765
|
-
code "@placement"
|
|
1766
|
-
dt "Events"
|
|
1767
|
-
dd
|
|
1768
|
-
code "dismiss"
|
|
1769
|
-
dt "Data"
|
|
1770
|
-
dd
|
|
1771
|
-
code "$placement"
|
|
1772
|
-
code "$type"
|
|
1773
|
-
code "$leaving"
|
|
1774
|
-
|
|
1775
|
-
# ========================================================================
|
|
1776
|
-
# BUTTON
|
|
1777
|
-
# ========================================================================
|
|
1778
|
-
.section id: "button"
|
|
1779
|
-
SectionHead tag: "button", name: "Button", lines: 10
|
|
1780
|
-
.section-desc "Headless button with disabled-but-focusable pattern."
|
|
1781
|
-
.demo-row.btn-demo
|
|
1782
|
-
.demo-label "Normal, primary, and disabled"
|
|
1783
|
-
.btn-row
|
|
1784
|
-
Button @press: (=> p "Pressed!")
|
|
1785
|
-
"Click Me"
|
|
1786
|
-
Button @press: (=> p "Saved!")
|
|
1787
|
-
"Save"
|
|
1788
|
-
Button disabled: true
|
|
1789
|
-
"Disabled"
|
|
1790
|
-
.api
|
|
1791
|
-
dl
|
|
1792
|
-
dt "Props"
|
|
1793
|
-
dd
|
|
1794
|
-
code "@disabled"
|
|
1795
|
-
dt "Events"
|
|
1796
|
-
dd
|
|
1797
|
-
code "press"
|
|
1798
|
-
dt "Data"
|
|
1799
|
-
dd
|
|
1800
|
-
code "$disabled"
|
|
1801
|
-
|
|
1802
|
-
# ========================================================================
|
|
1803
|
-
# BADGE
|
|
1804
|
-
# ========================================================================
|
|
1805
|
-
.section id: "badge"
|
|
1806
|
-
SectionHead tag: "badge", name: "Badge", lines: 5
|
|
1807
|
-
.section-desc "Inline label with variant styles."
|
|
1808
|
-
.demo-row
|
|
1809
|
-
.demo-label "Variants"
|
|
1810
|
-
. style: "display:flex;gap:8px;align-items:center"
|
|
1811
|
-
Badge "Solid"
|
|
1812
|
-
Badge variant: "outline", "Outline"
|
|
1813
|
-
Badge variant: "subtle", "Subtle"
|
|
1814
|
-
.api
|
|
1815
|
-
dl
|
|
1816
|
-
dt "Props"
|
|
1817
|
-
dd
|
|
1818
|
-
code "@variant"
|
|
1819
|
-
dt "Data"
|
|
1820
|
-
dd
|
|
1821
|
-
code "$variant"
|
|
1822
|
-
|
|
1823
|
-
# ========================================================================
|
|
1824
|
-
# CARD
|
|
1825
|
-
# ========================================================================
|
|
1826
|
-
.section id: "card"
|
|
1827
|
-
SectionHead tag: "card", name: "Card", lines: 6
|
|
1828
|
-
.section-desc "Structured container with header, content, and footer."
|
|
1829
|
-
.demo-row.card-demo
|
|
1830
|
-
Card
|
|
1831
|
-
div $header: true
|
|
1832
|
-
h3 "Card Title"
|
|
1833
|
-
div $content: true
|
|
1834
|
-
"This is the card body. Cards can contain any content."
|
|
1835
|
-
div $footer: true
|
|
1836
|
-
button.demo-btn @click: (=> toasts = [...toasts, { message: 'Card action clicked!', type: 'success' }]), "Action"
|
|
1837
|
-
.api
|
|
1838
|
-
dl
|
|
1839
|
-
dt "Props"
|
|
1840
|
-
dd
|
|
1841
|
-
code "@interactive"
|
|
1842
|
-
dt "Data"
|
|
1843
|
-
dd
|
|
1844
|
-
code "$interactive"
|
|
1845
|
-
|
|
1846
|
-
# ========================================================================
|
|
1847
|
-
# SEPARATOR
|
|
1848
|
-
# ========================================================================
|
|
1849
|
-
.section id: "separator"
|
|
1850
|
-
SectionHead tag: "separator", name: "Separator", lines: 7
|
|
1851
|
-
.section-desc "Decorative or semantic divider between sections."
|
|
1852
|
-
.demo-row
|
|
1853
|
-
.demo-label "Horizontal (default)"
|
|
1854
|
-
div style: "width:100%"
|
|
1855
|
-
p "Above the separator"
|
|
1856
|
-
Separator
|
|
1857
|
-
p "Below the separator"
|
|
1858
|
-
.demo-row
|
|
1859
|
-
.demo-label "Vertical"
|
|
1860
|
-
div style: "display:flex;align-items:center;gap:12px;height:32px"
|
|
1861
|
-
span "Left"
|
|
1862
|
-
Separator orientation: "vertical"
|
|
1863
|
-
span "Right"
|
|
1864
|
-
.api
|
|
1865
|
-
dl
|
|
1866
|
-
dt "Props"
|
|
1867
|
-
dd
|
|
1868
|
-
code "@orientation"
|
|
1869
|
-
code "@decorative"
|
|
1870
|
-
dt "Data"
|
|
1871
|
-
dd
|
|
1872
|
-
code "$orientation"
|
|
1873
|
-
|
|
1874
|
-
# ========================================================================
|
|
1875
|
-
# PROGRESS
|
|
1876
|
-
# ========================================================================
|
|
1877
|
-
.section id: "progress"
|
|
1878
|
-
SectionHead tag: "progress", name: "Progress", lines: 14
|
|
1879
|
-
.section-desc "Progress bar with value exposed as CSS custom property."
|
|
1880
|
-
.demo-row
|
|
1881
|
-
.demo-label "65% complete"
|
|
1882
|
-
Progress value: progressVal
|
|
1883
|
-
div.progress-track
|
|
1884
|
-
div.progress-fill style: "width: var(--progress-percent)"
|
|
1885
|
-
.api
|
|
1886
|
-
dl
|
|
1887
|
-
dt "Props"
|
|
1888
|
-
dd
|
|
1889
|
-
code "@value"
|
|
1890
|
-
code "@max"
|
|
1891
|
-
code "@label"
|
|
1892
|
-
dt "Data"
|
|
1893
|
-
dd
|
|
1894
|
-
code "$complete"
|
|
1895
|
-
|
|
1896
|
-
# ========================================================================
|
|
1897
|
-
# METER
|
|
1898
|
-
# ========================================================================
|
|
1899
|
-
.section id: "meter"
|
|
1900
|
-
SectionHead tag: "meter", name: "Meter", lines: 23
|
|
1901
|
-
.section-desc "Gauge for known-range measurements with low/high/optimum thresholds."
|
|
1902
|
-
.demo-row
|
|
1903
|
-
.demo-label "Score: 72/100"
|
|
1904
|
-
Meter value: meterVal, min: 0, max: 100, low: 30, high: 80, optimum: 60
|
|
1905
|
-
.api
|
|
1906
|
-
dl
|
|
1907
|
-
dt "Props"
|
|
1908
|
-
dd
|
|
1909
|
-
code "@value"
|
|
1910
|
-
code "@min"
|
|
1911
|
-
code "@max"
|
|
1912
|
-
code "@low"
|
|
1913
|
-
code "@high"
|
|
1914
|
-
code "@optimum"
|
|
1915
|
-
code "@label"
|
|
1916
|
-
dt "Data"
|
|
1917
|
-
dd
|
|
1918
|
-
code "$level"
|
|
1919
|
-
|
|
1920
|
-
# ========================================================================
|
|
1921
|
-
# SPINNER
|
|
1922
|
-
# ========================================================================
|
|
1923
|
-
.section id: "spinner"
|
|
1924
|
-
SectionHead tag: "spinner", name: "Spinner", lines: 6
|
|
1925
|
-
.section-desc "Loading indicator with accessible status."
|
|
1926
|
-
.demo-row.spinner-demo
|
|
1927
|
-
.demo-label "Default"
|
|
1928
|
-
. style: "display:flex;gap:16px;align-items:center"
|
|
1929
|
-
Spinner
|
|
1930
|
-
Spinner size: "32px"
|
|
1931
|
-
Spinner label: "Saving...", size: "20px"
|
|
1932
|
-
.api
|
|
1933
|
-
dl
|
|
1934
|
-
dt "Props"
|
|
1935
|
-
dd
|
|
1936
|
-
code "@label"
|
|
1937
|
-
code "@size"
|
|
1938
|
-
|
|
1939
|
-
# ========================================================================
|
|
1940
|
-
# SKELETON
|
|
1941
|
-
# ========================================================================
|
|
1942
|
-
.section id: "skeleton"
|
|
1943
|
-
SectionHead tag: "skeleton", name: "Skeleton", lines: 10
|
|
1944
|
-
.section-desc "Loading placeholder with shimmer animation."
|
|
1945
|
-
.demo-row
|
|
1946
|
-
.demo-label "Shapes"
|
|
1947
|
-
. style: "display:flex;gap:12px;align-items:center"
|
|
1948
|
-
Skeleton circle: true, width: "40px", height: "40px"
|
|
1949
|
-
. style: "display:flex;flex-direction:column;gap:6px"
|
|
1950
|
-
Skeleton width: "200px", height: "14px"
|
|
1951
|
-
Skeleton width: "150px", height: "14px"
|
|
1952
|
-
.api
|
|
1953
|
-
dl
|
|
1954
|
-
dt "Props"
|
|
1955
|
-
dd
|
|
1956
|
-
code "@width"
|
|
1957
|
-
code "@height"
|
|
1958
|
-
code "@circle"
|
|
1959
|
-
code "@label"
|
|
1960
|
-
dt "Data"
|
|
1961
|
-
dd
|
|
1962
|
-
code "$circle"
|
|
1963
|
-
|
|
1964
|
-
# ========================================================================
|
|
1965
|
-
# AVATAR
|
|
1966
|
-
# ========================================================================
|
|
1967
|
-
.section id: "avatar"
|
|
1968
|
-
SectionHead tag: "avatar", name: "Avatar", lines: 23
|
|
1969
|
-
.section-desc "Image with fallback to initials or placeholder."
|
|
1970
|
-
.demo-row
|
|
1971
|
-
.demo-label "With image"
|
|
1972
|
-
Avatar src: "https://i.pravatar.cc/80?u=linda", alt: "Alice Chen"
|
|
1973
|
-
.demo-row
|
|
1974
|
-
.demo-label "Initials fallback"
|
|
1975
|
-
Avatar alt: "Bob Park", fallback: "BP"
|
|
1976
|
-
.demo-row
|
|
1977
|
-
.demo-label "Placeholder"
|
|
1978
|
-
Avatar
|
|
1979
|
-
.api
|
|
1980
|
-
dl
|
|
1981
|
-
dt "Props"
|
|
1982
|
-
dd
|
|
1983
|
-
code "@src"
|
|
1984
|
-
code "@alt"
|
|
1985
|
-
code "@fallback"
|
|
1986
|
-
dt "Data"
|
|
1987
|
-
dd
|
|
1988
|
-
code "$status"
|
|
1989
|
-
code "$initials"
|
|
1990
|
-
code "$placeholder"
|
|
1991
|
-
|
|
1992
|
-
# ========================================================================
|
|
1993
|
-
# LABEL
|
|
1994
|
-
# ========================================================================
|
|
1995
|
-
.section id: "label"
|
|
1996
|
-
SectionHead tag: "label", name: "Label", lines: 6
|
|
1997
|
-
.section-desc "Standalone accessible form label."
|
|
1998
|
-
.demo-row
|
|
1999
|
-
.demo-label "With required indicator"
|
|
2000
|
-
Label required: true
|
|
2001
|
-
"Email address"
|
|
2002
|
-
.api
|
|
2003
|
-
dl
|
|
2004
|
-
dt "Props"
|
|
2005
|
-
dd
|
|
2006
|
-
code "@for"
|
|
2007
|
-
code "@required"
|
|
2008
|
-
dt "Data"
|
|
2009
|
-
dd
|
|
2010
|
-
code "$required"
|
|
2011
|
-
|
|
2012
|
-
# ========================================================================
|
|
2013
|
-
# SCROLL AREA
|
|
2014
|
-
# ========================================================================
|
|
2015
|
-
.section id: "scroll-area"
|
|
2016
|
-
SectionHead tag: "scroll-area", name: "ScrollArea", lines: 115
|
|
2017
|
-
.section-desc "Custom scrollbar with draggable thumb and auto-hide."
|
|
2018
|
-
.demo-row
|
|
2019
|
-
.demo-label "Scrollable content"
|
|
2020
|
-
.scroll-demo
|
|
2021
|
-
ScrollArea
|
|
2022
|
-
div style: "padding: 4px 12px"
|
|
2023
|
-
p "Item 1 — Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
|
2024
|
-
p "Item 2 — Sed do eiusmod tempor incididunt ut labore et dolore."
|
|
2025
|
-
p "Item 3 — Ut enim ad minim veniam, quis nostrud exercitation."
|
|
2026
|
-
p "Item 4 — Duis aute irure dolor in reprehenderit in voluptate."
|
|
2027
|
-
p "Item 5 — Excepteur sint occaecat cupidatat non proident."
|
|
2028
|
-
p "Item 6 — Sunt in culpa qui officia deserunt mollit anim id."
|
|
2029
|
-
p "Item 7 — Lorem ipsum dolor sit amet, consectetur adipiscing."
|
|
2030
|
-
p "Item 8 — Sed do eiusmod tempor incididunt ut labore et dolore."
|
|
2031
|
-
p "Item 9 — Ut enim ad minim veniam, quis nostrud exercitation."
|
|
2032
|
-
p "Item 10 — Duis aute irure dolor in reprehenderit in voluptate."
|
|
2033
|
-
p "Item 11 — Excepteur sint occaecat cupidatat non proident."
|
|
2034
|
-
p "Item 12 — Sunt in culpa qui officia deserunt mollit anim id."
|
|
2035
|
-
p "Item 13 — Lorem ipsum dolor sit amet, consectetur adipiscing."
|
|
2036
|
-
p "Item 14 — Sed do eiusmod tempor incididunt ut labore et dolore."
|
|
2037
|
-
p "Item 15 — Ut enim ad minim veniam, quis nostrud exercitation."
|
|
2038
|
-
.api
|
|
2039
|
-
dl
|
|
2040
|
-
dt "Props"
|
|
2041
|
-
dd
|
|
2042
|
-
code "@orientation"
|
|
2043
|
-
dt "Data"
|
|
2044
|
-
dd
|
|
2045
|
-
code "$orientation"
|
|
2046
|
-
code "$hovering"
|
|
2047
|
-
code "$scrolling"
|
|
2048
|
-
code "$dragging"
|
|
2049
|
-
code "$viewport"
|
|
2050
|
-
code "$scrollbar"
|
|
2051
|
-
code "$thumb"
|
|
2052
|
-
|
|
2053
|
-
# ========================================================================
|
|
2054
|
-
# FIELD + FIELDSET
|
|
2055
|
-
# ========================================================================
|
|
2056
|
-
.section id: "field"
|
|
2057
|
-
SectionHead tag: "field", name: "Field + Fieldset", lines: 48
|
|
2058
|
-
.section-desc "Form field wrapper with label, description, and error."
|
|
2059
|
-
.demo-row
|
|
2060
|
-
Field label: "Email", description: "We'll never share your email.", required: true, error: fieldError
|
|
2061
|
-
input type: "email", placeholder: "you@example.com", value: fieldEmail
|
|
2062
|
-
@input: (e) =>
|
|
2063
|
-
fieldEmail = e.target.value
|
|
2064
|
-
fieldError = if fieldEmail and not fieldEmail.includes('@') then 'Invalid email address' else ''
|
|
2065
|
-
.demo-row
|
|
2066
|
-
Fieldset legend: "Account Info"
|
|
2067
|
-
Field label: "Username"
|
|
2068
|
-
input type: "text", placeholder: "username"
|
|
2069
|
-
Field label: "Password"
|
|
2070
|
-
input type: "password", placeholder: "password"
|
|
2071
|
-
.api
|
|
2072
|
-
dl
|
|
2073
|
-
dt "Field"
|
|
2074
|
-
dd
|
|
2075
|
-
code "@label"
|
|
2076
|
-
code "@description"
|
|
2077
|
-
code "@error"
|
|
2078
|
-
code "@disabled"
|
|
2079
|
-
code "@required"
|
|
2080
|
-
dt "Fieldset"
|
|
2081
|
-
dd
|
|
2082
|
-
code "@legend"
|
|
2083
|
-
code "@disabled"
|
|
2084
|
-
dt "Data"
|
|
2085
|
-
dd
|
|
2086
|
-
code "$disabled"
|
|
2087
|
-
code "$invalid"
|
|
2088
|
-
code "$label"
|
|
2089
|
-
code "$required"
|
|
2090
|
-
code "$description"
|
|
2091
|
-
code "$error"
|
|
2092
|
-
code "$legend"
|
|
2093
|
-
|
|
2094
|
-
# ========================================================================
|
|
2095
|
-
# FORM
|
|
2096
|
-
# ========================================================================
|
|
2097
|
-
.section id: "form"
|
|
2098
|
-
SectionHead tag: "form", name: "Form", lines: 21
|
|
2099
|
-
.section-desc "Form wrapper with submit handling and validation state."
|
|
2100
|
-
.demo-row
|
|
2101
|
-
Form
|
|
2102
|
-
Field label: "Name"
|
|
2103
|
-
input type: "text", placeholder: "Your name"
|
|
2104
|
-
Field label: "Email"
|
|
2105
|
-
input type: "email", placeholder: "you@example.com"
|
|
2106
|
-
button type: "submit"
|
|
2107
|
-
"Submit"
|
|
2108
|
-
.api
|
|
2109
|
-
dl
|
|
2110
|
-
dt "Props"
|
|
2111
|
-
dd
|
|
2112
|
-
code "@disabled"
|
|
2113
|
-
dt "Events"
|
|
2114
|
-
dd
|
|
2115
|
-
code "submit"
|
|
2116
|
-
dt "Data"
|
|
2117
|
-
dd
|
|
2118
|
-
code "$disabled"
|
|
2119
|
-
code "$submitting"
|
|
2120
|
-
code "$submitted"
|
|
2121
|
-
|
|
2122
|
-
# ========================================================================
|
|
2123
|
-
# BUTTON GROUP
|
|
2124
|
-
# ========================================================================
|
|
2125
|
-
.section id: "button-group"
|
|
2126
|
-
SectionHead tag: "button-group", name: "ButtonGroup", lines: 11
|
|
2127
|
-
.section-desc "Groups related buttons with ARIA group semantics."
|
|
2128
|
-
.demo-row
|
|
2129
|
-
.demo-label "Horizontal"
|
|
2130
|
-
ButtonGroup label: "Actions"
|
|
2131
|
-
button "Cut"
|
|
2132
|
-
button "Copy"
|
|
2133
|
-
button "Paste"
|
|
2134
|
-
.api
|
|
2135
|
-
dl
|
|
2136
|
-
dt "Props"
|
|
2137
|
-
dd
|
|
2138
|
-
code "@orientation"
|
|
2139
|
-
code "@disabled"
|
|
2140
|
-
code "@label"
|
|
2141
|
-
dt "Data"
|
|
2142
|
-
dd
|
|
2143
|
-
code "$orientation"
|
|
2144
|
-
code "$disabled"
|
|
2145
|
-
|
|
2146
|
-
# ========================================================================
|
|
2147
|
-
# GRID
|
|
2148
|
-
# ========================================================================
|
|
2149
|
-
.section id: "grid"
|
|
2150
|
-
SectionHead tag: "grid", name: "Grid", lines: 799
|
|
2151
|
-
.section-desc "Virtual-scrolling data grid. Click to select, arrows to navigate, double-click to edit."
|
|
2152
|
-
.demo-row
|
|
2153
|
-
. style: "display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px"
|
|
2154
|
-
.demo-label style: "margin-bottom:0", "#{gridData.length} rows, #{gridColumns.length} columns"
|
|
2155
|
-
span.grid-cell-ref gridCellRef
|
|
2156
|
-
Grid data: gridData, columns: gridColumns, striped: true
|
|
2157
|
-
. style: "margin-top:12px;display:flex;gap:8px;align-items:center"
|
|
2158
|
-
button.demo-btn @click: (=> @_loadGridRows(1000))
|
|
2159
|
-
"1K rows"
|
|
2160
|
-
button.demo-btn @click: (=> @_loadGridRows(10000))
|
|
2161
|
-
"10K rows"
|
|
2162
|
-
button.demo-btn @click: (=> @_loadGridRows(100000))
|
|
2163
|
-
"100K rows"
|
|
2164
|
-
.api
|
|
2165
|
-
dl
|
|
2166
|
-
dt "Props"
|
|
2167
|
-
dd
|
|
2168
|
-
code "@data"
|
|
2169
|
-
code "@columns"
|
|
2170
|
-
code "@rowHeight"
|
|
2171
|
-
code "@overscan"
|
|
2172
|
-
code "@striped"
|
|
2173
|
-
code "@beforeEdit"
|
|
2174
|
-
code "@afterEdit"
|
|
2175
|
-
dt "Keyboard"
|
|
2176
|
-
dd
|
|
2177
|
-
kbd "Arrows"
|
|
2178
|
-
kbd "Tab"
|
|
2179
|
-
kbd "Enter"
|
|
2180
|
-
kbd "F2"
|
|
2181
|
-
kbd "Esc"
|
|
2182
|
-
kbd "Home"
|
|
2183
|
-
kbd "End"
|
|
2184
|
-
kbd "PgUp"
|
|
2185
|
-
kbd "PgDn"
|
|
2186
|
-
kbd "Ctrl+A"
|
|
2187
|
-
kbd "Ctrl+C"
|
|
2188
|
-
kbd "Ctrl+V"
|
|
2189
|
-
kbd "Ctrl+X"
|
|
2190
|
-
dt "Data"
|
|
2191
|
-
dd
|
|
2192
|
-
code "$editing"
|
|
2193
|
-
code "$selecting"
|
|
2194
|
-
code "$sorted"
|
|
2195
|
-
|
|
2196
|
-
# ========================================================================
|
|
2197
|
-
# ACCORDION
|
|
2198
|
-
# ========================================================================
|
|
2199
|
-
.section id: "accordion"
|
|
2200
|
-
SectionHead tag: "accordion", name: "Accordion", lines: 86
|
|
2201
|
-
.section-desc "Expand/collapse sections, single or multiple mode."
|
|
2202
|
-
.demo-row
|
|
2203
|
-
.demo-label "Single mode"
|
|
2204
|
-
Accordion
|
|
2205
|
-
div data-item: "a"
|
|
2206
|
-
button.accordion-trigger data-trigger: true
|
|
2207
|
-
"Section A"
|
|
2208
|
-
div.accordion-content data-content: true
|
|
2209
|
-
p "Content for section A."
|
|
2210
|
-
div data-item: "b"
|
|
2211
|
-
button.accordion-trigger data-trigger: true
|
|
2212
|
-
"Section B"
|
|
2213
|
-
div.accordion-content data-content: true
|
|
2214
|
-
p "Content for section B."
|
|
2215
|
-
div data-item: "c"
|
|
2216
|
-
button.accordion-trigger data-trigger: true
|
|
2217
|
-
"Section C"
|
|
2218
|
-
div.accordion-content data-content: true
|
|
2219
|
-
p "Content for section C."
|
|
2220
|
-
.api
|
|
2221
|
-
dl
|
|
2222
|
-
dt "Props"
|
|
2223
|
-
dd
|
|
2224
|
-
code "@multiple"
|
|
2225
|
-
dt "Events"
|
|
2226
|
-
dd
|
|
2227
|
-
code "change"
|
|
2228
|
-
dt "Keyboard"
|
|
2229
|
-
dd
|
|
2230
|
-
kbd "Enter"
|
|
2231
|
-
kbd "Space"
|
|
2232
|
-
kbd "↕"
|
|
2233
|
-
kbd "Home"
|
|
2234
|
-
kbd "End"
|
|
2235
|
-
dt "Data"
|
|
2236
|
-
dd
|
|
2237
|
-
code "$item"
|
|
2238
|
-
code "$trigger"
|
|
2239
|
-
code "$content"
|
|
2240
|
-
code "$open"
|
|
2241
|
-
code "$disabled"
|
|
2242
|
-
|
|
2243
|
-
# ========================================================================
|
|
2244
|
-
# TABLE
|
|
2245
|
-
# ========================================================================
|
|
2246
|
-
.section id: "table"
|
|
2247
|
-
SectionHead tag: "table", name: "Table", lines: 9
|
|
2248
|
-
.section-desc "Semantic table wrapper. For data-heavy tables, use Grid."
|
|
2249
|
-
.demo-row.table-demo
|
|
2250
|
-
Table caption: "Team", striped: true
|
|
2251
|
-
thead
|
|
2252
|
-
tr
|
|
2253
|
-
th "Name"
|
|
2254
|
-
th "Role"
|
|
2255
|
-
th "City"
|
|
2256
|
-
tbody
|
|
2257
|
-
tr
|
|
2258
|
-
td "Alice"
|
|
2259
|
-
td "Engineer"
|
|
2260
|
-
td "Seattle"
|
|
2261
|
-
tr
|
|
2262
|
-
td "Bob"
|
|
2263
|
-
td "Designer"
|
|
2264
|
-
td "Portland"
|
|
2265
|
-
tr
|
|
2266
|
-
td "Carol"
|
|
2267
|
-
td "Manager"
|
|
2268
|
-
td "Denver"
|
|
2269
|
-
.api
|
|
2270
|
-
dl
|
|
2271
|
-
dt "Props"
|
|
2272
|
-
dd
|
|
2273
|
-
code "@caption"
|
|
2274
|
-
code "@striped"
|
|
2275
|
-
dt "Data"
|
|
2276
|
-
dd
|
|
2277
|
-
code "$striped"
|
|
2278
|
-
|
|
2279
|
-
# ========================================================================
|
|
2280
|
-
# COLLAPSIBLE
|
|
2281
|
-
# ========================================================================
|
|
2282
|
-
.section id: "collapsible"
|
|
2283
|
-
SectionHead tag: "collapsible", name: "Collapsible", lines: 33
|
|
2284
|
-
.section-desc "Single open/close section. Simpler than Accordion."
|
|
2285
|
-
.demo-row.collapsible-demo
|
|
2286
|
-
Collapsible open <=> collapsibleOpen
|
|
2287
|
-
button $trigger: true
|
|
2288
|
-
span style: "font-size:10px;margin-right:6px"
|
|
2289
|
-
if collapsibleOpen then "▼" else "▶"
|
|
2290
|
-
"Show details"
|
|
2291
|
-
div $content: true
|
|
2292
|
-
p "These are the collapsible details. Click the trigger or press Enter/Space to toggle."
|
|
2293
|
-
.status "open: #{collapsibleOpen}"
|
|
2294
|
-
.api
|
|
2295
|
-
dl
|
|
2296
|
-
dt "Props"
|
|
2297
|
-
dd
|
|
2298
|
-
code "@open"
|
|
2299
|
-
code "@disabled"
|
|
2300
|
-
dt "Events"
|
|
2301
|
-
dd
|
|
2302
|
-
code "change"
|
|
2303
|
-
dt "Keyboard"
|
|
2304
|
-
dd
|
|
2305
|
-
kbd "Enter"
|
|
2306
|
-
kbd "Space"
|
|
2307
|
-
dt "Data"
|
|
2308
|
-
dd
|
|
2309
|
-
code "$open"
|
|
2310
|
-
code "$disabled"
|
|
2311
|
-
|
|
2312
|
-
# ========================================================================
|
|
2313
|
-
# PAGINATION
|
|
2314
|
-
# ========================================================================
|
|
2315
|
-
.section id: "pagination"
|
|
2316
|
-
SectionHead tag: "pagination", name: "Pagination", lines: 96
|
|
2317
|
-
.section-desc "Page navigation with prev/next buttons and ellipsis gaps."
|
|
2318
|
-
.demo-row
|
|
2319
|
-
.demo-label "10 pages"
|
|
2320
|
-
Pagination page <=> currentPage, total: 100, perPage: 10
|
|
2321
|
-
.status "page: #{currentPage}"
|
|
2322
|
-
.api
|
|
2323
|
-
dl
|
|
2324
|
-
dt "Props"
|
|
2325
|
-
dd
|
|
2326
|
-
code "@page"
|
|
2327
|
-
code "@total"
|
|
2328
|
-
code "@perPage"
|
|
2329
|
-
code "@siblingCount"
|
|
2330
|
-
dt "Events"
|
|
2331
|
-
dd
|
|
2332
|
-
code "change"
|
|
2333
|
-
dt "Keyboard"
|
|
2334
|
-
dd
|
|
2335
|
-
kbd "← →"
|
|
2336
|
-
kbd "Home"
|
|
2337
|
-
kbd "End"
|
|
2338
|
-
dt "Data"
|
|
2339
|
-
dd
|
|
2340
|
-
code "$active"
|
|
2341
|
-
code "$disabled"
|
|
2342
|
-
code "$ellipsis"
|
|
2343
|
-
|
|
2344
|
-
# ========================================================================
|
|
2345
|
-
# CAROUSEL
|
|
2346
|
-
# ========================================================================
|
|
2347
|
-
.section id: "carousel"
|
|
2348
|
-
SectionHead tag: "carousel", name: "Carousel", lines: 78
|
|
2349
|
-
.section-desc "Slide carousel with loop and keyboard navigation."
|
|
2350
|
-
.demo-row
|
|
2351
|
-
Carousel loop: true
|
|
2352
|
-
div $slide: true
|
|
2353
|
-
"🍎 Slide 1 — Apples"
|
|
2354
|
-
div $slide: true
|
|
2355
|
-
"🍌 Slide 2 — Bananas"
|
|
2356
|
-
div $slide: true
|
|
2357
|
-
"🍒 Slide 3 — Cherries"
|
|
2358
|
-
.api
|
|
2359
|
-
dl
|
|
2360
|
-
dt "Props"
|
|
2361
|
-
dd
|
|
2362
|
-
code "@orientation"
|
|
2363
|
-
code "@loop"
|
|
2364
|
-
code "@autoplay"
|
|
2365
|
-
code "@interval"
|
|
2366
|
-
code "@label"
|
|
2367
|
-
dt "Events"
|
|
2368
|
-
dd
|
|
2369
|
-
code "change"
|
|
2370
|
-
dt "Keyboard"
|
|
2371
|
-
dd
|
|
2372
|
-
kbd "← →"
|
|
2373
|
-
kbd "↕"
|
|
2374
|
-
kbd "Home"
|
|
2375
|
-
kbd "End"
|
|
2376
|
-
dt "Data"
|
|
2377
|
-
dd
|
|
2378
|
-
code "$orientation"
|
|
2379
|
-
code "$active"
|
|
2380
|
-
code "$prev"
|
|
2381
|
-
code "$next"
|
|
2382
|
-
|
|
2383
|
-
# ========================================================================
|
|
2384
|
-
# RESIZABLE
|
|
2385
|
-
# ========================================================================
|
|
2386
|
-
.section id: "resizable"
|
|
2387
|
-
SectionHead tag: "resizable", name: "Resizable", lines: 89
|
|
2388
|
-
.section-desc "Draggable resize handles between panels."
|
|
2389
|
-
.demo-row.resizable-demo
|
|
2390
|
-
Resizable
|
|
2391
|
-
div $panel: true, "Left"
|
|
2392
|
-
div $handle: true
|
|
2393
|
-
div $panel: true, "Right"
|
|
2394
|
-
.api
|
|
2395
|
-
dl
|
|
2396
|
-
dt "Props"
|
|
2397
|
-
dd
|
|
2398
|
-
code "@orientation"
|
|
2399
|
-
code "@minSize"
|
|
2400
|
-
code "@maxSize"
|
|
2401
|
-
dt "Events"
|
|
2402
|
-
dd
|
|
2403
|
-
code "resize"
|
|
2404
|
-
dt "Keyboard"
|
|
2405
|
-
dd
|
|
2406
|
-
kbd "← →"
|
|
2407
|
-
kbd "↕"
|
|
2408
|
-
dt "Data"
|
|
2409
|
-
dd
|
|
2410
|
-
code "$orientation"
|
|
2411
|
-
code "$dragging"
|
|
2412
|
-
|
|
2413
|
-
# ========================================================================
|
|
2414
|
-
# SOURCE CODE VIEWER
|
|
2415
|
-
# ========================================================================
|
|
2416
|
-
if sourceCode
|
|
2417
|
-
.source-overlay @click: (=> @_closeSource())
|
|
2418
|
-
.source-modal @click: (e => e.stopPropagation())
|
|
2419
|
-
.source-header
|
|
2420
|
-
.source-title
|
|
2421
|
-
span.source-name sourceName
|
|
2422
|
-
span.source-badge "#{sourceLines} lines"
|
|
2423
|
-
button.source-close @click: (=> @_closeSource())
|
|
2424
|
-
"×"
|
|
2425
|
-
.source-body
|
|
2426
|
-
pre.source-pre
|
|
2427
|
-
span.source-gutter
|
|
2428
|
-
code.source-code
|
|
2429
|
-
|
|
2430
|
-
</script>
|
|
2431
|
-
|
|
2432
|
-
</body>
|
|
2433
|
-
</html>
|