@kerfjs/ui 5.0.0-beta.106 → 5.0.0-beta.108
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 -1
- package/ai/application-ui-diagnostic-ids-v1.json +1 -0
- package/ai/application-ui-profile.defaults.json +6 -1
- package/ai/component-catalog.json +184 -39
- package/ai/component-composition-rules.json +20 -2
- package/ai/component-composition.d.ts +11 -0
- package/ai/component-composition.json +126 -21
- package/ai/component-composition.schema.json +32 -0
- package/ai/components/README.md +3 -2
- package/ai/components/button.md +9 -6
- package/ai/components/checkbox-group.md +89 -0
- package/ai/components/checkbox.md +3 -2
- package/ai/components/chip.md +1 -0
- package/ai/components/color-picker.md +10 -7
- package/ai/components/disclosure.md +6 -1
- package/ai/components/foundation.md +1 -1
- package/ai/components/list-detail-dialog.md +1 -1
- package/ai/components/list.md +1 -1
- package/ai/components/message-composer.md +2 -1
- package/ai/components/radio-group.md +4 -3
- package/ai/components/segmented-control.md +1 -0
- package/ai/components/split-button.md +5 -2
- package/ai/components/surface-scaffold.md +3 -1
- package/ai/components/switch.md +1 -1
- package/ai/components/text-field.md +3 -1
- package/ai/components/text.md +2 -0
- package/ai/components/toolbar-control-group.md +1 -0
- package/ai/components/toolbar.md +1 -1
- package/ai/components/wa-checkbox-group.md +5 -5
- package/ai/components/workbench-dialog.md +1 -1
- package/ai/public-api-signatures-v1.md +258 -35
- package/ai/skill.md +82 -65
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/browser/checkbox-group.js +5 -0
- package/dist/button.d.ts +18 -5
- package/dist/button.js +1 -1
- package/dist/catalog.js +11 -10
- package/dist/catalog.js.map +1 -1
- package/dist/checkbox-group.d.ts +70 -0
- package/dist/checkbox-group.js +7 -0
- package/dist/checkbox-group.js.map +1 -0
- package/dist/chip.d.ts +20 -2
- package/dist/chip.js +2 -1
- package/dist/{chunk-SQ2Q3OQI.js → chunk-2LM3PYHA.js} +2 -2
- package/dist/{chunk-SQ2Q3OQI.js.map → chunk-2LM3PYHA.js.map} +1 -1
- package/dist/{chunk-HYORKKYP.js → chunk-3VZ6SFD4.js} +1 -1
- package/dist/chunk-3VZ6SFD4.js.map +1 -0
- package/dist/{chunk-EKBMUXFV.js → chunk-3Z7N2NAZ.js} +141 -54
- package/dist/chunk-3Z7N2NAZ.js.map +1 -0
- package/dist/{chunk-23PPPNH6.js → chunk-4OV272LF.js} +2 -2
- package/dist/{chunk-23PPPNH6.js.map → chunk-4OV272LF.js.map} +1 -1
- package/dist/{chunk-2PXZBFEC.js → chunk-5J6Z4BWY.js} +1 -1
- package/dist/{chunk-2PXZBFEC.js.map → chunk-5J6Z4BWY.js.map} +1 -1
- package/dist/{chunk-TAHR457X.js → chunk-6CDILXF4.js} +5 -1
- package/dist/chunk-6CDILXF4.js.map +1 -0
- package/dist/{chunk-DDSCVEO5.js → chunk-CPSGUGAY.js} +6 -6
- package/dist/{chunk-DDSCVEO5.js.map → chunk-CPSGUGAY.js.map} +1 -1
- package/dist/{chunk-C3RLKKFQ.js → chunk-EYDXFOSH.js} +13 -8
- package/dist/chunk-EYDXFOSH.js.map +1 -0
- package/dist/{chunk-PE2KPZDW.js → chunk-HDXUHLTQ.js} +7 -2
- package/dist/chunk-HDXUHLTQ.js.map +1 -0
- package/dist/chunk-HU5IHXCI.js +73 -0
- package/dist/chunk-HU5IHXCI.js.map +1 -0
- package/dist/{chunk-DF2YKGIX.js → chunk-JCCN3U6X.js} +2 -2
- package/dist/{chunk-DF2YKGIX.js.map → chunk-JCCN3U6X.js.map} +1 -1
- package/dist/{chunk-UTCAOOXU.js → chunk-KPINJHIC.js} +8 -2
- package/dist/chunk-KPINJHIC.js.map +1 -0
- package/dist/{chunk-N7MBGONH.js → chunk-LMHN2TJL.js} +22 -2
- package/dist/chunk-LMHN2TJL.js.map +1 -0
- package/dist/{chunk-NS2TBYM4.js → chunk-LZUUUHNH.js} +7 -3
- package/dist/chunk-LZUUUHNH.js.map +1 -0
- package/dist/{chunk-GCAK23PU.js → chunk-MVKHSAKE.js} +2 -2
- package/dist/{chunk-GCAK23PU.js.map → chunk-MVKHSAKE.js.map} +1 -1
- package/dist/{chunk-OY2MXIBB.js → chunk-NB6POCFH.js} +3 -1
- package/dist/chunk-NB6POCFH.js.map +1 -0
- package/dist/{chunk-ECFCAKWE.js → chunk-NR6O74ST.js} +5 -1
- package/dist/chunk-NR6O74ST.js.map +1 -0
- package/dist/{chunk-7W3GKMN4.js → chunk-OQP3PFKQ.js} +7 -4
- package/dist/chunk-OQP3PFKQ.js.map +1 -0
- package/dist/{chunk-FKKJHGN5.js → chunk-P7EJ4CAD.js} +2 -2
- package/dist/{chunk-FKKJHGN5.js.map → chunk-P7EJ4CAD.js.map} +1 -1
- package/dist/{chunk-ZXZAECHZ.js → chunk-SOFPUW3O.js} +4 -4
- package/dist/{chunk-ZXZAECHZ.js.map → chunk-SOFPUW3O.js.map} +1 -1
- package/dist/{chunk-WJKHLOP5.js → chunk-TI2GV36S.js} +8 -2
- package/dist/chunk-TI2GV36S.js.map +1 -0
- package/dist/{chunk-QLA25V2K.js → chunk-WPNIKZMJ.js} +15 -1
- package/dist/chunk-WPNIKZMJ.js.map +1 -0
- package/dist/{chunk-FG6U7KQQ.js → chunk-WSEJ2FDE.js} +4 -4
- package/dist/{chunk-FG6U7KQQ.js.map → chunk-WSEJ2FDE.js.map} +1 -1
- package/dist/{chunk-ACUKTVS3.js → chunk-XWNXGFX3.js} +52 -42
- package/dist/chunk-XWNXGFX3.js.map +1 -0
- package/dist/{chunk-WU57BYYM.js → chunk-YVZCKXR3.js} +8 -2
- package/dist/chunk-YVZCKXR3.js.map +1 -0
- package/dist/{chunk-CMLPFIC5.js → chunk-ZN7KUMPY.js} +3 -1
- package/dist/chunk-ZN7KUMPY.js.map +1 -0
- package/dist/collapsible-panel.js +2 -2
- package/dist/color-picker.d.ts +30 -5
- package/dist/color-picker.js +1 -1
- package/dist/disclosure.d.ts +13 -4
- package/dist/disclosure.js.map +1 -1
- package/dist/help-tags-register.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +24 -23
- package/dist/list-action-row.js +1 -1
- package/dist/list-detail-dialog.d.ts +7 -1
- package/dist/list-detail-dialog.js +7 -5
- package/dist/list-detail-dialog.js.map +1 -1
- package/dist/list-header.d.ts +8 -1
- package/dist/list-header.js +1 -1
- package/dist/list.d.ts +7 -1
- package/dist/list.js +1 -1
- package/dist/message-composer.js +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/popup-menu-register.js +2 -2
- package/dist/popup-menu.d.ts +15 -5
- package/dist/popup-menu.js +1 -1
- package/dist/segmented-control.d.ts +3 -1
- package/dist/segmented-control.js +1 -1
- package/dist/select-register.js +3 -3
- package/dist/split-button.d.ts +14 -2
- package/dist/split-button.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/styles/anchored-surface.css +3 -0
- package/dist/styles/button.css +57 -2
- package/dist/styles/catalog/components/catalog-example.css +55 -18
- package/dist/styles/checkbox-group.css +63 -0
- package/dist/styles/checkbox.css +7 -6
- package/dist/styles/color-picker.css +69 -34
- package/dist/styles/components/actions/button/button.css +57 -2
- package/dist/styles/components/actions/split-button/split-button.css +51 -5
- package/dist/styles/components/actions/toolbar/toolbar.css +9 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +29 -1
- package/dist/styles/components/collections/framed-list/framed-list.css +6 -0
- package/dist/styles/components/collections/list/list.css +6 -0
- package/dist/styles/components/collections/list-header/list-header.css +7 -0
- package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +3 -0
- package/dist/styles/components/forms/checkbox/checkbox.css +7 -6
- package/dist/styles/components/forms/checkbox-group/checkbox-group.css +63 -0
- package/dist/styles/components/forms/color-picker/color-picker.css +69 -34
- package/dist/styles/components/forms/radio-group/radio-group.css +7 -5
- package/dist/styles/components/forms/select/select.css +6 -2
- package/dist/styles/components/forms/switch/switch.css +3 -3
- package/dist/styles/components/layout/pane/pane.css +24 -0
- package/dist/styles/components/layout/workbench/workbench.css +4 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +77 -1
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +6 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +17 -0
- package/dist/styles/components/surfaces/content-item/content-item.css +30 -0
- package/dist/styles/components/surfaces/disclosure/disclosure.css +38 -0
- package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +3 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +8 -0
- package/dist/styles/components/typography/text/text.css +10 -0
- package/dist/styles/content-item.css +30 -0
- package/dist/styles/disclosure.css +38 -0
- package/dist/styles/foundation.css +78 -13
- package/dist/styles/framed-list.css +6 -0
- package/dist/styles/list-header.css +7 -0
- package/dist/styles/list.css +6 -0
- package/dist/styles/nav-stack.css +77 -1
- package/dist/styles/pane.css +24 -0
- package/dist/styles/radio-group.css +7 -5
- package/dist/styles/select.css +6 -2
- package/dist/styles/split-button.css +51 -5
- package/dist/styles/styles.css +1 -0
- package/dist/styles/sunken-panel.css +3 -0
- package/dist/styles/surface-scaffold.css +8 -0
- package/dist/styles/switch.css +3 -3
- package/dist/styles/tab-bar.css +6 -0
- package/dist/styles/tab-navigator.css +17 -0
- package/dist/styles/text.css +10 -0
- package/dist/styles/toolbar-control-group.css +29 -1
- package/dist/styles/toolbar.css +9 -0
- package/dist/styles/webawesome.css +56 -12
- package/dist/styles/workbench.css +4 -0
- package/dist/surface-scaffold.d.ts +15 -1
- package/dist/surface-scaffold.js +1 -1
- package/dist/text-field.d.ts +7 -1
- package/dist/text-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +8 -2
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar.d.ts +6 -1
- package/dist/toolbar.js +1 -1
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-color-fields.js +2 -2
- package/dist/wire-color-pickers.d.ts +4 -3
- package/dist/wire-color-pickers.js +1 -1
- package/dist/wire-comboboxes.js +1 -1
- package/dist/wire-workbench.js +1 -1
- package/dist/workbench-dialog.d.ts +11 -2
- package/dist/workbench-dialog.js +6 -3
- package/dist/workbench-dialog.js.map +1 -1
- package/dist/workbench.js +1 -1
- package/docs/accessibility.md +58 -3
- package/docs/anchored-surface.md +6 -1
- package/docs/catalog.md +26 -1
- package/docs/color-picker.md +39 -8
- package/docs/component-contract.md +47 -3
- package/docs/component-selection.md +58 -21
- package/docs/design/templates/button/full-width-dark.svg +1 -0
- package/docs/design/templates/button/full-width.svg +1 -0
- package/docs/design/templates/button/tones-dark.svg +1 -1
- package/docs/design/templates/button/tones.svg +1 -1
- package/docs/design/templates/button-dark.svg +1 -1
- package/docs/design/templates/button.svg +1 -1
- package/docs/design/templates/checkbox/error-dark.svg +1 -1
- package/docs/design/templates/checkbox/error.svg +1 -1
- package/docs/design/templates/checkbox/states-dark.svg +1 -1
- package/docs/design/templates/checkbox/states.svg +1 -1
- package/docs/design/templates/checkbox-dark.svg +1 -1
- package/docs/design/templates/checkbox-group/horizontal-dark.svg +1 -0
- package/docs/design/templates/checkbox-group/horizontal.svg +1 -0
- package/docs/design/templates/checkbox-group/vertical-dark.svg +1 -0
- package/docs/design/templates/checkbox-group/vertical.svg +1 -0
- package/docs/design/templates/checkbox-group-dark.svg +1 -0
- package/docs/design/templates/checkbox-group.svg +1 -0
- package/docs/design/templates/checkbox.svg +1 -1
- package/docs/design/templates/color-picker/gray-dark.svg +1 -1
- package/docs/design/templates/color-picker/gray.svg +1 -1
- package/docs/design/templates/color-picker/hsb-dark.svg +1 -0
- package/docs/design/templates/color-picker/hsb.svg +1 -0
- package/docs/design/templates/color-picker/rgb-dark.svg +1 -1
- package/docs/design/templates/color-picker/rgb.svg +1 -1
- package/docs/design/templates/color-picker-dark.svg +1 -1
- package/docs/design/templates/color-picker.svg +1 -1
- package/docs/design/templates/disclosure/embedded-dark.svg +1 -0
- package/docs/design/templates/disclosure/embedded.svg +1 -0
- package/docs/design/templates/disclosure-dark.svg +1 -1
- package/docs/design/templates/disclosure.svg +1 -1
- package/docs/design/templates/radio-group/horizontal-dark.svg +1 -1
- package/docs/design/templates/radio-group/horizontal.svg +1 -1
- package/docs/design/templates/radio-group/vertical-dark.svg +1 -1
- package/docs/design/templates/radio-group/vertical.svg +1 -1
- package/docs/design/templates/radio-group-dark.svg +1 -1
- package/docs/design/templates/radio-group.svg +1 -1
- package/docs/design/templates/split-button/full-width-dark.svg +1 -0
- package/docs/design/templates/split-button/full-width.svg +1 -0
- package/docs/design/templates/split-button/pill-dark.svg +1 -0
- package/docs/design/templates/split-button/pill.svg +1 -0
- package/docs/design/templates/split-button/states-dark.svg +1 -0
- package/docs/design/templates/split-button/states.svg +1 -0
- package/docs/design/templates/split-button/tones-dark.svg +1 -0
- package/docs/design/templates/split-button/tones.svg +1 -0
- package/docs/design/templates/split-button-dark.svg +1 -0
- package/docs/design/templates/split-button.svg +1 -0
- package/docs/design/templates/switch/states-dark.svg +1 -1
- package/docs/design/templates/switch/states.svg +1 -1
- package/docs/design/templates/switch-dark.svg +1 -1
- package/docs/design/templates/switch.svg +1 -1
- package/docs/design/templates/text-field/number-dark.svg +1 -0
- package/docs/design/templates/text-field/number.svg +1 -0
- package/docs/design/templates/text-field-dark.svg +1 -1
- package/docs/design/templates/text-field.svg +1 -1
- package/docs/design/templates.md +10 -3
- package/docs/disclosure.md +34 -0
- package/docs/layout.md +16 -5
- package/docs/list-detail-dialog.md +4 -0
- package/docs/nav-stack.md +6 -2
- package/docs/surface-scaffold.md +6 -2
- package/docs/ui-doctor.md +16 -4
- package/docs/webawesome-migration.md +3 -1
- package/docs/webawesome-theme.md +56 -18
- package/docs/workbench-dialog.md +4 -1
- package/docs/workbench.md +7 -1
- package/docs/writing.md +3 -3
- package/doctor/copy-capitalization-checks.mjs +10 -7
- package/llms.txt +65 -23
- package/package.json +7 -1
- package/dist/chunk-7W3GKMN4.js.map +0 -1
- package/dist/chunk-ACUKTVS3.js.map +0 -1
- package/dist/chunk-C3RLKKFQ.js.map +0 -1
- package/dist/chunk-CMLPFIC5.js.map +0 -1
- package/dist/chunk-ECFCAKWE.js.map +0 -1
- package/dist/chunk-EKBMUXFV.js.map +0 -1
- package/dist/chunk-HYORKKYP.js.map +0 -1
- package/dist/chunk-N7MBGONH.js.map +0 -1
- package/dist/chunk-NS2TBYM4.js.map +0 -1
- package/dist/chunk-OY2MXIBB.js.map +0 -1
- package/dist/chunk-PE2KPZDW.js.map +0 -1
- package/dist/chunk-QLA25V2K.js.map +0 -1
- package/dist/chunk-TAHR457X.js.map +0 -1
- package/dist/chunk-UTCAOOXU.js.map +0 -1
- package/dist/chunk-WJKHLOP5.js.map +0 -1
- package/dist/chunk-WU57BYYM.js.map +0 -1
|
@@ -82,6 +82,20 @@ type DialogSurfaceProps = DialogSurfaceName & DialogSurfaceOptions;
|
|
|
82
82
|
interface DialogSurfaceOptions {
|
|
83
83
|
/** The dialog's id, for `openDialog(document.getElementById(id))`. */
|
|
84
84
|
id?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Id of the element whose text is the dialog's accessible description,
|
|
87
|
+
* such as the `heading` ToolbarText's `descriptionId` or app-owned summary
|
|
88
|
+
* copy in the body; rendered as `aria-describedby` on the `<dialog>`.
|
|
89
|
+
*/
|
|
90
|
+
describedBy?: string;
|
|
91
|
+
/**
|
|
92
|
+
* An alert dialog: a confirmation that interrupts the person to report
|
|
93
|
+
* something urgent or ask before a destructive action ("Delete this
|
|
94
|
+
* topic?"). Renders `role="alertdialog"` on the `<dialog>`; set
|
|
95
|
+
* `describedBy` to the element holding the message, and leave
|
|
96
|
+
* `lightDismiss` off so the person answers it.
|
|
97
|
+
*/
|
|
98
|
+
alert?: boolean;
|
|
85
99
|
/** The body content. */
|
|
86
100
|
children: KerfUiContent;
|
|
87
101
|
/**
|
|
@@ -196,7 +210,7 @@ interface DialogSurfaceOptions {
|
|
|
196
210
|
* floating header and footer measurement, the bottom sheet's keyboard
|
|
197
211
|
* clearance and grabber, and re-render resilience while open.
|
|
198
212
|
*/
|
|
199
|
-
declare function DialogSurface({ id, label, labelledBy, heading, headerActions, footer, withoutHeader, lightDismiss, closeLabel, children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, minHeight, resizable, enterMotion, exitMotion, bodyLayout, headerPresentation, footerPresentation, footerOffset, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
|
|
213
|
+
declare function DialogSurface({ id, label, labelledBy, describedBy, alert, heading, headerActions, footer, withoutHeader, lightDismiss, closeLabel, children, size, presentation, preferredWidth, bodyInset, footerInset, viewportGutter, maxHeight, height, minHeight, resizable, enterMotion, exitMotion, bodyLayout, headerPresentation, footerPresentation, footerOffset, rootAttributes, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
|
|
200
214
|
/** Where a PopoverDialogSurface appears: the top layer, or in flow. */
|
|
201
215
|
type PopoverDialogSurfacePresentation = 'overlay' | 'embedded';
|
|
202
216
|
/** Application `data-*` metadata on the surface root. */
|
package/dist/surface-scaffold.js
CHANGED
package/dist/text-field.d.ts
CHANGED
|
@@ -50,6 +50,12 @@ interface TextFieldOptions {
|
|
|
50
50
|
showCount?: boolean;
|
|
51
51
|
/** Single-line value kind (default `text`). */
|
|
52
52
|
type?: TextFieldType;
|
|
53
|
+
/** Native lower bound for `type="number"` (number or numeric string). */
|
|
54
|
+
min?: number | string;
|
|
55
|
+
/** Native upper bound for `type="number"` (number or numeric string). */
|
|
56
|
+
max?: number | string;
|
|
57
|
+
/** Native number increment (number, numeric string, or `"any"`). */
|
|
58
|
+
step?: number | string;
|
|
53
59
|
/** A multi-line field: a `<textarea>`. */
|
|
54
60
|
multiline?: boolean;
|
|
55
61
|
/** A multi-line field's height in lines (default 3). */
|
|
@@ -78,6 +84,6 @@ interface TextFieldOptions {
|
|
|
78
84
|
* The whole field is one `<label>`, so clicking anywhere on it focuses the
|
|
79
85
|
* input; the input is named by `label` (or `ariaLabel`) directly.
|
|
80
86
|
*/
|
|
81
|
-
declare function TextField({ label, ariaLabel, value, name, placeholder, hint, error, size, icon, clearable, clearLabel, maxLength, showCount, type, multiline, rows, maxRows, disabled, readOnly, required, autocomplete, id, className, rootAttributes, slot, }: TextFieldProps): kerfjs.SafeHtml;
|
|
87
|
+
declare function TextField({ label, ariaLabel, value, name, placeholder, hint, error, size, icon, clearable, clearLabel, maxLength, showCount, type, min, max, step, multiline, rows, maxRows, disabled, readOnly, required, autocomplete, id, className, rootAttributes, slot, }: TextFieldProps): kerfjs.SafeHtml;
|
|
82
88
|
|
|
83
89
|
export { TextField, type TextFieldName, type TextFieldOptions, type TextFieldProps, type TextFieldRootAttributes, type TextFieldSize, type TextFieldType };
|
package/dist/text-field.js
CHANGED
|
@@ -19,7 +19,7 @@ type ToolbarControlGroupSelectedTone = 'brand' | 'neutral' | 'pop';
|
|
|
19
19
|
type ToolbarControlGroupOverflow = 'visible' | 'scroll' | 'wrap';
|
|
20
20
|
type ToolbarControlGroupExpandedOverflow = 'clip' | 'visible';
|
|
21
21
|
type ToolbarControlGroupMenuInset = 'standard' | 'compact' | 'list-zero';
|
|
22
|
-
type ToolbarControlGroupVisibility = 'always' | 'compact-only' | 'hide-collapsed-tiny' | 'yield-to-expanded-sibling';
|
|
22
|
+
type ToolbarControlGroupVisibility = 'always' | 'compact-only' | 'hide-collapsed-tiny' | 'yield-to-expanded-sibling' | 'yield-to-priority-row';
|
|
23
23
|
type ToolbarControlGroupSizing = 'content' | 'grow' | 'fill';
|
|
24
24
|
type ToolbarControlGroupPlacement = 'start' | 'end';
|
|
25
25
|
interface ToolbarActionLinkProps {
|
|
@@ -82,7 +82,13 @@ interface ToolbarControlGroupProps {
|
|
|
82
82
|
overflow?: ToolbarControlGroupOverflow;
|
|
83
83
|
/** Let app-owned anchored surfaces extend outside an expanded search group. Collapsed searches retain their clipping. */
|
|
84
84
|
expandedOverflow?: ToolbarControlGroupExpandedOverflow;
|
|
85
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* Responsive visibility owned by the enclosing Toolbar container.
|
|
87
|
+
* `yield-to-priority-row` hides this trailing group exactly while its
|
|
88
|
+
* Toolbar's `responsive="trailing-priority"` row is active (an expanded
|
|
89
|
+
* trailing sibling at the Toolbar's `responsiveAt` width), so the app never
|
|
90
|
+
* restates that breakpoint with `hideBelow`.
|
|
91
|
+
*/
|
|
86
92
|
visibility?: ToolbarControlGroupVisibility;
|
|
87
93
|
/** Hide below this Toolbar content width; requires wireToolbarVisibility. */
|
|
88
94
|
hideBelow?: CssLength;
|
package/dist/toolbar.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ type ToolbarPosition = 'header' | 'footer';
|
|
|
9
9
|
/** Control-band density: `default` (60px with 44px groups) or `compact`. */
|
|
10
10
|
type ToolbarDensity = 'default' | 'compact';
|
|
11
11
|
interface ToolbarProps {
|
|
12
|
+
/**
|
|
13
|
+
* The toolbar's id, so app code can address it: name it as a scrolling
|
|
14
|
+
* List's chrome in `wireScrollDividers({ targets })`, or find it in tests.
|
|
15
|
+
*/
|
|
16
|
+
id?: string;
|
|
12
17
|
leading?: KerfUiContent;
|
|
13
18
|
center?: KerfUiContent;
|
|
14
19
|
trailing?: KerfUiContent;
|
|
@@ -73,6 +78,6 @@ interface ToolbarProps {
|
|
|
73
78
|
* toolbar) forwards, so the app configures that toolbar instead of styling it.
|
|
74
79
|
*/
|
|
75
80
|
type ToolbarConfig = Pick<ToolbarProps, 'density' | 'dividerSides' | 'centerAlign' | 'responsive' | 'responsiveAt' | 'safeAreaEdges'>;
|
|
76
|
-
declare function Toolbar({ leading, center, trailing, label, position, density, dividerSides, centerAlign, responsive, responsiveAt, safeAreaEdges, className, slot, }: ToolbarProps): kerfjs.SafeHtml;
|
|
81
|
+
declare function Toolbar({ id, leading, center, trailing, label, position, density, dividerSides, centerAlign, responsive, responsiveAt, safeAreaEdges, className, slot, }: ToolbarProps): kerfjs.SafeHtml;
|
|
77
82
|
|
|
78
83
|
export { Sides, Toolbar, type ToolbarConfig, type ToolbarDensity, type ToolbarPosition, type ToolbarProps };
|
package/dist/toolbar.js
CHANGED
package/dist/wire-catalog.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { wireColorPickers } from './chunk-
|
|
2
|
-
import { ColorPicker } from './chunk-
|
|
1
|
+
import { wireColorPickers } from './chunk-XWNXGFX3.js';
|
|
2
|
+
import { ColorPicker } from './chunk-3Z7N2NAZ.js';
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
import { openAnchoredSurface } from './chunk-3WYREXW4.js';
|
|
@@ -19,9 +19,10 @@ interface WireColorPickersOptions {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Make every ColorPicker under `root` interactive. The area takes pointer
|
|
22
|
-
* drags and the arrow keys (Shift for steps of 10%); the
|
|
23
|
-
* sliders are native ranges
|
|
24
|
-
*
|
|
22
|
+
* drags and the arrow keys (Shift for steps of 10%); the model's channel
|
|
23
|
+
* sliders and the opacity slider are native ranges, each changing only its
|
|
24
|
+
* own channel; channel, hex, and opacity fields commit on Enter or blur; the
|
|
25
|
+
* model menu switches the channel sliders and fields; the screen sampler
|
|
25
26
|
* opens the EyeDropper where the browser has it; preset and sample swatches
|
|
26
27
|
* apply their color. Each change updates the picker at once, dispatches a
|
|
27
28
|
* bubbling `kui-color-input` (or `kui-color-change` when committed) event
|
package/dist/wire-comboboxes.js
CHANGED
package/dist/wire-workbench.js
CHANGED
|
@@ -34,8 +34,17 @@ interface WorkbenchDialogProps {
|
|
|
34
34
|
label: string;
|
|
35
35
|
/** The dialog's primary title: an xl heading in the work area's toolbar. */
|
|
36
36
|
title: string;
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* A short supporting line under the title. It is the dialog's accessible
|
|
39
|
+
* description (`aria-describedby` to its `<id>-description`) unless
|
|
40
|
+
* `describedBy` names other content.
|
|
41
|
+
*/
|
|
38
42
|
description?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Id of the element whose text is the dialog's accessible description, in
|
|
45
|
+
* place of `description`, such as app-owned summary copy in `main`.
|
|
46
|
+
*/
|
|
47
|
+
describedBy?: string;
|
|
39
48
|
/** Groups after the title in the work area's toolbar. */
|
|
40
49
|
leading?: KerfUiContent;
|
|
41
50
|
/** Header controls before the close control, such as a `ToolbarControlGroup`. */
|
|
@@ -92,6 +101,6 @@ interface WorkbenchDialogProps {
|
|
|
92
101
|
* Escape or a press outside it before the dialog sees the Escape. Built from
|
|
93
102
|
* `DialogSurface` and `Workbench`.
|
|
94
103
|
*/
|
|
95
|
-
declare function WorkbenchDialog({ id, label, title, description, leading, actions, main, mainFooter, mainBottomToolbar, leftRail, rightRail, bottomDrawer, compact, closeLabel, lightDismiss, size, preferredWidth, height, maxHeight, viewportGutter, mainMinSize, rootAttributes, className, slot, }: WorkbenchDialogProps): kerfjs.SafeHtml;
|
|
104
|
+
declare function WorkbenchDialog({ id, label, title, description, describedBy, leading, actions, main, mainFooter, mainBottomToolbar, leftRail, rightRail, bottomDrawer, compact, closeLabel, lightDismiss, size, preferredWidth, height, maxHeight, viewportGutter, mainMinSize, rootAttributes, className, slot, }: WorkbenchDialogProps): kerfjs.SafeHtml;
|
|
96
105
|
|
|
97
106
|
export { WorkbenchDialog, type WorkbenchDialogProps, type WorkbenchDialogRootAttributes };
|
package/dist/workbench-dialog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DialogSurface } from './chunk-
|
|
1
|
+
import { DialogSurface } from './chunk-6CDILXF4.js';
|
|
2
2
|
export { closeDialog, openDialog } from './chunk-ATGAJVZ6.js';
|
|
3
3
|
|
|
4
|
-
import { Workbench } from './chunk-
|
|
4
|
+
import { Workbench } from './chunk-CPSGUGAY.js';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
@@ -10,7 +10,7 @@ import { ToolbarText } from './chunk-EKHDLBRP.js';
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
import { ToolbarControlGroup } from './chunk-
|
|
13
|
+
import { ToolbarControlGroup } from './chunk-5J6Z4BWY.js';
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -33,6 +33,7 @@ function WorkbenchDialog({
|
|
|
33
33
|
label,
|
|
34
34
|
title,
|
|
35
35
|
description,
|
|
36
|
+
describedBy,
|
|
36
37
|
leading,
|
|
37
38
|
actions,
|
|
38
39
|
main,
|
|
@@ -59,6 +60,7 @@ function WorkbenchDialog({
|
|
|
59
60
|
{
|
|
60
61
|
id,
|
|
61
62
|
label,
|
|
63
|
+
describedBy: describedBy ?? (description === void 0 ? void 0 : `${id}-description`),
|
|
62
64
|
withoutHeader: true,
|
|
63
65
|
lightDismiss,
|
|
64
66
|
closeLabel,
|
|
@@ -88,6 +90,7 @@ function WorkbenchDialog({
|
|
|
88
90
|
{
|
|
89
91
|
text: title,
|
|
90
92
|
description,
|
|
93
|
+
descriptionId: description === void 0 ? void 0 : `${id}-description`,
|
|
91
94
|
size: "xlarge",
|
|
92
95
|
id: `${id}-title`,
|
|
93
96
|
headingLevel: 2
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/surfaces/workbench-dialog/workbench-dialog.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../src/components/surfaces/workbench-dialog/workbench-dialog.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAwGA,SAAS,WAAA,CACP,OACA,OAAA,EAC4B;AAC5B,EAAA,OAAO,SAAS,OAAA,GAAU,EAAE,GAAG,KAAA,EAAO,YAAA,EAAc,WAAU,GAAI,KAAA;AACpE;AAaO,SAAS,eAAA,CAAgB;AAAA,EAC9B,EAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,UAAA,GAAa,OAAA;AAAA,EACb,YAAA,GAAe,KAAA;AAAA,EACf,IAAA,GAAO,OAAA;AAAA,EACP,cAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAyB;AACvB,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,KAAA;AAAA,MACA,aACE,WAAA,KACC,WAAA,KAAgB,MAAA,GAAY,MAAA,GAAY,GAAG,EAAE,CAAA,YAAA,CAAA,CAAA;AAAA,MAEhD,aAAA,EAAa,IAAA;AAAA,MACb,YAAA;AAAA,MACA,UAAA;AAAA,MACA,IAAA;AAAA,MACA,YAAA,EAAc,UAAU,YAAA,GAAe,OAAA;AAAA,MACvC,cAAA;AAAA,MACA,MAAA,EACE,UACI,MAAA,GACA,SAAA,KAAc,SACX,MAAA,IAAU,MAAA,CAAO,GAAG,CAAA,GACrB,MAAA;AAAA,MAER,SAAA,EAAW,UAAU,MAAA,GAAY,SAAA;AAAA,MACjC,cAAA,EAAgB,UAAU,MAAA,GAAY,cAAA;AAAA,MACtC,SAAA,EAAU,MAAA;AAAA,MACV,UAAA,EAAW,MAAA;AAAA,MACX,cAAA,EAAgB;AAAA,QACd,GAAG,cAAA;AAAA,QACH,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,SAAA;AAAA,MACA,IAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACC,EAAA,EAAI,GAAG,EAAE,CAAA,UAAA,CAAA;AAAA,UACT,KAAA;AAAA,UACA,WAAA,EAAa;AAAA,YACX,KAAA,EAAO,KAAA;AAAA,YACP,KAAA,kBACE,GAAA;AAAA,cAAC,WAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAM,KAAA;AAAA,gBACN,WAAA;AAAA,gBACA,aAAA,EACE,WAAA,KAAgB,MAAA,GAAY,MAAA,GAAY,GAAG,EAAE,CAAA,YAAA,CAAA;AAAA,gBAE/C,IAAA,EAAK,QAAA;AAAA,gBACL,EAAA,EAAI,GAAG,EAAE,CAAA,MAAA,CAAA;AAAA,gBACT,YAAA,EAAc;AAAA;AAAA,aAChB;AAAA,YAEF,OAAA;AAAA,YACA,QAAA,EAAU,OAAA;AAAA;AAAA,YAEV,qBACE,GAAA,CAAC,mBAAA,EAAA,EAAoB,UAAA,EAAW,YAAA,EAAa,QAAM,IAAA,EACjD,QAAA,kBAAA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,YAAA,EAAY,UAAA;AAAA,gBACZ,mBAAA,EAAkB,EAAA;AAAA,gBAElB,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,IAAA,EAAM,CAAA,EAAG,MAAK,GAAA,EAAI;AAAA;AAAA,aAChC,EACF;AAAA,WAEJ;AAAA,UACA,IAAA;AAAA,UACA,UAAA;AAAA,UACA,iBAAA;AAAA,UACA,QAAA,EAAU,WAAA,CAAY,QAAA,EAAU,OAAO,CAAA;AAAA,UACvC,SAAA,EAAW,WAAA,CAAY,SAAA,EAAW,OAAO,CAAA;AAAA,UACzC,YAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ","file":"workbench-dialog.js","sourcesContent":["import { X } from 'lucide';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport type { CssLength } from '../../../shared/styles/css-values.js';\nimport { remify } from '../../../shared/styles/css-values.js';\nimport { ToolbarControlGroup } from '../../actions/toolbar-control-group/toolbar-control-group.js';\nimport { ToolbarText } from '../../actions/toolbar-text/toolbar-text.js';\nimport {\n Workbench,\n type WorkbenchMainBottomToolbar,\n type WorkbenchPanel,\n} from '../../layout/workbench/workbench.js';\nimport { LucideIcon } from '../../media/lucide-icon/lucide-icon.js';\nimport {\n DialogSurface,\n type DialogSurfaceHeight,\n type DialogSurfaceMaxHeight,\n type DialogSurfaceRootAttributes,\n type DialogSurfaceSize,\n} from '../surface-scaffold/surface-scaffold.js';\n\n// Open and close it like any DialogSurface, from the same import.\nexport {\n closeDialog,\n type DialogCloseSource,\n type DialogRequestCloseDetail,\n openDialog,\n} from '../surface-scaffold/surface-scaffold.js';\n\n/**\n * Application `data-*` identity on the dialog root, such as `data-key`; the\n * dialog's own configuration attributes stay protected.\n */\nexport type WorkbenchDialogRootAttributes = DialogSurfaceRootAttributes;\n\nexport interface WorkbenchDialogProps {\n /**\n * The dialog's id, for `openDialog(document.getElementById(id))`. The\n * Workbench inside is `<id>-workbench`, so its rails are\n * `<id>-workbench-left-rail` and `<id>-workbench-right-rail`.\n */\n id: string;\n /** The dialog's accessible name. */\n label: string;\n /** The dialog's primary title: an xl heading in the work area's toolbar. */\n title: string;\n /**\n * A short supporting line under the title. It is the dialog's accessible\n * description (`aria-describedby` to its `<id>-description`) unless\n * `describedBy` names other content.\n */\n description?: string;\n /**\n * Id of the element whose text is the dialog's accessible description, in\n * place of `description`, such as app-owned summary copy in `main`.\n */\n describedBy?: string;\n /** Groups after the title in the work area's toolbar. */\n leading?: KerfUiContent;\n /** Header controls before the close control, such as a `ToolbarControlGroup`. */\n actions?: KerfUiContent;\n /** The work area. */\n main: KerfUiContent;\n /** Fixed content over the work area's bottom toolbar, such as a status line. */\n mainFooter?: KerfUiContent;\n /** The work area's bottom toolbar, usually the dialog's buttons. */\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n /**\n * Side rails with their own toolbars. On compact devices each presents as\n * an overlay over the work area; the app starts it collapsed and its\n * `toolbar.toggle` shows it.\n */\n leftRail?: WorkbenchPanel;\n rightRail?: WorkbenchPanel;\n /** A bottom drawer under the work area. */\n bottomDrawer?: WorkbenchPanel;\n /**\n * Fill the screen with the rails as overlays: derive from\n * `deviceClass().value.compact`.\n */\n compact?: boolean;\n /** The close control's accessible name (default `Close`). */\n closeLabel?: string;\n /** Close on a press on the backdrop; otherwise the panel pulses. */\n lightDismiss?: boolean;\n /** Roomy preferred width preset (default `large`). */\n size?: DialogSurfaceSize;\n /** Roomy preferred width; takes precedence over `size`. */\n preferredWidth?: CssLength;\n /** Roomy definite height (default 560px), bounded by the viewport. */\n height?: DialogSurfaceHeight;\n /** Roomy height cap in place of a definite height. */\n maxHeight?: DialogSurfaceMaxHeight;\n /** Roomy edge clearance from the viewport. */\n viewportGutter?: CssLength;\n /** Minimum work-area width beside inline rails, in px (Workbench default 320). */\n mainMinSize?: number;\n rootAttributes?: WorkbenchDialogRootAttributes;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A rail presents as an overlay in a compact dialog, as the app left it otherwise. */\nfunction compactRail(\n panel: WorkbenchPanel | undefined,\n compact: boolean,\n): WorkbenchPanel | undefined {\n return panel && compact ? { ...panel, presentation: 'overlay' } : panel;\n}\n\n/**\n * A workbench dialog: a modal whose body is a `Workbench`. The work area's\n * toolbar carries the dialog's primary title, its actions, and the close\n * control; side rails keep their own toolbars and run the dialog's full\n * height. On compact devices it fills the screen and its rails become\n * overlays over the work area, shown by their toolbar toggles, so the work\n * area keeps its width. Open it with `openDialog()`; the app owns each\n * rail's `collapsed` state, and `wireWorkbench` closes an overlay rail on\n * Escape or a press outside it before the dialog sees the Escape. Built from\n * `DialogSurface` and `Workbench`.\n */\nexport function WorkbenchDialog({\n id,\n label,\n title,\n description,\n describedBy,\n leading,\n actions,\n main,\n mainFooter,\n mainBottomToolbar,\n leftRail,\n rightRail,\n bottomDrawer,\n compact = false,\n closeLabel = 'Close',\n lightDismiss = false,\n size = 'large',\n preferredWidth,\n height,\n maxHeight,\n viewportGutter,\n mainMinSize,\n rootAttributes,\n className = '',\n slot,\n}: WorkbenchDialogProps) {\n return (\n <DialogSurface\n id={id}\n label={label}\n describedBy={\n describedBy ??\n (description === undefined ? undefined : `${id}-description`)\n }\n withoutHeader\n lightDismiss={lightDismiss}\n closeLabel={closeLabel}\n size={size}\n presentation={compact ? 'fullscreen' : 'modal'}\n preferredWidth={preferredWidth}\n height={\n compact\n ? undefined\n : maxHeight === undefined\n ? (height ?? remify(560))\n : height\n }\n maxHeight={compact ? undefined : maxHeight}\n viewportGutter={compact ? undefined : viewportGutter}\n bodyInset=\"none\"\n bodyLayout=\"fill\"\n rootAttributes={{\n ...rootAttributes,\n 'data-dialog-layout': 'workbench',\n }}\n className={className}\n slot={slot}\n >\n <Workbench\n id={`${id}-workbench`}\n label={label}\n mainToolbar={{\n label: title,\n title: (\n <ToolbarText\n text={title}\n description={description}\n descriptionId={\n description === undefined ? undefined : `${id}-description`\n }\n size=\"xlarge\"\n id={`${id}-title`}\n headingLevel={2}\n />\n ),\n leading,\n trailing: actions,\n // After any hidden right rail's toggle, so Close stays outermost.\n end: (\n <ToolbarControlGroup appearance=\"borderless\" single>\n <button\n type=\"button\"\n aria-label={closeLabel}\n data-dialog-close=\"\"\n >\n <LucideIcon icon={X} name=\"x\" />\n </button>\n </ToolbarControlGroup>\n ),\n }}\n main={main}\n mainFooter={mainFooter}\n mainBottomToolbar={mainBottomToolbar}\n leftRail={compactRail(leftRail, compact)}\n rightRail={compactRail(rightRail, compact)}\n bottomDrawer={bottomDrawer}\n mainMinSize={mainMinSize}\n />\n </DialogSurface>\n );\n}\n"]}
|
package/dist/workbench.js
CHANGED
package/docs/accessibility.md
CHANGED
|
@@ -364,7 +364,16 @@ holds an optional icon `ToolbarControlGroup` and a direct extra-large
|
|
|
364
364
|
`ToolbarText`; controls belong in a trailing `ToolbarControlGroup`. By default
|
|
365
365
|
the title carries no native heading role, so for a **dialog or panel** the
|
|
366
366
|
application connects the title id and optional supporting-copy id to the owning
|
|
367
|
-
host through `aria-labelledby` and `aria-describedby`.
|
|
367
|
+
host through `aria-labelledby` and `aria-describedby`. `DialogSurface` and
|
|
368
|
+
`PopoverDialogSurface` take these as `labelledBy` and `describedBy`, so the
|
|
369
|
+
supporting line (or app-owned summary copy in the body) is the dialog's
|
|
370
|
+
accessible description; `WorkbenchDialog` wires its title `description`
|
|
371
|
+
automatically (`<id>-description`), and `ListDetailDialog` takes an explicit
|
|
372
|
+
`describedBy`, since its detail description describes the selection, not the
|
|
373
|
+
dialog. A `DialogSurface` that asks before a destructive action ("Delete this
|
|
374
|
+
topic?") sets `alert`, which renders `role="alertdialog"` on the native
|
|
375
|
+
`<dialog>`; pair it with `describedBy` on the message so it is announced, and
|
|
376
|
+
leave `lightDismiss` off so the person answers it. For a **page or view**
|
|
368
377
|
title, pass `headingLevel` (usually `1`) to `ToolbarText`: it then exposes
|
|
369
378
|
`role="heading"` with a matching `aria-level`, giving the view a heading landmark
|
|
370
379
|
so screen-reader heading navigation and "main heading" semantics work — the same
|
|
@@ -473,7 +482,9 @@ controls; Enter and Space use native button activation. The application handles
|
|
|
473
482
|
the supplied `data-action`, reads `data-segment-value`, updates `value`, and
|
|
474
483
|
re-renders. Keep labels unique and meaningful even when `content` shows only an
|
|
475
484
|
icon. The filled track uses the normal neutral text role for readable unselected
|
|
476
|
-
labels in light and dark themes.
|
|
485
|
+
labels in light and dark themes. A whole-control `disabled` disables every
|
|
486
|
+
native button and marks the group `aria-disabled` while `aria-pressed` still
|
|
487
|
+
reports the current choice. Use tabs—not a segmented control—when choices switch page regions that
|
|
477
488
|
need `tab`/`tabpanel` semantics.
|
|
478
489
|
|
|
479
490
|
## ChoiceChips
|
|
@@ -533,6 +544,12 @@ its label; the input itself reports `required`. The focus ring is drawn on the
|
|
|
533
544
|
box around the input (`:focus-within`), 3px with a 1px offset like every Kerf
|
|
534
545
|
control.
|
|
535
546
|
|
|
547
|
+
For `type="number"`, `min`, `max`, and `step` pass through to the native input.
|
|
548
|
+
Each accepts a number or string; `step="any"` allows arbitrary decimals.
|
|
549
|
+
They are omitted for other input types and `multiline` textareas. Native
|
|
550
|
+
constraint validation (`rangeUnderflow`, `rangeOverflow`, and `stepMismatch`)
|
|
551
|
+
then applies without custom field wiring.
|
|
552
|
+
|
|
536
553
|
`clearable` adds a native `<button>` named by `clearLabel` (default "Clear")
|
|
537
554
|
after the input. It is hidden while the field is empty, is a normal Tab stop,
|
|
538
555
|
and with `wireTextFields(root)` empties the field, dispatches bubbling `input`
|
|
@@ -542,6 +559,36 @@ disabled or read-only field's clear button is disabled. `showCount` (with
|
|
|
542
559
|
`wireTextFields` keeps current. Compact text grows to 16px on coarse-pointer
|
|
543
560
|
touch screens so focusing a field never zooms the page in iOS.
|
|
544
561
|
|
|
562
|
+
## Button and SplitButton focus
|
|
563
|
+
|
|
564
|
+
`Button` and each `SplitButton` half draw the 3px focus ring 1px outside the
|
|
565
|
+
box, against the surrounding surface, because a loud fill can share the ring's
|
|
566
|
+
hue (the brand fill matches the focus color in both schemes). An ancestor that
|
|
567
|
+
clips overflow would crop that ring, so `focusRingInset` draws it inside the
|
|
568
|
+
box instead, the name and meaning `Select` uses. An inset ring alone would
|
|
569
|
+
touch the fill (1.0:1 on brand, at most 2.3:1 on any loud fill), so the inset
|
|
570
|
+
ring is two-tone: the ring color on the outer 3px and a 3px surface-colored
|
|
571
|
+
line inside it. The ring then meets a surface color on both edges and clears
|
|
572
|
+
3:1 against each on every tone (about 4.0:1 in light, 9.9:1 in dark against
|
|
573
|
+
the line), whatever the fill. Forced-colors mode drops the line and keeps the
|
|
574
|
+
system ring.
|
|
575
|
+
|
|
576
|
+
The line paints the surface the control sits on, not always the base surface:
|
|
577
|
+
a surface that changes the background behind its children publishes the
|
|
578
|
+
surface context (`--kui-color-surface-current`, `-region`, and `-tint`; see
|
|
579
|
+
`docs/component-contract.md`), and the line layers it the same way the page
|
|
580
|
+
does. On a sunken panel, a quiet `ContentItem`, a lowered `FramedList`, a
|
|
581
|
+
raised `List`, popup, or dialog, a highlighted `FramedList` row, a sunken
|
|
582
|
+
Pane, Workbench area, or TabNavigator scene, or a Pane or TabNavigator app
|
|
583
|
+
`background`, the line matches the pixels outside the box, so it reads as a
|
|
584
|
+
cut through the fill instead of a light halo. On a doubly sunken surface the
|
|
585
|
+
brand ring still clears 3:1 against the line (about 3.2:1 in light, 6.9:1 in
|
|
586
|
+
dark). A sunken surface's grain is not part of the line. Translucent glass
|
|
587
|
+
chrome (an overlay header, bar, or bottom toolbar, a dialog's floating
|
|
588
|
+
header) has no single color over scrolling content, so the line paints the
|
|
589
|
+
material over the surface beneath it: exact at rest, an approximation while
|
|
590
|
+
content scrolls under the bar.
|
|
591
|
+
|
|
545
592
|
## Checkbox, RadioGroup, and Switch
|
|
546
593
|
|
|
547
594
|
Each control is a native input inside its `<label>`, positioned invisibly over
|
|
@@ -563,6 +610,13 @@ forced-colors mode paints checked state with `Highlight`.
|
|
|
563
610
|
its `aria-description`; `error` sets `aria-invalid` on the group, `required`
|
|
564
611
|
sets native `required` on each radio plus `aria-required` on the group, and a
|
|
565
612
|
choice's `hint` is that radio's `aria-description`.
|
|
613
|
+
- `CheckboxGroup` is a `<fieldset>` (natively a group) of `Checkbox`es, named
|
|
614
|
+
by its `<legend>` (`label`), `ariaLabel`, or `labelledBy`. Each checkbox
|
|
615
|
+
is its own Tab stop and Space toggles it; every checked value submits under
|
|
616
|
+
`name`. The group's `hint` and `error` form its `aria-description`; `error`
|
|
617
|
+
sets `aria-invalid` on the group and the danger border on each box, and a
|
|
618
|
+
choice's `hint` is that checkbox's `aria-description`. `disabled` disables
|
|
619
|
+
the fieldset and so, natively, every checkbox in it.
|
|
566
620
|
- `Switch` is an `<input type="checkbox" role="switch">`, so assistive
|
|
567
621
|
technology announces on and off; Space toggles it. Its `hint` is its
|
|
568
622
|
`aria-description`. The thumb's slide is skipped when reduced motion is
|
|
@@ -747,7 +801,8 @@ the Tab order while collapsed or not inline. `wireWorkbench`, given a panel's
|
|
|
747
801
|
`collapsed` signal, returns focus stranded in a closing panel to the control that
|
|
748
802
|
opened it, else the restore control, else a control whose `aria-controls` names the
|
|
749
803
|
panel; an open overlay panel takes focus and keeps Tab inside it (the ARIA dialog
|
|
750
|
-
pattern)
|
|
804
|
+
pattern), whether its own toggle or a persistent toggle outside the Workbench
|
|
805
|
+
opened it, as soon as the panel can take focus. See [`workbench.md`](workbench.md).
|
|
751
806
|
|
|
752
807
|
## Chrome material
|
|
753
808
|
|
package/docs/anchored-surface.md
CHANGED
|
@@ -26,7 +26,12 @@ help that leaves focus on its trigger. Escape and an outside press dismiss it;
|
|
|
26
26
|
`placement` (`bottom` or `top`), `align` (`start` or `end`), `gap`, and
|
|
27
27
|
`viewportMargin` feed the shared `kerfjs/overlay` positioning core: it flips
|
|
28
28
|
vertically when the other side fits, keeps the surface `viewportMargin` (default
|
|
29
|
-
8px) inside the viewport edges, and follows scroll and
|
|
29
|
+
8px) inside the viewport edges, and follows scroll, resize, and changes to the
|
|
30
|
+
anchor's own size. Anchor help for a field to the whole field rather than to a
|
|
31
|
+
button inside it: the surface then clears every line of a field that wraps, and
|
|
32
|
+
moves as the field grows (a SearchField's trailing help action opens beside
|
|
33
|
+
`[data-component="search-field"]`, which also keeps typing in the field from
|
|
34
|
+
dismissing it). The surface fits
|
|
30
35
|
its height to the room beside the anchor: when neither side holds it, it opens
|
|
31
36
|
on the roomier side, caps its height to that room, and scrolls its content.
|
|
32
37
|
The room is exposed to the content as `--kui-anchored-surface-available-height`
|
package/docs/catalog.md
CHANGED
|
@@ -219,7 +219,32 @@ for a control whose own inline padding contributes about 8px, and
|
|
|
219
219
|
8px inset (such as a plain `PopupMenu` trigger), so its text lines up with the
|
|
220
220
|
example label past the trigger's own padding and border. Use
|
|
221
221
|
`align="none"` (the default) for a content item or composition that owns its
|
|
222
|
-
geometry.
|
|
222
|
+
geometry. Every form field specimen (TextField, Select, ColorField, TagField,
|
|
223
|
+
Slider, Switch, Checkbox, RadioGroup, CheckboxGroup, ColorSwatches) uses
|
|
224
|
+
`inline-control`, so field borders and label text share one column across the
|
|
225
|
+
catalog; a field that already insets itself by 8px (Combobox) stays at `none`.
|
|
226
|
+
A field is a control a person fills in or picks a value with inline, swatch
|
|
227
|
+
pickers included. A field composition (fields in a `Grid` or a form `List`)
|
|
228
|
+
uses `inline-control` too. A width-sized content specimen — one that fills a
|
|
229
|
+
sized `viewport` or its container rather than its content, such as a
|
|
230
|
+
ProgressBar, a group-title `Text`, or Web Awesome's Progress Bar and Skeleton —
|
|
231
|
+
joins the same column with `inline-control`, so a bar's label lines up with the
|
|
232
|
+
example label and note text. Web Awesome integration specimens follow their
|
|
233
|
+
Kerf counterpart's demo: controls and control compositions (Button, Button
|
|
234
|
+
Group, Dropdown, Dropdown Item, the Tab family, Badge, Tag, Avatar, Progress
|
|
235
|
+
Ring, Toast and Toast Item, the dialog, drawer, popover, and tooltip triggers,
|
|
236
|
+
Animation, and the intersection, mutation, and resize observer compositions)
|
|
237
|
+
use `inline-control`, as the Kerf Button demo does, so the control box sits on
|
|
238
|
+
the 8px column; a specimen led by bare text or a bare glyph (Copy Button,
|
|
239
|
+
Breadcrumb and Breadcrumb Item, Divider, Markdown, Relative Time, Pagination's
|
|
240
|
+
summary, Stepper and Step markers, Spinner, Icon) uses `glyph`, as Kerf's flush
|
|
241
|
+
`Text`, `LoadingSpinner`, and `LucideIcon` demos do, so its text lands on the
|
|
242
|
+
text column instead of flush at the example's edge. A panel — a multi-part picker or
|
|
243
|
+
a drop zone such as ColorPicker and FilePicker, or a framed specimen such as
|
|
244
|
+
Web Awesome's Zoomable Frame — owns its geometry and stays flush at `none`, as
|
|
245
|
+
does an edge-to-edge composition (a toolbar, tab bar, or pane). A sized
|
|
246
|
+
`viewport` takes the alignment offset out of its width, so it still ends at the
|
|
247
|
+
example's inline-end edge.
|
|
223
248
|
|
|
224
249
|
```tsx
|
|
225
250
|
import { CatalogExample, CatalogExampleStack } from "@kerfjs/ui/catalog";
|
package/docs/color-picker.md
CHANGED
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
`@kerfjs/ui/color-picker` is a full inline color picker panel:
|
|
4
4
|
|
|
5
5
|
- a saturation and brightness area;
|
|
6
|
-
- a
|
|
7
|
-
|
|
6
|
+
- a slider for each channel of the color model — red, green, and blue (RGB);
|
|
7
|
+
hue, saturation, and lightness (HSL); hue, saturation, and brightness
|
|
8
|
+
(HSB); or one gray level (Grayscale) — each track painting the colors that
|
|
9
|
+
channel produces while the others hold, except the hue track, which always
|
|
10
|
+
shows the full-saturation, full-brightness rainbow so a dark or gray color
|
|
11
|
+
still shows every hue; and, optionally, an opacity slider on a
|
|
12
|
+
checkerboard;
|
|
13
|
+
- a color-model menu (RGB, HSL, HSB, Grayscale) that switches the channel
|
|
14
|
+
sliders and fields together;
|
|
8
15
|
- a hex field (8 digits below full opacity) and an opacity field;
|
|
9
16
|
- a screen sampler where the browser offers the EyeDropper API;
|
|
10
17
|
- optional preset and sample swatches.
|
|
@@ -28,7 +35,8 @@ const stop = wireColorPickers(root, {
|
|
|
28
35
|
- `id` and `label` (required): identity and the picker's accessible name.
|
|
29
36
|
- `value` (required): CSS color text (`#rrggbb[aa]`, `rgb()`, `hsl()`);
|
|
30
37
|
invalid text shows black.
|
|
31
|
-
- `mode`: `rgb` (default), `hsl`, `hsb`, or `gray` — which channel
|
|
38
|
+
- `mode`: `rgb` (default), `hsl`, `hsb`, or `gray` — which channel sliders
|
|
39
|
+
and fields show.
|
|
32
40
|
- `alpha` (default true): the opacity slider and field. Without it the value
|
|
33
41
|
is always opaque.
|
|
34
42
|
- `name`, `form`: a hidden input submits the hex value.
|
|
@@ -49,7 +57,9 @@ picker with a new `value` (or `mode`), the picker adopts it.
|
|
|
49
57
|
|
|
50
58
|
- **The area** takes pointer drags and the arrow keys (Shift for 10% steps);
|
|
51
59
|
Page Up and Down change brightness, Home and End saturation.
|
|
52
|
-
- **
|
|
60
|
+
- **Channel and opacity sliders** are native range inputs (arrow keys, Page
|
|
61
|
+
Up and Down, Home and End). Each changes only its own channel; a slider and
|
|
62
|
+
the field of the same channel always agree.
|
|
53
63
|
- **Fields** commit on Enter or blur; Escape restores the shown value; invalid
|
|
54
64
|
text restores it too.
|
|
55
65
|
- **Swatches** (presets and samples) apply their color.
|
|
@@ -59,13 +69,34 @@ Each change dispatches a bubbling `kui-color-input` (live) or
|
|
|
59
69
|
`onInput` or `onChange`. The value is `#rrggbb`, or `#rrggbbaa` below full
|
|
60
70
|
opacity. The picker keeps hue, saturation, and brightness as its own state,
|
|
61
71
|
so a hue survives while the color is gray, and conversions round-trip without
|
|
62
|
-
drift
|
|
72
|
+
drift: switching models never changes the color, and a channel edit keeps
|
|
73
|
+
every other channel's exact value (an HSL saturation survives lightness
|
|
74
|
+
reaching black or white). The 2D area stays in every model as the primary
|
|
75
|
+
picking surface; the sliders are the precise, per-channel controls.
|
|
63
76
|
|
|
64
77
|
## Accessibility and geometry
|
|
65
78
|
|
|
66
79
|
The picker is a named group. The area is a slider named "Saturation and
|
|
67
|
-
Brightness" whose spoken value gives both
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
Brightness" whose spoken value gives both. Each channel slider is named for
|
|
81
|
+
its channel (Red, Hue, Lightness, Gray Level) and speaks its unit (`210°`,
|
|
82
|
+
`40%`, or a plain 0–255 byte); the opacity slider speaks a percentage. Every
|
|
83
|
+
field is named the same way (Red, Hue, Hex Color, Opacity). The panel takes
|
|
84
|
+
the shared block-content inset, fills its container up to 320px, and spaces
|
|
85
|
+
its rows 12px apart; the sliders form one group 8px apart.
|
|
86
|
+
|
|
87
|
+
The saturation and brightness area and every slider track draw a 1px inner
|
|
88
|
+
edge halfway between the text color and the color under it, so an area or a
|
|
89
|
+
track as dark as a dark surface (the area's black bottom, a hue at low
|
|
90
|
+
brightness, a faint opacity) or as light as a light one keeps a boundary of at
|
|
91
|
+
least 3:1 against the surface around it. Increased contrast draws the edge in
|
|
92
|
+
the full text color and forced colors in `CanvasText`.
|
|
93
|
+
|
|
94
|
+
Every thumb draws a two-tone ring: a white border inside a dark outline. The
|
|
95
|
+
white holds at least 3:1 against a dark color and the outline against a light
|
|
96
|
+
one, so a thumb stays findable wherever it sits.
|
|
97
|
+
|
|
98
|
+
Every track runs in the writing direction, as the native range does: in
|
|
99
|
+
right-to-left text the gradient starts at the right, so the thumb at a
|
|
100
|
+
channel's minimum (or at no opacity) sits over the color it sets.
|
|
70
101
|
|
|
71
102
|
Use `ColorSwatches` for a small fixed palette.
|
|
@@ -65,6 +65,14 @@ diagnostic even when both the wrapper and a rendered root reject that parent.
|
|
|
65
65
|
When one catalog entry exports another JSX component with different placement,
|
|
66
66
|
`jsxExports` gives that export its own parent contract. The extra export does
|
|
67
67
|
not stand for the entry's root when a parent zone is checked.
|
|
68
|
+
An entry whose own geometry an owner already provides in some configuration
|
|
69
|
+
declares `insetFreeChildren`: `{ prop, equals }` conditions under which its
|
|
70
|
+
direct JSX children must bring no content-item inset (`Disclosure` with
|
|
71
|
+
`appearance="embedded"`). A child brings that inset when its
|
|
72
|
+
`layout.geometry` owns its margin, border, and padding (`self` on all three),
|
|
73
|
+
unless one of its own `insetFreeWhen` conditions holds (`Text` with `flush` or
|
|
74
|
+
`variant="span"`). `ui-composition` reports a child that statically brings the
|
|
75
|
+
inset as `KUI-L204` and names the child's inset-free form when it has one.
|
|
68
76
|
Generated `boundaries.rootClass` prefers the public `kui-<entry-id>` class when
|
|
69
77
|
present, so a sibling export's class cannot become the entry's root class.
|
|
70
78
|
|
|
@@ -411,6 +419,30 @@ a `Pane` overlay header, through `wireScrollDividers`, on its own Pane root).
|
|
|
411
419
|
A scroll owner reads it only through its own `scrollClearance` prop, or, for an
|
|
412
420
|
overlay-header Pane's content, through its own `headerPresentation`.
|
|
413
421
|
|
|
422
|
+
The surface context needs no exception either. A component that changes the
|
|
423
|
+
background behind its children publishes, on its own painted element, the
|
|
424
|
+
foundation tokens `--kui-color-surface-current` (the opaque surface beneath:
|
|
425
|
+
a raised `DialogSurface`, popover dialog, `AnchoredSurface`, or `List`
|
|
426
|
+
`surface`, and a sunken Pane's opaque auto chrome, set it and clear both
|
|
427
|
+
layers), `--kui-color-surface-current-region` (a layout region's fill: a sunken
|
|
428
|
+
`Pane`, `Workbench` area, or `TabNavigator` scene, and a `Pane`'s or
|
|
429
|
+
`TabNavigator`'s app `background`), and `--kui-color-surface-current-tint` (a
|
|
430
|
+
content surface's fill: a `SunkenPanel`, a sunken `Disclosure`, a lowered
|
|
431
|
+
`FramedList` and its highlighted row, a quiet, hovered, pressed, or selected
|
|
432
|
+
`ContentItem`, a `TabBar` strip, and translucent glass chrome at rest — a
|
|
433
|
+
`Pane` overlay header, `NavStack` overlay chrome or bottom toolbar, a
|
|
434
|
+
`TabNavigator` overlay bar, and a dialog's floating header; clear chrome
|
|
435
|
+
paints nothing and keeps the inherited context). Interactive rows (`ListItem`,
|
|
436
|
+
`ListActionRow`, `SummaryRow`) are buttons or links themselves, so no control
|
|
437
|
+
nests on their hover or selection fill and they publish nothing. They are undeclared at `:root`
|
|
438
|
+
and a scoped `[data-kui-tint]` resets them. A control that must match what
|
|
439
|
+
lies behind it (the inset focus ring's inner line on `Button` and
|
|
440
|
+
`SplitButton`) layers tint over region over the opaque color, falling back to
|
|
441
|
+
`--kui-color-surface`. Custom properties cannot fold an inherited value into a
|
|
442
|
+
new one, so a content surface inside a sunken region composes exactly while a
|
|
443
|
+
third translucent level keeps only the innermost content tint. An application
|
|
444
|
+
surface that paints its own background sets the same tokens on its own root.
|
|
445
|
+
|
|
414
446
|
Applications and component packages built on the package follow the same
|
|
415
447
|
rules, and the downstream tools enforce them against the composition catalog
|
|
416
448
|
instead of package source: `kerf-ui-analyze` / `kerf-ui-doctor` report a rule
|
|
@@ -609,7 +641,14 @@ preferences remove that entrance animation.
|
|
|
609
641
|
Use `visibility="yield-to-expanded-sibling"` on trailing groups that should
|
|
610
642
|
leave a 480px-or-narrower toolbar while a sibling trailing group is expanded.
|
|
611
643
|
They return when it collapses or the toolbar widens; leading and center zones
|
|
612
|
-
remain visible.
|
|
644
|
+
remain visible. In a `responsive="trailing-priority"` Toolbar, use
|
|
645
|
+
`visibility="yield-to-priority-row"` instead: the group leaves exactly while
|
|
646
|
+
the expanded trailing control has its own row, from the same container query
|
|
647
|
+
as the row at the Toolbar's `responsiveAt` (832px for `narrow`, 704px for
|
|
648
|
+
`compact`, both inclusive). Do not restate that width with `hideBelow`, which
|
|
649
|
+
hides strictly below its threshold: at exactly 704px the row is active while
|
|
650
|
+
`hideBelow={rem(44)}` still shows the group, which then wraps onto a third
|
|
651
|
+
row.
|
|
613
652
|
A group's controls are plain `<button>`s (a standalone `Button` belongs outside a group); a popup menu is a `PopupMenu`, which renders its own
|
|
614
653
|
trigger. By default a group stays on one row: each icon sits beside its label,
|
|
615
654
|
and the enclosing `Toolbar`'s responsive policy relocates whole groups. Set
|
|
@@ -624,14 +663,19 @@ compact segment never becomes an oval. An icon-only `Select` joins a group as
|
|
|
624
663
|
one more segment with its siblings' inset, radius, hover, and focus ring; only a
|
|
625
664
|
lone Select grows the group to its icon-and-caret pill.
|
|
626
665
|
|
|
627
|
-
Select menus use native viewport shifting with 10px gutters: default menus grow to content (up to 20rem), while `fitMenu` matches trigger width and long labels wrap. Keep popup sizing and position repairs out of consumer CSS.
|
|
666
|
+
Select menus use native viewport shifting with 10px gutters: default menus grow to content (up to 20rem), while `fitMenu` matches trigger width and long labels wrap. A listbox (like a PopupMenu menu) shifts only along its trigger's edge, never over the trigger: when neither side fits, it opens on the side with more room and scrolls inside its capped height, so a second press on the trigger still closes it. Keep popup sizing and position repairs out of consumer CSS.
|
|
628
667
|
|
|
629
668
|
For a rail view heading, use `Select presentation="title"`: its intrinsic
|
|
630
669
|
36px borderless trigger has a bold large label flush with its leading edge and
|
|
631
670
|
a caret beside that label. Set `focusRingInset` when a NavStack or panel clips
|
|
632
671
|
outside painting; the Select keeps its focus outline 3px inside the trigger
|
|
633
672
|
and drops it while the listbox is open. Both settings belong to Select, not an
|
|
634
|
-
application `::part()` override.
|
|
673
|
+
application `::part()` override. `Button` and `SplitButton` take the same
|
|
674
|
+
`focusRingInset` for a clipping ancestor: the ring moves inside the box (each
|
|
675
|
+
half's, for a SplitButton) with a line inside it in the color of the surface
|
|
676
|
+
it sits on (the surface context), so it stays visible on a loud fill of its
|
|
677
|
+
own hue without a halo on a sunken or tinted surface. Never re-offset their outline from
|
|
678
|
+
application CSS.
|
|
635
679
|
|
|
636
680
|
Set `menuInset` to configure the menu surface
|
|
637
681
|
without application `::part(menu)` CSS; the default `standard` keeps each menu's
|