@lumiose/ui 0.1.1 → 0.1.2
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 +3 -2
- 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 +3 -2
- package/dist/combobox/combobox.tsx +6 -5
- package/dist/context-menu/context-menu.tsx +4 -3
- package/dist/dialog/dialog.tsx +2 -1
- package/dist/field/field.tsx +11 -10
- package/dist/form/reset.ts +4 -2
- package/dist/input/input.tsx +4 -1
- package/dist/menu/menu.tsx +9 -8
- package/dist/navigation-menu/navigation-menu.tsx +4 -3
- package/dist/number-field/number-field.tsx +4 -3
- package/dist/otp-field/otp-field.tsx +9 -8
- package/dist/popover/popover-hover.script.ts +27 -0
- package/dist/popover/popover.script.ts +19 -25
- package/dist/popover/popover.tsx +8 -3
- package/dist/preview-card/preview-card.tsx +2 -1
- package/dist/radio-group/radio-group.tsx +3 -2
- package/dist/select/select.script.ts +26 -0
- package/dist/select/select.tsx +36 -10
- package/dist/slider/slider.tsx +4 -3
- package/dist/switch/switch.tsx +4 -3
- package/dist/tabs/tabs.tsx +3 -2
- package/dist/toast/toast.tsx +3 -2
- 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/tooltip/tooltip.tsx +4 -1
- package/docs/README.md +9 -6
- 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 +107 -72
- 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 +1 -1
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
|
|
@@ -48,7 +47,8 @@ Anatomy, API, Example, Styling, Keyboard and focus, Without JavaScript, Browser
|
|
|
48
47
|
with `onCheckedChange`, `value` with `onValueChange`. Pass a signal's value and write it back in
|
|
49
48
|
the callback to keep both in sync, or leave both out and the element keeps its own state. Custom
|
|
50
49
|
elements report changes with lowercase DOM events, like native ones: `openchange`,
|
|
51
|
-
`checkedchange` and `change`.
|
|
50
|
+
`checkedchange` and `change`. The callbacks run inside `batch()`, as event handlers do: what
|
|
51
|
+
they write renders together, and the DOM is current as soon as the event returns.
|
|
52
52
|
- **Keyboard contracts.** Every component follows its WAI-ARIA Authoring Practices pattern, and
|
|
53
53
|
its end-to-end tests check the keyboard paths.
|
|
54
54
|
- **WCAG 2.2 AA.** Every component meets it: the components own semantics, keyboard and
|
|
@@ -81,7 +81,7 @@ custom properties, named as in shadcn/ui, are listed in [Theming](theming.md#the
|
|
|
81
81
|
| [Tooltip](tooltip.md) | Available: native hint popover, opened by its script |
|
|
82
82
|
| [Menu](menu.md) | Available: popover menu, opens without JavaScript |
|
|
83
83
|
| [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
|
|
84
|
+
| [Select](select.md) | Available: native `<select>`, customizable where supported, no script but for `label`s |
|
|
85
85
|
| [Tabs](tabs.md) | Available: server HTML with the full state, `<lu-tabs>` adds the keys |
|
|
86
86
|
| [Field](field.md) | Available: label, description, errors; native validation in the field |
|
|
87
87
|
| [Fieldset](fieldset.md) | Available: native `<fieldset>` and `<legend>`, no script |
|
|
@@ -176,7 +176,10 @@ errors are yours.
|
|
|
176
176
|
`@lumiose/ui` is opt-in, so its size is reported apart from the runtime's caps:
|
|
177
177
|
`pnpm --filter @lumiose/ui size` prints, per component, the JavaScript a server-rendered page loads
|
|
178
178
|
for its custom elements, the JavaScript an island that uses it loads, and its CSS (minified, gzip
|
|
179
|
-
and brotli).
|
|
179
|
+
and brotli). The scripts load as separate modules, in islands too: each component's script, and
|
|
180
|
+
the modules several scripts share (the dismissal model, the placement fallback, the hover timing),
|
|
181
|
+
each a file of its own, as an app's build splits them. The sizes on the component pages are those
|
|
182
|
+
files' brotli sizes added up.
|
|
180
183
|
|
|
181
184
|
## Related
|
|
182
185
|
|
|
@@ -190,13 +193,13 @@ and brotli).
|
|
|
190
193
|
|
|
191
194
|
> 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
195
|
|
|
193
|
-
**Status:**
|
|
194
|
-
|
|
196
|
+
**Status:** in development, on npm with its own 0.x versions, apart from the version the other
|
|
197
|
+
Lumiose packages share.
|
|
195
198
|
|
|
196
199
|
## Add the package
|
|
197
200
|
|
|
198
201
|
`@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.
|
|
202
|
+
with the app's own code, and `lumiose` is its peer dependency. Install it from npm:
|
|
200
203
|
|
|
201
204
|
```sh
|
|
202
205
|
pnpm add @lumiose/ui
|
|
@@ -578,8 +581,9 @@ closed item are HTML features: an accordion in a server-rendered page works befo
|
|
|
578
581
|
loads, and with none. Disabled triggers ignore the pointer through CSS. `value`, `onValueChange`
|
|
579
582
|
and `bind:value` need the component to run in an island.
|
|
580
583
|
|
|
581
|
-
A page that renders an `Accordion` loads
|
|
582
|
-
|
|
584
|
+
A page that renders an `Accordion` loads its script once, with the panel and animation modules it
|
|
585
|
+
shares with Collapsible: 1.3 kB (brotli) without the Lumiose runtime; an island loads the same
|
|
586
|
+
modules. It defines `<lu-accordion>`, which adds the arrow keys, Home and End, and sets
|
|
583
587
|
the panels' animation hooks (shared with [Collapsible](collapsible.md)); a disabled trigger does
|
|
584
588
|
not toggle, also from the keyboard.
|
|
585
589
|
|
|
@@ -602,7 +606,7 @@ not toggle, also from the keyboard.
|
|
|
602
606
|
|
|
603
607
|
# Autocomplete
|
|
604
608
|
|
|
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.
|
|
609
|
+
> 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
610
|
|
|
607
611
|
```ts
|
|
608
612
|
import { Autocomplete } from "@lumiose/ui"; // or "@lumiose/ui/autocomplete"
|
|
@@ -747,7 +751,7 @@ Focus stays in the input: the highlight moves through `aria-activedescendant`.
|
|
|
747
751
|
## Without JavaScript, and the element's script
|
|
748
752
|
|
|
749
753
|
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.
|
|
754
|
+
no script; the suggestions need it. `<lu-combobox>`'s script (5.8 kB brotli, shared with Combobox)
|
|
751
755
|
filters and opens them, moves the highlight, fills in a choice (firing `input` and `change` on the
|
|
752
756
|
input) and runs inline completion.
|
|
753
757
|
|
|
@@ -946,8 +950,8 @@ when it fails) and hides its fallback, from sight and from assistive technology,
|
|
|
946
950
|
the avatar twice; an avatar without an image shows its fallback.
|
|
947
951
|
`onLoadingStatusChange` needs the component to run in an island.
|
|
948
952
|
|
|
949
|
-
A page that renders an `Avatar` loads a 0.5 kB (brotli) script, without the Lumiose runtime;
|
|
950
|
-
|
|
953
|
+
A page that renders an `Avatar` loads a 0.5 kB (brotli) script, without the Lumiose runtime; an
|
|
954
|
+
island loads the same module. `<lu-avatar>` reads the image's state when it connects (a cached image shows
|
|
951
955
|
at once), then follows its `load` and `error` events and changes to its `src` and `srcset`. An
|
|
952
956
|
image that is complete without a size (an SVG without intrinsic dimensions, or a broken image) is
|
|
953
957
|
told apart with `decode()`.
|
|
@@ -1180,7 +1184,7 @@ A native checkbox: toggling, submission, `required`, reset and `disabled` (its o
|
|
|
1180
1184
|
work with no script.
|
|
1181
1185
|
|
|
1182
1186
|
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;
|
|
1187
|
+
script once, without the Lumiose runtime; an island loads the same module. It turns server HTML's
|
|
1184
1188
|
`data-indeterminate` into the `indeterminate` property (which has no attribute), makes read-only
|
|
1185
1189
|
inputs ignore clicks, Space and the label, runs the parent checkbox of a group and a [Radio
|
|
1186
1190
|
Group](radio-group.md)'s arrow keys, and adds an
|
|
@@ -1207,7 +1211,7 @@ browser.
|
|
|
1207
1211
|
> 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
1212
|
|
|
1209
1213
|
```ts
|
|
1210
|
-
import { CheckboxGroup, Checkbox, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/checkbox-group"
|
|
1214
|
+
import { CheckboxGroup, Checkbox, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/checkbox-group", "@lumiose/ui/checkbox" and "@lumiose/ui/fieldset"
|
|
1211
1215
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
1212
1216
|
```
|
|
1213
1217
|
|
|
@@ -1319,7 +1323,7 @@ Every supported browser.
|
|
|
1319
1323
|
|
|
1320
1324
|
# Collapsible
|
|
1321
1325
|
|
|
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.
|
|
1326
|
+
> 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
1327
|
|
|
1324
1328
|
```ts
|
|
1325
1329
|
import { Collapsible } from "@lumiose/ui"; // or "@lumiose/ui/collapsible"
|
|
@@ -1460,8 +1464,9 @@ Collapsible in a server-rendered page works before any script loads, and with no
|
|
|
1460
1464
|
trigger ignores the pointer through CSS. `open`, `onOpenChange` and `bind:open` need the component
|
|
1461
1465
|
to run in an island.
|
|
1462
1466
|
|
|
1463
|
-
A page that renders a `Collapsible` loads
|
|
1464
|
-
|
|
1467
|
+
A page that renders a `Collapsible` loads 0.9 kB (brotli) of modules once (its script, and the
|
|
1468
|
+
panel and animation modules it shares with Accordion), without the Lumiose runtime; an island
|
|
1469
|
+
loads the same modules. It covers every Collapsible and [Accordion](accordion.md) panel on the
|
|
1465
1470
|
page:
|
|
1466
1471
|
|
|
1467
1472
|
- the animation hooks above, set on every opening and closing, whatever caused it (the trigger,
|
|
@@ -1487,7 +1492,7 @@ page:
|
|
|
1487
1492
|
|
|
1488
1493
|
# Combobox
|
|
1489
1494
|
|
|
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.
|
|
1495
|
+
> 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
1496
|
|
|
1492
1497
|
```ts
|
|
1493
1498
|
import { Combobox } from "@lumiose/ui"; // or "@lumiose/ui/combobox"
|
|
@@ -1800,8 +1805,9 @@ In the server HTML the input is empty even with a selected value: the input rend
|
|
|
1800
1805
|
options, so the server does not know the selected option's label when it writes the input. The
|
|
1801
1806
|
script puts the label in as it upgrades the element (decision-62).
|
|
1802
1807
|
|
|
1803
|
-
A page that renders a `Combobox` loads the script once,
|
|
1804
|
-
|
|
1808
|
+
A page that renders a `Combobox` loads the script once, with the dismissal and placement modules
|
|
1809
|
+
it shares with Menu and Popover: 5.8 kB (brotli) without the Lumiose runtime, and an island loads
|
|
1810
|
+
the same modules. It defines `lu-combobox`, which upgrades every combobox on
|
|
1805
1811
|
the page in place: it reads the selection the server rendered (`aria-selected="true"`), puts its
|
|
1806
1812
|
label in the input (text typed before it ran is kept, as a search), renders the chips, and from
|
|
1807
1813
|
then on owns the value, the filtering, the popup,
|
|
@@ -1859,7 +1865,7 @@ The element is also an API of its own, for scripts and other frameworks:
|
|
|
1859
1865
|
|
|
1860
1866
|
# Context Menu
|
|
1861
1867
|
|
|
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.
|
|
1868
|
+
> 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
1869
|
|
|
1864
1870
|
```ts
|
|
1865
1871
|
import { ContextMenu } from "@lumiose/ui"; // or "@lumiose/ui/context-menu"
|
|
@@ -2034,8 +2040,8 @@ Opening a menu at the pointer needs the script: without JavaScript a right-click
|
|
|
2034
2040
|
browser's own menu, and the popup stays hidden. `open`, `onOpenChange` and `bind:open` need the
|
|
2035
2041
|
component to run in an island.
|
|
2036
2042
|
|
|
2037
|
-
A page that renders a `ContextMenu` loads Menu's script and a 0.
|
|
2038
|
-
4
|
|
2043
|
+
A page that renders a `ContextMenu` loads Menu's script and a 0.9 kB (brotli) one of its own,
|
|
2044
|
+
5.4 kB together, without the Lumiose runtime; an island loads the same modules. The element opens the menu on a
|
|
2039
2045
|
right-click, a long press or the keys, at the pointer, through a zero-size anchor that it moves
|
|
2040
2046
|
there (CSS anchor positioning places the popup, with Menu's flips; without it, the shared
|
|
2041
2047
|
placement script does). Menu's script does the rest: keys, items, submenus, and dismissal shared
|
|
@@ -2280,7 +2286,7 @@ server-rendered page works before any script loads, and with none. `open`, `onOp
|
|
|
2280
2286
|
|
|
2281
2287
|
Where the native element falls short of Base UI's dialog, a small script closes the gap: a page
|
|
2282
2288
|
that renders a `Dialog` loads it once, as a 1.5 kB (brotli) module without the Lumiose runtime, and
|
|
2283
|
-
|
|
2289
|
+
an island loads the same module. It covers every `<dialog>` on the page:
|
|
2284
2290
|
|
|
2285
2291
|
- a right-click or a second finger outside does not close the dialog;
|
|
2286
2292
|
- `data-nested-dialog-open` and `--lu-nested-dialogs` on a dialog with open dialogs inside;
|
|
@@ -2500,8 +2506,9 @@ The trigger, the close buttons, Escape and the click outside are HTML features,
|
|
|
2500
2506
|
drawer in a server-rendered page works before any script loads, and with none, against its edge.
|
|
2501
2507
|
`open`, `onOpenChange` and `bind:open` need the component to run in an island.
|
|
2502
2508
|
|
|
2503
|
-
A page that renders a `Drawer` loads Dialog's script and a 1 kB (brotli) one of its own (2.
|
|
2504
|
-
together
|
|
2509
|
+
A page that renders a `Drawer` loads Dialog's script and a 1.1 kB (brotli) one of its own (2.8 kB
|
|
2510
|
+
together, with the animation module it shares with Toast), without the Lumiose runtime; an island
|
|
2511
|
+
loads the same modules. The drawer's script handles the
|
|
2505
2512
|
swipe, with the mouse and pen through pointer events and on touch screens through touch events,
|
|
2506
2513
|
taking the gesture from scrolling only once it is a swipe.
|
|
2507
2514
|
|
|
@@ -2778,8 +2785,8 @@ the message Error's id (`Field.Error` without children or `match`) even when the
|
|
|
2778
2785
|
Errors with children or a `match`. Give a field that must read well without JavaScript a message
|
|
2779
2786
|
Error, and its Descriptions before the control.
|
|
2780
2787
|
|
|
2781
|
-
A page that renders a `Field` loads a 1.7 kB (brotli) script once, without the Lumiose runtime;
|
|
2782
|
-
|
|
2788
|
+
A page that renders a `Field` loads a 1.7 kB (brotli) script once, without the Lumiose runtime; an
|
|
2789
|
+
island loads the same module. On a submit attempt (a submit button, Enter in a field, `requestSubmit()` or
|
|
2783
2790
|
the form's `reportValidity()`; a silent `checkValidity()` changes nothing) it cancels the browser's
|
|
2784
2791
|
`invalid` bubble for fields that have an Error part for the problem and shows it there instead (the
|
|
2785
2792
|
browser's message, or one your `validate` set), with the timing above, and focuses the first
|
|
@@ -3142,7 +3149,7 @@ Every browser; input types and constraints as the browser supports them.
|
|
|
3142
3149
|
|
|
3143
3150
|
# Menu
|
|
3144
3151
|
|
|
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.
|
|
3152
|
+
> 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
3153
|
|
|
3147
3154
|
```ts
|
|
3148
3155
|
import { Menu } from "@lumiose/ui"; // or "@lumiose/ui/menu"
|
|
@@ -3463,8 +3470,9 @@ submenu closes it, but the browser leaves focus on the page rather than on the s
|
|
|
3463
3470
|
Tab starts over from the top (the script returns focus to the trigger). `open`, `onOpenChange` and
|
|
3464
3471
|
the `bind:` props need the component to run in the browser, in an island.
|
|
3465
3472
|
|
|
3466
|
-
The keyboard contract comes from a small script: a page that renders a `Menu` loads it once,
|
|
3467
|
-
|
|
3473
|
+
The keyboard contract comes from a small script: a page that renders a `Menu` loads it once, with
|
|
3474
|
+
the dismissal and placement modules it shares with Popover and Combobox: 4.4 kB (brotli) without
|
|
3475
|
+
the Lumiose runtime, and an island loads the same modules. It defines `lu-menu`,
|
|
3468
3476
|
which upgrades every menu on the page in place, and adds what the native popover lacks: focus on
|
|
3469
3477
|
open and its return on close, the arrows, Home, End and typeahead, Escape one level at a time, Tab,
|
|
3470
3478
|
submenus, checkbox and radio items, disabled items, `data-highlighted`, and the pointer behaviour
|
|
@@ -3510,7 +3518,7 @@ The element is also an API of its own, for scripts and other frameworks:
|
|
|
3510
3518
|
|
|
3511
3519
|
# Menubar
|
|
3512
3520
|
|
|
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
|
|
3521
|
+
> 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
3522
|
|
|
3515
3523
|
```ts
|
|
3516
3524
|
import { Menu, Menubar } from "@lumiose/ui"; // or "@lumiose/ui/menu" and "@lumiose/ui/menubar"
|
|
@@ -3679,8 +3687,8 @@ flex row (a column when vertical); each `<lu-menu>` adds no box.
|
|
|
3679
3687
|
Each trigger opens its menu through `popovertarget`, and the browser light-dismisses it: without
|
|
3680
3688
|
JavaScript every trigger is a tab stop, and the menus open with Enter, Space or a click.
|
|
3681
3689
|
|
|
3682
|
-
A page that renders a `Menubar` loads Menu's script and a
|
|
3683
|
-
together, without the Lumiose runtime;
|
|
3690
|
+
A page that renders a `Menubar` loads Menu's script and a 1.1 kB (brotli) one of its own, 5.5 kB
|
|
3691
|
+
together, without the Lumiose runtime; an island loads the same modules. The menubar's script makes the bar one
|
|
3684
3692
|
tab stop once the page has loaded, and adds the arrow keys between items and menus and the hover
|
|
3685
3693
|
switching. Each menu stays Menu's: its keys, items, submenus and dismissal.
|
|
3686
3694
|
|
|
@@ -3805,7 +3813,7 @@ above. `role="meter"` reaches screen readers in recent versions; older ones read
|
|
|
3805
3813
|
|
|
3806
3814
|
# Navigation Menu
|
|
3807
3815
|
|
|
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
|
|
3816
|
+
> 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
3817
|
|
|
3810
3818
|
```ts
|
|
3811
3819
|
import { NavigationMenu } from "@lumiose/ui"; // or "@lumiose/ui/navigation-menu"
|
|
@@ -4040,8 +4048,9 @@ The `<nav>`, its links and the triggers are HTML: each trigger opens its content
|
|
|
4040
4048
|
`popovertarget`, one at a time (an auto popover closes the others), and Escape or a click outside
|
|
4041
4049
|
closes it. `value`, `onValueChange` and `bind:value` need the component to run in an island.
|
|
4042
4050
|
|
|
4043
|
-
A page that renders a `NavigationMenu` loads
|
|
4044
|
-
Menu
|
|
4051
|
+
A page that renders a `NavigationMenu` loads its script, with the dismissal and placement modules
|
|
4052
|
+
it shares with Menu and Popover: 4.0 kB (brotli) without the Lumiose runtime; an island loads the
|
|
4053
|
+
same modules. `<lu-navigation-menu>`
|
|
4045
4054
|
takes over the trigger's click (so a click keeps a content opened by hover open), opens contents on
|
|
4046
4055
|
hover, adds the arrow keys, closes a content when focus leaves its item, dismisses contents as Menu
|
|
4047
4056
|
and Popover do (a press of the main button outside, an Escape, another layer opening), keeps
|
|
@@ -4249,7 +4258,7 @@ Scrubbing uses pointer capture, without pointer lock.
|
|
|
4249
4258
|
|
|
4250
4259
|
# OTP Field
|
|
4251
4260
|
|
|
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.
|
|
4261
|
+
> 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
4262
|
|
|
4254
4263
|
```ts
|
|
4255
4264
|
import { OTPField } from "@lumiose/ui"; // or "@lumiose/ui/otp-field"
|
|
@@ -4388,7 +4397,7 @@ auto-submits.
|
|
|
4388
4397
|
## Without JavaScript, and the element's script
|
|
4389
4398
|
|
|
4390
4399
|
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.
|
|
4400
|
+
submission work with no script, and the slots stay hidden. `<lu-otp-field>`'s script (1.6 kB
|
|
4392
4401
|
brotli) shows the slots, cleans the value as it changes (firing `valueinvalid` for refused input),
|
|
4393
4402
|
fires `valuecomplete`, auto-submits, and follows a form reset.
|
|
4394
4403
|
|
|
@@ -4412,7 +4421,7 @@ does not zoom into it on focus.
|
|
|
4412
4421
|
|
|
4413
4422
|
# Popover
|
|
4414
4423
|
|
|
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.
|
|
4424
|
+
> 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
4425
|
|
|
4417
4426
|
```ts
|
|
4418
4427
|
import { Popover } from "@lumiose/ui"; // or "@lumiose/ui/popover"
|
|
@@ -4645,11 +4654,14 @@ The trigger, the close buttons, Escape, the click outside and the placement are
|
|
|
4645
4654
|
features: a popover in a server-rendered page works before any script loads, and with none. So
|
|
4646
4655
|
does a modal popover, through invoker commands and `closedby` (where a browser lacks them,
|
|
4647
4656
|
[Dialog](dialog.md)'s script, which a modal popover loads, stands in). Opening on hover needs the
|
|
4648
|
-
|
|
4657
|
+
scripts.
|
|
4649
4658
|
`open`, `onOpenChange` and `bind:open` need the component to run in an island.
|
|
4650
4659
|
|
|
4651
|
-
A page that renders a `Popover` loads
|
|
4652
|
-
|
|
4660
|
+
A page that renders a `Popover` loads its script once, with the dismissal and placement modules it
|
|
4661
|
+
shares with Menu, Combobox and Tooltip: 3.2 kB (brotli) without the Lumiose runtime. A trigger
|
|
4662
|
+
with `openOnHover` adds 1.0 kB, the hover timing it shares with
|
|
4663
|
+
[Preview Card](preview-card.md); a page without one goes without it. An island loads the same
|
|
4664
|
+
modules. The scripts cover every Popover on the page:
|
|
4653
4665
|
|
|
4654
4666
|
- focus on open (the first focusable element, or the popup) and its return on close;
|
|
4655
4667
|
- dismissal, shared with [Menu](menu.md) and [Combobox](combobox.md): a trigger's click makes the
|
|
@@ -4686,7 +4698,7 @@ popover's `dialog::backdrop`) styles the layer under it, without an element of i
|
|
|
4686
4698
|
|
|
4687
4699
|
# Preview Card
|
|
4688
4700
|
|
|
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
|
|
4701
|
+
> 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
4702
|
|
|
4691
4703
|
```ts
|
|
4692
4704
|
import { PreviewCard } from "@lumiose/ui"; // or "@lumiose/ui/preview-card"
|
|
@@ -4800,8 +4812,9 @@ the link, with a fade (none where motion is reduced).
|
|
|
4800
4812
|
|
|
4801
4813
|
## Without JavaScript, and the client script
|
|
4802
4814
|
|
|
4803
|
-
The link is a plain link and the card never opens. A page that renders a `PreviewCard` loads
|
|
4804
|
-
|
|
4815
|
+
The link is a plain link and the card never opens. A page that renders a `PreviewCard` loads its
|
|
4816
|
+
script once, with the hover timing, dismissal and placement modules it shares with Popover: 3.4 kB
|
|
4817
|
+
(brotli) without the Lumiose runtime; an island loads the same modules. It runs hover and focus with
|
|
4805
4818
|
their delays, dismissal, `data-popup-open`, and the placement in browsers without CSS anchor
|
|
4806
4819
|
positioning.
|
|
4807
4820
|
|
|
@@ -4940,7 +4953,7 @@ above.
|
|
|
4940
4953
|
> 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
4954
|
|
|
4942
4955
|
```ts
|
|
4943
|
-
import { Radio, RadioGroup, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/radio-group"
|
|
4956
|
+
import { Radio, RadioGroup, Fieldset } from "@lumiose/ui"; // or "@lumiose/ui/radio-group" and "@lumiose/ui/fieldset"
|
|
4944
4957
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
4945
4958
|
```
|
|
4946
4959
|
|
|
@@ -5217,7 +5230,7 @@ supported browser.
|
|
|
5217
5230
|
|
|
5218
5231
|
# Select
|
|
5219
5232
|
|
|
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
|
|
5233
|
+
> 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
5234
|
|
|
5222
5235
|
```ts
|
|
5223
5236
|
import { Select } from "@lumiose/ui"; // or "@lumiose/ui/select"
|
|
@@ -5273,11 +5286,17 @@ handlers. Name it with a `<label for>` pointing at its `id`, or `aria-label`, or
|
|
|
5273
5286
|
|
|
5274
5287
|
### Select.Item
|
|
5275
5288
|
|
|
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
|
|
5289
|
+
| Prop | Type | Default | |
|
|
5290
|
+
| ---------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
5291
|
+
| `value` | `string` | | Required: the value the select takes, and submits, when selected. |
|
|
5292
|
+
| `disabled` | `boolean` | `false` | The option cannot be selected; the arrow keys skip it. |
|
|
5293
|
+
| `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. |
|
|
5294
|
+
|
|
5295
|
+
A customizable select's picker shows each item's content, with or without `label`. The classic
|
|
5296
|
+
select, which shows text only, shows the `label`. An item with a `label` renders the `<option>`'s
|
|
5297
|
+
`label` and `aria-label`, and a hidden copy of it first in its content (`<span hidden
|
|
5298
|
+
data-label>`), which typeahead matches: so `option.text`, and `<selectedcontent>`'s
|
|
5299
|
+
`textContent`, start with the label, while the rendered text does not.
|
|
5281
5300
|
|
|
5282
5301
|
### Select.Group
|
|
5283
5302
|
|
|
@@ -5292,7 +5311,7 @@ handlers. Name it with a `<label for>` pointing at its `id`, or `aria-label`, or
|
|
|
5292
5311
|
|
|
5293
5312
|
**Differences from Base UI's Select.** Select is the native control, chosen over the listbox
|
|
5294
5313
|
pattern because it works without JavaScript, carries forms, autofill, validation and the mobile
|
|
5295
|
-
pickers, and
|
|
5314
|
+
pickers, and needs no script. So it has no `open`, `onOpenChange` or `modal` (the platform fires no
|
|
5296
5315
|
event when the picker opens; style `:open` instead), no `Label` (use `<label for>`), no `multiple`
|
|
5297
5316
|
(use [Combobox](combobox.md) with `multiple`), no `alignItemWithTrigger` (the picker opens below the
|
|
5298
5317
|
control and flips), no `Portal`, `Positioner`, `Popup`, `List`, `Icon`, `ItemText`,
|
|
@@ -5421,7 +5440,7 @@ A click on a `<label for>` focuses the select without opening it. A click on the
|
|
|
5421
5440
|
picker; a click on an option selects it; a click outside closes the picker. Other browsers keep
|
|
5422
5441
|
their own select keyboard and pickers, which differ by platform.
|
|
5423
5442
|
|
|
5424
|
-
## Without JavaScript
|
|
5443
|
+
## Without JavaScript, and the client script
|
|
5425
5444
|
|
|
5426
5445
|
Select needs none: it is a native control, in server HTML and with JavaScript off, on every
|
|
5427
5446
|
browser. It submits under its `name`, is validated (`required`), resets with its form, takes the
|
|
@@ -5429,6 +5448,15 @@ browser's autofill and is disabled by a disabled `<fieldset>`. `value`, `onValue
|
|
|
5429
5448
|
`bind:value` need the component to run in the browser, in an island; there `value` sets the
|
|
5430
5449
|
control's value when it changes, and its `change` event calls `onValueChange`.
|
|
5431
5450
|
|
|
5451
|
+
Items with a `label` are the exception. A customizable select's picker shows an `<option>`'s
|
|
5452
|
+
`label` attribute instead of its content, through the browser's own style, which no CSS
|
|
5453
|
+
overrides. So a page whose selects have such items loads a 0.2 kB (brotli) script once, without
|
|
5454
|
+
the Lumiose runtime (an island loads the same module). When a customizable select is pressed or
|
|
5455
|
+
takes focus, before its picker opens, the script removes the attribute from its items: the picker
|
|
5456
|
+
shows their content, typeahead matches the label's hidden copy, and `aria-label` keeps their name.
|
|
5457
|
+
A classic select keeps the attribute, which it shows. Without the script, the customizable
|
|
5458
|
+
picker shows the labels alone.
|
|
5459
|
+
|
|
5432
5460
|
## Browser support
|
|
5433
5461
|
|
|
5434
5462
|
- **Customizable select** (`appearance: base-select`, `::picker(select)`, `<selectedcontent>`, a
|
|
@@ -5439,8 +5467,8 @@ control's value when it changes, and its `change` event calls `onValueChange`.
|
|
|
5439
5467
|
`Trigger`). Older browsers without customizable select drop them from server HTML, so an
|
|
5440
5468
|
island's select falls back to rendering on the client there
|
|
5441
5469
|
([LUM4006](https://itsjavi.com/lumiose/docs/errors/LUM4006/)).
|
|
5442
|
-
- **Typeahead** matches an option's text, or its `label`: give options
|
|
5443
|
-
`label`.
|
|
5470
|
+
- **Typeahead** matches an option's text, or its `label`: give options whose content starts with
|
|
5471
|
+
an icon (an emoji, a symbol) a `label`.
|
|
5444
5472
|
- **`:open`** comes with customizable select.
|
|
5445
5473
|
|
|
5446
5474
|
## Related
|
|
@@ -6098,7 +6126,7 @@ The [WAI-ARIA tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/):
|
|
|
6098
6126
|
The server HTML is complete: the selected tab, its panel and the tab stop are right before any
|
|
6099
6127
|
script loads, and the panels of the other tabs are `hidden`. Selecting another tab needs
|
|
6100
6128
|
`<lu-tabs>`' script, a 1.2 kB (brotli) module that a page rendering `Tabs` loads once, without
|
|
6101
|
-
the Lumiose runtime;
|
|
6129
|
+
the Lumiose runtime; an island loads the same module. A `Tabs.Indicator` is placed by CSS alone until then; the
|
|
6102
6130
|
script makes it follow a new selection. `value`, `onValueChange` and `bind:value` need the
|
|
6103
6131
|
component to run in an island.
|
|
6104
6132
|
|
|
@@ -6120,7 +6148,7 @@ component to run in an island.
|
|
|
6120
6148
|
|
|
6121
6149
|
# Toast
|
|
6122
6150
|
|
|
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.
|
|
6151
|
+
> 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
6152
|
|
|
6125
6153
|
```ts
|
|
6126
6154
|
import { Toast } from "@lumiose/ui"; // or "@lumiose/ui/toast"
|
|
@@ -6404,7 +6432,7 @@ and back when it closes or leaves the page.
|
|
|
6404
6432
|
|
|
6405
6433
|
What is server-rendered and what needs the client:
|
|
6406
6434
|
|
|
6407
|
-
| Server HTML | The element's script (2.
|
|
6435
|
+
| Server HTML | The element's script (2.8 kB, loaded once per page, as an island loads it) |
|
|
6408
6436
|
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
6409
6437
|
| 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
6438
|
| 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 +6562,7 @@ group's script presses it on server pages too. For a value a form submits, use a
|
|
|
6534
6562
|
> 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
6563
|
|
|
6536
6564
|
```ts
|
|
6537
|
-
import { Toggle, ToggleGroup } from "@lumiose/ui"; // or "@lumiose/ui/toggle-group"
|
|
6565
|
+
import { Toggle, ToggleGroup } from "@lumiose/ui"; // or "@lumiose/ui/toggle" and "@lumiose/ui/toggle-group"
|
|
6538
6566
|
import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
6539
6567
|
```
|
|
6540
6568
|
|
|
@@ -6558,7 +6586,7 @@ import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
|
6558
6586
|
|
|
6559
6587
|
| Prop | Type | Default | |
|
|
6560
6588
|
| --------------- | ------------------------------ | -------------- | -------------------------------------------------------------------------- |
|
|
6561
|
-
| `value` | `string[]` | |
|
|
6589
|
+
| `value` | `string[]` | | The pressed toggles. Pair it with `onValueChange`, which updates it. |
|
|
6562
6590
|
| `defaultValue` | `string[]` | `[]` | The toggles pressed at first. |
|
|
6563
6591
|
| `onValueChange` | `(value: string[]) => void` | | Called after the user presses or releases a toggle. |
|
|
6564
6592
|
| `bind:value` | `Signal<string[]>` | | Stands in for `value` and `onValueChange`. |
|
|
@@ -6570,6 +6598,11 @@ import "@lumiose/ui/themes/default.css"; // optional: the default theme
|
|
|
6570
6598
|
Every other prop passes through to `<lu-toggle-group>`: `aria-label`, `aria-labelledby`, `id`,
|
|
6571
6599
|
`class`. Name the group with one of the first two.
|
|
6572
6600
|
|
|
6601
|
+
With `value`, the group is controlled: after the user presses or releases a toggle, the toggles
|
|
6602
|
+
show `value` again, so a press shows only once `onValueChange` has updated `value` with it. One
|
|
6603
|
+
that leaves `value` as it was keeps the toggles as they were: an `onValueChange` that ignores an
|
|
6604
|
+
empty array keeps one toggle pressed. Setting `value` to the toggles already pressed does nothing.
|
|
6605
|
+
|
|
6573
6606
|
Each toggle's `value` is its identity in the group; its `onPressedChange` still fires. A
|
|
6574
6607
|
`pressedchange` event (`detail.pressed`) bubbles from a toggle before it changes, and
|
|
6575
6608
|
`event.preventDefault()` cancels the change.
|
|
@@ -6580,7 +6613,8 @@ Each toggle's `value` is its identity in the group; its `onPressedChange` still
|
|
|
6580
6613
|
## Example
|
|
6581
6614
|
|
|
6582
6615
|
```tsx check
|
|
6583
|
-
import { Toggle
|
|
6616
|
+
import { Toggle } from "@lumiose/ui/toggle";
|
|
6617
|
+
import { ToggleGroup } from "@lumiose/ui/toggle-group";
|
|
6584
6618
|
import { signal } from "lumiose";
|
|
6585
6619
|
|
|
6586
6620
|
export function TextAlignment() {
|
|
@@ -6633,7 +6667,7 @@ and single tab stop take over: the toggles are toolbar items.
|
|
|
6633
6667
|
## Without JavaScript, and the element's script
|
|
6634
6668
|
|
|
6635
6669
|
The server HTML has each toggle's `aria-pressed` and the tab stop. `<lu-toggle-group>`'s script
|
|
6636
|
-
(0
|
|
6670
|
+
(1.0 kB brotli) presses the toggles and moves focus, on server pages and in islands; when the tab
|
|
6637
6671
|
stop's toggle goes or is disabled, or a disabled group is enabled, the first pressed (else enabled)
|
|
6638
6672
|
toggle takes the tab stop. With no script
|
|
6639
6673
|
at all the toggles show their state but do not change. For values a form submits, use a
|
|
@@ -6653,7 +6687,7 @@ Custom elements and `aria-pressed`: every supported browser.
|
|
|
6653
6687
|
|
|
6654
6688
|
# Toolbar
|
|
6655
6689
|
|
|
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.
|
|
6690
|
+
> 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
6691
|
|
|
6658
6692
|
```ts
|
|
6659
6693
|
import { Toolbar } from "@lumiose/ui"; // or "@lumiose/ui/toolbar"
|
|
@@ -6775,7 +6809,7 @@ its text selected, as in Base UI. Base UI advises at most one input, last.
|
|
|
6775
6809
|
## Without JavaScript, and the element's script
|
|
6776
6810
|
|
|
6777
6811
|
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.
|
|
6812
|
+
without JavaScript or before the script runs. `<lu-toolbar>`'s script (1.2 kB brotli with Button's)
|
|
6779
6813
|
makes the toolbar one tab stop, moves focus with the keys and keeps the tab stop on the last focused
|
|
6780
6814
|
item.
|
|
6781
6815
|
|
|
@@ -6794,7 +6828,7 @@ Custom elements and `role="toolbar"`: every supported browser and screen reader.
|
|
|
6794
6828
|
|
|
6795
6829
|
# Tooltip
|
|
6796
6830
|
|
|
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.
|
|
6831
|
+
> 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
6832
|
|
|
6799
6833
|
```ts
|
|
6800
6834
|
import { Tooltip } from "@lumiose/ui"; // or "@lumiose/ui/tooltip"
|
|
@@ -6905,8 +6939,9 @@ A tooltip inside a popover keeps the popover open, and one inside a dialog belon
|
|
|
6905
6939
|
## Without JavaScript, and the client script
|
|
6906
6940
|
|
|
6907
6941
|
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
|
-
|
|
6942
|
+
announce it. A page that renders a `Tooltip` loads its script once, with the placement module it
|
|
6943
|
+
shares with Popover and Menu: 2.1 kB (brotli) without the Lumiose runtime; an island loads the
|
|
6944
|
+
same modules. It opens and closes every tooltip on the page, and places them
|
|
6910
6945
|
in browsers without CSS anchor positioning.
|
|
6911
6946
|
|
|
6912
6947
|
## Browser support
|