@nldd/design-system 0.8.87 → 0.8.89
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/custom-elements.json +305 -66
- package/dist/components/components.js +1007 -218
- package/dist/components/content/image/image.d.ts +23 -3
- package/dist/components/content/image/image.d.ts.map +1 -1
- package/dist/components/content/image/image.js +74 -17
- package/dist/components/content/image/image.js.map +1 -1
- package/dist/components/content/image/image.template.js +1 -1
- package/dist/components/content/image/image.template.js.map +1 -1
- package/dist/components/{dist-LX8LuMac.js → dist-BLaE_n_F.js} +1 -1
- package/dist/components/{dist-CX3DK4i7.js → dist-BeymuiGt.js} +3 -3
- package/dist/components/{dist-CbCO0WCd.js → dist-CENYEz7C.js} +1 -1
- package/dist/components/{dist-B_Mnmrj4.js → dist-CYLM5ciE.js} +1 -1
- package/dist/components/{dist-fIxe0l7k.js → dist-DHA-0RyT.js} +91 -34
- package/dist/components/{dist-CgDuh26K.js → dist-D_ckX1sK.js} +1 -1
- package/dist/components/{dist-eVFegyjM.js → dist-Dh_b9r4M.js} +1 -1
- package/dist/components/{dist-DXZ-cFAl.js → dist-DkZlotgT.js} +2 -2
- package/dist/components/{dist-CSrO_mYe.js → dist-TCqV9dho.js} +1 -1
- package/dist/components/{dist-ByH8hQze.js → dist-Y54Lma86.js} +2 -2
- package/dist/components/{dist-CRwuSgMM.js → dist-yyE8P2O6.js} +2 -2
- package/dist/components/inputs/radio-button/radio-button.d.ts +58 -18
- package/dist/components/inputs/radio-button/radio-button.d.ts.map +1 -1
- package/dist/components/inputs/radio-button/radio-button.js +136 -29
- package/dist/components/inputs/radio-button/radio-button.js.map +1 -1
- package/dist/components/inputs/radio-button/radio-button.styles.d.ts.map +1 -1
- package/dist/components/inputs/radio-button/radio-button.styles.js +17 -23
- package/dist/components/inputs/radio-button/radio-button.styles.js.map +1 -1
- package/dist/components/inputs/radio-button/radio-button.template.d.ts.map +1 -1
- package/dist/components/inputs/radio-button/radio-button.template.js +13 -10
- package/dist/components/inputs/radio-button/radio-button.template.js.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.d.ts +65 -18
- package/dist/components/inputs/radio-button-field/radio-button-field.d.ts.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.js +151 -29
- package/dist/components/inputs/radio-button-field/radio-button-field.js.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.styles.d.ts.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.styles.js +17 -0
- package/dist/components/inputs/radio-button-field/radio-button-field.styles.js.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.template.d.ts.map +1 -1
- package/dist/components/inputs/radio-button-field/radio-button-field.template.js +21 -12
- package/dist/components/inputs/radio-button-field/radio-button-field.template.js.map +1 -1
- package/dist/components/inputs/radio-button-group/radio-button-group.d.ts +3 -0
- package/dist/components/inputs/radio-button-group/radio-button-group.d.ts.map +1 -1
- package/dist/components/inputs/radio-button-group/radio-button-group.js +16 -4
- package/dist/components/inputs/radio-button-group/radio-button-group.js.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.d.ts +46 -13
- package/dist/components/inputs/segmented-control/segmented-control.d.ts.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.js +145 -16
- package/dist/components/inputs/segmented-control/segmented-control.js.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.styles.d.ts.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.styles.js +16 -0
- package/dist/components/inputs/segmented-control/segmented-control.styles.js.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.template.d.ts.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.template.js +47 -24
- package/dist/components/inputs/segmented-control/segmented-control.template.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.cursor.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.cursor.js +14 -1
- package/dist/components/inputs/text-editor/text-editor.cursor.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.js +3 -1
- package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.d.ts +36 -2
- package/dist/components/inputs/toggle-button/toggle-button.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.js +116 -3
- package/dist/components/inputs/toggle-button/toggle-button.js.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.styles.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.styles.js +17 -1
- package/dist/components/inputs/toggle-button/toggle-button.styles.js.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.template.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.template.js +25 -2
- package/dist/components/inputs/toggle-button/toggle-button.template.js.map +1 -1
- package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts +4 -0
- package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button-group/toggle-button-group.js +21 -2
- package/dist/components/inputs/toggle-button-group/toggle-button-group.js.map +1 -1
- package/dist/components/layout/page/page.d.ts +23 -5
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +39 -34
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/layout/page/page.styles.d.ts.map +1 -1
- package/dist/components/layout/page/page.styles.js +2 -0
- package/dist/components/layout/page/page.styles.js.map +1 -1
- package/dist/components/layout/sheet/sheet.template.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.template.js +3 -0
- package/dist/components/layout/sheet/sheet.template.js.map +1 -1
- package/dist/components/layout/window/window.template.d.ts.map +1 -1
- package/dist/components/layout/window/window.template.js +3 -0
- package/dist/components/layout/window/window.template.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.d.ts +1 -1
- package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.js +4 -3
- package/dist/components/lists-and-tables/list/list.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.template.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.template.js +15 -10
- package/dist/components/lists-and-tables/list/list.template.js.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.d.ts +4 -2
- package/dist/components/navigation/menu-bar/menu-bar.d.ts.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.js +4 -2
- package/dist/components/navigation/menu-bar/menu-bar.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js +3 -0
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js.map +1 -1
- package/dist/components/status-and-feedback/notification/notification-region.d.ts +4 -0
- package/dist/components/status-and-feedback/notification/notification-region.d.ts.map +1 -1
- package/dist/components/status-and-feedback/notification/notification-region.js +161 -19
- package/dist/components/status-and-feedback/notification/notification-region.js.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.d.ts +17 -0
- package/dist/components/status-and-feedback/notification/notification.d.ts.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.js +33 -0
- package/dist/components/status-and-feedback/notification/notification.js.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/notification/notification.styles.js +6 -0
- package/dist/components/status-and-feedback/notification/notification.styles.js.map +1 -1
- package/dist/css/variables.css +2 -2
- package/dist/nldd.min.js +629 -540
- package/dist/types/vue.d.ts +24 -20
- package/dist/utilities/described-by-mixin.d.ts +2 -2
- package/dist/utilities/described-by-mixin.d.ts.map +1 -1
- package/dist/utilities/described-by-mixin.js +11 -6
- package/dist/utilities/described-by-mixin.js.map +1 -1
- package/dist/utilities/radio-grouping.d.ts +66 -0
- package/dist/utilities/radio-grouping.d.ts.map +1 -0
- package/dist/utilities/radio-grouping.js +133 -0
- package/dist/utilities/radio-grouping.js.map +1 -0
- package/dist/utilities/radio-position.d.ts +20 -0
- package/dist/utilities/radio-position.d.ts.map +1 -0
- package/dist/utilities/radio-position.js +11 -0
- package/dist/utilities/radio-position.js.map +1 -0
- package/package.json +10 -10
package/dist/types/vue.d.ts
CHANGED
|
@@ -1354,7 +1354,7 @@ declare module 'vue' {
|
|
|
1354
1354
|
type NLDDImageProps = {
|
|
1355
1355
|
/** Image URL */
|
|
1356
1356
|
'src'?: NLDDImage['src'];
|
|
1357
|
-
/** Alt text
|
|
1357
|
+
/** Alt text for the image from `src`. Required unless `decorative`; slotted media carries its own. */
|
|
1358
1358
|
'alt'?: NLDDImage['alt'];
|
|
1359
1359
|
/** Responsive source set */
|
|
1360
1360
|
'srcset'?: NLDDImage['srcset'];
|
|
@@ -2246,7 +2246,7 @@ declare module 'vue' {
|
|
|
2246
2246
|
type NLDDRadioButtonProps = {
|
|
2247
2247
|
/** Checked state */
|
|
2248
2248
|
'checked'?: NLDDRadioButton['checked'];
|
|
2249
|
-
/** Renders the shape
|
|
2249
|
+
/** Renders the shape only: no role, no focus, no name/value, nothing announced. For a control that owns the state elsewhere, such as a list row or an nldd-radio-button-field that is itself the radio; putting a second radio in there would nest a control inside a control. */
|
|
2250
2250
|
'decorative'?: NLDDRadioButton['decorative'];
|
|
2251
2251
|
/** Disabled state */
|
|
2252
2252
|
'disabled'?: NLDDRadioButton['disabled'];
|
|
@@ -2254,15 +2254,19 @@ declare module 'vue' {
|
|
|
2254
2254
|
'no-tab'?: NLDDRadioButton['noTab'];
|
|
2255
2255
|
/** Takes the control out of the tab order (tabindex="-1"), for a control owned by a roving container (a row of an nldd-list, where the arrow keys move between rows) that manages focus itself. Still mouse- and script-focusable. */
|
|
2256
2256
|
'noTab'?: NLDDRadioButton['noTab'];
|
|
2257
|
-
/** Required state */
|
|
2257
|
+
/** Required state. What it asks is whether anything in the group is checked, as a native radio does. */
|
|
2258
2258
|
'required'?: NLDDRadioButton['required'];
|
|
2259
|
+
/** Draws the focus ring around the shape. Set by nldd-radio-button-field, which is the radio itself and holds the focus. Not part of the public API. */
|
|
2260
|
+
'focus-ring'?: NLDDRadioButton['focusRing'];
|
|
2261
|
+
/** Draws the focus ring around the shape. Set by nldd-radio-button-field, which is the radio itself and holds the focus. Not part of the public API. */
|
|
2262
|
+
'focusRing'?: NLDDRadioButton['focusRing'];
|
|
2259
2263
|
/** Radio group name for form submission; ties the buttons of one group together */
|
|
2260
2264
|
'name'?: NLDDRadioButton['name'];
|
|
2261
2265
|
/** Value submitted with the form when this radio button is checked */
|
|
2262
2266
|
'value'?: NLDDRadioButton['value'];
|
|
2263
|
-
/** Accessible label
|
|
2267
|
+
/** Accessible label, set as aria-label on this element: it is the radio. */
|
|
2264
2268
|
'accessible-label'?: NLDDRadioButton['accessibleLabel'];
|
|
2265
|
-
/** Accessible label
|
|
2269
|
+
/** Accessible label, set as aria-label on this element: it is the radio. */
|
|
2266
2270
|
'accessibleLabel'?: NLDDRadioButton['accessibleLabel'];
|
|
2267
2271
|
/** Marks the control as invalid. Announced with aria-invalid; nothing is drawn for it. Note: aria-labelledby is not supported as IDREF resolution cannot cross shadow DOM boundaries. */
|
|
2268
2272
|
'invalid'?: NLDDRadioButton['invalid'];
|
|
@@ -2280,9 +2284,9 @@ declare module 'vue' {
|
|
|
2280
2284
|
'disabled'?: NLDDRadioButtonField['disabled'];
|
|
2281
2285
|
/** Value for form submission */
|
|
2282
2286
|
'value'?: NLDDRadioButtonField['value'];
|
|
2283
|
-
/** Radio group name for form submission
|
|
2287
|
+
/** Radio group name for form submission; ties the fields of one group together. Set automatically by nldd-radio-button-group. */
|
|
2284
2288
|
'name'?: NLDDRadioButtonField['name'];
|
|
2285
|
-
/** Required state
|
|
2289
|
+
/** Required state. What it asks is whether anything in the group is checked, as a native radio does. Set automatically by nldd-radio-button-group. */
|
|
2286
2290
|
'required'?: NLDDRadioButtonField['required'];
|
|
2287
2291
|
/** Label text for the radio button */
|
|
2288
2292
|
'label'?: NLDDRadioButtonField['label'];
|
|
@@ -2386,7 +2390,7 @@ declare module 'vue' {
|
|
|
2386
2390
|
'value'?: NLDDSegmentedControl['value'];
|
|
2387
2391
|
/** Control size: 'sm' | 'md' | 'lg' (default: 'md') */
|
|
2388
2392
|
'size'?: NLDDSegmentedControl['size'];
|
|
2389
|
-
/**
|
|
2393
|
+
/** Selection mode: 'radio' | 'checkbox' (default: 'radio'). */
|
|
2390
2394
|
'type'?: NLDDSegmentedControl['type'];
|
|
2391
2395
|
/** Content type for all items: 'text' | 'icon' | 'icon-and-text' (default: 'text') */
|
|
2392
2396
|
'variant'?: NLDDSegmentedControl['variant'];
|
|
@@ -2394,7 +2398,7 @@ declare module 'vue' {
|
|
|
2394
2398
|
'disabled'?: NLDDSegmentedControl['disabled'];
|
|
2395
2399
|
/** Width mode: 'full' (stretches to container), 'fit-content' (per-item content size), or any CSS length (e.g. '240px') */
|
|
2396
2400
|
'width'?: NLDDSegmentedControl['width'];
|
|
2397
|
-
/** Name for form submission
|
|
2401
|
+
/** Name for form submission */
|
|
2398
2402
|
'name'?: NLDDSegmentedControl['name'];
|
|
2399
2403
|
/** Accessible name for the group, set as aria-label */
|
|
2400
2404
|
'accessible-label'?: NLDDSegmentedControl['accessibleLabel'];
|
|
@@ -2412,7 +2416,7 @@ declare module 'vue' {
|
|
|
2412
2416
|
};
|
|
2413
2417
|
|
|
2414
2418
|
type NLDDSegmentedControlItemProps = {
|
|
2415
|
-
/** Required state.
|
|
2419
|
+
/** Required state of the native checkbox. In radio mode the group carries the constraint. */
|
|
2416
2420
|
'required'?: NLDDSegmentedControlItem['required'];
|
|
2417
2421
|
/** Value for this item */
|
|
2418
2422
|
'value'?: NLDDSegmentedControlItem['value'];
|
|
@@ -2424,13 +2428,13 @@ declare module 'vue' {
|
|
|
2424
2428
|
'size'?: NLDDSegmentedControlItem['size'];
|
|
2425
2429
|
/** Content type: 'text' | 'icon' | 'icon-and-text' (default: 'text'). Set by nldd-segmented-control. */
|
|
2426
2430
|
'variant'?: NLDDSegmentedControlItem['variant'];
|
|
2427
|
-
/**
|
|
2431
|
+
/** Selection mode: 'radio' | 'checkbox' (default: 'radio'). In radio mode the item is the radio itself, in checkbox mode it renders a native checkbox. Set by nldd-segmented-control. */
|
|
2428
2432
|
'input-type'?: NLDDSegmentedControlItem['inputType'];
|
|
2429
|
-
/**
|
|
2433
|
+
/** Selection mode: 'radio' | 'checkbox' (default: 'radio'). In radio mode the item is the radio itself, in checkbox mode it renders a native checkbox. Set by nldd-segmented-control. */
|
|
2430
2434
|
'inputType'?: NLDDSegmentedControlItem['inputType'];
|
|
2431
|
-
/** Name of the group for form submission, put on the native
|
|
2435
|
+
/** Name of the group for form submission, put on the native checkbox. Set by nldd-segmented-control. */
|
|
2432
2436
|
'group-name'?: NLDDSegmentedControlItem['groupName'];
|
|
2433
|
-
/** Name of the group for form submission, put on the native
|
|
2437
|
+
/** Name of the group for form submission, put on the native checkbox. Set by nldd-segmented-control. */
|
|
2434
2438
|
'groupName'?: NLDDSegmentedControlItem['groupName'];
|
|
2435
2439
|
/** Text label (shown for variant "text" and "icon-and-text"; used as aria-label and tooltip for variant "icon") */
|
|
2436
2440
|
'text'?: NLDDSegmentedControlItem['text'];
|
|
@@ -3218,7 +3222,7 @@ declare module 'vue' {
|
|
|
3218
3222
|
type NLDDToggleButtonProps = {
|
|
3219
3223
|
/** Required state. Set by nldd-toggle-button-group. */
|
|
3220
3224
|
'required'?: NLDDToggleButton['required'];
|
|
3221
|
-
/**
|
|
3225
|
+
/** What the button is: a button with aria-pressed, a native checkbox, or a radio (default: 'button') */
|
|
3222
3226
|
'type'?: NLDDToggleButton['type'];
|
|
3223
3227
|
/** Button size (default: 'md') */
|
|
3224
3228
|
'size'?: NLDDToggleButton['size'];
|
|
@@ -3719,7 +3723,7 @@ declare module 'vue' {
|
|
|
3719
3723
|
'nldd-multi-line-text-field': DefineComponent<NLDDMultiLineTextFieldProps>;
|
|
3720
3724
|
/** A four-column layout with a primary sidebar, secondary sidebar, main content area, and inspector. The sidebars show navigation or lists, the main area shows primary content, and the inspector shows additional details or properties of the selection. Panes are shown automatically when content is slotted into them. */
|
|
3721
3725
|
'nldd-navigation-split-view': DefineComponent<NLDDNavigationSplitViewProps>;
|
|
3722
|
-
/** A short message that arrives over the interface and leaves on its own: a save that worked, a request that failed. Not a banner, which stands in the page and stays there — this one floats, stacks, and goes away. It places itself. Write it wherever it belongs in your code and it moves to one shared region: top right from md, full width across the top below that. Nothing about the position is settable, so notifications from anywhere in an application land in the same place and stack in the same order. More than one is a deck, not a list: the front one is readable and the older ones peek out below it, so a burst of messages takes the room of roughly one. The newest is in front. Behind it a notification is a bare surface, cut to the height of the one in front; dismiss the front and it slides up into the place that came free while its message fades in, because it was standing there all along. Under the front notification sits a strip as wide as the deck and as tall as the deck is when it fans out. Pointing at it fans the deck out to fill it, which is the only hint that there is more here than the message you can read; clicking it, or moving focus into the region, lays the whole deck out as a list. Clicking or tabbing away puts it back. The notification itself is not a button: a click on the message you are reading does nothing. Only the front of the deck counts down, and only while the deck is closed: open means someone is reading. The rest wait, so nothing disappears from under the one you are reading. `critical` never leaves on its own: a failure is worth reading, and the count-down would take it away while you were. That also keeps this within WCAG 2.2.1, which allows a time limit when what disappears is not essential. The clock pauses while a pointer moves over the notification and while focus is inside it, and resumes where it left off rather than starting over. A pointer that merely happens to rest where the notification appears does not count: it never moved, so nobody is reading. role follows the variant: `critical` becomes role="alert", the rest role="status". Focus never moves on its own. Escape dismisses the notification that focus is in. */
|
|
3726
|
+
/** A short message that arrives over the interface and leaves on its own: a save that worked, a request that failed. Not a banner, which stands in the page and stays there — this one floats, stacks, and goes away. It places itself. Write it wherever it belongs in your code and it moves to one shared region: top right from md, full width across the top below that. Nothing about the position is settable, so notifications from anywhere in an application land in the same place and stack in the same order. A modal overlay is the one thing that moves it. An nldd-sheet, nldd-window or nldd-modal-dialog paints in the browser's top layer, above the whole page and out of reach of any z-index, and while one is open everything outside it is inert. So the region goes in: into the topmost overlay that is open, and back down as they close. A notification already on screen travels with it, and one raised from inside a sheet is readable and reachable where it is raised. More than one is a deck, not a list: the front one is readable and the older ones peek out below it, so a burst of messages takes the room of roughly one. The newest is in front. Behind it a notification is a bare surface, cut to the height of the one in front; dismiss the front and it slides up into the place that came free while its message fades in, because it was standing there all along. Under the front notification sits a strip as wide as the deck and as tall as the deck is when it fans out. Pointing at it fans the deck out to fill it, which is the only hint that there is more here than the message you can read; clicking it, or moving focus into the region, lays the whole deck out as a list. Clicking or tabbing away puts it back. The notification itself is not a button: a click on the message you are reading does nothing. Only the front of the deck counts down, and only while the deck is closed: open means someone is reading. The rest wait, so nothing disappears from under the one you are reading. `critical` never leaves on its own: a failure is worth reading, and the count-down would take it away while you were. That also keeps this within WCAG 2.2.1, which allows a time limit when what disappears is not essential. The clock pauses while a pointer moves over the notification and while focus is inside it, and resumes where it left off rather than starting over. A pointer that merely happens to rest where the notification appears does not count: it never moved, so nobody is reading. role follows the variant: `critical` becomes role="alert", the rest role="status". Focus never moves on its own. Escape dismisses the notification that focus is in. */
|
|
3723
3727
|
'nldd-notification': DefineComponent<NLDDNotificationProps>;
|
|
3724
3728
|
/** A numeric input field with decrement and increment buttons. */
|
|
3725
3729
|
'nldd-number-field': DefineComponent<NLDDNumberFieldProps>;
|
|
@@ -3727,7 +3731,7 @@ declare module 'vue' {
|
|
|
3727
3731
|
'nldd-one-half-one-half-section': DefineComponent<NLDDOneHalfOneHalfSectionProps>;
|
|
3728
3732
|
/** A section with a 1/3 sidebar on the left and 2/3 main content on the right. The columns wrap automatically when they become smaller than 280px. Padding and gap adjust via container queries. */
|
|
3729
3733
|
'nldd-one-third-two-thirds-section': DefineComponent<NLDDOneThirdTwoThirdsSectionProps>;
|
|
3730
|
-
/** A page layout with optional sticky header and footer. Without sticky-header, the host is the scroll container and the header is in normal flow. With sticky-header, the header becomes absolute and .page__scroll takes over scrolling
|
|
3734
|
+
/** A page layout with optional sticky header and footer. Without sticky-header, the host is the scroll container and the header is in normal flow. With sticky-header, the header becomes absolute and .page__scroll takes over scrolling, padded by the measured header height. That padding freezes once you scroll, so a collapsing bar cannot drag the content up under the cursor. In root-scroll mode (--context-scroll-mode: root, derived upstream by nldd-app-view) the page stops owning a scroller: the document scrolls and the sticky header/footer stick against the document, offset by --context-inset-top/bottom. The mode is read on connect/resize and reflected to [data-scroll] so the CSS can branch. The page passes those insets on to its own content, with its sticky header and footer added: anything sticky inside (an nldd-sidebar-section, a sticky table head) reads --context-inset-top / --context-inset-bottom and clears every bar above and below it without being told a number. The heights are measured, because a top title bar shrinks as you scroll past its anchor. While the page owns the scroller, only its own bars count: the chrome above the page sits outside that scroller and does not push sticky content down. */
|
|
3731
3735
|
'nldd-page': DefineComponent<NLDDPageProps>;
|
|
3732
3736
|
/** The footer band at the bottom of a page. Hosts three optional rows in a fixed order: breadcrumbs (top), consumer-defined main content (middle), and a legal-bar (bottom). Dividers are drawn automatically between non-empty rows. Establishes its own container query (`page-footer-container`) so the responsive padding and gap react to the footer's own width, not the viewport. The host has `id="page-footer"` so a skip-link can target it directly. Use the sub-components `nldd-page-footer-legal-bar` and `nldd-page-footer-legal-bar-item` for the bottom row. */
|
|
3733
3737
|
'nldd-page-footer': DefineComponent<NLDDPageFooterProps>;
|
|
@@ -3747,9 +3751,9 @@ declare module 'vue' {
|
|
|
3747
3751
|
/** Exports both NLDDProgressCircle and NLDDProgressCircleSegmentIndicator. A circular progress indicator that mirrors the API of nldd-progress-bar: single-value or multi-segment, progress or distribution mode, 24 colors, fade transitions between determinate/indeterminate, indeterminate indicator. Visual differences vs the bar: - SVG arcs instead of rectangular bars. - Label below the circle (not above). - No center text; the consumer can wrap the circle if needed. - One combined tooltip on the whole circle showing all segment info (no per-segment tooltips). - Indeterminate uses a rotating elastic arc (Material-style) instead of the bar's Knight Rider scanner. */
|
|
3748
3752
|
'nldd-progress-circle': DefineComponent<NLDDProgressCircleProps>;
|
|
3749
3753
|
'nldd-progress-circle-segment-indicator': DefineComponent<NLDDProgressCircleSegmentIndicatorProps>;
|
|
3750
|
-
/** WAI-ARIA:
|
|
3754
|
+
/** WAI-ARIA: put the buttons of one group in a container with role="radiogroup" and a name of its own. A screen reader counts the options from that container, so a bare <fieldset> (which is a group, not a radiogroup) leaves them uncounted. nldd-radio-button-group does this for you. Radio buttons with the same name, in the same form and the same tree, form one group the way native radios do: checking one unchecks the others, the arrow keys move between them, Tab stops at the group once, and a screen reader hears each one's place in it. The element itself is the radio, because an input per shadow root would leave every button a group of one. The shape is all this component draws. A radio with a label beside it is nldd-radio-button-field. <fieldset role="radiogroup" aria-labelledby="options-label"> <legend id="options-label">Kies een optie</legend> <nldd-radio-button name="options" value="1" accessible-label="Optie 1"></nldd-radio-button> <nldd-radio-button name="options" value="2" accessible-label="Optie 2"></nldd-radio-button> </fieldset> */
|
|
3751
3755
|
'nldd-radio-button': DefineComponent<NLDDRadioButtonProps>;
|
|
3752
|
-
/** A radio button with an inline label. Use inside nldd-radio-button-group
|
|
3756
|
+
/** A radio button with an inline label. Use inside nldd-radio-button-group, which sets the name and labels the group. Fields that stand on their own group by name, the way native radios do: checking one unchecks the others, the arrow keys move between them and Tab stops at the group once. Put them in a container with role="radiogroup", or a screen reader has nothing to count them from. The field is the radio: it carries the role, the state, the label it is announced by and the focus, and the nldd-radio-button inside only draws the shape. A radio of its own in there would be a second control inside a control, and a group of one to count. Form-associated: the checked field submits its `value` under `name`. Unchecking siblings is the group's job, so exactly one value per group reaches the form. */
|
|
3753
3757
|
'nldd-radio-button-field': DefineComponent<NLDDRadioButtonFieldProps>;
|
|
3754
3758
|
/** Groups nldd-radio-button-field elements, handles keyboard navigation, and forwards name and disabled state to all child fields. Use inside nldd-form-field which provides the group label. */
|
|
3755
3759
|
'nldd-radio-button-group': DefineComponent<NLDDRadioButtonGroupProps>;
|
|
@@ -3819,7 +3823,7 @@ declare module 'vue' {
|
|
|
3819
3823
|
'nldd-title': DefineComponent<NLDDTitleProps>;
|
|
3820
3824
|
/** A cell component for displaying a title with optional overline and subtitle in lists. `vertical-alignment="center"` (default) stretches the cell to fill the full row height and centers its content within that space. Use `min-height` to set a minimum centered region. For strict top alignment without a minimum height, use `vertical-alignment="top"`. Each text region (overline, title, supporting text) accepts either a string attribute or slotted DOM content. The slot is the source of truth: if the consumer provides slotted content, it replaces the attribute-based render for that region. Use slots when you need inline elements like `<nldd-tag>`, `<nldd-icon>` or other components mixed with text. Note that `query` highlighting and `**bold**` parsing only apply to the attribute path — slotted content is rendered as-is. */
|
|
3821
3825
|
'nldd-title-cell': DefineComponent<NLDDTitleCellProps>;
|
|
3822
|
-
/** A selectable button that toggles between selected and unselected. Available as a button (aria-pressed), checkbox, or radio
|
|
3826
|
+
/** A selectable button that toggles between selected and unselected. Available as a button (aria-pressed), a checkbox, or a radio. In radio mode the button itself is the radio: it carries the role, the state and its place in the group. A native radio in a shadow root of its own would be a group of one, counted as "1 of 1" and stopped at by Tab. */
|
|
3823
3827
|
'nldd-toggle-button': DefineComponent<NLDDToggleButtonProps>;
|
|
3824
3828
|
/** Groups nldd-toggle-button elements and manages selection, keyboard navigation, and forwarding of type, name, size, and disabled state to all buttons. For type="radio" (single-select), arrow keys navigate between buttons and automatically select the focused one. For type="checkbox" (multi-select), multiple buttons can be selected simultaneously. */
|
|
3825
3829
|
'nldd-toggle-button-group': DefineComponent<NLDDToggleButtonGroupProps>;
|
|
@@ -16,7 +16,7 @@ export interface DescribedElement {
|
|
|
16
16
|
* `ariaDescribedByElements` takes the elements themselves and crosses the
|
|
17
17
|
* boundary.
|
|
18
18
|
*/
|
|
19
|
-
export declare function applyDescribedBy(target: Element | null | undefined, elements: readonly Element[]): void;
|
|
19
|
+
export declare function applyDescribedBy(target: Element | null | undefined, elements: readonly Element[], onSelf?: boolean): void;
|
|
20
20
|
/**
|
|
21
21
|
* Announces that a control is invalid, on the element assistive software meets.
|
|
22
22
|
*
|
|
@@ -29,7 +29,7 @@ export declare function applyDescribedBy(target: Element | null | undefined, ele
|
|
|
29
29
|
* A component that wraps another one hands the state on, the same way it hands
|
|
30
30
|
* on the description.
|
|
31
31
|
*/
|
|
32
|
-
export declare function applyInvalid(target: Element | null | undefined, invalid: boolean): void;
|
|
32
|
+
export declare function applyInvalid(target: Element | null | undefined, invalid: boolean, onSelf?: boolean): void;
|
|
33
33
|
/**
|
|
34
34
|
* Lets nldd-form-field hand a control the help and error texts that describe
|
|
35
35
|
* it, wherever that control renders them.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"described-by-mixin.d.ts","sourceRoot":"","sources":["../../src/utilities/described-by-mixin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA2B,MAAM,KAAK,CAAC;AAI1D,KAAK,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEnF,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAChC,mBAAmB,EAAE,SAAS,OAAO,EAAE,CAAC;IACxC,yEAAyE;IACzE,eAAe,IAAI,OAAO,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"described-by-mixin.d.ts","sourceRoot":"","sources":["../../src/utilities/described-by-mixin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA2B,MAAM,KAAK,CAAC;AAI1D,KAAK,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAEnF,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAChC,mBAAmB,EAAE,SAAS,OAAO,EAAE,CAAC;IACxC,yEAAyE;IACzE,eAAe,IAAI,OAAO,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,UAAQ,GACZ,IAAI,CAaN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,IAAI,CAQvG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,CAAC,UAAU,CAAC,EAC5D,IAAI,EAAE,CAAC,GACL,CAAC,GAAG,WAAW,CAAC,gBAAgB,CAAC,CA2CnC"}
|
|
@@ -15,13 +15,13 @@ import { property } from 'lit/decorators.js';
|
|
|
15
15
|
* `ariaDescribedByElements` takes the elements themselves and crosses the
|
|
16
16
|
* boundary.
|
|
17
17
|
*/
|
|
18
|
-
export function applyDescribedBy(target, elements) {
|
|
18
|
+
export function applyDescribedBy(target, elements, onSelf = false) {
|
|
19
19
|
if (!target)
|
|
20
20
|
return;
|
|
21
21
|
// A component that wraps another one hands the question on rather than
|
|
22
22
|
// answering it. nldd-checkbox-field renders an nldd-checkbox, and only that
|
|
23
23
|
// one knows which element inside itself is the control.
|
|
24
|
-
if ('describedByElements' in target) {
|
|
24
|
+
if (!onSelf && 'describedByElements' in target) {
|
|
25
25
|
target.describedByElements = [...elements];
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
@@ -40,10 +40,10 @@ export function applyDescribedBy(target, elements) {
|
|
|
40
40
|
* A component that wraps another one hands the state on, the same way it hands
|
|
41
41
|
* on the description.
|
|
42
42
|
*/
|
|
43
|
-
export function applyInvalid(target, invalid) {
|
|
43
|
+
export function applyInvalid(target, invalid, onSelf = false) {
|
|
44
44
|
if (!target)
|
|
45
45
|
return;
|
|
46
|
-
if ('invalid' in target) {
|
|
46
|
+
if (!onSelf && 'invalid' in target) {
|
|
47
47
|
target.invalid = invalid;
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -75,12 +75,17 @@ export function DescribedBy(Base) {
|
|
|
75
75
|
const apply = {
|
|
76
76
|
hostUpdated: () => {
|
|
77
77
|
const target = this.describedTarget();
|
|
78
|
-
|
|
78
|
+
// A component that is the control itself, such as an
|
|
79
|
+
// nldd-radio-button carrying role="radio", puts the ARIA on its own
|
|
80
|
+
// element. Handing it on there would hand it to itself, and a
|
|
81
|
+
// component that does that renders forever.
|
|
82
|
+
const onSelf = target === this;
|
|
83
|
+
applyDescribedBy(target, this.describedByElements, onSelf);
|
|
79
84
|
// Optional: nldd-button carries this mixin for its description and
|
|
80
85
|
// has no validity of its own.
|
|
81
86
|
const invalid = this.invalid;
|
|
82
87
|
if (invalid !== undefined)
|
|
83
|
-
applyInvalid(target, invalid);
|
|
88
|
+
applyInvalid(target, invalid, onSelf);
|
|
84
89
|
},
|
|
85
90
|
};
|
|
86
91
|
this.addController(apply);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"described-by-mixin.js","sourceRoot":"","sources":["../../src/utilities/described-by-mixin.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAc7C;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,
|
|
1
|
+
{"version":3,"file":"described-by-mixin.js","sourceRoot":"","sources":["../../src/utilities/described-by-mixin.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAc7C;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC/B,MAAkC,EAClC,QAA4B,EAC5B,MAAM,GAAG,KAAK;IAEd,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,uEAAuE;IACvE,4EAA4E;IAC5E,wDAAwD;IACxD,IAAI,CAAC,MAAM,IAAI,qBAAqB,IAAI,MAAM,EAAE,CAAC;QAC/C,MAAsC,CAAC,mBAAmB,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC5E,OAAO;IACR,CAAC;IAED,MAAM,EAAE,GAAG,MAA0E,CAAC;IACtF,EAAE,CAAC,uBAAuB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAkC,EAAE,OAAgB,EAAE,MAAM,GAAG,KAAK;IAChG,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,CAAC,MAAM,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QACnC,MAAyC,CAAC,OAAO,GAAG,OAAO,CAAC;QAC7D,OAAO;IACR,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;QACpD,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAC1B,IAAO;IAEP,MAAe,gBAAiB,SAAQ,IAAI;QAK3C,YAAY,GAAG,IAAW;YACzB,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YALhB,4DAA4D;YAE5D,wBAAmB,GAAuB,EAAE,CAAC;YAI5C,MAAM,KAAK,GAAuB;gBACjC,WAAW,EAAE,GAAG,EAAE;oBACjB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;oBACtC,qDAAqD;oBACrD,oEAAoE;oBACpE,8DAA8D;oBAC9D,4CAA4C;oBAC5C,MAAM,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;oBAC/B,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;oBAC3D,mEAAmE;oBACnE,8BAA8B;oBAC9B,MAAM,OAAO,GAAI,IAA8B,CAAC,OAAO,CAAC;oBACxD,IAAI,OAAO,KAAK,SAAS;wBAAE,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClE,CAAC;aACD,CAAC;YACF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAED;;;;;;;WAOG;QACH,eAAe;YACd,OAAO,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,yBAAyB,CAAC,IAAI,IAAI,CAAC;QAC1E,CAAC;KACD;IAjCA;QADC,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;iEACc;IAkC9C,2EAA2E;IAC3E,2EAA2E;IAC3E,wEAAwE;IACxE,WAAW;IACX,OAAO,gBAAgE,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { type RadioPosition } from './radio-position.js';
|
|
3
|
+
/**
|
|
4
|
+
* Groups a radio with the ones that share its name, the way the browser does.
|
|
5
|
+
*
|
|
6
|
+
* The platform groups native radios by name, within one tree and one form, and
|
|
7
|
+
* every radio of ours renders in a shadow root of its own. Left to the browser
|
|
8
|
+
* each of them is a group of one: checking one leaves the others checked, Tab
|
|
9
|
+
* stops at every option, and none of them knows its place in the set.
|
|
10
|
+
*
|
|
11
|
+
* A group component around the radios (nldd-radio-button-group) hands its
|
|
12
|
+
* members their position and wins where it is there. This is for the radios
|
|
13
|
+
* that stand on their own, in a `<fieldset role="radiogroup">` or a layout of
|
|
14
|
+
* the consumer's own.
|
|
15
|
+
*/
|
|
16
|
+
/** What a radio has to offer to be grouped with the others of its name. */
|
|
17
|
+
export interface GroupedRadio extends HTMLElement {
|
|
18
|
+
name: string;
|
|
19
|
+
checked: boolean;
|
|
20
|
+
disabled: boolean;
|
|
21
|
+
readonly internals: ElementInternals;
|
|
22
|
+
commitFormValue(): void;
|
|
23
|
+
/** Checks this radio, the way a click does. */
|
|
24
|
+
select(): void;
|
|
25
|
+
}
|
|
26
|
+
type RadioHost = GroupedRadio & ReactiveControllerHost;
|
|
27
|
+
export declare class RadioGrouping implements ReactiveController {
|
|
28
|
+
private host;
|
|
29
|
+
/** Its place among the radios that share its name, or null when it has none. */
|
|
30
|
+
position: RadioPosition | null;
|
|
31
|
+
/**
|
|
32
|
+
* Whether anything in the group is checked, which is what `required` asks of
|
|
33
|
+
* a radio: one of these, not this one. A radio without a group answers for
|
|
34
|
+
* itself, because it is the whole group.
|
|
35
|
+
*/
|
|
36
|
+
answered: boolean;
|
|
37
|
+
/** Where it was grouped last, so the radios it leaves behind hear of it. */
|
|
38
|
+
private _groupedIn;
|
|
39
|
+
constructor(host: RadioHost);
|
|
40
|
+
hostConnected(): void;
|
|
41
|
+
hostDisconnected(): void;
|
|
42
|
+
/** Reads which group this radio is in now, and recounts the one it left. */
|
|
43
|
+
regroup(): void;
|
|
44
|
+
/** Counts the group again, after this radio was checked or disabled. */
|
|
45
|
+
refresh(): void;
|
|
46
|
+
/** Unchecks the others, as checking a native radio does. */
|
|
47
|
+
uncheckOthers(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Moves to the next radio of the group and checks it, as the arrow keys do
|
|
50
|
+
* for native radios. Disabled options are stepped over, and the ends wrap.
|
|
51
|
+
*
|
|
52
|
+
* @returns whether the key was handled.
|
|
53
|
+
*/
|
|
54
|
+
moveWithArrow(e: KeyboardEvent): boolean;
|
|
55
|
+
private _key;
|
|
56
|
+
/** Compared by value: a recount hands out new objects for the same place, and
|
|
57
|
+
* asking for a render on every one of those is a render per radio per
|
|
58
|
+
* keystroke, each of them scheduled from inside an update that had just
|
|
59
|
+
* finished. */
|
|
60
|
+
private _apply;
|
|
61
|
+
private static _radiosIn;
|
|
62
|
+
/** A radio on its own keeps the place the browser gives it: none. */
|
|
63
|
+
private static _recount;
|
|
64
|
+
}
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=radio-grouping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-grouping.d.ts","sourceRoot":"","sources":["../../src/utilities/radio-grouping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,KAAK,CAAC;AACtE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;;;;;;GAYG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,YAAa,SAAQ,WAAW;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,eAAe,IAAI,IAAI,CAAC;IACxB,+CAA+C;IAC/C,MAAM,IAAI,IAAI,CAAC;CACf;AAED,KAAK,SAAS,GAAG,YAAY,GAAG,sBAAsB,CAAC;AA0BvD,qBAAa,aAAc,YAAW,kBAAkB;IAe3C,OAAO,CAAC,IAAI;IAbxB,gFAAgF;IAChF,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAQ;IAEtC;;;;OAIG;IACH,QAAQ,UAAS;IAEjB,4EAA4E;IAC5E,OAAO,CAAC,UAAU,CAA8B;gBAE5B,IAAI,EAAE,SAAS;IAKnC,aAAa,IAAI,IAAI;IAKrB,gBAAgB,IAAI,IAAI;IAIxB,4EAA4E;IAC5E,OAAO,IAAI,IAAI;IAUf,wEAAwE;IACxE,OAAO,IAAI,IAAI;IAKf,4DAA4D;IAC5D,aAAa,IAAI,IAAI;IAYrB;;;;;OAKG;IACH,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO;IAcxC,OAAO,CAAC,IAAI;IAKZ;;;oBAGgB;IAChB,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,MAAM,CAAC,SAAS;IAUxB,qEAAqE;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ;CAUvB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { radioPositions } from './radio-position.js';
|
|
2
|
+
/**
|
|
3
|
+
* Both tags in one list, because the platform groups on the name and not on the
|
|
4
|
+
* element. A button and a field that share a name are one group to the browser,
|
|
5
|
+
* and two lists would have them counting different sets.
|
|
6
|
+
*/
|
|
7
|
+
const RADIO_TAGS = 'nldd-radio-button, nldd-radio-button-field';
|
|
8
|
+
const ARROW_STEPS = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 };
|
|
9
|
+
/** The controller of each radio, so a recount can reach its siblings. */
|
|
10
|
+
const groupings = new WeakMap();
|
|
11
|
+
/** A radio that draws the shape for something else owns no state of its own. */
|
|
12
|
+
function isMember(radio) {
|
|
13
|
+
return !radio.decorative;
|
|
14
|
+
}
|
|
15
|
+
export class RadioGrouping {
|
|
16
|
+
constructor(host) {
|
|
17
|
+
this.host = host;
|
|
18
|
+
/** Its place among the radios that share its name, or null when it has none. */
|
|
19
|
+
this.position = null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether anything in the group is checked, which is what `required` asks of
|
|
22
|
+
* a radio: one of these, not this one. A radio without a group answers for
|
|
23
|
+
* itself, because it is the whole group.
|
|
24
|
+
*/
|
|
25
|
+
this.answered = false;
|
|
26
|
+
/** Where it was grouped last, so the radios it leaves behind hear of it. */
|
|
27
|
+
this._groupedIn = null;
|
|
28
|
+
groupings.set(host, this);
|
|
29
|
+
host.addController(this);
|
|
30
|
+
}
|
|
31
|
+
hostConnected() {
|
|
32
|
+
// A tick later, once the radios parsed after this one are there too.
|
|
33
|
+
queueMicrotask(() => this.regroup());
|
|
34
|
+
}
|
|
35
|
+
hostDisconnected() {
|
|
36
|
+
this.regroup();
|
|
37
|
+
}
|
|
38
|
+
/** Reads which group this radio is in now, and recounts the one it left. */
|
|
39
|
+
regroup() {
|
|
40
|
+
const was = this._groupedIn;
|
|
41
|
+
const now = this._key();
|
|
42
|
+
this._groupedIn = now;
|
|
43
|
+
const moved = !now || !was || was.root !== now.root || was.name !== now.name || was.form !== now.form;
|
|
44
|
+
if (was && moved)
|
|
45
|
+
RadioGrouping._recount(was);
|
|
46
|
+
if (now)
|
|
47
|
+
RadioGrouping._recount(now);
|
|
48
|
+
else
|
|
49
|
+
this._apply(null, this.host.checked);
|
|
50
|
+
}
|
|
51
|
+
/** Counts the group again, after this radio was checked or disabled. */
|
|
52
|
+
refresh() {
|
|
53
|
+
if (this._groupedIn)
|
|
54
|
+
RadioGrouping._recount(this._groupedIn);
|
|
55
|
+
else
|
|
56
|
+
this._apply(null, this.host.checked);
|
|
57
|
+
}
|
|
58
|
+
/** Unchecks the others, as checking a native radio does. */
|
|
59
|
+
uncheckOthers() {
|
|
60
|
+
const key = this._key();
|
|
61
|
+
if (!key)
|
|
62
|
+
return;
|
|
63
|
+
for (const radio of RadioGrouping._radiosIn(key)) {
|
|
64
|
+
if (radio === this.host || !radio.checked)
|
|
65
|
+
continue;
|
|
66
|
+
radio.checked = false;
|
|
67
|
+
// Synchronously: a change listener that reads the form should not find
|
|
68
|
+
// two values under one name.
|
|
69
|
+
radio.commitFormValue();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Moves to the next radio of the group and checks it, as the arrow keys do
|
|
74
|
+
* for native radios. Disabled options are stepped over, and the ends wrap.
|
|
75
|
+
*
|
|
76
|
+
* @returns whether the key was handled.
|
|
77
|
+
*/
|
|
78
|
+
moveWithArrow(e) {
|
|
79
|
+
const step = ARROW_STEPS[e.key];
|
|
80
|
+
const key = step ? this._key() : null;
|
|
81
|
+
if (!key || !this.position)
|
|
82
|
+
return false;
|
|
83
|
+
const radios = RadioGrouping._radiosIn(key).filter((radio) => !radio.disabled);
|
|
84
|
+
const at = radios.indexOf(this.host);
|
|
85
|
+
if (at === -1)
|
|
86
|
+
return false;
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
const next = radios[(at + step + radios.length) % radios.length];
|
|
89
|
+
next.focus();
|
|
90
|
+
next.select();
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
_key() {
|
|
94
|
+
if (!this.host.isConnected || !isMember(this.host) || !this.host.name)
|
|
95
|
+
return null;
|
|
96
|
+
return { root: this.host.getRootNode(), name: this.host.name, form: this.host.internals.form };
|
|
97
|
+
}
|
|
98
|
+
/** Compared by value: a recount hands out new objects for the same place, and
|
|
99
|
+
* asking for a render on every one of those is a render per radio per
|
|
100
|
+
* keystroke, each of them scheduled from inside an update that had just
|
|
101
|
+
* finished. */
|
|
102
|
+
_apply(position, answered) {
|
|
103
|
+
const same = this.answered === answered
|
|
104
|
+
&& this.position?.posInSet === position?.posInSet
|
|
105
|
+
&& this.position?.setSize === position?.setSize
|
|
106
|
+
&& this.position?.tabbable === position?.tabbable;
|
|
107
|
+
if (same)
|
|
108
|
+
return;
|
|
109
|
+
this.position = position;
|
|
110
|
+
this.answered = answered;
|
|
111
|
+
this.host.requestUpdate();
|
|
112
|
+
}
|
|
113
|
+
static _radiosIn({ root, name, form }) {
|
|
114
|
+
const radios = root.querySelectorAll?.(RADIO_TAGS) ?? [];
|
|
115
|
+
return Array.from(radios).filter((radio) => groupings.has(radio)
|
|
116
|
+
&& radio.isConnected
|
|
117
|
+
&& radio.name === name
|
|
118
|
+
&& isMember(radio)
|
|
119
|
+
&& radio.internals.form === form);
|
|
120
|
+
}
|
|
121
|
+
/** A radio on its own keeps the place the browser gives it: none. */
|
|
122
|
+
static _recount(key) {
|
|
123
|
+
const radios = RadioGrouping._radiosIn(key);
|
|
124
|
+
const positions = radios.length > 1
|
|
125
|
+
? radioPositions(radios, (radio) => radio.checked, (radio) => radio.disabled)
|
|
126
|
+
: [];
|
|
127
|
+
const answered = radios.some((radio) => radio.checked);
|
|
128
|
+
radios.forEach((radio, index) => {
|
|
129
|
+
groupings.get(radio)?._apply(positions[index] ?? null, answered);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=radio-grouping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-grouping.js","sourceRoot":"","sources":["../../src/utilities/radio-grouping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a radio sits in its group, for a component that renders its native
|
|
3
|
+
* radio in a shadow root of its own.
|
|
4
|
+
*
|
|
5
|
+
* The browser groups radios by name within one tree scope. One input per
|
|
6
|
+
* shadow root makes every radio a group of one: a screen reader announces
|
|
7
|
+
* "1 of 1" for each, and each is a stop of its own for Tab. Whatever holds the
|
|
8
|
+
* group knows better, so it hands every radio its place, and the radio puts
|
|
9
|
+
* that on its input.
|
|
10
|
+
*/
|
|
11
|
+
export interface RadioPosition {
|
|
12
|
+
posInSet: number;
|
|
13
|
+
setSize: number;
|
|
14
|
+
/** The group's one stop for Tab: the checked radio, or the first enabled
|
|
15
|
+
* one when none is checked, which is where the browser would land too. */
|
|
16
|
+
tabbable: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** A position for every radio of a group, in the order given. */
|
|
19
|
+
export declare function radioPositions<T>(radios: readonly T[], isChecked: (radio: T) => boolean, isDisabled: (radio: T) => boolean): RadioPosition[];
|
|
20
|
+
//# sourceMappingURL=radio-position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-position.d.ts","sourceRoot":"","sources":["../../src/utilities/radio-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;+EAC2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,CAAC,EAC/B,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,EAChC,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAC/B,aAAa,EAAE,CAQjB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** A position for every radio of a group, in the order given. */
|
|
2
|
+
export function radioPositions(radios, isChecked, isDisabled) {
|
|
3
|
+
const enabled = radios.filter((radio) => !isDisabled(radio));
|
|
4
|
+
const stop = enabled.find(isChecked) ?? enabled[0];
|
|
5
|
+
return radios.map((radio, index) => ({
|
|
6
|
+
posInSet: index + 1,
|
|
7
|
+
setSize: radios.length,
|
|
8
|
+
tabbable: radio === stop,
|
|
9
|
+
}));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=radio-position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-position.js","sourceRoot":"","sources":["../../src/utilities/radio-position.ts"],"names":[],"mappings":"AAkBA,iEAAiE;AACjE,MAAM,UAAU,cAAc,CAC7B,MAAoB,EACpB,SAAgC,EAChC,UAAiC;IAEjC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,QAAQ,EAAE,KAAK,GAAG,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK,KAAK,IAAI;KACxB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nldd/design-system",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.89",
|
|
4
4
|
"description": "Design System voor Nederlandse Digitale Dienst",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/components/components.js",
|
|
@@ -473,7 +473,7 @@
|
|
|
473
473
|
],
|
|
474
474
|
"repository": {
|
|
475
475
|
"type": "git",
|
|
476
|
-
"url": "https://github.com/
|
|
476
|
+
"url": "https://github.com/NederlandseDigitaleDienst/design-system.git"
|
|
477
477
|
},
|
|
478
478
|
"publishConfig": {
|
|
479
479
|
"access": "public",
|
|
@@ -533,25 +533,25 @@
|
|
|
533
533
|
"@semantic-release/changelog": "^7.0.0",
|
|
534
534
|
"@semantic-release/exec": "^7.1.0",
|
|
535
535
|
"@semantic-release/git": "^11.0.1",
|
|
536
|
-
"@storybook/addon-a11y": "^10.
|
|
537
|
-
"@storybook/addon-docs": "^10.
|
|
538
|
-
"@storybook/addon-themes": "^10.
|
|
539
|
-
"@storybook/addon-vitest": "^10.
|
|
540
|
-
"@storybook/web-components-vite": "^10.
|
|
536
|
+
"@storybook/addon-a11y": "^10.6.0",
|
|
537
|
+
"@storybook/addon-docs": "^10.6.0",
|
|
538
|
+
"@storybook/addon-themes": "^10.6.0",
|
|
539
|
+
"@storybook/addon-vitest": "^10.6.0",
|
|
540
|
+
"@storybook/web-components-vite": "^10.6.0",
|
|
541
541
|
"@vitest/browser-playwright": "4.1.11",
|
|
542
542
|
"@vitest/coverage-v8": "4.1.11",
|
|
543
543
|
"conventional-changelog": "^8.1.0",
|
|
544
544
|
"conventional-changelog-conventionalcommits": "10.2.1",
|
|
545
545
|
"eslint": "^10.8.0",
|
|
546
546
|
"eslint-plugin-lit-a11y": "^5.1.1",
|
|
547
|
-
"eslint-plugin-storybook": "^10.
|
|
547
|
+
"eslint-plugin-storybook": "^10.6.0",
|
|
548
548
|
"globals": "^17.8.0",
|
|
549
549
|
"playwright": "^1.57.0",
|
|
550
550
|
"semantic-release": "^25.0.2",
|
|
551
|
-
"storybook": "^10.
|
|
551
|
+
"storybook": "^10.6.0",
|
|
552
552
|
"typescript": "^5.3.0",
|
|
553
553
|
"typescript-eslint": "^8.58.0",
|
|
554
|
-
"vite": "8.
|
|
554
|
+
"vite": "8.3.0",
|
|
555
555
|
"vitest": "4.1.11",
|
|
556
556
|
"vue": "^3.5.40",
|
|
557
557
|
"vue-tsc": "^3.3.7"
|