@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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Checkbox } from './chunk-C26Q6P4Q.js';
|
|
2
|
+
import { filterDataAttributes } from './chunk-KH4KEMSP.js';
|
|
3
|
+
import { jsxs, jsx } from 'kerfjs/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var CHECKBOX_GROUP_PROTECTED = /* @__PURE__ */ new Set([
|
|
6
|
+
"data-component",
|
|
7
|
+
"data-size",
|
|
8
|
+
"data-orientation",
|
|
9
|
+
"data-invalid"
|
|
10
|
+
]);
|
|
11
|
+
function CheckboxGroup({
|
|
12
|
+
label,
|
|
13
|
+
ariaLabel,
|
|
14
|
+
labelledBy,
|
|
15
|
+
name,
|
|
16
|
+
choices,
|
|
17
|
+
value = [],
|
|
18
|
+
hint,
|
|
19
|
+
error,
|
|
20
|
+
size = "default",
|
|
21
|
+
orientation = "vertical",
|
|
22
|
+
disabled = false,
|
|
23
|
+
action,
|
|
24
|
+
form,
|
|
25
|
+
id,
|
|
26
|
+
className = "",
|
|
27
|
+
rootAttributes = {},
|
|
28
|
+
slot
|
|
29
|
+
}) {
|
|
30
|
+
const description = [hint, error].filter(Boolean).join(" ") || void 0;
|
|
31
|
+
const checked = new Set(value);
|
|
32
|
+
return /* @__PURE__ */ jsxs(
|
|
33
|
+
"fieldset",
|
|
34
|
+
{
|
|
35
|
+
...filterDataAttributes(rootAttributes, CHECKBOX_GROUP_PROTECTED),
|
|
36
|
+
class: `kui-checkbox-group ${className}`.trim(),
|
|
37
|
+
"data-component": "checkbox-group",
|
|
38
|
+
"data-size": size,
|
|
39
|
+
"data-orientation": orientation,
|
|
40
|
+
"data-invalid": error ? "" : void 0,
|
|
41
|
+
id,
|
|
42
|
+
"aria-label": ariaLabel,
|
|
43
|
+
"aria-labelledby": labelledBy,
|
|
44
|
+
"aria-description": description,
|
|
45
|
+
"aria-invalid": error ? "true" : void 0,
|
|
46
|
+
disabled,
|
|
47
|
+
slot,
|
|
48
|
+
children: [
|
|
49
|
+
label === void 0 ? null : /* @__PURE__ */ jsx("legend", { class: "kui-checkbox-group__label", children: label }),
|
|
50
|
+
/* @__PURE__ */ jsx("div", { class: "kui-checkbox-group__choices", children: choices.map((choice) => /* @__PURE__ */ jsx(
|
|
51
|
+
Checkbox,
|
|
52
|
+
{
|
|
53
|
+
label: choice.label,
|
|
54
|
+
name,
|
|
55
|
+
value: choice.value,
|
|
56
|
+
checked: checked.has(choice.value),
|
|
57
|
+
hint: choice.hint,
|
|
58
|
+
size,
|
|
59
|
+
disabled: choice.disabled,
|
|
60
|
+
action,
|
|
61
|
+
form
|
|
62
|
+
}
|
|
63
|
+
)) }),
|
|
64
|
+
hint === void 0 ? null : /* @__PURE__ */ jsx("span", { class: "kui-checkbox-group__hint", "aria-hidden": "true", children: hint }),
|
|
65
|
+
error === void 0 ? null : /* @__PURE__ */ jsx("span", { class: "kui-checkbox-group__error", "aria-hidden": "true", children: error })
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { CheckboxGroup };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=chunk-HU5IHXCI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/forms/checkbox-group/checkbox-group.tsx"],"names":[],"mappings":";;;;AASA,IAAM,wBAAA,uBAA+B,GAAA,CAAI;AAAA,EACvC,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AA8DM,SAAS,aAAA,CAAoC;AAAA,EAClD,KAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAQ,EAAC;AAAA,EACT,IAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,WAAA,GAAc,UAAA;AAAA,EACd,QAAA,GAAW,KAAA;AAAA,EACX,MAAA;AAAA,EACA,IAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,iBAAiB,EAAC;AAAA,EAClB;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,WAAA,GAAc,CAAC,IAAA,EAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,IAAK,MAAA;AAC/D,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAY,KAAK,CAAA;AACrC,EAAA,uBACE,IAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACE,GAAG,oBAAA,CAAqB,cAAA,EAAgB,wBAAwB,CAAA;AAAA,MACjE,KAAA,EAAO,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC9C,gBAAA,EAAe,gBAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,kBAAA,EAAkB,WAAA;AAAA,MAClB,cAAA,EAAc,QAAQ,EAAA,GAAK,MAAA;AAAA,MAC3B,EAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,kBAAA,EAAkB,WAAA;AAAA,MAClB,cAAA,EAAc,QAAQ,MAAA,GAAS,MAAA;AAAA,MAC/B,QAAA;AAAA,MACA,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,KAAA,KAAU,SAAY,IAAA,mBACrB,GAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,6BAA6B,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,4BAElD,KAAA,EAAA,EAAI,KAAA,EAAM,+BACR,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,qBACZ,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,IAAA;AAAA,YACA,OAAO,MAAA,CAAO,KAAA;AAAA,YACd,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA;AAAA,YACjC,MAAM,MAAA,CAAO,IAAA;AAAA,YACb,IAAA;AAAA,YACA,UAAU,MAAA,CAAO,QAAA;AAAA,YACjB,MAAA;AAAA,YACA;AAAA;AAAA,SAEH,CAAA,EACH,CAAA;AAAA,QACC,IAAA,KAAS,SAAY,IAAA,mBACpB,GAAA,CAAC,UAAK,KAAA,EAAM,0BAAA,EAA2B,aAAA,EAAY,MAAA,EAChD,QAAA,EAAA,IAAA,EACH,CAAA;AAAA,QAED,KAAA,KAAU,SAAY,IAAA,mBACrB,GAAA,CAAC,UAAK,KAAA,EAAM,2BAAA,EAA4B,aAAA,EAAY,MAAA,EACjD,QAAA,EAAA,KAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-HU5IHXCI.js","sourcesContent":["import { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport { Checkbox } from '../checkbox/checkbox.js';\n\n/** `default` is a 20px box beside 16px text; `compact` 18px and 14px. */\nexport type CheckboxGroupSize = 'default' | 'compact';\n\n/** `vertical` stacks the choices; `horizontal` lines them up and wraps. */\nexport type CheckboxGroupOrientation = 'vertical' | 'horizontal';\n\nconst CHECKBOX_GROUP_PROTECTED = new Set([\n 'data-component',\n 'data-size',\n 'data-orientation',\n 'data-invalid',\n]);\n\n/** Application `data-*` metadata; the CheckboxGroup's own markers stay protected. */\nexport type CheckboxGroupRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined>\n>;\n\nexport interface CheckboxGroupChoice<Value extends string = string> {\n value: Value;\n /** Visible label; it is also the checkbox's accessible name. */\n label: string;\n /** Supporting text under this choice's label, also its description. */\n hint?: string;\n disabled?: boolean;\n}\n\n/**\n * A group is named by a visible `label` (its legend), by `ariaLabel`, or by\n * `labelledBy`, the id of a visible heading elsewhere that names it.\n */\nexport type CheckboxGroupName =\n | { label: string; ariaLabel?: never; labelledBy?: never }\n | { label?: never; ariaLabel: string; labelledBy?: never }\n | { label?: never; ariaLabel?: never; labelledBy: string };\n\nexport interface CheckboxGroupOptions<Value extends string = string> {\n /** Native input `name`: the form field every checked value submits under. */\n name: string;\n choices: readonly CheckboxGroupChoice<Value>[];\n /** The checked values. Omit for none. */\n value?: readonly NoInfer<Value>[];\n /** Supporting text below the choices, also the group's description. */\n hint?: string;\n /** A validation message: shown in the danger color and marking it invalid. */\n error?: string;\n size?: CheckboxGroupSize;\n orientation?: CheckboxGroupOrientation;\n /** Disable the whole group. */\n disabled?: boolean;\n /** Delegated `data-action` on every checkbox; listen for `change`. */\n action?: string;\n /** Associate the checkboxes with a form outside their ancestor chain. */\n form?: string;\n /** The fieldset's id. */\n id?: string;\n className?: string;\n /** Safe `data-*` metadata (a `data-key`). */\n rootAttributes?: CheckboxGroupRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport type CheckboxGroupProps<Value extends string = string> =\n CheckboxGroupName & CheckboxGroupOptions<Value>;\n\n/**\n * Any number of related options among a few visible choices: a native\n * fieldset of `Checkbox`es with the group label above and hint and error text\n * below, laid out like a `RadioGroup` so stacked checkboxes and radios share\n * one control column and one 28px pitch. Every checked value submits under\n * `name`.\n */\nexport function CheckboxGroup<Value extends string>({\n label,\n ariaLabel,\n labelledBy,\n name,\n choices,\n value = [],\n hint,\n error,\n size = 'default',\n orientation = 'vertical',\n disabled = false,\n action,\n form,\n id,\n className = '',\n rootAttributes = {},\n slot,\n}: CheckboxGroupProps<Value>) {\n const description = [hint, error].filter(Boolean).join(' ') || undefined;\n const checked = new Set<string>(value);\n return (\n <fieldset\n {...filterDataAttributes(rootAttributes, CHECKBOX_GROUP_PROTECTED)}\n class={`kui-checkbox-group ${className}`.trim()}\n data-component=\"checkbox-group\"\n data-size={size}\n data-orientation={orientation}\n data-invalid={error ? '' : undefined}\n id={id}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n aria-description={description}\n aria-invalid={error ? 'true' : undefined}\n disabled={disabled}\n slot={slot}\n >\n {label === undefined ? null : (\n <legend class=\"kui-checkbox-group__label\">{label}</legend>\n )}\n <div class=\"kui-checkbox-group__choices\">\n {choices.map((choice) => (\n <Checkbox\n label={choice.label}\n name={name}\n value={choice.value}\n checked={checked.has(choice.value)}\n hint={choice.hint}\n size={size}\n disabled={choice.disabled}\n action={action}\n form={form}\n />\n ))}\n </div>\n {hint === undefined ? null : (\n <span class=\"kui-checkbox-group__hint\" aria-hidden=\"true\">\n {hint}\n </span>\n )}\n {error === undefined ? null : (\n <span class=\"kui-checkbox-group__error\" aria-hidden=\"true\">\n {error}\n </span>\n )}\n </fieldset>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PopupMenu } from './chunk-
|
|
1
|
+
import { PopupMenu } from './chunk-OQP3PFKQ.js';
|
|
2
2
|
import { listIconTilePresentation, withWordBreaks, nativeDraggable } from './chunk-ZNROKDSZ.js';
|
|
3
3
|
import { Skeleton } from './chunk-CVD5IZGB.js';
|
|
4
4
|
import { LoadingSpinner } from './chunk-WVS6CUCT.js';
|
|
@@ -173,4 +173,4 @@ function ListActionRow({
|
|
|
173
173
|
|
|
174
174
|
export { ListActionRow };
|
|
175
175
|
|
|
176
|
-
//# sourceMappingURL=chunk-
|
|
176
|
+
//# sourceMappingURL=chunk-JCCN3U6X.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/collections/list-action-row/list-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-DF2YKGIX.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport {\n type ListIconTile,\n listIconTilePresentation,\n} from '../../../shared/content/list-icon-tile.js';\nimport { nativeDraggable } from '../../../shared/dom/draggable.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport { em, remify } from '../../../shared/styles/css-values.js';\nimport { withWordBreaks } from '../../../shared/text/word-breaks.js';\nimport {\n PopupMenu,\n type PopupMenuEntry,\n type PopupMenuPlacement,\n} from '../../actions/popup-menu/popup-menu.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\nimport { Skeleton } from '../../feedback/skeleton/skeleton.js';\n\nexport type {\n ListIconTile,\n ListIconTileColor,\n ListIconTileTone,\n} from '../../../shared/content/list-icon-tile.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-icon-tile',\n 'data-icon-tile-tone',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-trailing-visibility',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n 'data-dragging',\n 'data-drop-position',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-kui-disabled',\n]);\n\ntype ListActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-icon-tile'?: never;\n 'data-icon-tile-tone'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-trailing-visibility'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n 'data-dragging'?: never;\n 'data-drop-position'?: never;\n }\n>;\n\ntype ListActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\n/** A trailing overflow `PopupMenu` rendered as the row's sibling trailing control. */\nexport interface ListActionRowTrailingMenu {\n /** Accessible name of the icon-only menu trigger, such as `Actions for report.json`. */\n label: string;\n /** Decorative trigger icon, typically a `MoreHorizontal` `LucideIcon`. */\n icon: SafeHtml;\n /** The menu's commands, headings, and dividers; items dispatch their own `data-action`s. */\n items: readonly PopupMenuEntry[];\n /** Where the menu opens relative to its trigger. Defaults to `bottom-end`. */\n placement?: PopupMenuPlacement;\n disabled?: boolean;\n}\n\ninterface ListActionRowTrailingButtonProps {\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n trailingActionAttributes?: ListActionRowTrailingAttributes;\n trailingMenu?: never;\n}\n\ninterface ListActionRowTrailingMenuProps {\n /** A trailing overflow menu in place of the trailing button. Import `@kerfjs/ui/popup-menu/register` once. */\n trailingMenu: ListActionRowTrailingMenu;\n trailingAction?: never;\n trailingActionLabel?: never;\n trailingActionIcon?: never;\n trailingActionDisabled?: never;\n trailingActionTitle?: never;\n trailingActionAttributes?: never;\n}\n\ninterface ListActionRowCommonProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n description?: string | SafeHtml;\n status?: string | SafeHtml;\n busy?: boolean;\n /** Row height: `standard` is 44px; `compact` is 36px (42px with `iconTile`), the height of a compact `ListItem`. */\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */\n iconTile?: ListIconTile;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions: label, description, icon, and status text become skeletons; the `busy` indicator stays live. */\n placeholder?: boolean;\n /** Native HTML drag source (`draggable=\"true\"` on the row root); a placeholder is never draggable. Pair with `wireListReorder` for pointer and keyboard reordering. */\n draggable?: boolean;\n /** Dim this row as one of the rows being dragged. */\n dragging?: boolean;\n /** Draw the insertion line at this row's leading (`before`) or trailing (`after`) block edge. */\n dropPosition?: 'before' | 'after';\n trailingActionVisibility?: 'always' | 'interaction';\n className?: string;\n rootAttributes?: ListActionRowRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** Exactly one trailing control: a native button (`trailingAction*`) or an overflow menu (`trailingMenu`). */\nexport type ListActionRowProps = ListActionRowCommonProps &\n (ListActionRowTrailingButtonProps | ListActionRowTrailingMenuProps);\n\nexport function ListActionRow({\n label,\n description,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n icon,\n iconTile,\n action,\n itemId,\n selected = false,\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n draggable,\n dragging = false,\n dropPosition,\n trailingAction,\n trailingActionLabel,\n trailingActionIcon,\n trailingActionDisabled = false,\n trailingActionTitle,\n trailingActionVisibility = 'always',\n trailingMenu,\n className = '',\n rootAttributes = {},\n trailingActionAttributes = {},\n slot,\n}: ListActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTrailingAttributes = filterControlAttributes(\n trailingActionAttributes,\n PROTECTED_TRAILING_DATA_ATTRIBUTES,\n );\n const tile = icon\n ? listIconTilePresentation(iconTile, 'list-action-row')\n : null;\n const iconSize = tile?.tile ? 32 : 18;\n\n return (\n <div\n {...extensionRootAttributes}\n class={`kui-list-action-row ${className}`.trim()}\n data-component=\"list-action-row\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-icon-tile={tile?.tile}\n data-icon-tile-tone={tile?.tone}\n data-multiline={multiline ? 'true' : undefined}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-trailing-visibility={trailingActionVisibility}\n data-state={state}\n data-selected={String(selected)}\n data-pressed={pressed === undefined ? undefined : String(pressed)}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={nativeDraggable(draggable, placeholder)}\n data-dragging={dragging ? 'true' : undefined}\n data-drop-position={dropPosition}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n <button\n type=\"button\"\n class=\"kui-list-action-row__primary\"\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {icon && (\n <span\n class=\"kui-list-action-row__icon\"\n style={placeholder ? undefined : tile?.style}\n >\n {placeholder ? (\n <Skeleton\n block\n width={remify(iconSize)}\n height={remify(iconSize)}\n />\n ) : (\n icon\n )}\n </span>\n )}\n <span class=\"kui-list-action-row__label\">\n <span class=\"kui-list-action-row__primary-label\">\n {placeholder ? (\n <Skeleton width={em(9)} />\n ) : multiline ? (\n withWordBreaks(label)\n ) : (\n label\n )}\n </span>\n {description && (\n <span class=\"kui-list-action-row__description\">\n {placeholder ? <Skeleton width={em(11)} /> : description}\n </span>\n )}\n {(busy || status) && (\n <span class=\"kui-list-action-row__status\">\n {/* The busy spinner is component-owned chrome drawn from a\n known prop, so a placeholder keeps it live; only the status\n text is a value and becomes a skeleton. */}\n {busy && <LoadingSpinner />}\n {status && (placeholder ? <Skeleton width={em(6)} /> : status)}\n </span>\n )}\n </span>\n </button>\n {trailingMenu ? (\n <PopupMenu\n label={trailingMenu.label}\n icon={trailingMenu.icon}\n items={trailingMenu.items}\n placement={trailingMenu.placement ?? 'bottom-end'}\n caret={false}\n disabled={Boolean(trailingMenu.disabled) || placeholder}\n />\n ) : (\n <button\n {...extensionTrailingAttributes}\n type=\"button\"\n class=\"kui-list-action-row__trailing-action\"\n data-action={placeholder ? undefined : trailingAction}\n data-item-id={itemId}\n aria-label={trailingActionLabel}\n title={trailingActionTitle ?? trailingActionLabel}\n disabled={trailingActionDisabled || placeholder || undefined}\n data-kui-disabled={trailingActionDisabled ? 'true' : undefined}\n >\n {trailingActionIcon}\n </button>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/collections/list-action-row/list-action-row.tsx"],"names":[],"mappings":"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","file":"chunk-JCCN3U6X.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport {\n type ListIconTile,\n listIconTilePresentation,\n} from '../../../shared/content/list-icon-tile.js';\nimport { nativeDraggable } from '../../../shared/dom/draggable.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport { em, remify } from '../../../shared/styles/css-values.js';\nimport { withWordBreaks } from '../../../shared/text/word-breaks.js';\nimport {\n PopupMenu,\n type PopupMenuEntry,\n type PopupMenuPlacement,\n} from '../../actions/popup-menu/popup-menu.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\nimport { Skeleton } from '../../feedback/skeleton/skeleton.js';\n\nexport type {\n ListIconTile,\n ListIconTileColor,\n ListIconTileTone,\n} from '../../../shared/content/list-icon-tile.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-has-icon',\n 'data-icon-tile',\n 'data-icon-tile-tone',\n 'data-multiline',\n 'data-density',\n 'data-divider',\n 'data-busy',\n 'data-trailing-visibility',\n 'data-state',\n 'data-selected',\n 'data-pressed',\n 'data-dragging',\n 'data-drop-position',\n]);\nconst PROTECTED_TRAILING_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-item-id',\n 'data-kui-disabled',\n]);\n\ntype ListActionRowRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-has-icon'?: never;\n 'data-icon-tile'?: never;\n 'data-icon-tile-tone'?: never;\n 'data-multiline'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-busy'?: never;\n 'data-trailing-visibility'?: never;\n 'data-state'?: never;\n 'data-selected'?: never;\n 'data-pressed'?: never;\n 'data-dragging'?: never;\n 'data-drop-position'?: never;\n }\n>;\n\ntype ListActionRowTrailingAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\n/** A trailing overflow `PopupMenu` rendered as the row's sibling trailing control. */\nexport interface ListActionRowTrailingMenu {\n /** Accessible name of the icon-only menu trigger, such as `Actions for report.json`. */\n label: string;\n /** Decorative trigger icon, typically a `MoreHorizontal` `LucideIcon`. */\n icon: SafeHtml;\n /** The menu's commands, headings, and dividers; items dispatch their own `data-action`s. */\n items: readonly PopupMenuEntry[];\n /** Where the menu opens relative to its trigger. Defaults to `bottom-end`. */\n placement?: PopupMenuPlacement;\n disabled?: boolean;\n}\n\ninterface ListActionRowTrailingButtonProps {\n trailingAction: string;\n trailingActionLabel: string;\n /** Decorative dormant content for the trailing button. Must not contain interactive descendants. */\n trailingActionIcon: SafeHtml;\n trailingActionDisabled?: boolean;\n trailingActionTitle?: string;\n trailingActionAttributes?: ListActionRowTrailingAttributes;\n trailingMenu?: never;\n}\n\ninterface ListActionRowTrailingMenuProps {\n /** A trailing overflow menu in place of the trailing button. Import `@kerfjs/ui/popup-menu/register` once. */\n trailingMenu: ListActionRowTrailingMenu;\n trailingAction?: never;\n trailingActionLabel?: never;\n trailingActionIcon?: never;\n trailingActionDisabled?: never;\n trailingActionTitle?: never;\n trailingActionAttributes?: never;\n}\n\ninterface ListActionRowCommonProps {\n /** Visible dormant content for the primary button. Must not contain interactive descendants. */\n label: string | SafeHtml;\n description?: string | SafeHtml;\n status?: string | SafeHtml;\n busy?: boolean;\n /** Row height: `standard` is 44px; `compact` is 36px (42px with `iconTile`), the height of a compact `ListItem`. */\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Decorative dormant content for the primary button. Must not contain interactive descendants. */\n icon?: SafeHtml;\n /** Present `icon` in a filled 32px rounded tile with an 18px glyph: a quiet tone preset, or `{ color, foreground? }` for an application color. */\n iconTile?: ListIconTile;\n action: string;\n itemId?: string;\n selected?: boolean;\n pressed?: boolean;\n accessibleLabel?: string;\n title?: string;\n multiline?: boolean;\n state?: string;\n disabled?: boolean;\n tabIndex?: number;\n /** Render as an unanimated loading skeleton, disabling both actions: label, description, icon, and status text become skeletons; the `busy` indicator stays live. */\n placeholder?: boolean;\n /** Native HTML drag source (`draggable=\"true\"` on the row root); a placeholder is never draggable. Pair with `wireListReorder` for pointer and keyboard reordering. */\n draggable?: boolean;\n /** Dim this row as one of the rows being dragged. */\n dragging?: boolean;\n /** Draw the insertion line at this row's leading (`before`) or trailing (`after`) block edge. */\n dropPosition?: 'before' | 'after';\n trailingActionVisibility?: 'always' | 'interaction';\n className?: string;\n rootAttributes?: ListActionRowRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** Exactly one trailing control: a native button (`trailingAction*`) or an overflow menu (`trailingMenu`). */\nexport type ListActionRowProps = ListActionRowCommonProps &\n (ListActionRowTrailingButtonProps | ListActionRowTrailingMenuProps);\n\nexport function ListActionRow({\n label,\n description,\n status,\n busy = false,\n density = 'standard',\n divider = 'none',\n icon,\n iconTile,\n action,\n itemId,\n selected = false,\n pressed,\n accessibleLabel,\n title,\n multiline = false,\n state,\n disabled = false,\n tabIndex,\n placeholder = false,\n draggable,\n dragging = false,\n dropPosition,\n trailingAction,\n trailingActionLabel,\n trailingActionIcon,\n trailingActionDisabled = false,\n trailingActionTitle,\n trailingActionVisibility = 'always',\n trailingMenu,\n className = '',\n rootAttributes = {},\n trailingActionAttributes = {},\n slot,\n}: ListActionRowProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTrailingAttributes = filterControlAttributes(\n trailingActionAttributes,\n PROTECTED_TRAILING_DATA_ATTRIBUTES,\n );\n const tile = icon\n ? listIconTilePresentation(iconTile, 'list-action-row')\n : null;\n const iconSize = tile?.tile ? 32 : 18;\n\n return (\n <div\n {...extensionRootAttributes}\n class={`kui-list-action-row ${className}`.trim()}\n data-component=\"list-action-row\"\n data-item-id={itemId}\n data-has-icon={String(Boolean(icon))}\n data-icon-tile={tile?.tile}\n data-icon-tile-tone={tile?.tone}\n data-multiline={multiline ? 'true' : undefined}\n data-density={density}\n data-divider={divider}\n data-busy={busy ? 'true' : undefined}\n data-trailing-visibility={trailingActionVisibility}\n data-state={state}\n data-selected={String(selected)}\n data-pressed={pressed === undefined ? undefined : String(pressed)}\n data-placeholder={placeholder ? 'true' : undefined}\n draggable={nativeDraggable(draggable, placeholder)}\n data-dragging={dragging ? 'true' : undefined}\n data-drop-position={dropPosition}\n aria-busy={placeholder || busy ? 'true' : undefined}\n slot={slot}\n >\n <button\n type=\"button\"\n class=\"kui-list-action-row__primary\"\n title={placeholder ? undefined : title}\n disabled={disabled || placeholder}\n tabindex={placeholder ? -1 : tabIndex}\n data-kui-disabled={disabled ? 'true' : undefined}\n data-action={placeholder ? undefined : action}\n data-item-id={itemId}\n aria-label={accessibleLabel}\n aria-current={selected ? 'page' : undefined}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {icon && (\n <span\n class=\"kui-list-action-row__icon\"\n style={placeholder ? undefined : tile?.style}\n >\n {placeholder ? (\n <Skeleton\n block\n width={remify(iconSize)}\n height={remify(iconSize)}\n />\n ) : (\n icon\n )}\n </span>\n )}\n <span class=\"kui-list-action-row__label\">\n <span class=\"kui-list-action-row__primary-label\">\n {placeholder ? (\n <Skeleton width={em(9)} />\n ) : multiline ? (\n withWordBreaks(label)\n ) : (\n label\n )}\n </span>\n {description && (\n <span class=\"kui-list-action-row__description\">\n {placeholder ? <Skeleton width={em(11)} /> : description}\n </span>\n )}\n {(busy || status) && (\n <span class=\"kui-list-action-row__status\">\n {/* The busy spinner is component-owned chrome drawn from a\n known prop, so a placeholder keeps it live; only the status\n text is a value and becomes a skeleton. */}\n {busy && <LoadingSpinner />}\n {status && (placeholder ? <Skeleton width={em(6)} /> : status)}\n </span>\n )}\n </span>\n </button>\n {trailingMenu ? (\n <PopupMenu\n label={trailingMenu.label}\n icon={trailingMenu.icon}\n items={trailingMenu.items}\n placement={trailingMenu.placement ?? 'bottom-end'}\n caret={false}\n disabled={Boolean(trailingMenu.disabled) || placeholder}\n />\n ) : (\n <button\n {...extensionTrailingAttributes}\n type=\"button\"\n class=\"kui-list-action-row__trailing-action\"\n data-action={placeholder ? undefined : trailingAction}\n data-item-id={itemId}\n aria-label={trailingActionLabel}\n title={trailingActionTitle ?? trailingActionLabel}\n disabled={trailingActionDisabled || placeholder || undefined}\n data-kui-disabled={trailingActionDisabled ? 'true' : undefined}\n >\n {trailingActionIcon}\n </button>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -11,7 +11,9 @@ var BUTTON_PROTECTED = /* @__PURE__ */ new Set([
|
|
|
11
11
|
"data-size",
|
|
12
12
|
"data-loading",
|
|
13
13
|
"data-icon-only",
|
|
14
|
-
"data-shape"
|
|
14
|
+
"data-shape",
|
|
15
|
+
"data-fill",
|
|
16
|
+
"data-focus-ring-inset"
|
|
15
17
|
]);
|
|
16
18
|
function Button({
|
|
17
19
|
children,
|
|
@@ -19,6 +21,7 @@ function Button({
|
|
|
19
21
|
emphasis = "primary",
|
|
20
22
|
size = "default",
|
|
21
23
|
shape = "rounded",
|
|
24
|
+
fill = false,
|
|
22
25
|
pressed,
|
|
23
26
|
icon,
|
|
24
27
|
loading = false,
|
|
@@ -30,6 +33,7 @@ function Button({
|
|
|
30
33
|
href,
|
|
31
34
|
target,
|
|
32
35
|
action,
|
|
36
|
+
focusRingInset = false,
|
|
33
37
|
badge,
|
|
34
38
|
badgeLabel,
|
|
35
39
|
badgeTone = "danger",
|
|
@@ -51,6 +55,8 @@ function Button({
|
|
|
51
55
|
"data-loading": loading ? "" : void 0,
|
|
52
56
|
"data-icon-only": children === void 0 ? "" : void 0,
|
|
53
57
|
"data-shape": shape === "pill" ? "pill" : void 0,
|
|
58
|
+
"data-fill": fill ? "true" : void 0,
|
|
59
|
+
"data-focus-ring-inset": focusRingInset ? "true" : void 0,
|
|
54
60
|
"data-action": action,
|
|
55
61
|
"aria-label": ariaLabel && badge !== void 0 && badgeLabel ? `${ariaLabel}, ${badgeLabel}` : ariaLabel,
|
|
56
62
|
title,
|
|
@@ -113,4 +119,4 @@ function Button({
|
|
|
113
119
|
|
|
114
120
|
export { Button };
|
|
115
121
|
|
|
116
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-KPINJHIC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/actions/button/button.tsx"],"names":[],"mappings":"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","file":"chunk-KPINJHIC.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport { Badge, type BadgeTone } from '../../feedback/badge/badge.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\n\n/** The color family: `neutral` (default), `brand` for the main action, `success` for a positive one, `danger` for a destructive one. */\nexport type ButtonTone = 'neutral' | 'brand' | 'success' | 'danger';\n\n/**\n * How loudly it asks: `primary` (default) fills the button, `secondary`\n * outlines it, and `plain` shows only its text until hovered.\n */\nexport type ButtonEmphasis = 'primary' | 'secondary' | 'plain';\n\n/** `default` is the 44px control height; `compact` is 33px with smaller text. */\nexport type ButtonSize = 'default' | 'compact';\n\n/** Corner shape: the shared `rounded` control radius (default) or a full `pill`. */\nexport type ButtonShape = 'rounded' | 'pill';\n/** What a form button does: `button` (default), `submit`, or `reset`. */\nexport type ButtonType = 'button' | 'submit' | 'reset';\n\nconst BUTTON_PROTECTED = new Set([\n 'data-component',\n 'data-action',\n 'data-tone',\n 'data-emphasis',\n 'data-size',\n 'data-loading',\n 'data-icon-only',\n 'data-shape',\n 'data-fill',\n 'data-focus-ring-inset',\n]);\n\n/** Application `data-*` metadata; the Button's own markers stay protected. */\nexport type ButtonRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined>\n>;\n\n/** A Button's visible label: text or rendered content, never empty. */\nexport type ButtonLabel =\n string | Exclude<KerfUiContent, null | undefined | boolean>;\n\n/**\n * A labeled button (its label names it; `ariaLabel` only when the label is\n * not enough), or an icon-only square named by `ariaLabel`.\n */\nexport type ButtonContent =\n | {\n /** The label. */\n children: ButtonLabel;\n /** A leading icon, such as a `LucideIcon`; it is decorative. */\n icon?: KerfUiContent;\n ariaLabel?: string;\n }\n | {\n children?: undefined;\n /** The icon of an icon-only square button. */\n icon: KerfUiContent;\n /** The accessible name an icon-only button needs. */\n ariaLabel: string;\n };\n\nexport type ButtonProps = ButtonContent & ButtonOptions;\n\nexport interface ButtonOptions {\n tone?: ButtonTone;\n emphasis?: ButtonEmphasis;\n size?: ButtonSize;\n /** Corner shape (default `rounded`). */\n shape?: ButtonShape;\n /**\n * Span the full width of the parent instead of sizing to the label, as on\n * `SplitButton`. The label stays centered and ellipsizes when it no longer\n * fits.\n */\n fill?: boolean;\n /**\n * Make it a toggle: `aria-pressed` reports the state, and a pressed look is\n * drawn on top of the tone and emphasis. The application owns the state and\n * flips it in its `action` handler. A link (`href`) cannot be a toggle.\n */\n pressed?: boolean;\n /**\n * Busy: a spinner replaces the label (which still names it) and the button\n * reports `aria-busy`. Presses still reach it; the application decides\n * what a press does while it is busy.\n */\n loading?: boolean;\n disabled?: boolean;\n /** A form button's behavior (default `button`, which never submits). */\n type?: ButtonType;\n name?: string;\n value?: string;\n /** The id of the form it belongs to, when it sits outside that form. */\n form?: string;\n /** Render a link with button styling instead of a `<button>`. */\n href?: string;\n /** Where a link opens. */\n target?: '_self' | '_blank' | '_parent' | '_top';\n /** Delegated `data-action` the application handles. */\n action?: string;\n /**\n * Keep the button's focus ring inside its box when an ancestor clips\n * overflow. The inset ring is two-tone, a surface-colored line inside the\n * ring color, so it stays visible on a loud fill of the ring's own hue.\n */\n focusRingInset?: boolean;\n /**\n * A count, short text, or `true` for a text-free dot over the button's\n * top-trailing corner, such as how many items a filter hides. It stays out\n * of the accessible name unless `badgeLabel` names it.\n */\n badge?: number | string | true;\n /** Words for the badge (\"3 hidden\"), added to the button's name. */\n badgeLabel?: string;\n /** The badge's tone (default `danger`). */\n badgeTone?: BadgeTone;\n /**\n * Native hover text that says more than the name, such as \"More Actions\n * for report.pdf\". An icon-only Button already gets a help tag with its\n * `ariaLabel` (with `@kerfjs/ui/help-tags-register`); a `title` replaces\n * that tag.\n */\n title?: string;\n id?: string;\n className?: string;\n /** Safe `data-*` metadata (a `data-key`, `data-dialog-close`). */\n rootAttributes?: ButtonRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standalone action button: a native `<button>` (or a link with `href`)\n * in one of four tones and three emphases, at the 44px control height or\n * compact, with a label or as an icon-only square, rounded or pill-shaped,\n * sized to its label or filling its parent's width, and optionally a\n * `pressed` toggle. Inside a\n * `ToolbarControlGroup`, use a plain `<button>`, which the group styles; use\n * Button for a dialog footer, a form, or a standalone action beside other\n * content.\n */\nexport function Button({\n children,\n tone = 'neutral',\n emphasis = 'primary',\n size = 'default',\n shape = 'rounded',\n fill = false,\n pressed,\n icon,\n loading = false,\n disabled = false,\n type = 'button',\n name,\n value,\n form,\n href,\n target,\n action,\n focusRingInset = false,\n badge,\n badgeLabel,\n badgeTone = 'danger',\n ariaLabel,\n title,\n id,\n className = '',\n rootAttributes = {},\n slot,\n}: ButtonProps) {\n const shared = {\n ...filterDataAttributes(rootAttributes, BUTTON_PROTECTED),\n id,\n class: `kui-button ${className}`.trim(),\n 'data-component': 'button',\n 'data-tone': tone,\n 'data-emphasis': emphasis,\n 'data-size': size,\n 'data-loading': loading ? '' : undefined,\n 'data-icon-only': children === undefined ? '' : undefined,\n 'data-shape': shape === 'pill' ? 'pill' : undefined,\n 'data-fill': fill ? 'true' : undefined,\n 'data-focus-ring-inset': focusRingInset ? 'true' : undefined,\n 'data-action': action,\n 'aria-label':\n ariaLabel && badge !== undefined && badgeLabel\n ? `${ariaLabel}, ${badgeLabel}`\n : ariaLabel,\n title,\n 'aria-busy': loading ? 'true' : undefined,\n slot,\n };\n const content = (\n <>\n {icon === undefined ? null : (\n <span class=\"kui-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {children === undefined ? null : (\n <span class=\"kui-button__label\">{children}</span>\n )}\n {badge === undefined || badge === '' ? null : badge === true ? (\n <Badge\n tone={badgeTone}\n size=\"dot\"\n placement=\"corner\"\n {...(ariaLabel || !badgeLabel\n ? { ariaHidden: true as const }\n : { label: badgeLabel })}\n />\n ) : (\n <Badge\n tone={badgeTone}\n appearance=\"solid\"\n size=\"compact\"\n placement=\"corner\"\n {...(ariaLabel || !badgeLabel\n ? { ariaHidden: true as const }\n : { label: badgeLabel })}\n >\n {String(badge)}\n </Badge>\n )}\n {loading ? (\n <span class=\"kui-button__spinner\" aria-hidden=\"true\">\n <LoadingSpinner />\n </span>\n ) : null}\n </>\n );\n // A disabled link has no destination and is announced as disabled.\n if (href !== undefined) {\n if (pressed !== undefined)\n throw new TypeError('A link Button cannot be a toggle (pressed).');\n return (\n <a\n {...shared}\n href={disabled ? undefined : href}\n target={disabled ? undefined : target}\n role={disabled ? 'link' : undefined}\n aria-disabled={disabled ? 'true' : undefined}\n >\n {content}\n </a>\n );\n }\n return (\n <button\n {...shared}\n type={type}\n name={name}\n value={value}\n form={form}\n disabled={disabled}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {content}\n </button>\n );\n}\n"]}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
import { filterDataAttributes } from './chunk-KH4KEMSP.js';
|
|
1
2
|
import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
var chipProtectedAttributes = /* @__PURE__ */ new Set([
|
|
5
|
+
"data-component",
|
|
6
|
+
"data-tone",
|
|
7
|
+
"data-appearance",
|
|
8
|
+
"data-shape",
|
|
9
|
+
"data-size",
|
|
10
|
+
"data-disabled",
|
|
11
|
+
"data-truncate",
|
|
12
|
+
"data-item-id",
|
|
13
|
+
"data-link",
|
|
14
|
+
"data-action"
|
|
15
|
+
]);
|
|
4
16
|
function removeButton(action, label, disabled) {
|
|
5
17
|
return /* @__PURE__ */ jsx(
|
|
6
18
|
"button",
|
|
@@ -44,6 +56,7 @@ function Chip({
|
|
|
44
56
|
size = "default",
|
|
45
57
|
disabled = false,
|
|
46
58
|
itemId,
|
|
59
|
+
rootAttributes = {},
|
|
47
60
|
className = "",
|
|
48
61
|
slot,
|
|
49
62
|
href,
|
|
@@ -72,11 +85,16 @@ function Chip({
|
|
|
72
85
|
)
|
|
73
86
|
] });
|
|
74
87
|
const rootClass = `kui-chip ${className}`.trim();
|
|
88
|
+
const identity = filterDataAttributes(
|
|
89
|
+
rootAttributes,
|
|
90
|
+
chipProtectedAttributes
|
|
91
|
+
);
|
|
75
92
|
if (href !== void 0) {
|
|
76
93
|
const textLabel = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
|
|
77
94
|
return /* @__PURE__ */ jsx(
|
|
78
95
|
"a",
|
|
79
96
|
{
|
|
97
|
+
...identity,
|
|
80
98
|
class: rootClass,
|
|
81
99
|
href: disabled ? void 0 : href,
|
|
82
100
|
download: disabled ? void 0 : downloadValue(download),
|
|
@@ -103,6 +121,7 @@ function Chip({
|
|
|
103
121
|
return /* @__PURE__ */ jsx(
|
|
104
122
|
"button",
|
|
105
123
|
{
|
|
124
|
+
...identity,
|
|
106
125
|
class: rootClass,
|
|
107
126
|
type: "button",
|
|
108
127
|
disabled,
|
|
@@ -124,6 +143,7 @@ function Chip({
|
|
|
124
143
|
return /* @__PURE__ */ jsxs(
|
|
125
144
|
"span",
|
|
126
145
|
{
|
|
146
|
+
...identity,
|
|
127
147
|
class: rootClass,
|
|
128
148
|
"data-component": "chip",
|
|
129
149
|
"data-tone": tone,
|
|
@@ -144,4 +164,4 @@ function Chip({
|
|
|
144
164
|
|
|
145
165
|
export { Chip };
|
|
146
166
|
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
167
|
+
//# sourceMappingURL=chunk-LMHN2TJL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/feedback/chip/chip.tsx"],"names":[],"mappings":"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","file":"chunk-LMHN2TJL.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport type { SemanticTone } from '../../../shared/styles/semantic-tone.js';\nimport type { BadgeAppearance, BadgeShape, BadgeSize } from '../badge/badge.js';\n\n/**\n * A chip color role: a shared semantic tone, or `inherit`, which follows the\n * surrounding foreground (a chip inside a `brand-loud` ContentItem bubble)\n * and derives its fill, border, and focus ring from `currentColor`.\n */\nexport type ChipTone = SemanticTone | 'inherit';\n\nconst chipProtectedAttributes = new Set([\n 'data-component',\n 'data-tone',\n 'data-appearance',\n 'data-shape',\n 'data-size',\n 'data-disabled',\n 'data-truncate',\n 'data-item-id',\n 'data-link',\n 'data-action',\n]);\n\n/** Safe `data-*` identity on a Chip root; Chip-owned attributes are protected. */\nexport type ChipRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-tone'?: never;\n 'data-appearance'?: never;\n 'data-shape'?: never;\n 'data-size'?: never;\n 'data-disabled'?: never;\n 'data-truncate'?: never;\n 'data-item-id'?: never;\n 'data-link'?: never;\n 'data-action'?: never;\n }\n>;\n\ninterface ChipCommonProps {\n /** Decorative leading icon, normally an unsized LucideIcon. */\n icon?: SafeHtml;\n tone?: ChipTone;\n appearance?: BadgeAppearance;\n shape?: BadgeShape;\n size?: BadgeSize;\n disabled?: boolean;\n /** Record identifier available to an application delegated action handler. */\n itemId?: string;\n /**\n * Safe `data-*` identity on the chip root (a plain, link, or action chip),\n * for tests and delegated handlers; use `itemId` for the record id.\n */\n rootAttributes?: ChipRootAttributes;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ntype ChipLabelProps =\n | { children: SafeHtml | string | number; truncate?: false }\n | { children: string; truncate: true };\n\ninterface ChipNoLinkProps {\n href?: never;\n download?: never;\n external?: never;\n}\n\ninterface ChipNoActionProps {\n action?: never;\n actionLabel?: never;\n}\n\n/**\n * An action chip renders its whole root as a native\n * `<button type=\"button\">` carrying `data-action` (and `data-item-id`) for an\n * application delegated handler. It cannot also be a link or carry a remove\n * button, because nested interactive content is invalid.\n */\ninterface ChipActionProps {\n /** Delegated action name; the chip renders as a native `<button>`. */\n action: string;\n /**\n * Accessible name when the visible label alone is unclear, such as\n * \"Insert filter is:mine\". Start it with, or include, the visible label so\n * speech input still matches.\n */\n actionLabel?: string;\n href?: never;\n download?: never;\n external?: never;\n removeAction?: never;\n removeLabel?: never;\n}\n\n/**\n * A link chip renders a native `<a>` with Chip geometry. It cannot also carry\n * a remove button, because a button inside a link is invalid.\n */\ninterface ChipLinkProps {\n /** Native destination; the chip renders as an `<a>`. */\n href: string;\n /** Download the destination: `true`, or the suggested file name. */\n download?: string | boolean;\n /** Open in a new tab with a safe rel and announce that behavior. */\n external?: boolean;\n removeAction?: never;\n removeLabel?: never;\n action?: never;\n actionLabel?: never;\n}\n\n/**\n * A plain chip, a removable chip (a delegated action plus a specific\n * accessible name), a link chip (`href`, optional `download`/`external`), or\n * an action chip (`action`, optional `actionLabel`) whose whole body is a\n * native button.\n */\nexport type ChipProps = ChipCommonProps &\n ChipLabelProps &\n (\n | ({ removeAction: string; removeLabel: string } & ChipNoLinkProps &\n ChipNoActionProps)\n | ({ removeAction?: never; removeLabel?: never } & ChipNoLinkProps &\n ChipNoActionProps)\n | ChipLinkProps\n | ChipActionProps\n );\n\nfunction removeButton(action: string, label: string, disabled: boolean) {\n return (\n <button\n class=\"kui-chip__remove\"\n type=\"button\"\n data-action={action}\n aria-label={label}\n disabled={disabled}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" aria-hidden=\"true\">\n <path\n d=\"M3.5 3.5 12.5 12.5M12.5 3.5 3.5 12.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n );\n}\n\nfunction downloadValue(download: string | boolean | undefined) {\n switch (download) {\n case undefined:\n case false:\n return undefined;\n case true:\n return '';\n default:\n return download;\n }\n}\n\n/**\n * A short label with an optional native remove button, a native link when\n * `href` is set, or a native button when `action` is set. The application\n * owns removal, the link destination, and the action handler.\n */\nexport function Chip({\n children,\n icon,\n truncate = false,\n tone = 'neutral',\n appearance = 'quiet',\n shape = 'pill',\n size = 'default',\n disabled = false,\n itemId,\n rootAttributes = {},\n className = '',\n slot,\n href,\n download,\n external = false,\n removeAction,\n removeLabel,\n action,\n actionLabel,\n}: ChipProps) {\n if (truncate && typeof children !== 'string')\n throw new TypeError('Chip truncate requires a plain text label');\n if (\n action !== undefined &&\n (href !== undefined ||\n removeAction !== undefined ||\n removeLabel !== undefined)\n )\n throw new TypeError(\n 'Chip action cannot be combined with href or removeAction, because nested interactive content is invalid',\n );\n const content = (\n <>\n {icon === undefined ? null : (\n <span class=\"kui-chip__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span\n class=\"kui-chip__label\"\n title={truncate ? String(children) : undefined}\n >\n {children}\n </span>\n </>\n );\n const rootClass = `kui-chip ${className}`.trim();\n const identity = filterDataAttributes(\n rootAttributes,\n chipProtectedAttributes,\n );\n if (href !== undefined) {\n const textLabel =\n typeof children === 'string' || typeof children === 'number'\n ? String(children)\n : undefined;\n return (\n <a\n {...identity}\n class={rootClass}\n href={disabled ? undefined : href}\n download={disabled ? undefined : downloadValue(download)}\n target={disabled || !external ? undefined : '_blank'}\n rel={disabled || !external ? undefined : 'noopener noreferrer'}\n tabindex={disabled ? -1 : undefined}\n aria-label={\n external && textLabel !== undefined\n ? `${textLabel} (opens in new tab)`\n : undefined\n }\n aria-disabled={disabled ? 'true' : undefined}\n data-component=\"chip\"\n data-link=\"\"\n data-tone={tone}\n data-appearance={appearance}\n data-shape={shape}\n data-size={size}\n data-disabled={disabled ? '' : undefined}\n data-truncate={truncate ? '' : undefined}\n data-item-id={itemId}\n slot={slot}\n >\n {content}\n </a>\n );\n }\n if (action !== undefined) {\n return (\n <button\n {...identity}\n class={rootClass}\n type=\"button\"\n disabled={disabled}\n aria-label={actionLabel?.trim() || undefined}\n data-action={action}\n data-component=\"chip\"\n data-tone={tone}\n data-appearance={appearance}\n data-shape={shape}\n data-size={size}\n data-disabled={disabled ? '' : undefined}\n data-truncate={truncate ? '' : undefined}\n data-item-id={itemId}\n slot={slot}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n {...identity}\n class={rootClass}\n data-component=\"chip\"\n data-tone={tone}\n data-appearance={appearance}\n data-shape={shape}\n data-size={size}\n data-disabled={disabled ? '' : undefined}\n data-truncate={truncate ? '' : undefined}\n data-item-id={itemId}\n slot={slot}\n >\n {content}\n {removeAction !== undefined && removeLabel !== undefined\n ? removeButton(removeAction, removeLabel, disabled)\n : null}\n </span>\n );\n}\n"]}
|
|
@@ -13,6 +13,7 @@ function SegmentedControl({
|
|
|
13
13
|
layout = "content",
|
|
14
14
|
className = "",
|
|
15
15
|
placeholder = false,
|
|
16
|
+
disabled = false,
|
|
16
17
|
slot
|
|
17
18
|
}) {
|
|
18
19
|
return /* @__PURE__ */ jsx(
|
|
@@ -27,12 +28,15 @@ function SegmentedControl({
|
|
|
27
28
|
"data-size": size,
|
|
28
29
|
"data-layout": layout,
|
|
29
30
|
"data-placeholder": placeholder ? "true" : void 0,
|
|
31
|
+
"data-disabled": disabled ? "true" : void 0,
|
|
30
32
|
role: "group",
|
|
31
33
|
"aria-label": label,
|
|
34
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
32
35
|
"aria-busy": placeholder ? "true" : void 0,
|
|
33
36
|
slot,
|
|
34
37
|
children: choices.map((choice) => {
|
|
35
38
|
const selected = !placeholder && choice.value === value;
|
|
39
|
+
const unavailable = disabled || choice.disabled;
|
|
36
40
|
return /* @__PURE__ */ jsx(
|
|
37
41
|
"button",
|
|
38
42
|
{
|
|
@@ -44,9 +48,9 @@ function SegmentedControl({
|
|
|
44
48
|
"aria-label": choice.label,
|
|
45
49
|
"aria-pressed": String(selected),
|
|
46
50
|
title: placeholder ? void 0 : choice.title,
|
|
47
|
-
disabled:
|
|
51
|
+
disabled: unavailable || placeholder,
|
|
48
52
|
tabindex: placeholder ? "-1" : "0",
|
|
49
|
-
"data-kui-disabled":
|
|
53
|
+
"data-kui-disabled": unavailable ? "true" : void 0,
|
|
50
54
|
children: choice.content ?? /* @__PURE__ */ jsx("span", { children: choice.label })
|
|
51
55
|
}
|
|
52
56
|
);
|
|
@@ -57,4 +61,4 @@ function SegmentedControl({
|
|
|
57
61
|
|
|
58
62
|
export { SegmentedControl };
|
|
59
63
|
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
64
|
+
//# sourceMappingURL=chunk-LZUUUHNH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/forms/segmented-control/segmented-control.tsx"],"names":[],"mappings":";;;AAkCO,SAAS,gBAAA,CAAuC;AAAA,EACrD,EAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,GAAS,gBAAA;AAAA,EACT,UAAA,GAAa,QAAA;AAAA,EACb,KAAA,GAAQ,SAAA;AAAA,EACR,IAAA,GAAO,SAAA;AAAA,EACP,MAAA,GAAS,SAAA;AAAA,EACT,SAAA,GAAY,EAAA;AAAA,EACZ,WAAA,GAAc,KAAA;AAAA,EACd,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAiC;AAC/B,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACjD,gBAAA,EAAe,mBAAA;AAAA,MACf,2BAAA,EAA2B,EAAA;AAAA,MAC3B,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,YAAA,EAAY,KAAA;AAAA,MACZ,WAAA,EAAW,IAAA;AAAA,MACX,aAAA,EAAa,MAAA;AAAA,MACb,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,eAAA,EAAe,WAAW,MAAA,GAAS,MAAA;AAAA,MACnC,IAAA,EAAK,OAAA;AAAA,MACL,YAAA,EAAY,KAAA;AAAA,MACZ,eAAA,EAAe,WAAW,MAAA,GAAS,MAAA;AAAA,MACnC,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAClC,IAAA;AAAA,MAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AAGvB,QAAA,MAAM,QAAA,GAAW,CAAC,WAAA,IAAe,MAAA,CAAO,KAAA,KAAU,KAAA;AAClD,QAAA,MAAM,WAAA,GAAc,YAAY,MAAA,CAAO,QAAA;AACvC,QAAA,uBACE,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,6BAAA;AAAA,YACN,aAAA,EAAa,cAAc,MAAA,GAAY,MAAA;AAAA,YACvC,sBAAoB,MAAA,CAAO,KAAA;AAAA,YAC3B,eAAA,EAAe,OAAO,QAAQ,CAAA;AAAA,YAC9B,cAAY,MAAA,CAAO,KAAA;AAAA,YACnB,cAAA,EAAc,OAAO,QAAQ,CAAA;AAAA,YAC7B,KAAA,EAAO,WAAA,GAAc,MAAA,GAAY,MAAA,CAAO,KAAA;AAAA,YACxC,UAAU,WAAA,IAAe,WAAA;AAAA,YACzB,QAAA,EAAU,cAAc,IAAA,GAAO,GAAA;AAAA,YAC/B,mBAAA,EAAmB,cAAc,MAAA,GAAS,MAAA;AAAA,YAEzC,QAAA,EAAA,MAAA,CAAO,OAAA,oBAAW,GAAA,CAAC,MAAA,EAAA,EAAM,iBAAO,KAAA,EAAM;AAAA;AAAA,SACzC;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ","file":"chunk-LZUUUHNH.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\n\nexport type SegmentedControlAppearance = 'filled' | 'outlined' | 'toolbar';\nexport type SegmentedControlShape = 'rounded' | 'pill';\nexport type SegmentedControlSize = 'small' | 'default';\nexport type SegmentedControlLayout = 'content' | 'equal';\n\nexport interface SegmentedControlChoice<Value extends string = string> {\n value: Value;\n label: string;\n content?: KerfUiContent;\n title?: string;\n disabled?: boolean;\n}\n\nexport interface SegmentedControlProps<Value extends string = string> {\n id: string;\n label: string;\n value: NoInfer<Value>;\n choices: readonly SegmentedControlChoice<Value>[];\n action?: string;\n appearance?: SegmentedControlAppearance;\n shape?: SegmentedControlShape;\n size?: SegmentedControlSize;\n layout?: SegmentedControlLayout;\n className?: string;\n /** Render as a loading placeholder: every choice keeps its live label or icon, none is selected, and every segment is disabled. */\n placeholder?: boolean;\n /** Disable the whole control: every segment is disabled and dimmed, the selection stays visible, and the group reports `aria-disabled`. A choice's own `disabled` still disables just that segment. */\n disabled?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function SegmentedControl<Value extends string>({\n id,\n label,\n value,\n choices,\n action = 'select-segment',\n appearance = 'filled',\n shape = 'rounded',\n size = 'default',\n layout = 'content',\n className = '',\n placeholder = false,\n disabled = false,\n slot,\n}: SegmentedControlProps<Value>) {\n return (\n <div\n class={`kui-segmented-control ${className}`.trim()}\n data-component=\"segmented-control\"\n data-segmented-control-id={id}\n data-value={value}\n data-appearance={appearance}\n data-shape={shape}\n data-size={size}\n data-layout={layout}\n data-placeholder={placeholder ? 'true' : undefined}\n data-disabled={disabled ? 'true' : undefined}\n role=\"group\"\n aria-label={label}\n aria-disabled={disabled ? 'true' : undefined}\n aria-busy={placeholder ? 'true' : undefined}\n slot={slot}\n >\n {choices.map((choice) => {\n // The choices are known chrome; only the selection is unknown while\n // loading, so a placeholder shows every choice and selects none.\n const selected = !placeholder && choice.value === value;\n const unavailable = disabled || choice.disabled;\n return (\n <button\n type=\"button\"\n class=\"kui-segmented-control__item\"\n data-action={placeholder ? undefined : action}\n data-segment-value={choice.value}\n data-selected={String(selected)}\n aria-label={choice.label}\n aria-pressed={String(selected)}\n title={placeholder ? undefined : choice.title}\n disabled={unavailable || placeholder}\n tabindex={placeholder ? '-1' : '0'}\n data-kui-disabled={unavailable ? 'true' : undefined}\n >\n {choice.content ?? <span>{choice.label}</span>}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { followAnchor, positionPopup } from './chunk-
|
|
1
|
+
import { followAnchor, positionPopup } from './chunk-HDXUHLTQ.js';
|
|
2
2
|
|
|
3
3
|
// src/components/forms/combobox/wiring/wire-comboboxes.ts
|
|
4
4
|
var INPUT = ".kui-combobox__input";
|
|
@@ -166,4 +166,4 @@ function wireComboboxes(root, { onCommit, commitKeys = [","] }) {
|
|
|
166
166
|
|
|
167
167
|
export { wireComboboxes };
|
|
168
168
|
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-MVKHSAKE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/forms/combobox/wiring/wire-comboboxes.ts"],"names":[],"mappings":"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","file":"chunk-GCAK23PU.js","sourcesContent":["import {\n followAnchor,\n positionPopup,\n} from '../../../../shared/popup/position-popup.js';\n\ntype Root = HTMLElement | Document;\n\nconst INPUT = '.kui-combobox__input';\n\n/** A committed combobox value. */\nexport interface ComboboxCommit {\n id: string;\n value: string;\n /** True when the value matched no suggestion (the person created it). */\n created: boolean;\n /** The field's input; clear or keep its text after applying the commit. */\n input: HTMLInputElement;\n}\n\nexport interface WireComboboxesOptions {\n onCommit: (commit: ComboboxCommit) => void;\n /** Characters that commit the typed text besides Enter. Default `[',']`. */\n commitKeys?: readonly string[];\n}\n\ninterface Parts {\n field: HTMLElement;\n input: HTMLInputElement;\n listbox: HTMLElement;\n create: HTMLElement | null;\n}\n\n// `Combobox` renders the input inside its field with its listbox, and every\n// suggestion option with `data-value`, so the lookups below cannot miss.\nfunction partsOf(input: HTMLInputElement): Parts {\n const field = input.closest<HTMLElement>('[data-component=\"combobox\"]')!;\n const listbox = field.querySelector<HTMLElement>('[role=\"listbox\"]')!;\n return {\n field,\n input,\n listbox,\n create: listbox.querySelector<HTMLElement>('[data-create]'),\n };\n}\n\nconst visibleOptions = (parts: Parts) =>\n [...parts.listbox.querySelectorAll<HTMLElement>('[role=\"option\"]')].filter(\n (option) => !option.hidden,\n );\n\nconst matches = (option: HTMLElement, text: string) =>\n option.textContent!.toLowerCase().includes(text) ||\n option.dataset.value!.toLowerCase().includes(text);\n\nfunction setActive(parts: Parts, option: HTMLElement | null) {\n for (const item of parts.listbox.querySelectorAll('[role=\"option\"]'))\n item.setAttribute('aria-selected', String(item === option));\n if (option) {\n parts.input.setAttribute('aria-activedescendant', option.id);\n option.scrollIntoView?.({ block: 'nearest' });\n } else parts.input.removeAttribute('aria-activedescendant');\n}\n\nfunction activeOption(parts: Parts): HTMLElement | null {\n const id = parts.input.getAttribute('aria-activedescendant');\n return id\n ? parts.listbox.querySelector<HTMLElement>(`#${CSS.escape(id)}`)\n : null;\n}\n\n// The listbox is a manual popover in the top layer, so no clipping or\n// scrolling ancestor (an AnchoredSurface, a dialog, a scrolling List) cuts\n// it off; it follows the field while shown.\nconst following = new WeakMap<HTMLElement, () => void>();\n\nfunction show(parts: Parts) {\n const { listbox } = parts;\n listbox.hidden = false;\n if (!listbox.matches(':popover-open')) listbox.showPopover();\n if (following.has(listbox)) return;\n const control = parts.input.parentElement!;\n const place = async () => {\n if (!listbox.isConnected || listbox.hidden) return;\n listbox.style.width = `${control.getBoundingClientRect().width}px`;\n await positionPopup(control, listbox, {\n placement: 'bottom-start',\n gap: 4,\n });\n // Placement caps the height to the room its side has; keep the list's\n // own cap too.\n listbox.style.maxHeight = `min(${listbox.style.maxHeight}, var(--_kui-combobox-max-height))`;\n };\n following.set(\n listbox,\n followAnchor(control, listbox, () => void place()),\n );\n}\n\nfunction hide(parts: Parts) {\n const { listbox } = parts;\n listbox.hidden = true;\n if (listbox.matches(':popover-open')) listbox.hidePopover();\n following.get(listbox)?.();\n following.delete(listbox);\n}\n\nfunction close(parts: Parts) {\n hide(parts);\n parts.input.setAttribute('aria-expanded', 'false');\n setActive(parts, null);\n}\n\n/** Filter the suggestions to the typed text and show the create option. */\nfunction update(parts: Parts) {\n const typed = parts.input.value.trim();\n const text = typed.toLowerCase();\n let exact = false;\n for (const option of parts.listbox.querySelectorAll<HTMLElement>(\n '[role=\"option\"]:not([data-create])',\n )) {\n option.hidden = text !== '' && !matches(option, text);\n if (option.dataset.value!.toLowerCase() === text) exact = true;\n }\n if (parts.create) {\n parts.create.hidden = typed === '' || exact;\n parts.create.dataset.value = typed;\n // A create option exists only when the field has a create label.\n parts.create.textContent = parts.field.dataset.createLabel!.replaceAll(\n '{value}',\n typed,\n );\n }\n const options = visibleOptions(parts);\n if (options.length === 0) hide(parts);\n else show(parts);\n parts.input.setAttribute('aria-expanded', String(options.length > 0));\n if (!options.includes(activeOption(parts)!)) setActive(parts, null);\n}\n\n/**\n * Wire every `Combobox` below root: typing filters the suggestions (and offers\n * to create the typed text), ArrowDown/ArrowUp move the active option, Enter or\n * a commit key (comma by default) commits the active option or the typed text,\n * a click commits an option, and Escape or leaving the field closes the list.\n * Typed text that matches no suggestion commits only when the field offers\n * creation; otherwise Enter commits the first matching suggestion. Dispose with the owning application.\n */\nexport function wireComboboxes(\n root: Root,\n { onCommit, commitKeys = [','] }: WireComboboxesOptions,\n): () => void {\n const commit = (parts: Parts, active: HTMLElement | null) => {\n // Without a create option, Enter on partial text takes the first match.\n const option =\n active ?? (parts.create ? null : (visibleOptions(parts)[0] ?? null));\n const typed = parts.input.value.trim();\n // Callers commit only with an option or non-empty typed text.\n const value = option ? option.dataset.value! : typed;\n const suggestion = [\n ...parts.listbox.querySelectorAll<HTMLElement>(\n '[role=\"option\"]:not([data-create])',\n ),\n ].find((item) => item.dataset.value!.toLowerCase() === value.toLowerCase());\n const created = !suggestion;\n if (created && !parts.create) return;\n close(parts);\n onCommit({\n id: parts.field.dataset.comboboxId!,\n value: suggestion?.dataset.value ?? value,\n created,\n input: parts.input,\n });\n };\n const inputOf = (event: Event) =>\n event.target instanceof HTMLInputElement && event.target.matches(INPUT)\n ? event.target\n : null;\n const onInput = (event: Event) => {\n const input = inputOf(event);\n const parts = input && partsOf(input);\n if (parts) update(parts);\n };\n const onFocus = onInput;\n const onKeyDown = (event: Event) => {\n const keyboard = event as KeyboardEvent;\n const input = inputOf(keyboard);\n const parts = input && partsOf(input);\n if (!parts || keyboard.isComposing) return;\n const options = visibleOptions(parts);\n const current = activeOption(parts);\n const index = current ? options.indexOf(current) : -1;\n if (keyboard.key === 'ArrowDown' || keyboard.key === 'ArrowUp') {\n keyboard.preventDefault();\n if (parts.listbox.hidden) update(parts);\n const open = visibleOptions(parts);\n if (open.length === 0) return;\n const step = keyboard.key === 'ArrowDown' ? 1 : -1;\n const next =\n index < 0\n ? step > 0\n ? 0\n : open.length - 1\n : (index + step + open.length) % open.length;\n setActive(parts, open[next]!);\n } else if (keyboard.key === 'Enter' || commitKeys.includes(keyboard.key)) {\n if (!parts.input.value.trim() && !current) return;\n keyboard.preventDefault();\n commit(parts, current);\n } else if (keyboard.key === 'Escape' && !parts.listbox.hidden) {\n keyboard.preventDefault();\n close(parts);\n }\n };\n const onPointerDown = (event: Event) => {\n const option =\n event.target instanceof Element\n ? event.target.closest<HTMLElement>('.kui-combobox__option')\n : null;\n const input = option\n ?.closest('[data-component=\"combobox\"]')\n ?.querySelector<HTMLInputElement>(INPUT);\n const parts = input && partsOf(input);\n if (!option || !parts) return;\n // Keep focus in the field; commit on the press itself.\n event.preventDefault();\n commit(parts, option);\n };\n const onFocusOut = (event: Event) => {\n const input = inputOf(event);\n const parts = input && partsOf(input);\n if (parts) close(parts);\n };\n root.addEventListener('input', onInput);\n root.addEventListener('focusin', onFocus);\n root.addEventListener('keydown', onKeyDown);\n root.addEventListener('pointerdown', onPointerDown);\n root.addEventListener('focusout', onFocusOut);\n return () => {\n root.removeEventListener('input', onInput);\n root.removeEventListener('focusin', onFocus);\n root.removeEventListener('keydown', onKeyDown);\n root.removeEventListener('pointerdown', onPointerDown);\n root.removeEventListener('focusout', onFocusOut);\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/forms/combobox/wiring/wire-comboboxes.ts"],"names":[],"mappings":"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","file":"chunk-MVKHSAKE.js","sourcesContent":["import {\n followAnchor,\n positionPopup,\n} from '../../../../shared/popup/position-popup.js';\n\ntype Root = HTMLElement | Document;\n\nconst INPUT = '.kui-combobox__input';\n\n/** A committed combobox value. */\nexport interface ComboboxCommit {\n id: string;\n value: string;\n /** True when the value matched no suggestion (the person created it). */\n created: boolean;\n /** The field's input; clear or keep its text after applying the commit. */\n input: HTMLInputElement;\n}\n\nexport interface WireComboboxesOptions {\n onCommit: (commit: ComboboxCommit) => void;\n /** Characters that commit the typed text besides Enter. Default `[',']`. */\n commitKeys?: readonly string[];\n}\n\ninterface Parts {\n field: HTMLElement;\n input: HTMLInputElement;\n listbox: HTMLElement;\n create: HTMLElement | null;\n}\n\n// `Combobox` renders the input inside its field with its listbox, and every\n// suggestion option with `data-value`, so the lookups below cannot miss.\nfunction partsOf(input: HTMLInputElement): Parts {\n const field = input.closest<HTMLElement>('[data-component=\"combobox\"]')!;\n const listbox = field.querySelector<HTMLElement>('[role=\"listbox\"]')!;\n return {\n field,\n input,\n listbox,\n create: listbox.querySelector<HTMLElement>('[data-create]'),\n };\n}\n\nconst visibleOptions = (parts: Parts) =>\n [...parts.listbox.querySelectorAll<HTMLElement>('[role=\"option\"]')].filter(\n (option) => !option.hidden,\n );\n\nconst matches = (option: HTMLElement, text: string) =>\n option.textContent!.toLowerCase().includes(text) ||\n option.dataset.value!.toLowerCase().includes(text);\n\nfunction setActive(parts: Parts, option: HTMLElement | null) {\n for (const item of parts.listbox.querySelectorAll('[role=\"option\"]'))\n item.setAttribute('aria-selected', String(item === option));\n if (option) {\n parts.input.setAttribute('aria-activedescendant', option.id);\n option.scrollIntoView?.({ block: 'nearest' });\n } else parts.input.removeAttribute('aria-activedescendant');\n}\n\nfunction activeOption(parts: Parts): HTMLElement | null {\n const id = parts.input.getAttribute('aria-activedescendant');\n return id\n ? parts.listbox.querySelector<HTMLElement>(`#${CSS.escape(id)}`)\n : null;\n}\n\n// The listbox is a manual popover in the top layer, so no clipping or\n// scrolling ancestor (an AnchoredSurface, a dialog, a scrolling List) cuts\n// it off; it follows the field while shown.\nconst following = new WeakMap<HTMLElement, () => void>();\n\nfunction show(parts: Parts) {\n const { listbox } = parts;\n listbox.hidden = false;\n if (!listbox.matches(':popover-open')) listbox.showPopover();\n if (following.has(listbox)) return;\n const control = parts.input.parentElement!;\n const place = async () => {\n if (!listbox.isConnected || listbox.hidden) return;\n listbox.style.width = `${control.getBoundingClientRect().width}px`;\n await positionPopup(control, listbox, {\n placement: 'bottom-start',\n gap: 4,\n });\n // Placement caps the height to the room its side has; keep the list's\n // own cap too.\n listbox.style.maxHeight = `min(${listbox.style.maxHeight}, var(--_kui-combobox-max-height))`;\n };\n following.set(\n listbox,\n followAnchor(control, listbox, () => void place()),\n );\n}\n\nfunction hide(parts: Parts) {\n const { listbox } = parts;\n listbox.hidden = true;\n if (listbox.matches(':popover-open')) listbox.hidePopover();\n following.get(listbox)?.();\n following.delete(listbox);\n}\n\nfunction close(parts: Parts) {\n hide(parts);\n parts.input.setAttribute('aria-expanded', 'false');\n setActive(parts, null);\n}\n\n/** Filter the suggestions to the typed text and show the create option. */\nfunction update(parts: Parts) {\n const typed = parts.input.value.trim();\n const text = typed.toLowerCase();\n let exact = false;\n for (const option of parts.listbox.querySelectorAll<HTMLElement>(\n '[role=\"option\"]:not([data-create])',\n )) {\n option.hidden = text !== '' && !matches(option, text);\n if (option.dataset.value!.toLowerCase() === text) exact = true;\n }\n if (parts.create) {\n parts.create.hidden = typed === '' || exact;\n parts.create.dataset.value = typed;\n // A create option exists only when the field has a create label.\n parts.create.textContent = parts.field.dataset.createLabel!.replaceAll(\n '{value}',\n typed,\n );\n }\n const options = visibleOptions(parts);\n if (options.length === 0) hide(parts);\n else show(parts);\n parts.input.setAttribute('aria-expanded', String(options.length > 0));\n if (!options.includes(activeOption(parts)!)) setActive(parts, null);\n}\n\n/**\n * Wire every `Combobox` below root: typing filters the suggestions (and offers\n * to create the typed text), ArrowDown/ArrowUp move the active option, Enter or\n * a commit key (comma by default) commits the active option or the typed text,\n * a click commits an option, and Escape or leaving the field closes the list.\n * Typed text that matches no suggestion commits only when the field offers\n * creation; otherwise Enter commits the first matching suggestion. Dispose with the owning application.\n */\nexport function wireComboboxes(\n root: Root,\n { onCommit, commitKeys = [','] }: WireComboboxesOptions,\n): () => void {\n const commit = (parts: Parts, active: HTMLElement | null) => {\n // Without a create option, Enter on partial text takes the first match.\n const option =\n active ?? (parts.create ? null : (visibleOptions(parts)[0] ?? null));\n const typed = parts.input.value.trim();\n // Callers commit only with an option or non-empty typed text.\n const value = option ? option.dataset.value! : typed;\n const suggestion = [\n ...parts.listbox.querySelectorAll<HTMLElement>(\n '[role=\"option\"]:not([data-create])',\n ),\n ].find((item) => item.dataset.value!.toLowerCase() === value.toLowerCase());\n const created = !suggestion;\n if (created && !parts.create) return;\n close(parts);\n onCommit({\n id: parts.field.dataset.comboboxId!,\n value: suggestion?.dataset.value ?? value,\n created,\n input: parts.input,\n });\n };\n const inputOf = (event: Event) =>\n event.target instanceof HTMLInputElement && event.target.matches(INPUT)\n ? event.target\n : null;\n const onInput = (event: Event) => {\n const input = inputOf(event);\n const parts = input && partsOf(input);\n if (parts) update(parts);\n };\n const onFocus = onInput;\n const onKeyDown = (event: Event) => {\n const keyboard = event as KeyboardEvent;\n const input = inputOf(keyboard);\n const parts = input && partsOf(input);\n if (!parts || keyboard.isComposing) return;\n const options = visibleOptions(parts);\n const current = activeOption(parts);\n const index = current ? options.indexOf(current) : -1;\n if (keyboard.key === 'ArrowDown' || keyboard.key === 'ArrowUp') {\n keyboard.preventDefault();\n if (parts.listbox.hidden) update(parts);\n const open = visibleOptions(parts);\n if (open.length === 0) return;\n const step = keyboard.key === 'ArrowDown' ? 1 : -1;\n const next =\n index < 0\n ? step > 0\n ? 0\n : open.length - 1\n : (index + step + open.length) % open.length;\n setActive(parts, open[next]!);\n } else if (keyboard.key === 'Enter' || commitKeys.includes(keyboard.key)) {\n if (!parts.input.value.trim() && !current) return;\n keyboard.preventDefault();\n commit(parts, current);\n } else if (keyboard.key === 'Escape' && !parts.listbox.hidden) {\n keyboard.preventDefault();\n close(parts);\n }\n };\n const onPointerDown = (event: Event) => {\n const option =\n event.target instanceof Element\n ? event.target.closest<HTMLElement>('.kui-combobox__option')\n : null;\n const input = option\n ?.closest('[data-component=\"combobox\"]')\n ?.querySelector<HTMLInputElement>(INPUT);\n const parts = input && partsOf(input);\n if (!option || !parts) return;\n // Keep focus in the field; commit on the press itself.\n event.preventDefault();\n commit(parts, option);\n };\n const onFocusOut = (event: Event) => {\n const input = inputOf(event);\n const parts = input && partsOf(input);\n if (parts) close(parts);\n };\n root.addEventListener('input', onInput);\n root.addEventListener('focusin', onFocus);\n root.addEventListener('keydown', onKeyDown);\n root.addEventListener('pointerdown', onPointerDown);\n root.addEventListener('focusout', onFocusOut);\n return () => {\n root.removeEventListener('input', onInput);\n root.removeEventListener('focusin', onFocus);\n root.removeEventListener('keydown', onKeyDown);\n root.removeEventListener('pointerdown', onPointerDown);\n root.removeEventListener('focusout', onFocusOut);\n };\n}\n"]}
|
|
@@ -43,6 +43,7 @@ function List({
|
|
|
43
43
|
textInsets = "",
|
|
44
44
|
controlInsets = "",
|
|
45
45
|
className = "",
|
|
46
|
+
id,
|
|
46
47
|
rootAttributes = {},
|
|
47
48
|
slot
|
|
48
49
|
}) {
|
|
@@ -72,6 +73,7 @@ function List({
|
|
|
72
73
|
{
|
|
73
74
|
...safeRootAttributes,
|
|
74
75
|
...gridAttributes,
|
|
76
|
+
id,
|
|
75
77
|
class: `kui-list ${className}`.trim(),
|
|
76
78
|
"data-component": "list",
|
|
77
79
|
"data-gap": String(Boolean(gap)),
|
|
@@ -98,4 +100,4 @@ function List({
|
|
|
98
100
|
|
|
99
101
|
export { List };
|
|
100
102
|
|
|
101
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-NB6POCFH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/collections/list/list.tsx"],"names":[],"mappings":"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","file":"chunk-NB6POCFH.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n filterRootAttributes,\n type StructuralRootAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport {\n type HorizontalAlignment,\n horizontalAlignment,\n type ListVerticalAlignment,\n verticalAlignment,\n} from '../../../shared/layout/flex-alignment.js';\nimport { gapLength } from '../../../shared/layout/gap.js';\nimport type { ScrollClearance } from '../../../shared/layout/scroll-clearance.js';\nimport type { Sides } from '../../../shared/layout/sides.js';\nimport {\n type CssFlex,\n type CssFlexKeyword,\n type CssLength,\n type UiGap,\n} from '../../../shared/styles/css-values.js';\n\n/** Attributes a multi-select List owns as an ARIA grid. */\nconst listGridAttributes = ['role', 'aria-label', 'aria-multiselectable'];\n\nconst listProtectedAttributes = new Set([\n 'data-component',\n 'data-gap',\n 'data-flex',\n 'data-fill',\n 'data-h-align',\n 'data-v-align',\n 'data-scrollable',\n 'data-scroll-clearance',\n 'data-frame',\n 'data-surface',\n 'data-inset',\n 'data-content-width',\n 'data-content-align',\n 'data-text-insets',\n 'data-control-insets',\n]);\n\ntype ListRootAttributes = StructuralRootAttributes &\n Readonly<{\n 'data-component'?: never;\n 'data-gap'?: never;\n 'data-flex'?: never;\n 'data-fill'?: never;\n 'data-h-align'?: never;\n 'data-v-align'?: never;\n 'data-scrollable'?: never;\n 'data-scroll-clearance'?: never;\n 'data-frame'?: never;\n 'data-surface'?: never;\n 'data-inset'?: never;\n 'data-content-width'?: never;\n 'data-content-align'?: never;\n 'data-text-insets'?: never;\n 'data-control-insets'?: never;\n }>;\n\n/**\n * A solid surface painted behind a List: `base` is the page surface\n * (`--kui-color-surface`), `raised` the raised surface\n * (`--kui-color-surface-raised`). A lowered region is a `SunkenPanel`.\n */\nexport type ListSurface = 'base' | 'raised';\n\n/**\n * A preset inset on all four sides. `document` is the reading inset for long\n * content such as a reader view: 24px block and 32px inline, narrowing to\n * 16px inline below 576px. It replaces any `textInsets`/`controlInsets`.\n */\nexport type ListInset = 'document';\n\n/**\n * A readable measure for a page's content column: `compact` 440px, `medium`\n * 640px, or `wide` 864px of content, the same steps as a catalog example's\n * `contentWidth`.\n */\nexport type ListContentWidth = 'compact' | 'medium' | 'wide';\n\nexport interface ListProps {\n children?: KerfUiContent;\n /** Make this list a labeled multi-select grid for `ContentItem selectionMode=\"multiple\"` rows. */\n selectionMode?: 'multiple';\n /** Accessible name for the multi-select grid. */\n ariaLabel?: string;\n /** Standard gap (`true`), one spacing value, or separate column and row values. Defaults to no gap. */\n gap?: boolean | UiGap;\n /** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */\n flex?: boolean | CssFlexKeyword | CssFlex;\n /**\n * Fill the height of a parent with a definite height, such as an app root or\n * a fixed-height frame, when this list is that parent's layout root. Inside a\n * flex layout use `flex` instead. Defaults to false.\n */\n fill?: boolean;\n /** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */\n hAlign?: HorizontalAlignment;\n /** Vertical distribution. Defaults to top. */\n vAlign?: ListVerticalAlignment;\n /**\n * Own vertical scrolling and overscroll containment. Children keep their\n * natural height and scroll instead of shrinking. To bound the list by a\n * `max-height` ancestor (no definite height), give that ancestor a flex\n * column and use `flex`; `fill` needs a definite-height parent.\n */\n scrollable?: boolean;\n /**\n * Clear chrome that lies over this scrollable List's block-start and/or\n * block-end edge, such as a `DialogSurface` floating footer. The List adds\n * the inherited `--kui-scroll-clearance-block-*` context that chrome\n * publishes to its own block padding and `scroll-padding`, so its rows\n * scroll visibly beneath the chrome while the first and last rows (and any\n * row focused or scrolled into view) can still rest clear of it. Opt in only\n * the one scroller that reaches the covered edge. Defaults to none.\n */\n scrollClearance?: ScrollClearance;\n /**\n * Draw a bordered, rounded frame around the stack: a 1px neutral border,\n * the standard control radius, and a 4px inset on every side that keeps the\n * first and last rows' focus rings inside a scrolling frame's clip. It\n * replaces any `inset`/`textInsets`/`controlInsets`. With `scrollable` and\n * `maxHeight` it is a bounded result picker of `ListItem` rows.\n */\n frame?: boolean;\n /**\n * The List's maximum block size, a typed `CssLength` from\n * `@kerfjs/ui/css-values` (such as `rem(14)`). Pair it with `scrollable` so\n * rows beyond it scroll; it bounds the List without a flex-column ancestor.\n */\n maxHeight?: CssLength;\n /**\n * The List's minimum block size, a typed `CssLength` (such as `rem(4.25)`),\n * so a short or empty result set keeps a stable box. Defaults to no minimum.\n */\n minHeight?: CssLength;\n /**\n * Paint a solid surface behind the stack, including its insets: for a strip\n * of chrome (a banner above a sunken work area) that must not show the\n * lowered tint around its content. Omitted, the List is transparent.\n */\n surface?: ListSurface;\n /** Physical divider edges in canonical top/right/bottom/left order. */\n dividerSides?: Sides;\n /** A preset four-sided inset; see `ListInset`. */\n /**\n * Cap the list's content at a readable measure, plus its insets, so a page\n * column needs no application CSS. Composes with `inset=\"document\"`.\n */\n contentWidth?: ListContentWidth;\n /** Where a `contentWidth` column sits: `center` (default) or `start`. */\n contentAlign?: 'start' | 'center';\n inset?: ListInset;\n /** Physical sides that receive the standard 17px text inset. */\n textInsets?: Sides;\n /** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */\n controlInsets?: Sides;\n className?: string;\n /**\n * The list's id, so app code can address it: name it as a\n * `wireScrollDividers` scroller (with a `Toolbar` above it as its chrome),\n * or find it in tests.\n */\n id?: string;\n /**\n * Safe `data-*`, `aria-*`, and structural `role` metadata (a named drop\n * `region`, `aria-busy`); List-owned structural attributes remain\n * protected, and a multi-select List owns its grid role and name.\n */\n rootAttributes?: ListRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list's configuration, apart from its content and styling hooks: the props a\n * composite that renders a `List` for the app (the Workbench's `mainHeader` /\n * `mainFooter` chrome) forwards, so the app configures that list instead of\n * styling it. An omitted or `undefined` field keeps the composite's default.\n */\nexport type ListConfig = Pick<\n ListProps,\n 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' | 'textInsets' | 'controlInsets'\n>;\n\n/** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */\nexport function List({\n children,\n selectionMode,\n ariaLabel,\n gap = false,\n flex = false,\n fill = false,\n hAlign = 'full',\n vAlign = 'top',\n scrollable = false,\n scrollClearance,\n frame = false,\n maxHeight,\n minHeight,\n surface,\n inset,\n contentWidth,\n contentAlign = 'center',\n dividerSides = '',\n textInsets = '',\n controlInsets = '',\n className = '',\n id,\n rootAttributes = {},\n slot,\n}: ListProps) {\n if (selectionMode === 'multiple' && !ariaLabel) {\n throw new Error('Multi-select List requires an ariaLabel');\n }\n const multiple = selectionMode === 'multiple';\n const safeRootAttributes = filterRootAttributes(\n rootAttributes,\n multiple\n ? new Set([...listProtectedAttributes, ...listGridAttributes])\n : listProtectedAttributes,\n );\n const gridAttributes = multiple\n ? {\n role: 'grid',\n 'aria-label': ariaLabel,\n 'aria-multiselectable': 'true',\n }\n : {};\n const gapStyle =\n gap === true\n ? '--_kui-list-gap:var(--kui-list-gap)'\n : gap === false\n ? ''\n : typeof gap === 'string'\n ? `--_kui-list-gap:${gapLength(gap)}`\n : `--_kui-list-column-gap:${gapLength(gap.column)};--_kui-list-row-gap:${gapLength(gap.row)}`;\n const flexValue = flex === true ? '1 1 auto' : flex || undefined;\n const style = [\n gapStyle,\n flexValue ? `--_kui-list-flex:${flexValue}` : '',\n maxHeight === undefined ? '' : `--_kui-list-max-height:${maxHeight}`,\n minHeight === undefined ? '' : `--_kui-list-min-height:${minHeight}`,\n ]\n .filter(Boolean)\n .join(';');\n\n return (\n <div\n {...safeRootAttributes}\n {...gridAttributes}\n id={id}\n class={`kui-list ${className}`.trim()}\n data-component=\"list\"\n data-gap={String(Boolean(gap))}\n data-flex={String(Boolean(flex))}\n data-fill={fill ? 'true' : undefined}\n data-h-align={horizontalAlignment(hAlign)}\n data-v-align={verticalAlignment(vAlign)}\n data-scrollable={String(scrollable)}\n data-scroll-clearance={scrollClearance}\n data-frame={frame ? 'true' : undefined}\n data-surface={surface}\n data-inset={inset}\n data-content-width={contentWidth}\n data-content-align={contentWidth === undefined ? undefined : contentAlign}\n divider-sides={dividerSides || undefined}\n data-text-insets={textInsets || undefined}\n data-control-insets={controlInsets || undefined}\n style={style || undefined}\n slot={slot}\n >\n {children}\n </div>\n );\n}\n\nexport type {\n HorizontalAlignment,\n ListVerticalAlignment,\n VerticalAlignment,\n} from '../../../shared/layout/flex-alignment.js';\nexport type { ScrollClearance } from '../../../shared/layout/scroll-clearance.js';\nexport type { Sides } from '../../../shared/layout/sides.js';\nexport type {\n CssFlex,\n CssFlexKeyword,\n CssLength,\n UiGap,\n UiGapValue,\n UiSpaceName,\n} from '../../../shared/styles/css-values.js';\n"]}
|
|
@@ -16,6 +16,7 @@ var PROTECTED_ROOT_DATA_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
16
16
|
"data-divider",
|
|
17
17
|
"data-inline",
|
|
18
18
|
"data-width",
|
|
19
|
+
"data-wrap",
|
|
19
20
|
"data-indicator-tone",
|
|
20
21
|
"data-toggle"
|
|
21
22
|
]);
|
|
@@ -35,6 +36,7 @@ function ListHeader({
|
|
|
35
36
|
divider = "none",
|
|
36
37
|
inline = false,
|
|
37
38
|
width = "fill",
|
|
39
|
+
wrap = false,
|
|
38
40
|
indicatorTone = "neutral",
|
|
39
41
|
action,
|
|
40
42
|
actionLabel,
|
|
@@ -83,6 +85,7 @@ function ListHeader({
|
|
|
83
85
|
"data-divider": divider,
|
|
84
86
|
"data-inline": String(inline),
|
|
85
87
|
"data-width": width,
|
|
88
|
+
"data-wrap": wrap ? "true" : void 0,
|
|
86
89
|
"data-indicator-tone": indicatorTone,
|
|
87
90
|
"data-toggle": "true",
|
|
88
91
|
"data-placeholder": placeholder ? "true" : void 0,
|
|
@@ -123,6 +126,7 @@ function ListHeader({
|
|
|
123
126
|
"data-divider": divider,
|
|
124
127
|
"data-inline": String(inline),
|
|
125
128
|
"data-width": width,
|
|
129
|
+
"data-wrap": wrap ? "true" : void 0,
|
|
126
130
|
"data-indicator-tone": indicatorTone,
|
|
127
131
|
"data-toggle": "false",
|
|
128
132
|
"data-placeholder": placeholder ? "true" : void 0,
|
|
@@ -162,4 +166,4 @@ function ListHeader({
|
|
|
162
166
|
|
|
163
167
|
export { ListHeader };
|
|
164
168
|
|
|
165
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-NR6O74ST.js.map
|