@lumiose/ui 0.1.1 → 0.1.3
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 +2 -2
- package/dist/accordion/accordion.tsx +6 -4
- package/dist/autocomplete/autocomplete.tsx +6 -5
- package/dist/avatar/avatar.tsx +4 -3
- package/dist/batched.ts +11 -0
- package/dist/checkbox/checkbox.tsx +4 -3
- package/dist/checkbox-group/checkbox-group.tsx +3 -2
- package/dist/collapsible/collapsible.tsx +5 -3
- package/dist/collapsible/panel.ts +3 -1
- package/dist/combobox/combobox.tsx +8 -6
- package/dist/combobox/context.ts +2 -1
- package/dist/context-menu/context-menu.tsx +6 -4
- package/dist/dialog/dialog.tsx +4 -2
- package/dist/drawer/drawer.tsx +2 -1
- package/dist/field/field.tsx +13 -11
- package/dist/form/reset.ts +4 -2
- package/dist/input/input.tsx +4 -1
- package/dist/menu/menu.tsx +13 -11
- package/dist/meter/meter.tsx +2 -1
- package/dist/navigation-menu/navigation-menu.tsx +6 -4
- package/dist/not-inside.ts +13 -0
- package/dist/number-field/number-field.tsx +6 -4
- package/dist/otp-field/otp-field.tsx +11 -9
- package/dist/popover/hover.ts +2 -1
- package/dist/popover/popover-hover.script.ts +27 -0
- package/dist/popover/popover.script.ts +19 -25
- package/dist/popover/popover.tsx +18 -9
- package/dist/preview-card/preview-card.tsx +4 -2
- package/dist/progress/progress.tsx +2 -1
- package/dist/radio-group/radio-group.tsx +5 -3
- package/dist/select/select.script.ts +26 -0
- package/dist/select/select.tsx +43 -11
- package/dist/slider/slider.tsx +6 -4
- package/dist/switch/switch.tsx +4 -3
- package/dist/tabs/tabs.tsx +5 -3
- package/dist/toast/toast.tsx +5 -3
- package/dist/toggle/toggle.tsx +6 -5
- package/dist/toggle-group/toggle-group.script.ts +12 -4
- package/dist/toggle-group/toggle-group.tsx +16 -4
- package/dist/toolbar/toolbar.tsx +2 -1
- package/dist/tooltip/tooltip.tsx +6 -2
- package/docs/README.md +16 -7
- package/docs/accordion.md +3 -2
- package/docs/autocomplete.md +2 -2
- package/docs/avatar.md +2 -2
- package/docs/checkbox-group.md +1 -1
- package/docs/checkbox.md +1 -1
- package/docs/collapsible.md +4 -3
- package/docs/combobox.md +4 -3
- package/docs/context-menu.md +3 -3
- package/docs/dialog.md +1 -1
- package/docs/drawer.md +3 -2
- package/docs/field.md +2 -2
- package/docs/installation.md +3 -3
- package/docs/llms-full.txt +114 -73
- package/docs/llms.txt +14 -14
- package/docs/menu.md +4 -3
- package/docs/menubar.md +3 -3
- package/docs/navigation-menu.md +4 -3
- package/docs/otp-field.md +2 -2
- package/docs/popover.md +7 -4
- package/docs/preview-card.md +4 -3
- package/docs/radio-group.md +1 -1
- package/docs/select.md +25 -10
- package/docs/tabs.md +1 -1
- package/docs/toast.md +2 -2
- package/docs/toggle-group.md +10 -4
- package/docs/toolbar.md +2 -2
- package/docs/tooltip.md +4 -3
- package/package.json +5 -5
package/docs/llms-full.txt
CHANGED
|
@@ -13,9 +13,8 @@ props, events and styling hooks. The Lumiose docs: `node_modules/lumiose/docs/ll
|
|
|
13
13
|
|
|
14
14
|
> `@lumiose/ui`: accessible, unstyled UI primitives built on native elements (`<dialog>`, popover, invoker commands, CSS anchor positioning), server-rendered without hydration. Style them with your own CSS or the optional default theme.
|
|
15
15
|
|
|
16
|
-
**Status:** in development. `@lumiose/ui` keeps its own 0.x versions, apart from
|
|
17
|
-
other Lumiose packages share
|
|
18
|
-
workspace. The goal for its 1.0 is parity with [Base UI](https://base-ui.com)'s components; the
|
|
16
|
+
**Status:** in development. `@lumiose/ui` is on npm and keeps its own 0.x versions, apart from
|
|
17
|
+
the version all other Lumiose packages share. The goal for its 1.0 is parity with [Base UI](https://base-ui.com)'s components; the
|
|
19
18
|
table below lists them as they land.
|
|
20
19
|
|
|
21
20
|
These pages ship in the package, in `node_modules/@lumiose/ui/docs`, so they match the installed
|
|
@@ -43,12 +42,19 @@ Anatomy, API, Example, Styling, Keyboard and focus, Without JavaScript, Browser
|
|
|
43
42
|
runtime.
|
|
44
43
|
- **Parts.** Each component is a set of parts named as in Base UI (`Dialog.Root`,
|
|
45
44
|
`Dialog.Trigger`, `Dialog.Popup`, …). Every part that renders an element takes that element's
|
|
46
|
-
props (`class`, `style`, `aria-*`, events) and passes them through.
|
|
45
|
+
props (`class`, `style`, `aria-*`, events) and passes them through. A part finds its `Root`
|
|
46
|
+
through context, so a `Root` and its parts render on the same side of an island boundary, even
|
|
47
|
+
where the JSX nests them. A part the page passes to an island as a slot (children or a JSX prop)
|
|
48
|
+
renders in the page, outside the `Root` the island renders, and the server throws "Combobox
|
|
49
|
+
parts must be inside <Combobox.Root>"; an island inside a `Root` the page renders does not see
|
|
50
|
+
that `Root` either. Pass the data as props and render the `Root` and its parts inside the
|
|
51
|
+
island ([Islands](https://itsjavi.com/lumiose/docs/concepts/islands/)).
|
|
47
52
|
- **Signals.** A component's state is a prop and a callback: `open` with `onOpenChange`, `checked`
|
|
48
53
|
with `onCheckedChange`, `value` with `onValueChange`. Pass a signal's value and write it back in
|
|
49
54
|
the callback to keep both in sync, or leave both out and the element keeps its own state. Custom
|
|
50
55
|
elements report changes with lowercase DOM events, like native ones: `openchange`,
|
|
51
|
-
`checkedchange` and `change`.
|
|
56
|
+
`checkedchange` and `change`. The callbacks run inside `batch()`, as event handlers do: what
|
|
57
|
+
they write renders together, and the DOM is current as soon as the event returns.
|
|
52
58
|
- **Keyboard contracts.** Every component follows its WAI-ARIA Authoring Practices pattern, and
|
|
53
59
|
its end-to-end tests check the keyboard paths.
|
|
54
60
|
- **WCAG 2.2 AA.** Every component meets it: the components own semantics, keyboard and
|
|
@@ -81,7 +87,7 @@ custom properties, named as in shadcn/ui, are listed in [Theming](theming.md#the
|
|
|
81
87
|
| [Tooltip](tooltip.md) | Available: native hint popover, opened by its script |
|
|
82
88
|
| [Menu](menu.md) | Available: popover menu, opens without JavaScript |
|
|
83
89
|
| [Combobox](combobox.md) | Available: `<lu-combobox>`, a form control that filters its options |
|
|
84
|
-
| [Select](select.md) | Available: native `<select>`, customizable where supported, no script
|
|
90
|
+
| [Select](select.md) | Available: native `<select>`, customizable where supported, no script but for `label`s |
|
|
85
91
|
| [Tabs](tabs.md) | Available: server HTML with the full state, `<lu-tabs>` adds the keys |
|
|
86
92
|
| [Field](field.md) | Available: label, description, errors; native validation in the field |
|
|
87
93
|
| [Fieldset](fieldset.md) | Available: native `<fieldset>` and `<legend>`, no script |
|
|
@@ -176,7 +182,10 @@ errors are yours.
|
|
|
176
182
|
`@lumiose/ui` is opt-in, so its size is reported apart from the runtime's caps:
|
|
177
183
|
`pnpm --filter @lumiose/ui size` prints, per component, the JavaScript a server-rendered page loads
|
|
178
184
|
for its custom elements, the JavaScript an island that uses it loads, and its CSS (minified, gzip
|
|
179
|
-
and brotli).
|
|
185
|
+
and brotli). The scripts load as separate modules, in islands too: each component's script, and
|
|
186
|
+
the modules several scripts share (the dismissal model, the placement fallback, the hover timing),
|
|
187
|
+
each a file of its own, as an app's build splits them. The sizes on the component pages are those
|
|
188
|
+
files' brotli sizes added up.
|
|
180
189
|
|
|
181
190
|
## Related
|
|
182
191
|
|
|
@@ -190,13 +199,13 @@ and brotli).
|
|
|
190
199
|
|
|
191
200
|
> Add `@lumiose/ui` to a Lumiose app and import its stylesheets, and the default theme if you want its look. The components then render in server HTML, without an island, and a page loads only the small scripts of the components it renders.
|
|
192
201
|
|
|
193
|
-
**Status:**
|
|
194
|
-
|
|
202
|
+
**Status:** in development, on npm with its own 0.x versions, apart from the version the other
|
|
203
|
+
Lumiose packages share.
|
|
195
204
|
|
|
196
205
|
## Add the package
|
|
197
206
|
|
|
198
207
|
`@lumiose/ui` needs a Lumiose app: it ships its components as TSX, which the app's build compiles
|
|
199
|
-
with the app's own code, and `lumiose` is its peer dependency.
|
|
208
|
+
with the app's own code, and `lumiose` is its peer dependency. Install it from npm:
|
|
200
209
|
|
|
201
210
|
```sh
|
|
202
211
|
pnpm add @lumiose/ui
|
|
@@ -578,8 +587,9 @@ closed item are HTML features: an accordion in a server-rendered page works befo
|
|
|
578
587
|
loads, and with none. Disabled triggers ignore the pointer through CSS. `value`, `onValueChange`
|
|
579
588
|
and `bind:value` need the component to run in an island.
|
|
580
589
|
|
|
581
|
-
A page that renders an `Accordion` loads
|
|
582
|
-
|
|
590
|
+
A page that renders an `Accordion` loads its script once, with the panel and animation modules it
|
|
591
|
+
shares with Collapsible: 1.3 kB (brotli) without the Lumiose runtime; an island loads the same
|
|
592
|
+
modules. It defines `<lu-accordion>`, which adds the arrow keys, Home and End, and sets
|
|
583
593
|
the panels' animation hooks (shared with [Collapsible](collapsible.md)); a disabled trigger does
|
|
584
594
|
not toggle, also from the keyboard.
|
|
585
595
|
|
|
@@ -602,7 +612,7 @@ not toggle, also from the keyboard.
|
|
|
602
612
|
|
|
603
613
|
# Autocomplete
|
|
604
614
|
|
|
605
|
-
> A text input with suggestions, for text that may be anything (a search, a tag, an address): the WAI-ARIA combobox pattern with list autocomplete, after Base UI's Autocomplete. Unlike a [Combobox](combobox.md), the text is the value: the input has the name and submits what is typed, and choosing a suggestion only fills it in. It runs on the Combobox's element (`<lu-combobox free>`, 5.
|
|
615
|
+
> A text input with suggestions, for text that may be anything (a search, a tag, an address): the WAI-ARIA combobox pattern with list autocomplete, after Base UI's Autocomplete. Unlike a [Combobox](combobox.md), the text is the value: the input has the name and submits what is typed, and choosing a suggestion only fills it in. It runs on the Combobox's element (`<lu-combobox free>`, 5.8 kB) and parts, on server-rendered pages and in islands; `bind:value` keeps a signal in sync. Filtering, inline completion, groups, an empty state and a status.
|
|
606
616
|
|
|
607
617
|
```ts
|
|
608
618
|
import { Autocomplete } from "@lumiose/ui"; // or "@lumiose/ui/autocomplete"
|
|
@@ -747,7 +757,7 @@ Focus stays in the input: the highlight moves through `aria-activedescendant`.
|
|
|
747
757
|
## Without JavaScript, and the element's script
|
|
748
758
|
|
|
749
759
|
The input is a native text field with the name: typing, `required`, submission and reset work with
|
|
750
|
-
no script; the suggestions need it. `<lu-combobox>`'s script (5.
|
|
760
|
+
no script; the suggestions need it. `<lu-combobox>`'s script (5.8 kB brotli, shared with Combobox)
|
|
751
761
|
filters and opens them, moves the highlight, fills in a choice (firing `input` and `change` on the
|
|
752
762
|
input) and runs inline completion.
|
|
753
763
|
|
|
@@ -946,8 +956,8 @@ when it fails) and hides its fallback, from sight and from assistive technology,
|
|
|
946
956
|
the avatar twice; an avatar without an image shows its fallback.
|
|
947
957
|
`onLoadingStatusChange` needs the component to run in an island.
|
|
948
958
|
|
|
949
|
-
A page that renders an `Avatar` loads a 0.5 kB (brotli) script, without the Lumiose runtime;
|
|
950
|
-
|
|
959
|
+
A page that renders an `Avatar` loads a 0.5 kB (brotli) script, without the Lumiose runtime; an
|
|
960
|
+
island loads the same module. `<lu-avatar>` reads the image's state when it connects (a cached image shows
|
|
951
961
|
at once), then follows its `load` and `error` events and changes to its `src` and `srcset`. An
|
|
952
962
|
image that is complete without a size (an SVG without intrinsic dimensions, or a broken image) is
|
|
953
963
|
told apart with `decode()`.
|
|
@@ -1180,7 +1190,7 @@ A native checkbox: toggling, submission, `required`, reset and `disabled` (its o
|
|
|
1180
1190
|
work with no script.
|
|
1181
1191
|
|
|
1182
1192
|
A page that renders a Checkbox, Checkbox Group, Radio Group or Switch loads one 1.0 kB (brotli)
|
|
1183
|
-
script once, without the Lumiose runtime;
|
|
1193
|
+
script once, without the Lumiose runtime; an island loads the same module. It turns server HTML's
|
|
1184
1194
|
`data-indeterminate` into the `indeterminate` property (which has no attribute), makes read-only
|
|
1185
1195
|
inputs ignore clicks, Space and the label, runs the parent checkbox of a group and a [Radio
|
|
1186
1196
|
Group](radio-group.md)'s arrow keys, and adds an
|
|
@@ -1207,7 +1217,7 @@ browser.
|
|
|
1207
1217
|
> A group of checkboxes with one value, the list of the checked ones, after Base UI's CheckboxGroup: a native `<fieldset>` whose checkboxes share a name, so the form submits each checked value and a disabled group disables them all, without JavaScript. A parent checkbox checks them all and shows checked, mixed or unchecked as they are; `bind:value` keeps a signal in sync.
|
|
1208
1218
|
|
|
1209
1219
|
```ts
|
|
1210
|
-
import { CheckboxGroup, Checkbox, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/checkbox-group"
|
|
1220
|
+
import { CheckboxGroup, Checkbox, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/checkbox-group", "@lumiose/ui/checkbox" and "@lumiose/ui/fieldset"
|
|
1211
1221
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
1212
1222
|
```
|
|
1213
1223
|
|
|
@@ -1319,7 +1329,7 @@ Every supported browser.
|
|
|
1319
1329
|
|
|
1320
1330
|
# Collapsible
|
|
1321
1331
|
|
|
1322
|
-
> A panel that its trigger shows and hides: a native `<details>` whose `<summary>` is the trigger, so it works in server HTML with no JavaScript, keeps the browser's keyboard handling, and opens when find-in-page or a link lands inside it. A 0.
|
|
1332
|
+
> A panel that its trigger shows and hides: a native `<details>` whose `<summary>` is the trigger, so it works in server HTML with no JavaScript, keeps the browser's keyboard handling, and opens when find-in-page or a link lands inside it. A 0.9 kB script adds Base UI's animation hooks. `bind:open` (or `open` and `onOpenChange`) keeps a signal in sync in islands.
|
|
1323
1333
|
|
|
1324
1334
|
```ts
|
|
1325
1335
|
import { Collapsible } from "@lumiose/ui"; // or "@lumiose/ui/collapsible"
|
|
@@ -1460,8 +1470,9 @@ Collapsible in a server-rendered page works before any script loads, and with no
|
|
|
1460
1470
|
trigger ignores the pointer through CSS. `open`, `onOpenChange` and `bind:open` need the component
|
|
1461
1471
|
to run in an island.
|
|
1462
1472
|
|
|
1463
|
-
A page that renders a `Collapsible` loads
|
|
1464
|
-
|
|
1473
|
+
A page that renders a `Collapsible` loads 0.9 kB (brotli) of modules once (its script, and the
|
|
1474
|
+
panel and animation modules it shares with Accordion), without the Lumiose runtime; an island
|
|
1475
|
+
loads the same modules. It covers every Collapsible and [Accordion](accordion.md) panel on the
|
|
1465
1476
|
page:
|
|
1466
1477
|
|
|
1467
1478
|
- the animation hooks above, set on every opening and closing, whatever caused it (the trigger,
|
|
@@ -1487,7 +1498,7 @@ page:
|
|
|
1487
1498
|
|
|
1488
1499
|
# Combobox
|
|
1489
1500
|
|
|
1490
|
-
> A text input that filters a list of options, for picking one value or several from many: the WAI-ARIA combobox pattern with list autocomplete, after Base UI's Combobox. The input shows the option's label and the form gets its value. `<lu-combobox>`, a 5.
|
|
1501
|
+
> A text input that filters a list of options, for picking one value or several from many: the WAI-ARIA combobox pattern with list autocomplete, after Base UI's Combobox. The input shows the option's label and the form gets its value. `<lu-combobox>`, a 5.8 kB form-associated light-DOM element, runs it on server-rendered pages and in islands; `bind:value` and `bind:open` keep signals in sync. Groups, an empty state, a status, a clear button, multiple values with chips, validation and async options.
|
|
1491
1502
|
|
|
1492
1503
|
```ts
|
|
1493
1504
|
import { Combobox } from "@lumiose/ui"; // or "@lumiose/ui/combobox"
|
|
@@ -1800,8 +1811,9 @@ In the server HTML the input is empty even with a selected value: the input rend
|
|
|
1800
1811
|
options, so the server does not know the selected option's label when it writes the input. The
|
|
1801
1812
|
script puts the label in as it upgrades the element (decision-62).
|
|
1802
1813
|
|
|
1803
|
-
A page that renders a `Combobox` loads the script once,
|
|
1804
|
-
|
|
1814
|
+
A page that renders a `Combobox` loads the script once, with the dismissal and placement modules
|
|
1815
|
+
it shares with Menu and Popover: 5.8 kB (brotli) without the Lumiose runtime, and an island loads
|
|
1816
|
+
the same modules. It defines `lu-combobox`, which upgrades every combobox on
|
|
1805
1817
|
the page in place: it reads the selection the server rendered (`aria-selected="true"`), puts its
|
|
1806
1818
|
label in the input (text typed before it ran is kept, as a search), renders the chips, and from
|
|
1807
1819
|
then on owns the value, the filtering, the popup,
|
|
@@ -1859,7 +1871,7 @@ The element is also an API of its own, for scripts and other frameworks:
|
|
|
1859
1871
|
|
|
1860
1872
|
# Context Menu
|
|
1861
1873
|
|
|
1862
|
-
> A menu opened at the pointer by a right-click in its trigger area, a long press on a touch screen, or Shift+F10 and the ContextMenu key: Menu's popup and items, with Menu's keys, typeahead, submenus and dismissal. A 0.
|
|
1874
|
+
> A menu opened at the pointer by a right-click in its trigger area, a long press on a touch screen, or Shift+F10 and the ContextMenu key: Menu's popup and items, with Menu's keys, typeahead, submenus and dismissal. A 0.9 kB script on top of Menu's (5.4 kB together) opens it; without JavaScript the browser shows its own menu. `bind:open` (or `open` and `onOpenChange`) keeps a signal in sync in islands.
|
|
1863
1875
|
|
|
1864
1876
|
```ts
|
|
1865
1877
|
import { ContextMenu } from "@lumiose/ui"; // or "@lumiose/ui/context-menu"
|
|
@@ -2034,8 +2046,8 @@ Opening a menu at the pointer needs the script: without JavaScript a right-click
|
|
|
2034
2046
|
browser's own menu, and the popup stays hidden. `open`, `onOpenChange` and `bind:open` need the
|
|
2035
2047
|
component to run in an island.
|
|
2036
2048
|
|
|
2037
|
-
A page that renders a `ContextMenu` loads Menu's script and a 0.
|
|
2038
|
-
4
|
|
2049
|
+
A page that renders a `ContextMenu` loads Menu's script and a 0.9 kB (brotli) one of its own,
|
|
2050
|
+
5.4 kB together, without the Lumiose runtime; an island loads the same modules. The element opens the menu on a
|
|
2039
2051
|
right-click, a long press or the keys, at the pointer, through a zero-size anchor that it moves
|
|
2040
2052
|
there (CSS anchor positioning places the popup, with Menu's flips; without it, the shared
|
|
2041
2053
|
placement script does). Menu's script does the rest: keys, items, submenus, and dismissal shared
|
|
@@ -2280,7 +2292,7 @@ server-rendered page works before any script loads, and with none. `open`, `onOp
|
|
|
2280
2292
|
|
|
2281
2293
|
Where the native element falls short of Base UI's dialog, a small script closes the gap: a page
|
|
2282
2294
|
that renders a `Dialog` loads it once, as a 1.5 kB (brotli) module without the Lumiose runtime, and
|
|
2283
|
-
|
|
2295
|
+
an island loads the same module. It covers every `<dialog>` on the page:
|
|
2284
2296
|
|
|
2285
2297
|
- a right-click or a second finger outside does not close the dialog;
|
|
2286
2298
|
- `data-nested-dialog-open` and `--lu-nested-dialogs` on a dialog with open dialogs inside;
|
|
@@ -2500,8 +2512,9 @@ The trigger, the close buttons, Escape and the click outside are HTML features,
|
|
|
2500
2512
|
drawer in a server-rendered page works before any script loads, and with none, against its edge.
|
|
2501
2513
|
`open`, `onOpenChange` and `bind:open` need the component to run in an island.
|
|
2502
2514
|
|
|
2503
|
-
A page that renders a `Drawer` loads Dialog's script and a 1 kB (brotli) one of its own (2.
|
|
2504
|
-
together
|
|
2515
|
+
A page that renders a `Drawer` loads Dialog's script and a 1.1 kB (brotli) one of its own (2.8 kB
|
|
2516
|
+
together, with the animation module it shares with Toast), without the Lumiose runtime; an island
|
|
2517
|
+
loads the same modules. The drawer's script handles the
|
|
2505
2518
|
swipe, with the mouse and pen through pointer events and on touch screens through touch events,
|
|
2506
2519
|
taking the gesture from scrolling only once it is a swipe.
|
|
2507
2520
|
|
|
@@ -2778,8 +2791,8 @@ the message Error's id (`Field.Error` without children or `match`) even when the
|
|
|
2778
2791
|
Errors with children or a `match`. Give a field that must read well without JavaScript a message
|
|
2779
2792
|
Error, and its Descriptions before the control.
|
|
2780
2793
|
|
|
2781
|
-
A page that renders a `Field` loads a 1.7 kB (brotli) script once, without the Lumiose runtime;
|
|
2782
|
-
|
|
2794
|
+
A page that renders a `Field` loads a 1.7 kB (brotli) script once, without the Lumiose runtime; an
|
|
2795
|
+
island loads the same module. On a submit attempt (a submit button, Enter in a field, `requestSubmit()` or
|
|
2783
2796
|
the form's `reportValidity()`; a silent `checkValidity()` changes nothing) it cancels the browser's
|
|
2784
2797
|
`invalid` bubble for fields that have an Error part for the problem and shows it there instead (the
|
|
2785
2798
|
browser's message, or one your `validate` set), with the timing above, and focuses the first
|
|
@@ -3142,7 +3155,7 @@ Every browser; input types and constraints as the browser supports them.
|
|
|
3142
3155
|
|
|
3143
3156
|
# Menu
|
|
3144
3157
|
|
|
3145
|
-
> A menu of commands, links, checkbox and radio items and submenus, opened by a button: the trigger's `popovertarget` opens it and CSS anchor positioning places it, so it works in server HTML with no JavaScript, and a 4.
|
|
3158
|
+
> A menu of commands, links, checkbox and radio items and submenus, opened by a button: the trigger's `popovertarget` opens it and CSS anchor positioning places it, so it works in server HTML with no JavaScript, and a 4.4 kB script adds the APG Menu Button keyboard contract where JavaScript runs. `bind:open`, `bind:checked` and `bind:value` keep signals in sync in islands.
|
|
3146
3159
|
|
|
3147
3160
|
```ts
|
|
3148
3161
|
import { Menu } from "@lumiose/ui"; // or "@lumiose/ui/menu"
|
|
@@ -3463,8 +3476,9 @@ submenu closes it, but the browser leaves focus on the page rather than on the s
|
|
|
3463
3476
|
Tab starts over from the top (the script returns focus to the trigger). `open`, `onOpenChange` and
|
|
3464
3477
|
the `bind:` props need the component to run in the browser, in an island.
|
|
3465
3478
|
|
|
3466
|
-
The keyboard contract comes from a small script: a page that renders a `Menu` loads it once,
|
|
3467
|
-
|
|
3479
|
+
The keyboard contract comes from a small script: a page that renders a `Menu` loads it once, with
|
|
3480
|
+
the dismissal and placement modules it shares with Popover and Combobox: 4.4 kB (brotli) without
|
|
3481
|
+
the Lumiose runtime, and an island loads the same modules. It defines `lu-menu`,
|
|
3468
3482
|
which upgrades every menu on the page in place, and adds what the native popover lacks: focus on
|
|
3469
3483
|
open and its return on close, the arrows, Home, End and typeahead, Escape one level at a time, Tab,
|
|
3470
3484
|
submenus, checkbox and radio items, disabled items, `data-highlighted`, and the pointer behaviour
|
|
@@ -3510,7 +3524,7 @@ The element is also an API of its own, for scripts and other frameworks:
|
|
|
3510
3524
|
|
|
3511
3525
|
# Menubar
|
|
3512
3526
|
|
|
3513
|
-
> A bar of menus, such as an app's File, Edit and View, after Base UI's Menubar and the WAI-ARIA menubar pattern: `Menu.Root`s inside `<lu-menubar role="menubar">`, whose triggers are the bar's items. Menu's popups, items, submenus and dismissal; the bar is one tab stop, the arrow keys move between its items and between open menus, and once a menu is open, hovering another item opens its menu instead. A
|
|
3527
|
+
> A bar of menus, such as an app's File, Edit and View, after Base UI's Menubar and the WAI-ARIA menubar pattern: `Menu.Root`s inside `<lu-menubar role="menubar">`, whose triggers are the bar's items. Menu's popups, items, submenus and dismissal; the bar is one tab stop, the arrow keys move between its items and between open menus, and once a menu is open, hovering another item opens its menu instead. A 1.1 kB script on top of Menu's (5.5 kB together); without JavaScript each trigger opens its menu.
|
|
3514
3528
|
|
|
3515
3529
|
```ts
|
|
3516
3530
|
import { Menu, Menubar } from "@lumiose/ui"; // or "@lumiose/ui/menu" and "@lumiose/ui/menubar"
|
|
@@ -3679,8 +3693,8 @@ flex row (a column when vertical); each `<lu-menu>` adds no box.
|
|
|
3679
3693
|
Each trigger opens its menu through `popovertarget`, and the browser light-dismisses it: without
|
|
3680
3694
|
JavaScript every trigger is a tab stop, and the menus open with Enter, Space or a click.
|
|
3681
3695
|
|
|
3682
|
-
A page that renders a `Menubar` loads Menu's script and a
|
|
3683
|
-
together, without the Lumiose runtime;
|
|
3696
|
+
A page that renders a `Menubar` loads Menu's script and a 1.1 kB (brotli) one of its own, 5.5 kB
|
|
3697
|
+
together, without the Lumiose runtime; an island loads the same modules. The menubar's script makes the bar one
|
|
3684
3698
|
tab stop once the page has loaded, and adds the arrow keys between items and menus and the hover
|
|
3685
3699
|
switching. Each menu stays Menu's: its keys, items, submenus and dismissal.
|
|
3686
3700
|
|
|
@@ -3805,7 +3819,7 @@ above. `role="meter"` reaches screen readers in recent versions; older ones read
|
|
|
3805
3819
|
|
|
3806
3820
|
# Navigation Menu
|
|
3807
3821
|
|
|
3808
|
-
> A site's navigation whose items open panels of links, after Base UI's NavigationMenu and the WAI-ARIA disclosure navigation pattern: a `<nav>` landmark around a list, each trigger opening its content through `popovertarget` (a native popover placed under it by CSS anchor positioning), so the links work and the panels open on a click, one at a time, in server HTML with no JavaScript. A
|
|
3822
|
+
> A site's navigation whose items open panels of links, after Base UI's NavigationMenu and the WAI-ARIA disclosure navigation pattern: a `<nav>` landmark around a list, each trigger opening its content through `popovertarget` (a native popover placed under it by CSS anchor positioning), so the links work and the panels open on a click, one at a time, in server HTML with no JavaScript. A 4.0 kB script adds hover intent, the arrow keys, closing when focus leaves and the direction a panel comes in from. `bind:value` (or `value` and `onValueChange`) keeps the open item in a signal.
|
|
3809
3823
|
|
|
3810
3824
|
```ts
|
|
3811
3825
|
import { NavigationMenu } from "@lumiose/ui"; // or "@lumiose/ui/navigation-menu"
|
|
@@ -4040,8 +4054,9 @@ The `<nav>`, its links and the triggers are HTML: each trigger opens its content
|
|
|
4040
4054
|
`popovertarget`, one at a time (an auto popover closes the others), and Escape or a click outside
|
|
4041
4055
|
closes it. `value`, `onValueChange` and `bind:value` need the component to run in an island.
|
|
4042
4056
|
|
|
4043
|
-
A page that renders a `NavigationMenu` loads
|
|
4044
|
-
Menu
|
|
4057
|
+
A page that renders a `NavigationMenu` loads its script, with the dismissal and placement modules
|
|
4058
|
+
it shares with Menu and Popover: 4.0 kB (brotli) without the Lumiose runtime; an island loads the
|
|
4059
|
+
same modules. `<lu-navigation-menu>`
|
|
4045
4060
|
takes over the trigger's click (so a click keeps a content opened by hover open), opens contents on
|
|
4046
4061
|
hover, adds the arrow keys, closes a content when focus leaves its item, dismisses contents as Menu
|
|
4047
4062
|
and Popover do (a press of the main button outside, an Escape, another layer opening), keeps
|
|
@@ -4249,7 +4264,7 @@ Scrubbing uses pointer capture, without pointer lock.
|
|
|
4249
4264
|
|
|
4250
4265
|
# OTP Field
|
|
4251
4266
|
|
|
4252
|
-
> A one-time code input, after Base UI's OTPField: one native `<input>` shown as one slot per character. SMS autofill (`autocomplete="one-time-code"`), paste, Backspace, the arrow keys, `maxlength`, `pattern`, `required` and the form's value are the platform's, without JavaScript too, and assistive technology meets one labelled text field. `<lu-otp-field>`'s 1.
|
|
4267
|
+
> A one-time code input, after Base UI's OTPField: one native `<input>` shown as one slot per character. SMS autofill (`autocomplete="one-time-code"`), paste, Backspace, the arrow keys, `maxlength`, `pattern`, `required` and the form's value are the platform's, without JavaScript too, and assistive technology meets one labelled text field. `<lu-otp-field>`'s 1.6 kB script lays the input over the slots, keeps the code to the allowed characters, and reports completion. `bind:value` keeps a signal in sync.
|
|
4253
4268
|
|
|
4254
4269
|
```ts
|
|
4255
4270
|
import { OTPField } from "@lumiose/ui"; // or "@lumiose/ui/otp-field"
|
|
@@ -4388,7 +4403,7 @@ auto-submits.
|
|
|
4388
4403
|
## Without JavaScript, and the element's script
|
|
4389
4404
|
|
|
4390
4405
|
The input is a native text field: autofill, typing, paste, `pattern` and `required` validation and
|
|
4391
|
-
submission work with no script, and the slots stay hidden. `<lu-otp-field>`'s script (1.
|
|
4406
|
+
submission work with no script, and the slots stay hidden. `<lu-otp-field>`'s script (1.6 kB
|
|
4392
4407
|
brotli) shows the slots, cleans the value as it changes (firing `valueinvalid` for refused input),
|
|
4393
4408
|
fires `valuecomplete`, auto-submits, and follows a form reset.
|
|
4394
4409
|
|
|
@@ -4412,7 +4427,7 @@ does not zoom into it on focus.
|
|
|
4412
4427
|
|
|
4413
4428
|
# Popover
|
|
4414
4429
|
|
|
4415
|
-
> A popup anchored to its trigger: a native `popover` opened and closed by the trigger's `popovertarget`, placed with CSS anchor positioning, so it works in server HTML with no JavaScript. A 3.
|
|
4430
|
+
> A popup anchored to its trigger: a native `popover` opened and closed by the trigger's `popovertarget`, placed with CSS anchor positioning, so it works in server HTML with no JavaScript. A 3.2 kB script moves focus into it and back, dismisses it as Base UI does (not on a right-click), keeps `aria-expanded` current and places it in browsers without anchor positioning. `bind:open` (or `open` and `onOpenChange`) keeps a signal in sync in islands. A trigger can open it on hover (`openOnHover`), and a `modal` popover is a modal `<dialog>` that makes the page behind it inert.
|
|
4416
4431
|
|
|
4417
4432
|
```ts
|
|
4418
4433
|
import { Popover } from "@lumiose/ui"; // or "@lumiose/ui/popover"
|
|
@@ -4645,11 +4660,14 @@ The trigger, the close buttons, Escape, the click outside and the placement are
|
|
|
4645
4660
|
features: a popover in a server-rendered page works before any script loads, and with none. So
|
|
4646
4661
|
does a modal popover, through invoker commands and `closedby` (where a browser lacks them,
|
|
4647
4662
|
[Dialog](dialog.md)'s script, which a modal popover loads, stands in). Opening on hover needs the
|
|
4648
|
-
|
|
4663
|
+
scripts.
|
|
4649
4664
|
`open`, `onOpenChange` and `bind:open` need the component to run in an island.
|
|
4650
4665
|
|
|
4651
|
-
A page that renders a `Popover` loads
|
|
4652
|
-
|
|
4666
|
+
A page that renders a `Popover` loads its script once, with the dismissal and placement modules it
|
|
4667
|
+
shares with Menu, Combobox and Tooltip: 3.2 kB (brotli) without the Lumiose runtime. A trigger
|
|
4668
|
+
with `openOnHover` adds 1.0 kB, the hover timing it shares with
|
|
4669
|
+
[Preview Card](preview-card.md); a page without one goes without it. An island loads the same
|
|
4670
|
+
modules. The scripts cover every Popover on the page:
|
|
4653
4671
|
|
|
4654
4672
|
- focus on open (the first focusable element, or the popup) and its return on close;
|
|
4655
4673
|
- dismissal, shared with [Menu](menu.md) and [Combobox](combobox.md): a trigger's click makes the
|
|
@@ -4686,7 +4704,7 @@ popover's `dialog::backdrop`) styles the layer under it, without an element of i
|
|
|
4686
4704
|
|
|
4687
4705
|
# Preview Card
|
|
4688
4706
|
|
|
4689
|
-
> A card that previews a link's destination while the pointer or keyboard focus rests on the link, after Base UI's PreviewCard. The trigger is the link itself, which works as a link without JavaScript; the card is a manual popover placed with [Popover](popover.md)'s placement and opened with its hover timing by a
|
|
4707
|
+
> A card that previews a link's destination while the pointer or keyboard focus rests on the link, after Base UI's PreviewCard. The trigger is the link itself, which works as a link without JavaScript; the card is a manual popover placed with [Popover](popover.md)'s placement and opened with its hover timing by a 3.4 kB script. It is hoverable, persistent and dismissible (WCAG 1.4.13). `bind:open` keeps a signal in sync.
|
|
4690
4708
|
|
|
4691
4709
|
```ts
|
|
4692
4710
|
import { PreviewCard } from "@lumiose/ui"; // or "@lumiose/ui/preview-card"
|
|
@@ -4800,8 +4818,9 @@ the link, with a fade (none where motion is reduced).
|
|
|
4800
4818
|
|
|
4801
4819
|
## Without JavaScript, and the client script
|
|
4802
4820
|
|
|
4803
|
-
The link is a plain link and the card never opens. A page that renders a `PreviewCard` loads
|
|
4804
|
-
|
|
4821
|
+
The link is a plain link and the card never opens. A page that renders a `PreviewCard` loads its
|
|
4822
|
+
script once, with the hover timing, dismissal and placement modules it shares with Popover: 3.4 kB
|
|
4823
|
+
(brotli) without the Lumiose runtime; an island loads the same modules. It runs hover and focus with
|
|
4805
4824
|
their delays, dismissal, `data-popup-open`, and the placement in browsers without CSS anchor
|
|
4806
4825
|
positioning.
|
|
4807
4826
|
|
|
@@ -4940,7 +4959,7 @@ above.
|
|
|
4940
4959
|
> A group of radios with one value, after Base UI's RadioGroup and Radio: native radios in a `<fieldset role="radiogroup">`. The browser gives the group one tab stop, arrow keys that move and select (skipping disabled radios), `required`, submission and reset, in server HTML and without JavaScript; a legend names the group. `bind:value` keeps a signal in sync.
|
|
4941
4960
|
|
|
4942
4961
|
```ts
|
|
4943
|
-
import { Radio, RadioGroup, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/radio-group"
|
|
4962
|
+
import { Radio, RadioGroup, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/radio-group" and "@lumiose/ui/fieldset"
|
|
4944
4963
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
4945
4964
|
```
|
|
4946
4965
|
|
|
@@ -5217,7 +5236,7 @@ supported browser.
|
|
|
5217
5236
|
|
|
5218
5237
|
# Select
|
|
5219
5238
|
|
|
5220
|
-
> A native `<select>` for picking one value from a list: it works with no JavaScript, submits with its form and keeps the platform's keyboard, typeahead and mobile pickers. Where the browser has customizable select (`appearance: base-select`, Chrome 135, Safari 26), `Select.Trigger` and `Select.Value` shape the button, the picker is styleable and options may hold more than text; elsewhere it is the classic select. No script
|
|
5239
|
+
> A native `<select>` for picking one value from a list: it works with no JavaScript, submits with its form and keeps the platform's keyboard, typeahead and mobile pickers. Where the browser has customizable select (`appearance: base-select`, Chrome 135, Safari 26), `Select.Trigger` and `Select.Value` shape the button, the picker is styleable and options may hold more than text; elsewhere it is the classic select. No script, but a tiny one for items with a `label`; `bind:value` keeps a signal in sync in islands.
|
|
5221
5240
|
|
|
5222
5241
|
```ts
|
|
5223
5242
|
import { Select } from "@lumiose/ui"; // or "@lumiose/ui/select"
|
|
@@ -5273,11 +5292,17 @@ handlers. Name it with a `<label for>` pointing at its `id`, or `aria-label`, or
|
|
|
5273
5292
|
|
|
5274
5293
|
### Select.Item
|
|
5275
5294
|
|
|
5276
|
-
| Prop | Type | Default |
|
|
5277
|
-
| ---------- | --------- | ------- |
|
|
5278
|
-
| `value` | `string` | | Required: the value the select takes, and submits, when selected.
|
|
5279
|
-
| `disabled` | `boolean` | `false` | The option cannot be selected; the arrow keys skip it.
|
|
5280
|
-
| `label` | `string` | | The option's
|
|
5295
|
+
| Prop | Type | Default | |
|
|
5296
|
+
| ---------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
5297
|
+
| `value` | `string` | | Required: the value the select takes, and submits, when selected. |
|
|
5298
|
+
| `disabled` | `boolean` | `false` | The option cannot be selected; the arrow keys skip it. |
|
|
5299
|
+
| `label` | `string` | | The option's name, for typeahead, assistive technology and the classic select, when its content starts with an icon or holds more than text. |
|
|
5300
|
+
|
|
5301
|
+
A customizable select's picker shows each item's content, with or without `label`. The classic
|
|
5302
|
+
select, which shows text only, shows the `label`. An item with a `label` renders the `<option>`'s
|
|
5303
|
+
`label` and `aria-label`, and a hidden copy of it first in its content (`<span hidden
|
|
5304
|
+
data-label>`), which typeahead matches: so `option.text`, and `<selectedcontent>`'s
|
|
5305
|
+
`textContent`, start with the label, while the rendered text does not.
|
|
5281
5306
|
|
|
5282
5307
|
### Select.Group
|
|
5283
5308
|
|
|
@@ -5292,7 +5317,7 @@ handlers. Name it with a `<label for>` pointing at its `id`, or `aria-label`, or
|
|
|
5292
5317
|
|
|
5293
5318
|
**Differences from Base UI's Select.** Select is the native control, chosen over the listbox
|
|
5294
5319
|
pattern because it works without JavaScript, carries forms, autofill, validation and the mobile
|
|
5295
|
-
pickers, and
|
|
5320
|
+
pickers, and needs no script. So it has no `open`, `onOpenChange` or `modal` (the platform fires no
|
|
5296
5321
|
event when the picker opens; style `:open` instead), no `Label` (use `<label for>`), no `multiple`
|
|
5297
5322
|
(use [Combobox](combobox.md) with `multiple`), no `alignItemWithTrigger` (the picker opens below the
|
|
5298
5323
|
control and flips), no `Portal`, `Positioner`, `Popup`, `List`, `Icon`, `ItemText`,
|
|
@@ -5421,7 +5446,7 @@ A click on a `<label for>` focuses the select without opening it. A click on the
|
|
|
5421
5446
|
picker; a click on an option selects it; a click outside closes the picker. Other browsers keep
|
|
5422
5447
|
their own select keyboard and pickers, which differ by platform.
|
|
5423
5448
|
|
|
5424
|
-
## Without JavaScript
|
|
5449
|
+
## Without JavaScript, and the client script
|
|
5425
5450
|
|
|
5426
5451
|
Select needs none: it is a native control, in server HTML and with JavaScript off, on every
|
|
5427
5452
|
browser. It submits under its `name`, is validated (`required`), resets with its form, takes the
|
|
@@ -5429,6 +5454,15 @@ browser's autofill and is disabled by a disabled `<fieldset>`. `value`, `onValue
|
|
|
5429
5454
|
`bind:value` need the component to run in the browser, in an island; there `value` sets the
|
|
5430
5455
|
control's value when it changes, and its `change` event calls `onValueChange`.
|
|
5431
5456
|
|
|
5457
|
+
Items with a `label` are the exception. A customizable select's picker shows an `<option>`'s
|
|
5458
|
+
`label` attribute instead of its content, through the browser's own style, which no CSS
|
|
5459
|
+
overrides. So a page whose selects have such items loads a 0.2 kB (brotli) script once, without
|
|
5460
|
+
the Lumiose runtime (an island loads the same module). When a customizable select is pressed or
|
|
5461
|
+
takes focus, before its picker opens, the script removes the attribute from its items: the picker
|
|
5462
|
+
shows their content, typeahead matches the label's hidden copy, and `aria-label` keeps their name.
|
|
5463
|
+
A classic select keeps the attribute, which it shows. Without the script, the customizable
|
|
5464
|
+
picker shows the labels alone.
|
|
5465
|
+
|
|
5432
5466
|
## Browser support
|
|
5433
5467
|
|
|
5434
5468
|
- **Customizable select** (`appearance: base-select`, `::picker(select)`, `<selectedcontent>`, a
|
|
@@ -5439,8 +5473,8 @@ control's value when it changes, and its `change` event calls `onValueChange`.
|
|
|
5439
5473
|
`Trigger`). Older browsers without customizable select drop them from server HTML, so an
|
|
5440
5474
|
island's select falls back to rendering on the client there
|
|
5441
5475
|
([LUM4006](https://itsjavi.com/lumiose/docs/errors/LUM4006/)).
|
|
5442
|
-
- **Typeahead** matches an option's text, or its `label`: give options
|
|
5443
|
-
`label`.
|
|
5476
|
+
- **Typeahead** matches an option's text, or its `label`: give options whose content starts with
|
|
5477
|
+
an icon (an emoji, a symbol) a `label`.
|
|
5444
5478
|
- **`:open`** comes with customizable select.
|
|
5445
5479
|
|
|
5446
5480
|
## Related
|
|
@@ -6098,7 +6132,7 @@ The [WAI-ARIA tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/):
|
|
|
6098
6132
|
The server HTML is complete: the selected tab, its panel and the tab stop are right before any
|
|
6099
6133
|
script loads, and the panels of the other tabs are `hidden`. Selecting another tab needs
|
|
6100
6134
|
`<lu-tabs>`' script, a 1.2 kB (brotli) module that a page rendering `Tabs` loads once, without
|
|
6101
|
-
the Lumiose runtime;
|
|
6135
|
+
the Lumiose runtime; an island loads the same module. A `Tabs.Indicator` is placed by CSS alone until then; the
|
|
6102
6136
|
script makes it follow a new selection. `value`, `onValueChange` and `bind:value` need the
|
|
6103
6137
|
component to run in an island.
|
|
6104
6138
|
|
|
@@ -6120,7 +6154,7 @@ component to run in an island.
|
|
|
6120
6154
|
|
|
6121
6155
|
# Toast
|
|
6122
6156
|
|
|
6123
|
-
> Short notices in a region of their own, after Base UI's toast: server HTML renders them (a form action's result), and islands add, update and close them through a toast manager. `<lu-toast-viewport>`, a 2.
|
|
6157
|
+
> Short notices in a region of their own, after Base UI's toast: server HTML renders them (a form action's result), and islands add, update and close them through a toast manager. `<lu-toast-viewport>`, a 2.8 kB light-DOM element, puts them in the top layer, times them (pausing on hover and focus), limits how many show, closes them on a swipe, Escape or their close button, focuses the region on F6, and makes screen readers announce them.
|
|
6124
6158
|
|
|
6125
6159
|
```ts
|
|
6126
6160
|
import { Toast } from "@lumiose/ui"; // or "@lumiose/ui/toast"
|
|
@@ -6404,7 +6438,7 @@ and back when it closes or leaves the page.
|
|
|
6404
6438
|
|
|
6405
6439
|
What is server-rendered and what needs the client:
|
|
6406
6440
|
|
|
6407
|
-
| Server HTML | The element's script (2.
|
|
6441
|
+
| Server HTML | The element's script (2.8 kB, loaded once per page, as an island loads it) |
|
|
6408
6442
|
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
6409
6443
|
| The region and the toasts a page renders, with their text, roles and buttons. | The top layer (a manual popover), so toasts sit above dialogs and survive other popovers' light dismiss. |
|
|
6410
6444
|
| Toasts show at the window's bottom end (`toast.css`). | Timers, pausing, the limit, closing (button, Escape, swipe), F6, focus when a toast goes. |
|
|
@@ -6534,7 +6568,7 @@ group's script presses it on server pages too. For a value a form submits, use a
|
|
|
6534
6568
|
> A set of [Toggles](toggle.md) with one value, after Base UI's ToggleGroup: text alignment (one pressed at a time) or text style (several). `<lu-toggle-group role="group">` presses its toggles and gives the group one tab stop that the arrow keys, Home and End move, following the orientation and the direction, on server pages and in islands. `bind:value` keeps a signal in sync.
|
|
6535
6569
|
|
|
6536
6570
|
```ts
|
|
6537
|
-
import { Toggle, ToggleGroup } from "@lumiose/ui"; // or "@lumiose/ui/toggle-group"
|
|
6571
|
+
import { Toggle, ToggleGroup } from "@lumiose/ui"; // or "@lumiose/ui/toggle" and "@lumiose/ui/toggle-group"
|
|
6538
6572
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
6539
6573
|
```
|
|
6540
6574
|
|
|
@@ -6558,7 +6592,7 @@ import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
|
6558
6592
|
|
|
6559
6593
|
| Prop | Type | Default | |
|
|
6560
6594
|
| --------------- | ------------------------------ | -------------- | -------------------------------------------------------------------------- |
|
|
6561
|
-
| `value` | `string[]` | |
|
|
6595
|
+
| `value` | `string[]` | | The pressed toggles. Pair it with `onValueChange`, which updates it. |
|
|
6562
6596
|
| `defaultValue` | `string[]` | `[]` | The toggles pressed at first. |
|
|
6563
6597
|
| `onValueChange` | `(value: string[]) => void` | | Called after the user presses or releases a toggle. |
|
|
6564
6598
|
| `bind:value` | `Signal<string[]>` | | Stands in for `value` and `onValueChange`. |
|
|
@@ -6570,6 +6604,11 @@ import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
|
6570
6604
|
Every other prop passes through to `<lu-toggle-group>`: `aria-label`, `aria-labelledby`, `id`,
|
|
6571
6605
|
`class`. Name the group with one of the first two.
|
|
6572
6606
|
|
|
6607
|
+
With `value`, the group is controlled: after the user presses or releases a toggle, the toggles
|
|
6608
|
+
show `value` again, so a press shows only once `onValueChange` has updated `value` with it. One
|
|
6609
|
+
that leaves `value` as it was keeps the toggles as they were: an `onValueChange` that ignores an
|
|
6610
|
+
empty array keeps one toggle pressed. Setting `value` to the toggles already pressed does nothing.
|
|
6611
|
+
|
|
6573
6612
|
Each toggle's `value` is its identity in the group; its `onPressedChange` still fires. A
|
|
6574
6613
|
`pressedchange` event (`detail.pressed`) bubbles from a toggle before it changes, and
|
|
6575
6614
|
`event.preventDefault()` cancels the change.
|
|
@@ -6580,7 +6619,8 @@ Each toggle's `value` is its identity in the group; its `onPressedChange` still
|
|
|
6580
6619
|
## Example
|
|
6581
6620
|
|
|
6582
6621
|
```tsx check
|
|
6583
|
-
import { Toggle
|
|
6622
|
+
import { Toggle } from "@lumiose/ui/toggle";
|
|
6623
|
+
import { ToggleGroup } from "@lumiose/ui/toggle-group";
|
|
6584
6624
|
import { signal } from "lumiose";
|
|
6585
6625
|
|
|
6586
6626
|
export function TextAlignment() {
|
|
@@ -6633,7 +6673,7 @@ and single tab stop take over: the toggles are toolbar items.
|
|
|
6633
6673
|
## Without JavaScript, and the element's script
|
|
6634
6674
|
|
|
6635
6675
|
The server HTML has each toggle's `aria-pressed` and the tab stop. `<lu-toggle-group>`'s script
|
|
6636
|
-
(0
|
|
6676
|
+
(1.0 kB brotli) presses the toggles and moves focus, on server pages and in islands; when the tab
|
|
6637
6677
|
stop's toggle goes or is disabled, or a disabled group is enabled, the first pressed (else enabled)
|
|
6638
6678
|
toggle takes the tab stop. With no script
|
|
6639
6679
|
at all the toggles show their state but do not change. For values a form submits, use a
|
|
@@ -6653,7 +6693,7 @@ Custom elements and `aria-pressed`: every supported browser.
|
|
|
6653
6693
|
|
|
6654
6694
|
# Toolbar
|
|
6655
6695
|
|
|
6656
|
-
> A set of controls with one tab stop, after Base UI's Toolbar and the APG toolbar pattern: `<lu-toolbar role="toolbar">` moves focus between its items with the arrow keys, Home and End, following the orientation and the text direction. Its items are native: buttons that stay focusable when disabled, links, inputs, and the toggles of a [Toggle Group](toggle-group.md) inside it. In the server HTML every item is a tab stop, so each is reachable without JavaScript; a 1.
|
|
6696
|
+
> A set of controls with one tab stop, after Base UI's Toolbar and the APG toolbar pattern: `<lu-toolbar role="toolbar">` moves focus between its items with the arrow keys, Home and End, following the orientation and the text direction. Its items are native: buttons that stay focusable when disabled, links, inputs, and the toggles of a [Toggle Group](toggle-group.md) inside it. In the server HTML every item is a tab stop, so each is reachable without JavaScript; a 1.2 kB script makes them one tab stop and moves it.
|
|
6657
6697
|
|
|
6658
6698
|
```ts
|
|
6659
6699
|
import { Toolbar } from "@lumiose/ui"; // or "@lumiose/ui/toolbar"
|
|
@@ -6775,7 +6815,7 @@ its text selected, as in Base UI. Base UI advises at most one input, last.
|
|
|
6775
6815
|
## Without JavaScript, and the element's script
|
|
6776
6816
|
|
|
6777
6817
|
The server HTML is a labelled toolbar whose items are all tab stops, so Tab reaches each one
|
|
6778
|
-
without JavaScript or before the script runs. `<lu-toolbar>`'s script (1.
|
|
6818
|
+
without JavaScript or before the script runs. `<lu-toolbar>`'s script (1.2 kB brotli with Button's)
|
|
6779
6819
|
makes the toolbar one tab stop, moves focus with the keys and keeps the tab stop on the last focused
|
|
6780
6820
|
item.
|
|
6781
6821
|
|
|
@@ -6794,7 +6834,7 @@ Custom elements and `role="toolbar"`: every supported browser and screen reader.
|
|
|
6794
6834
|
|
|
6795
6835
|
# Tooltip
|
|
6796
6836
|
|
|
6797
|
-
> A short tip next to its trigger, on hover or keyboard focus: a native `popover="hint"` with `role="tooltip"`, placed with CSS anchor positioning. The trigger is described by the tip in server HTML, so screen readers announce it without hovering; a 2.
|
|
6837
|
+
> A short tip next to its trigger, on hover or keyboard focus: a native `popover="hint"` with `role="tooltip"`, placed with CSS anchor positioning. The trigger is described by the tip in server HTML, so screen readers announce it without hovering; a 2.1 kB script opens and closes it as Base UI's tooltip does. `bind:open` (or `open` and `onOpenChange`) keeps a signal in sync in islands.
|
|
6798
6838
|
|
|
6799
6839
|
```ts
|
|
6800
6840
|
import { Tooltip } from "@lumiose/ui"; // or "@lumiose/ui/tooltip"
|
|
@@ -6905,8 +6945,9 @@ A tooltip inside a popover keeps the popover open, and one inside a dialog belon
|
|
|
6905
6945
|
## Without JavaScript, and the client script
|
|
6906
6946
|
|
|
6907
6947
|
Without JavaScript the tip never shows, but the trigger keeps its description: screen readers
|
|
6908
|
-
announce it. A page that renders a `Tooltip` loads
|
|
6909
|
-
|
|
6948
|
+
announce it. A page that renders a `Tooltip` loads its script once, with the placement module it
|
|
6949
|
+
shares with Popover and Menu: 2.1 kB (brotli) without the Lumiose runtime; an island loads the
|
|
6950
|
+
same modules. It opens and closes every tooltip on the page, and places them
|
|
6910
6951
|
in browsers without CSS anchor positioning.
|
|
6911
6952
|
|
|
6912
6953
|
## Browser support
|