@nldd/design-system 0.8.64 → 0.8.66
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/dist/components/actions/button/button.d.ts.map +1 -1
- package/dist/components/actions/button/button.js +7 -6
- package/dist/components/actions/button/button.js.map +1 -1
- package/dist/components/actions/button/button.styles.d.ts.map +1 -1
- package/dist/components/actions/button/button.styles.js +9 -5
- package/dist/components/actions/button/button.styles.js.map +1 -1
- package/dist/components/actions/button-bar/button-bar.d.ts.map +1 -1
- package/dist/components/actions/button-bar/button-bar.js +3 -2
- package/dist/components/actions/button-bar/button-bar.js.map +1 -1
- package/dist/components/actions/button-group/button-group.d.ts.map +1 -1
- package/dist/components/actions/button-group/button-group.js +3 -2
- package/dist/components/actions/button-group/button-group.js.map +1 -1
- package/dist/components/actions/icon-button/icon-button.d.ts +4 -0
- package/dist/components/actions/icon-button/icon-button.d.ts.map +1 -1
- package/dist/components/actions/icon-button/icon-button.js +13 -5
- package/dist/components/actions/icon-button/icon-button.js.map +1 -1
- package/dist/components/actions/icon-button/icon-button.styles.d.ts.map +1 -1
- package/dist/components/actions/icon-button/icon-button.styles.js +15 -10
- package/dist/components/actions/icon-button/icon-button.styles.js.map +1 -1
- package/dist/components/actions/icon-button/icon-button.template.d.ts.map +1 -1
- package/dist/components/actions/icon-button/icon-button.template.js +2 -0
- package/dist/components/actions/icon-button/icon-button.template.js.map +1 -1
- package/dist/components/actions/menu/menu.d.ts +1 -0
- package/dist/components/actions/menu/menu.d.ts.map +1 -1
- package/dist/components/actions/menu/menu.js +33 -15
- package/dist/components/actions/menu/menu.js.map +1 -1
- package/dist/components/actions/menu/menu.styles.d.ts.map +1 -1
- package/dist/components/actions/menu/menu.styles.js +8 -0
- package/dist/components/actions/menu/menu.styles.js.map +1 -1
- package/dist/components/actions/split-button/split-button.d.ts.map +1 -1
- package/dist/components/actions/split-button/split-button.js +5 -4
- package/dist/components/actions/split-button/split-button.js.map +1 -1
- package/dist/components/actions/toolbar/toolbar.d.ts +15 -2
- package/dist/components/actions/toolbar/toolbar.d.ts.map +1 -1
- package/dist/components/actions/toolbar/toolbar.js +116 -42
- package/dist/components/actions/toolbar/toolbar.js.map +1 -1
- package/dist/components/actions/toolbar/toolbar.styles.d.ts.map +1 -1
- package/dist/components/actions/toolbar/toolbar.styles.js +33 -18
- package/dist/components/actions/toolbar/toolbar.styles.js.map +1 -1
- package/dist/components/actions/toolbar/toolbar.template.d.ts.map +1 -1
- package/dist/components/actions/toolbar/toolbar.template.js +5 -2
- package/dist/components/actions/toolbar/toolbar.template.js.map +1 -1
- package/dist/components/components.js +104 -102
- package/dist/components/content/blockquote/blockquote.styles.d.ts.map +1 -1
- package/dist/components/content/blockquote/blockquote.styles.js +0 -3
- package/dist/components/content/blockquote/blockquote.styles.js.map +1 -1
- package/dist/components/content/byline/byline.d.ts.map +1 -1
- package/dist/components/content/byline/byline.js +3 -2
- package/dist/components/content/byline/byline.js.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.d.ts +24 -64
- package/dist/components/content/code-viewer/code-viewer.d.ts.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.js +239 -156
- package/dist/components/content/code-viewer/code-viewer.js.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.styles.d.ts.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.styles.js +33 -92
- package/dist/components/content/code-viewer/code-viewer.styles.js.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.template.d.ts.map +1 -1
- package/dist/components/content/code-viewer/code-viewer.template.js +10 -29
- package/dist/components/content/code-viewer/code-viewer.template.js.map +1 -1
- package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
- package/dist/components/content/icon/icon-aliases.js +43 -8
- package/dist/components/content/icon/icon-aliases.js.map +1 -1
- package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
- package/dist/components/content/icon/icon-registry.js +34 -4
- package/dist/components/content/icon/icon-registry.js.map +1 -1
- package/dist/components/content/icon/icon.d.ts.map +1 -1
- package/dist/components/content/icon/icon.js +3 -2
- package/dist/components/content/icon/icon.js.map +1 -1
- package/dist/components/content/image/image.d.ts.map +1 -1
- package/dist/components/content/image/image.js +7 -6
- package/dist/components/content/image/image.js.map +1 -1
- package/dist/components/content/image/image.styles.d.ts.map +1 -1
- package/dist/components/content/image/image.styles.js +2 -6
- package/dist/components/content/image/image.styles.js.map +1 -1
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.d.ts.map +1 -1
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.js +8 -7
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.js.map +1 -1
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.styles.d.ts.map +1 -1
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.styles.js +5 -1
- package/dist/components/content/keyboard-shortcut/keyboard-shortcut.styles.js.map +1 -1
- package/dist/components/content/rich-text/rich-text.d.ts.map +1 -1
- package/dist/components/content/rich-text/rich-text.js +3 -2
- package/dist/components/content/rich-text/rich-text.js.map +1 -1
- package/dist/components/content/tag/tag.d.ts.map +1 -1
- package/dist/components/content/tag/tag.js +5 -4
- package/dist/components/content/tag/tag.js.map +1 -1
- package/dist/components/content/title/title.d.ts.map +1 -1
- package/dist/components/content/title/title.js +2 -1
- package/dist/components/content/title/title.js.map +1 -1
- package/dist/components/content/token/token.d.ts +70 -0
- package/dist/components/content/token/token.d.ts.map +1 -0
- package/dist/components/content/token/token.js +170 -0
- package/dist/components/content/token/token.js.map +1 -0
- package/dist/components/content/token/token.styles.d.ts.map +1 -0
- package/dist/components/content/token/token.styles.js +122 -0
- package/dist/components/content/token/token.styles.js.map +1 -0
- package/dist/components/content/token/token.template.d.ts +6 -0
- package/dist/components/content/token/token.template.d.ts.map +1 -0
- package/dist/components/content/token/token.template.js +47 -0
- package/dist/components/content/token/token.template.js.map +1 -0
- package/dist/components/content/tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/content/tooltip/tooltip.js +14 -5
- package/dist/components/content/tooltip/tooltip.js.map +1 -1
- package/dist/components/content/tooltip/tooltip.styles.d.ts.map +1 -1
- package/dist/components/content/tooltip/tooltip.styles.js +11 -0
- package/dist/components/content/tooltip/tooltip.styles.js.map +1 -1
- package/dist/components/gherkin-DhZlEZiy.js +115 -0
- package/dist/components/index-Bfw_pYWB.js +405 -0
- package/dist/components/index-Bqf6o41r.js +81 -0
- package/dist/components/index-CKnwqp_9.js +688 -0
- package/dist/components/index-CXT1jMFt.js +384 -0
- package/dist/components/index-DO7aT0MT.js +177 -0
- package/dist/components/index-DWwviobk.js +703 -0
- package/dist/components/index-DjsXjoZJ.js +67143 -0
- package/dist/components/index.d.ts +20 -18
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +20 -18
- package/dist/components/index.js.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.d.ts +58 -29
- package/dist/components/inputs/code-editor/code-editor.d.ts.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.js +241 -52
- package/dist/components/inputs/code-editor/code-editor.js.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.styles.d.ts.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.styles.js +58 -46
- package/dist/components/inputs/code-editor/code-editor.styles.js.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.template.d.ts +1 -1
- package/dist/components/inputs/code-editor/code-editor.template.d.ts.map +1 -1
- package/dist/components/inputs/code-editor/code-editor.template.js +5 -22
- package/dist/components/inputs/code-editor/code-editor.template.js.map +1 -1
- package/dist/components/inputs/combo-box/combo-box.d.ts +15 -4
- package/dist/components/inputs/combo-box/combo-box.d.ts.map +1 -1
- package/dist/components/inputs/combo-box/combo-box.js +53 -9
- package/dist/components/inputs/combo-box/combo-box.js.map +1 -1
- package/dist/components/inputs/dropdown/dropdown.d.ts.map +1 -1
- package/dist/components/inputs/dropdown/dropdown.js +2 -1
- package/dist/components/inputs/dropdown/dropdown.js.map +1 -1
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts +1 -1
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.d.ts.map +1 -1
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js +6 -5
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.js.map +1 -1
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.styles.d.ts.map +1 -1
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.styles.js +8 -11
- package/dist/components/inputs/multi-line-text-field/multi-line-text-field.styles.js.map +1 -1
- package/dist/components/inputs/number-field/number-field.d.ts.map +1 -1
- package/dist/components/inputs/number-field/number-field.js +2 -1
- package/dist/components/inputs/number-field/number-field.js.map +1 -1
- package/dist/components/inputs/password-field/password-field.d.ts.map +1 -1
- package/dist/components/inputs/password-field/password-field.js +3 -2
- package/dist/components/inputs/password-field/password-field.js.map +1 -1
- package/dist/components/inputs/radio-button-group/radio-button-group.js +1 -1
- package/dist/components/inputs/radio-button-group/radio-button-group.js.map +1 -1
- package/dist/components/inputs/search-field/search-field.d.ts.map +1 -1
- package/dist/components/inputs/search-field/search-field.js +2 -1
- package/dist/components/inputs/search-field/search-field.js.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.d.ts +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.d.ts.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.js +10 -9
- package/dist/components/inputs/segmented-control/segmented-control.js.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.styles.d.ts.map +1 -1
- package/dist/components/inputs/segmented-control/segmented-control.styles.js +70 -36
- package/dist/components/inputs/segmented-control/segmented-control.styles.js.map +1 -1
- package/dist/components/inputs/stepper/stepper.d.ts.map +1 -1
- package/dist/components/inputs/stepper/stepper.js +2 -1
- package/dist/components/inputs/stepper/stepper.js.map +1 -1
- package/dist/components/inputs/switch/switch.d.ts.map +1 -1
- package/dist/components/inputs/switch/switch.js +2 -1
- package/dist/components/inputs/switch/switch.js.map +1 -1
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts +51 -0
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js +148 -0
- package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.annotations.d.ts +47 -0
- package/dist/components/inputs/text-editor/text-editor.annotations.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.annotations.js +327 -0
- package/dist/components/inputs/text-editor/text-editor.annotations.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.caret.d.ts +13 -0
- package/dist/components/inputs/text-editor/text-editor.caret.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.caret.js +27 -0
- package/dist/components/inputs/text-editor/text-editor.caret.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts +68 -0
- package/dist/components/inputs/text-editor/text-editor.commands.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.commands.js +420 -0
- package/dist/components/inputs/text-editor/text-editor.commands.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.d.ts +241 -0
- package/dist/components/inputs/text-editor/text-editor.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.drag.d.ts +30 -0
- package/dist/components/inputs/text-editor/text-editor.drag.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.drag.js +231 -0
- package/dist/components/inputs/text-editor/text-editor.drag.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.i18n.d.ts +8 -0
- package/dist/components/inputs/text-editor/text-editor.i18n.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.i18n.js +13 -0
- package/dist/components/inputs/text-editor/text-editor.i18n.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.js +780 -0
- package/dist/components/inputs/text-editor/text-editor.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.links.d.ts +18 -0
- package/dist/components/inputs/text-editor/text-editor.links.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.links.js +147 -0
- package/dist/components/inputs/text-editor/text-editor.links.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.markdown.d.ts +20 -0
- package/dist/components/inputs/text-editor/text-editor.markdown.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.markdown.js +372 -0
- package/dist/components/inputs/text-editor/text-editor.markdown.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts +32 -0
- package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.mentions.js +153 -0
- package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts +12 -0
- package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js +106 -0
- package/dist/components/inputs/text-editor/text-editor.ordered-list.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.styles.d.ts +2 -0
- package/dist/components/inputs/text-editor/text-editor.styles.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.styles.js +592 -0
- package/dist/components/inputs/text-editor/text-editor.styles.js.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.template.d.ts +4 -0
- package/dist/components/inputs/text-editor/text-editor.template.d.ts.map +1 -0
- package/dist/components/inputs/text-editor/text-editor.template.js +7 -0
- package/dist/components/inputs/text-editor/text-editor.template.js.map +1 -0
- package/dist/components/inputs/text-field/text-field.d.ts.map +1 -1
- package/dist/components/inputs/text-field/text-field.js +3 -2
- package/dist/components/inputs/text-field/text-field.js.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.js +4 -3
- package/dist/components/inputs/toggle-button/toggle-button.js.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.styles.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button/toggle-button.styles.js +14 -10
- package/dist/components/inputs/toggle-button/toggle-button.styles.js.map +1 -1
- package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts +1 -1
- package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts.map +1 -1
- package/dist/components/inputs/toggle-button-group/toggle-button-group.js +5 -4
- package/dist/components/inputs/toggle-button-group/toggle-button-group.js.map +1 -1
- package/dist/components/inputs/token-field/token-field.d.ts +257 -0
- package/dist/components/inputs/token-field/token-field.d.ts.map +1 -0
- package/dist/components/inputs/token-field/token-field.i18n.d.ts +9 -0
- package/dist/components/inputs/token-field/token-field.i18n.d.ts.map +1 -0
- package/dist/components/inputs/token-field/token-field.i18n.js +8 -0
- package/dist/components/inputs/token-field/token-field.i18n.js.map +1 -0
- package/dist/components/inputs/token-field/token-field.js +889 -0
- package/dist/components/inputs/token-field/token-field.js.map +1 -0
- package/dist/components/inputs/token-field/token-field.styles.d.ts +2 -0
- package/dist/components/inputs/token-field/token-field.styles.d.ts.map +1 -0
- package/dist/components/inputs/token-field/token-field.styles.js +194 -0
- package/dist/components/inputs/token-field/token-field.styles.js.map +1 -0
- package/dist/components/inputs/token-field/token-field.template.d.ts +8 -0
- package/dist/components/inputs/token-field/token-field.template.d.ts.map +1 -0
- package/dist/components/inputs/token-field/token-field.template.js +136 -0
- package/dist/components/inputs/token-field/token-field.template.js.map +1 -0
- package/dist/components/layout/app-view/app-view.d.ts +26 -6
- package/dist/components/layout/app-view/app-view.d.ts.map +1 -1
- package/dist/components/layout/app-view/app-view.js +103 -12
- package/dist/components/layout/app-view/app-view.js.map +1 -1
- package/dist/components/layout/app-view/app-view.styles.d.ts.map +1 -1
- package/dist/components/layout/app-view/app-view.styles.js +25 -0
- package/dist/components/layout/app-view/app-view.styles.js.map +1 -1
- package/dist/components/layout/box/box.d.ts.map +1 -1
- package/dist/components/layout/box/box.js +2 -1
- package/dist/components/layout/box/box.js.map +1 -1
- package/dist/components/layout/box/box.styles.d.ts.map +1 -1
- package/dist/components/layout/box/box.styles.js +1 -6
- package/dist/components/layout/box/box.styles.js.map +1 -1
- package/dist/components/layout/collection/collection.d.ts +5 -0
- package/dist/components/layout/collection/collection.d.ts.map +1 -1
- package/dist/components/layout/collection/collection.js +17 -1
- package/dist/components/layout/collection/collection.js.map +1 -1
- package/dist/components/layout/collection/collection.styles.d.ts.map +1 -1
- package/dist/components/layout/collection/collection.styles.js +18 -17
- package/dist/components/layout/collection/collection.styles.js.map +1 -1
- package/dist/components/layout/page/page.d.ts +31 -1
- package/dist/components/layout/page/page.d.ts.map +1 -1
- package/dist/components/layout/page/page.js +112 -26
- package/dist/components/layout/page/page.js.map +1 -1
- package/dist/components/layout/page/page.styles.d.ts.map +1 -1
- package/dist/components/layout/page/page.styles.js +48 -0
- package/dist/components/layout/page/page.styles.js.map +1 -1
- package/dist/components/layout/page-footer/page-footer.d.ts.map +1 -1
- package/dist/components/layout/page-footer/page-footer.js +2 -1
- package/dist/components/layout/page-footer/page-footer.js.map +1 -1
- package/dist/components/layout/page-sections/hero/hero.d.ts +7 -23
- package/dist/components/layout/page-sections/hero/hero.d.ts.map +1 -1
- package/dist/components/layout/page-sections/hero/hero.js +12 -73
- package/dist/components/layout/page-sections/hero/hero.js.map +1 -1
- package/dist/components/layout/page-sections/hero/hero.styles.d.ts.map +1 -1
- package/dist/components/layout/page-sections/hero/hero.styles.js +13 -159
- package/dist/components/layout/page-sections/hero/hero.styles.js.map +1 -1
- package/dist/components/layout/popover/popover.d.ts +1 -0
- package/dist/components/layout/popover/popover.d.ts.map +1 -1
- package/dist/components/layout/popover/popover.js +14 -1
- package/dist/components/layout/popover/popover.js.map +1 -1
- package/dist/components/layout/popover/popover.styles.d.ts.map +1 -1
- package/dist/components/layout/popover/popover.styles.js +11 -0
- package/dist/components/layout/popover/popover.styles.js.map +1 -1
- package/dist/components/layout/sheet/sheet.d.ts +5 -1
- package/dist/components/layout/sheet/sheet.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.js +20 -6
- package/dist/components/layout/sheet/sheet.js.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
- package/dist/components/layout/sheet/sheet.styles.js +60 -83
- package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
- package/dist/components/layout/spacer/spacer.d.ts.map +1 -1
- package/dist/components/layout/spacer/spacer.js +2 -1
- package/dist/components/layout/spacer/spacer.js.map +1 -1
- package/dist/components/layout/spacer/spacer.styles.d.ts.map +1 -1
- package/dist/components/layout/spacer/spacer.styles.js +0 -1
- package/dist/components/layout/spacer/spacer.styles.js.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.d.ts +3 -0
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.d.ts.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.js +49 -0
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.js.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.styles.d.ts.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.styles.js +55 -0
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.styles.js.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.template.d.ts.map +1 -1
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.template.js +18 -9
- package/dist/components/layout/split-views/bar-split-view/bar-split-view.template.js.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.d.ts +8 -0
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.d.ts.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.js +21 -0
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.js.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.d.ts.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.js +34 -0
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.styles.js.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.template.d.ts.map +1 -1
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.template.js +17 -7
- package/dist/components/layout/split-views/navigation-split-view/navigation-split-view.template.js.map +1 -1
- package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.d.ts +6 -0
- package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.d.ts.map +1 -1
- package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.js +17 -0
- package/dist/components/layout/split-views/side-by-side-split-view/side-by-side-split-view.js.map +1 -1
- package/dist/components/layout/split-views/split-view-divider/split-view-divider.d.ts.map +1 -1
- package/dist/components/layout/split-views/split-view-divider/split-view-divider.js +2 -1
- package/dist/components/layout/split-views/split-view-divider/split-view-divider.js.map +1 -1
- package/dist/components/layout/split-views/split-view-divider/split-view-divider.styles.js +10 -10
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.d.ts +10 -0
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.d.ts.map +1 -1
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.js +13 -0
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.js.map +1 -1
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.styles.d.ts.map +1 -1
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.styles.js +19 -0
- package/dist/components/layout/split-views/split-view-pane/split-view-pane.styles.js.map +1 -1
- package/dist/components/layout/window/window.d.ts.map +1 -1
- package/dist/components/layout/window/window.js +11 -2
- package/dist/components/layout/window/window.js.map +1 -1
- package/dist/components/lists-and-tables/cells/cell/cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/cell/cell.js +4 -3
- package/dist/components/lists-and-tables/cells/cell/cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/description-cell/description-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/description-cell/description-cell.js +3 -2
- package/dist/components/lists-and-tables/cells/description-cell/description-cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/drag-handle-cell/drag-handle-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/drag-handle-cell/drag-handle-cell.js +2 -1
- package/dist/components/lists-and-tables/cells/drag-handle-cell/drag-handle-cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.js +3 -2
- package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.js +10 -9
- package/dist/components/lists-and-tables/cells/text-cell/text-cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.js +3 -2
- package/dist/components/lists-and-tables/cells/timeline-track-cell/timeline-track-cell.js.map +1 -1
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.d.ts.map +1 -1
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.js +9 -8
- package/dist/components/lists-and-tables/cells/title-cell/title-cell.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.js +5 -4
- package/dist/components/lists-and-tables/list/list.js.map +1 -1
- package/dist/components/lists-and-tables/list/list.styles.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list/list.styles.js +3 -2
- package/dist/components/lists-and-tables/list/list.styles.js.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.d.ts.map +1 -1
- package/dist/components/lists-and-tables/list-item/list-item.js +2 -1
- package/dist/components/lists-and-tables/list-item/list-item.js.map +1 -1
- package/dist/components/lists-and-tables/table/table.d.ts.map +1 -1
- package/dist/components/lists-and-tables/table/table.js +4 -3
- package/dist/components/lists-and-tables/table/table.js.map +1 -1
- package/dist/components/navigation/breadcrumbs/breadcrumbs.d.ts.map +1 -1
- package/dist/components/navigation/breadcrumbs/breadcrumbs.js +2 -1
- package/dist/components/navigation/breadcrumbs/breadcrumbs.js.map +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.d.ts.map +1 -1
- package/dist/components/navigation/document-tab-bar/document-tab-bar.js +5 -4
- package/dist/components/navigation/document-tab-bar/document-tab-bar.js.map +1 -1
- package/dist/components/navigation/link/link.d.ts.map +1 -1
- package/dist/components/navigation/link/link.js +2 -1
- package/dist/components/navigation/link/link.js.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.d.ts.map +1 -1
- package/dist/components/navigation/menu-bar/menu-bar.js +2 -1
- package/dist/components/navigation/menu-bar/menu-bar.js.map +1 -1
- package/dist/components/navigation/menu-bar-item/menu-bar-item.d.ts.map +1 -1
- package/dist/components/navigation/menu-bar-item/menu-bar-item.js +4 -3
- package/dist/components/navigation/menu-bar-item/menu-bar-item.js.map +1 -1
- package/dist/components/navigation/skip-link/skip-link.d.ts.map +1 -1
- package/dist/components/navigation/skip-link/skip-link.js +2 -1
- package/dist/components/navigation/skip-link/skip-link.js.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.d.ts +7 -0
- package/dist/components/navigation/tab-bar/tab-bar.d.ts.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.js +31 -5
- package/dist/components/navigation/tab-bar/tab-bar.js.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.styles.d.ts.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.styles.js +74 -78
- package/dist/components/navigation/tab-bar/tab-bar.styles.js.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.template.d.ts.map +1 -1
- package/dist/components/navigation/tab-bar/tab-bar.template.js +8 -1
- package/dist/components/navigation/tab-bar/tab-bar.template.js.map +1 -1
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.d.ts.map +1 -1
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.js +7 -6
- package/dist/components/navigation/top-navigation-bar/top-navigation-bar.js.map +1 -1
- package/dist/components/navigation/top-title-bar/top-title-bar.d.ts +6 -1
- package/dist/components/navigation/top-title-bar/top-title-bar.d.ts.map +1 -1
- package/dist/components/navigation/top-title-bar/top-title-bar.js +47 -10
- package/dist/components/navigation/top-title-bar/top-title-bar.js.map +1 -1
- package/dist/components/shell-BlsXDxCn.js +222 -0
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js +4 -3
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.styles.js +0 -1
- package/dist/components/status-and-feedback/activity-indicator/activity-indicator.styles.js.map +1 -1
- package/dist/components/status-and-feedback/badge/badge.d.ts.map +1 -1
- package/dist/components/status-and-feedback/badge/badge.js +4 -3
- package/dist/components/status-and-feedback/badge/badge.js.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.d.ts +0 -1
- package/dist/components/status-and-feedback/banner/banner.d.ts.map +1 -1
- package/dist/components/status-and-feedback/banner/banner.js +13 -13
- package/dist/components/status-and-feedback/banner/banner.js.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js +5 -4
- package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.d.ts +1 -0
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.d.ts.map +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.js +35 -4
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.js.map +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.styles.js +11 -0
- package/dist/components/status-and-feedback/just-in-time-education/just-in-time-education.styles.js.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts.map +1 -1
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js +4 -3
- package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.js +9 -8
- package/dist/components/status-and-feedback/progress-bar/progress-bar.js.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.js +0 -6
- package/dist/components/status-and-feedback/progress-bar/progress-bar.styles.js.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.js +8 -7
- package/dist/components/status-and-feedback/progress-circle/progress-circle.js.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.d.ts.map +1 -1
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js +0 -2
- package/dist/components/status-and-feedback/progress-circle/progress-circle.styles.js.map +1 -1
- package/dist/components/status-and-feedback/status-bar/status-bar.d.ts.map +1 -1
- package/dist/components/status-and-feedback/status-bar/status-bar.js +3 -2
- package/dist/components/status-and-feedback/status-bar/status-bar.js.map +1 -1
- package/dist/components/toml-BOuWGMcf.js +76 -0
- package/dist/css/fouc.css +30 -0
- package/dist/css/global.css +1 -0
- package/dist/css/rich-text.css +0 -5
- package/dist/css/settings.css +25 -10
- package/dist/utilities/codemirror/codemirror-element.d.ts +66 -0
- package/dist/utilities/codemirror/codemirror-element.d.ts.map +1 -0
- package/dist/utilities/codemirror/codemirror-element.js +121 -0
- package/dist/utilities/codemirror/codemirror-element.js.map +1 -0
- package/dist/utilities/codemirror/languages.d.ts +4 -0
- package/dist/utilities/codemirror/languages.d.ts.map +1 -0
- package/dist/utilities/codemirror/languages.js +39 -0
- package/dist/utilities/codemirror/languages.js.map +1 -0
- package/dist/utilities/codemirror/theme.d.ts +4 -0
- package/dist/utilities/codemirror/theme.d.ts.map +1 -0
- package/dist/utilities/codemirror/theme.js +84 -0
- package/dist/utilities/codemirror/theme.js.map +1 -0
- package/dist/utilities/dismiss-from-title-bar.d.ts +19 -0
- package/dist/utilities/dismiss-from-title-bar.d.ts.map +1 -0
- package/dist/utilities/dismiss-from-title-bar.js +21 -0
- package/dist/utilities/dismiss-from-title-bar.js.map +1 -0
- package/dist/utilities/reflect-non-default.d.ts +30 -0
- package/dist/utilities/reflect-non-default.d.ts.map +1 -0
- package/dist/utilities/reflect-non-default.js +34 -0
- package/dist/utilities/reflect-non-default.js.map +1 -0
- package/dist/utilities/scroll-mode-controller.d.ts +69 -0
- package/dist/utilities/scroll-mode-controller.d.ts.map +1 -0
- package/dist/utilities/scroll-mode-controller.js +101 -0
- package/dist/utilities/scroll-mode-controller.js.map +1 -0
- package/package.json +92 -68
- package/dist/components/index-BNhqNvDd.js +0 -36784
- package/dist/components/inputs/token/token.d.ts +0 -42
- package/dist/components/inputs/token/token.d.ts.map +0 -1
- package/dist/components/inputs/token/token.js +0 -86
- package/dist/components/inputs/token/token.js.map +0 -1
- package/dist/components/inputs/token/token.styles.d.ts.map +0 -1
- package/dist/components/inputs/token/token.styles.js +0 -142
- package/dist/components/inputs/token/token.styles.js.map +0 -1
- package/dist/components/inputs/token/token.template.d.ts +0 -4
- package/dist/components/inputs/token/token.template.d.ts.map +0 -1
- package/dist/components/inputs/token/token.template.js +0 -41
- package/dist/components/inputs/token/token.template.js.map +0 -1
- package/dist/components/prism-bash-vbqaw3JR.js +0 -226
- package/dist/components/prism-css-B93tXdOU.js +0 -59
- package/dist/components/prism-gherkin-CMPYyXOQ.js +0 -82
- package/dist/components/prism-javascript-DeC_17Pw.js +0 -140
- package/dist/components/prism-json-DIMpow89.js +0 -25
- package/dist/components/prism-markdown-D-uFBkiz.js +0 -339
- package/dist/components/prism-markup-DfJYPYHA.js +0 -177
- package/dist/components/prism-python--N285k7w.js +0 -99
- package/dist/components/prism-rust-Cnm1tSdo.js +0 -157
- package/dist/components/prism-sql-BGqCBMyJ.js +0 -33
- package/dist/components/prism-toml-Ubdq-a5x.js +0 -45
- package/dist/components/prism-typescript-BPJAiB1s.js +0 -87
- package/dist/components/prism-yaml-DO0f9pf6.js +0 -71
- /package/dist/components/{inputs → content}/token/token.styles.d.ts +0 -0
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var NLDDTokenField_1;
|
|
8
|
+
/**
|
|
9
|
+
* Nederlandse Digitale Dienst Token Field Component (Lit + TypeScript)
|
|
10
|
+
*
|
|
11
|
+
* A multi-select input that looks like a normal input field: chosen values show
|
|
12
|
+
* as dismissible tokens in a wrapping row, followed by an inline text input that
|
|
13
|
+
* stretches to fill the remaining space and wraps to a new line (growing the
|
|
14
|
+
* field) when it no longer fits. Options are supplied as a slotted nldd-menu,
|
|
15
|
+
* exactly like nldd-combo-box; the menu filters as you type, with a chevron picker
|
|
16
|
+
* button, arrow-key roving across the tokens and ElementInternals form participation.
|
|
17
|
+
*
|
|
18
|
+
* @element nldd-token-field
|
|
19
|
+
* @attr {string} values - Initial token values as a comma-separated string
|
|
20
|
+
* (e.g. "nl, be, de"). Not reflected; the live value is
|
|
21
|
+
* the `.values` array property. Values can't contain commas.
|
|
22
|
+
* @attr {string} placeholder - Placeholder shown in the input
|
|
23
|
+
* @attr {string} type - Input type forwarded to the inner input (e.g. 'email')
|
|
24
|
+
* @attr {string} autocomplete - Autocomplete hint forwarded to the inner input
|
|
25
|
+
* @attr {string} accessible-label - Accessible label forwarded as aria-label to the input
|
|
26
|
+
* @attr {boolean} allow-custom - Allow free-typed values (not just menu options)
|
|
27
|
+
* @attr {boolean} valid - Marks the field valid (shows the valid icon)
|
|
28
|
+
* @attr {boolean} invalid - Marks the field invalid (shows the invalid icon)
|
|
29
|
+
* @attr {boolean} no-spellcheck - Disables browser spellchecking on the inner input
|
|
30
|
+
* @attr {boolean} readonly - Readonly: static tokens, no input/picker, read-only surface
|
|
31
|
+
* @attr {boolean} required - Marks the field required (invalid when it has no tokens)
|
|
32
|
+
* @attr {boolean} disabled - Disabled state
|
|
33
|
+
* @attr {string} token-control - Trailing control per token: 'dismiss' (default, a ✕ that removes it) or 'menu' (a ⌄ opening a per-token action menu supplied by the template prototypes)
|
|
34
|
+
* @attr {string} name - Name for form submission
|
|
35
|
+
* @attr {object} translations - Override translation keys; unset keys fall back to Dutch
|
|
36
|
+
*
|
|
37
|
+
* @slot - An nldd-menu with nldd-menu-item options; each item's `value`/`text`
|
|
38
|
+
* supplies a token's value and its display label.
|
|
39
|
+
* @slot template - `nldd-token` prototypes supplying each token's action menu when
|
|
40
|
+
* token-control="menu": a keyless one is the shared default, a
|
|
41
|
+
* `data-value="X"` one overrides value X. Only the prototype's nested
|
|
42
|
+
* `nldd-menu` is used today; its other props are ignored.
|
|
43
|
+
*
|
|
44
|
+
* @fires change - When the selected values change; detail: { values: string[] }
|
|
45
|
+
* @fires input - When the input text changes; detail: { value: string }
|
|
46
|
+
* @fires token-action - When a token's menu action is chosen (token-control="menu"); detail: { value: string, action: string }
|
|
47
|
+
*/
|
|
48
|
+
import { LitElement } from 'lit';
|
|
49
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
50
|
+
import { tokenFieldStyles } from './token-field.styles.js';
|
|
51
|
+
import { tokenFieldTemplate } from './token-field.template.js';
|
|
52
|
+
import { nlddTokenFieldTranslations } from './token-field.i18n.js';
|
|
53
|
+
import '../../actions/menu/menu.js';
|
|
54
|
+
let NLDDTokenField = NLDDTokenField_1 = class NLDDTokenField extends LitElement {
|
|
55
|
+
constructor() {
|
|
56
|
+
super(...arguments);
|
|
57
|
+
this._internals = this.attachInternals();
|
|
58
|
+
this._initialValues = [];
|
|
59
|
+
this._values = [];
|
|
60
|
+
this.placeholder = '';
|
|
61
|
+
/** Input type forwarded to the inner input (e.g. 'email' for the right mobile
|
|
62
|
+
* keyboard). Values are still handled as plain strings. */
|
|
63
|
+
this.type = 'text';
|
|
64
|
+
this.autocomplete = '';
|
|
65
|
+
this.accessibleLabel = '';
|
|
66
|
+
/** Allow committing free-typed values (not just menu options): a typed value
|
|
67
|
+
* becomes a token on Enter, a trailing comma, or blur. Also governs whether
|
|
68
|
+
* the input stays visible when no options remain. */
|
|
69
|
+
this.allowCustom = false;
|
|
70
|
+
this.valid = false;
|
|
71
|
+
this.invalid = false;
|
|
72
|
+
this.noSpellcheck = false;
|
|
73
|
+
/** Readonly: shows the tokens as static (no dismiss control, no input, no
|
|
74
|
+
* picker) with the read-only surface treatment. */
|
|
75
|
+
this.readonly = false;
|
|
76
|
+
this.required = false;
|
|
77
|
+
this.disabled = false;
|
|
78
|
+
/** Trailing control on each token: 'dismiss' shows a ✕ that removes it; 'menu'
|
|
79
|
+
* shows a ⌄ that opens a per-token action menu built from the `token-menu`
|
|
80
|
+
* template. Choosing an action fires `token-action` for the app to handle. */
|
|
81
|
+
this.tokenControl = 'dismiss';
|
|
82
|
+
this.name = '';
|
|
83
|
+
this.translations = {};
|
|
84
|
+
/** The current text in the inline input; drives the menu filter. */
|
|
85
|
+
this._text = '';
|
|
86
|
+
/** Whether the option menu is currently open (drives aria-expanded). */
|
|
87
|
+
this._isOpen = false;
|
|
88
|
+
/** ID of the highlighted menu item, mirrored to aria-activedescendant. */
|
|
89
|
+
this._highlightedId = '';
|
|
90
|
+
/** Which token carries the roving tabindex — the token group's single tab stop
|
|
91
|
+
* when the input is hidden (all values in, no custom, no options left). */
|
|
92
|
+
this._rovingIndex = 0;
|
|
93
|
+
this._menuId = `nldd-token-field-menu-${NLDDTokenField_1._idCounter++}`;
|
|
94
|
+
this._menu = null;
|
|
95
|
+
this._resizeObserver = null;
|
|
96
|
+
/** Watches the slotted menu for options added/removed after the initial slot
|
|
97
|
+
* change (e.g. a framework populating them asynchronously), so the field
|
|
98
|
+
* re-evaluates whether to show the input/picker and re-resolves token labels. */
|
|
99
|
+
this._menuObserver = null;
|
|
100
|
+
/** Watches the light-DOM `[slot="template"]` prototypes for changes (menu items,
|
|
101
|
+
* their attributes, or an added/removed prototype) and invalidates the cloned
|
|
102
|
+
* per-token menus so they re-clone. These components run on live sites, not just
|
|
103
|
+
* static demos, so the prototypes can change at runtime. */
|
|
104
|
+
this._templateObserver = null;
|
|
105
|
+
/** True between a picker pointerdown-while-open and its trailing click, so the
|
|
106
|
+
* click (which follows the native light-dismiss) doesn't reopen the menu. */
|
|
107
|
+
this._pickerPointerdownWhileOpen = false;
|
|
108
|
+
/** The index a token was just removed from through a field interaction (its ✕, a
|
|
109
|
+
* menu action the app handled, or Backspace/Delete). Set at the interaction — when
|
|
110
|
+
* focus is still reliably in the field, unlike at willUpdate time after a closing
|
|
111
|
+
* menu has moved it — and consumed in updated() to focus the token that shifted in
|
|
112
|
+
* (or the input). Null for background/programmatic value changes. */
|
|
113
|
+
this._removalFocusIndex = null;
|
|
114
|
+
/** When focus leaves the field entirely, reset the roving tab stop to the first
|
|
115
|
+
* token, so tabbing back in from a preceding component always starts there.
|
|
116
|
+
* Deferred a microtask because focusout fires before the matching focusin, so
|
|
117
|
+
* the incoming focus target has settled by the time this runs. A focused token
|
|
118
|
+
* (or the slotted menu) retargets document.activeElement to a node the field
|
|
119
|
+
* contains, so moves within the field don't reset. */
|
|
120
|
+
this._handleFocusOut = () => {
|
|
121
|
+
queueMicrotask(() => {
|
|
122
|
+
if (this.isConnected && !this.contains(document.activeElement))
|
|
123
|
+
this._rovingIndex = 0;
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
/** Cloned action menu per value, so each token's menu stays stable across
|
|
127
|
+
* re-renders (a fresh clone every render would drop its open/focus state). Pruned
|
|
128
|
+
* when a value leaves; see willUpdate. */
|
|
129
|
+
this._tokenMenuCache = new Map();
|
|
130
|
+
this._handleScrollOrResize = () => {
|
|
131
|
+
if (!this._isOpen)
|
|
132
|
+
return;
|
|
133
|
+
this._updateMenuWidth();
|
|
134
|
+
this._menu?.reposition();
|
|
135
|
+
};
|
|
136
|
+
this._handleMenuToggle = (e) => {
|
|
137
|
+
this._isOpen = e.newState === 'open';
|
|
138
|
+
if (!this._isOpen) {
|
|
139
|
+
this._highlightedId = '';
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
requestAnimationFrame(() => {
|
|
143
|
+
// The menu clears its highlight on open; seat it on the first option
|
|
144
|
+
// by default so that option is the active descendant and Enter picks
|
|
145
|
+
// it — unless something is already highlighted.
|
|
146
|
+
if (this._menu && !this._menu.getHighlighted())
|
|
147
|
+
this._menu.moveHighlight('next');
|
|
148
|
+
this._updateActiveDescendant();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
this._handleMenuSelect = (e) => {
|
|
153
|
+
const item = e.target;
|
|
154
|
+
this._commitValue(item.value || item.text);
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Tab inside the menu (a top-layer popover) would move focus to an arbitrary
|
|
158
|
+
* next element in DOM order. Instead close the menu and return focus to the
|
|
159
|
+
* input so Tab continues from there — same handling as the combo-box.
|
|
160
|
+
*/
|
|
161
|
+
this._handleMenuKeydown = (e) => {
|
|
162
|
+
if (e.key !== 'Tab')
|
|
163
|
+
return;
|
|
164
|
+
e.preventDefault();
|
|
165
|
+
this._closeMenu();
|
|
166
|
+
this._input?.focus();
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// Property order matches the story controls (values kept high, above
|
|
170
|
+
// placeholder, per the text-field convention). No `size` axis yet — the field
|
|
171
|
+
// is md-only for now; a sm variant lands later.
|
|
172
|
+
/** Selected token values. The attribute is a comma-separated string used to seed
|
|
173
|
+
* the initial values (like native `<input value>`); it is not reflected, so the
|
|
174
|
+
* live source is always the `.values` array property. Values can't contain
|
|
175
|
+
* commas — set those via the property. */
|
|
176
|
+
get values() {
|
|
177
|
+
return this._values;
|
|
178
|
+
}
|
|
179
|
+
set values(next) {
|
|
180
|
+
// A multi-select holds a *set* of values. Dedupe on every assignment so the
|
|
181
|
+
// keyed token render can never get a duplicate key (which silently drops a
|
|
182
|
+
// token) and the submitted form value stays one entry per value.
|
|
183
|
+
const unique = next ? next.filter((v, i) => next.indexOf(v) === i) : [];
|
|
184
|
+
const old = this._values;
|
|
185
|
+
this._values = unique;
|
|
186
|
+
this.requestUpdate('values', old);
|
|
187
|
+
}
|
|
188
|
+
_t(key) {
|
|
189
|
+
return this.translations[key] ?? nlddTokenFieldTranslations[key];
|
|
190
|
+
}
|
|
191
|
+
// — Lifecycle ————————————————————————————————————————————————————————————
|
|
192
|
+
connectedCallback() {
|
|
193
|
+
super.connectedCallback();
|
|
194
|
+
this._resizeObserver = new ResizeObserver(() => this._updateMenuWidth());
|
|
195
|
+
this._resizeObserver.observe(this);
|
|
196
|
+
window.addEventListener('scroll', this._handleScrollOrResize, true);
|
|
197
|
+
window.addEventListener('resize', this._handleScrollOrResize);
|
|
198
|
+
this.addEventListener('focusout', this._handleFocusOut);
|
|
199
|
+
this._templateObserver = new MutationObserver((records) => this._onTemplateMutation(records));
|
|
200
|
+
this._templateObserver.observe(this, {
|
|
201
|
+
childList: true, subtree: true, attributes: true, characterData: true,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
disconnectedCallback() {
|
|
205
|
+
super.disconnectedCallback();
|
|
206
|
+
this._resizeObserver?.disconnect();
|
|
207
|
+
this._resizeObserver = null;
|
|
208
|
+
this._menuObserver?.disconnect();
|
|
209
|
+
this._menuObserver = null;
|
|
210
|
+
this._templateObserver?.disconnect();
|
|
211
|
+
this._templateObserver = null;
|
|
212
|
+
window.removeEventListener('scroll', this._handleScrollOrResize, true);
|
|
213
|
+
window.removeEventListener('resize', this._handleScrollOrResize);
|
|
214
|
+
this.removeEventListener('focusout', this._handleFocusOut);
|
|
215
|
+
if (this._menu) {
|
|
216
|
+
this._menu.removeEventListener('toggle', this._handleMenuToggle);
|
|
217
|
+
this._menu.removeEventListener('select', this._handleMenuSelect);
|
|
218
|
+
this._menu.removeEventListener('keydown', this._handleMenuKeydown);
|
|
219
|
+
this._menu = null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
firstUpdated() {
|
|
223
|
+
this._initialValues = [...this.values];
|
|
224
|
+
this._updateFormValue();
|
|
225
|
+
// Give the host a lasting accessible name and grouping via ElementInternals.
|
|
226
|
+
// The input carries aria-label, but it is removed when every value is chosen
|
|
227
|
+
// (no custom, no options left) — exactly the state roving token navigation
|
|
228
|
+
// makes a first-class tab stop — so without this the field would lose its name.
|
|
229
|
+
this._internals.role = 'group';
|
|
230
|
+
this._internals.ariaLabel = this.accessibleLabel || null;
|
|
231
|
+
}
|
|
232
|
+
willUpdate(changed) {
|
|
233
|
+
// React to a values change BEFORE render, so the reactive state this
|
|
234
|
+
// touches (_highlightedId, via _syncMenuItems' active-descendant sync when
|
|
235
|
+
// hiding a token's highlighted option moves the highlight) folds into this
|
|
236
|
+
// same update. The identical work in updated() sets state after the update
|
|
237
|
+
// completed, which trips Lit's change-in-update warning.
|
|
238
|
+
//
|
|
239
|
+
// A token added or removed changes which options are still available:
|
|
240
|
+
// re-run the text filter (unhides options freed by a removed token) and
|
|
241
|
+
// re-hide the ones now selected. Close the menu if nothing is left to add.
|
|
242
|
+
if (changed.has('values')) {
|
|
243
|
+
this._rovingIndex = Math.max(0, Math.min(this._rovingIndex, this.values.length - 1));
|
|
244
|
+
for (const key of [...this._tokenMenuCache.keys()]) {
|
|
245
|
+
if (!this.values.includes(key))
|
|
246
|
+
this._tokenMenuCache.delete(key);
|
|
247
|
+
}
|
|
248
|
+
this._updateFormValue();
|
|
249
|
+
if (this._menu) {
|
|
250
|
+
this._syncMenuItems();
|
|
251
|
+
if (!this._showInput)
|
|
252
|
+
this._closeMenu();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (changed.has('required'))
|
|
256
|
+
this._updateValidity();
|
|
257
|
+
if (changed.has('readonly') && this.readonly)
|
|
258
|
+
this._closeMenu();
|
|
259
|
+
if (changed.has('accessibleLabel'))
|
|
260
|
+
this._internals.ariaLabel = this.accessibleLabel || null;
|
|
261
|
+
}
|
|
262
|
+
updated() {
|
|
263
|
+
// The input narrows/widens as tokens come and go; keep the open menu's
|
|
264
|
+
// pinned width in step with it. This reads layout (getBoundingClientRect),
|
|
265
|
+
// so it must run after render, not in willUpdate().
|
|
266
|
+
if (this._isOpen)
|
|
267
|
+
this._updateMenuWidth();
|
|
268
|
+
// Keep focus in the field after a token was removed while it held focus.
|
|
269
|
+
// Deferred past this update: _focusAfterRemoval sets _rovingIndex (to move the
|
|
270
|
+
// roving tab stop), which must schedule its own update rather than mutate state
|
|
271
|
+
// mid-update (Lit's change-in-update warning).
|
|
272
|
+
if (this._removalFocusIndex !== null) {
|
|
273
|
+
const index = this._removalFocusIndex;
|
|
274
|
+
this._removalFocusIndex = null;
|
|
275
|
+
void this.updateComplete.then(() => this._focusAfterRemoval(index));
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// — Form participation ————————————————————————————————————————————————————
|
|
279
|
+
/** Submit one entry per value under `name` (like a multi-select), so a form
|
|
280
|
+
* receives `name=value` repeated for each token. */
|
|
281
|
+
_updateFormValue() {
|
|
282
|
+
const data = new FormData();
|
|
283
|
+
for (const value of this.values)
|
|
284
|
+
data.append(this.name, value);
|
|
285
|
+
this._internals.setFormValue(this.name ? data : null);
|
|
286
|
+
this._updateValidity();
|
|
287
|
+
}
|
|
288
|
+
/** A required field with no tokens is invalid (valueMissing). */
|
|
289
|
+
_updateValidity() {
|
|
290
|
+
if (this.required && this.values.length === 0) {
|
|
291
|
+
this._internals.setValidity({ valueMissing: true }, this._t('components.token-field.required-error-text'), this._input ?? this);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
this._internals.setValidity({});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
formResetCallback() {
|
|
298
|
+
this.values = [...this._initialValues];
|
|
299
|
+
}
|
|
300
|
+
formDisabledCallback(disabled) {
|
|
301
|
+
this.disabled = disabled;
|
|
302
|
+
}
|
|
303
|
+
get _input() {
|
|
304
|
+
return this.shadowRoot?.querySelector('.token-field__input') ?? null;
|
|
305
|
+
}
|
|
306
|
+
/** The input + picker wrapper — the menu's anchor, so the menu lines up under
|
|
307
|
+
* the whole area (including the picker), not just the input. */
|
|
308
|
+
get _inputArea() {
|
|
309
|
+
return this.shadowRoot?.querySelector('.token-field__input-area') ?? null;
|
|
310
|
+
}
|
|
311
|
+
/** Programmatic focus goes to the inner input, or — when it is hidden (all values
|
|
312
|
+
* in, no custom, no options left) — to the token holding the roving tabindex. */
|
|
313
|
+
focus(options) {
|
|
314
|
+
if (this._input)
|
|
315
|
+
this._input.focus(options);
|
|
316
|
+
else
|
|
317
|
+
this._focusTokenAt(this._rovingIndex);
|
|
318
|
+
}
|
|
319
|
+
/** A token's display label: the matching slotted menu-item's text, else the
|
|
320
|
+
* raw value (covers values whose option is not currently present). */
|
|
321
|
+
/** Slotted menu options not yet selected — what the picker could still add. */
|
|
322
|
+
get _availableOptionCount() {
|
|
323
|
+
let n = 0;
|
|
324
|
+
// Scope to the options menu (a direct-child nldd-menu); this deliberately
|
|
325
|
+
// skips nldd-menu-items inside the token-menu template prototypes.
|
|
326
|
+
for (const el of this.querySelectorAll(':scope > nldd-menu nldd-menu-item')) {
|
|
327
|
+
const item = el;
|
|
328
|
+
const v = item.value || item.text; // property, not attribute: consumers (Vue) set the property
|
|
329
|
+
if (v && !this.values.includes(v))
|
|
330
|
+
n++;
|
|
331
|
+
}
|
|
332
|
+
return n;
|
|
333
|
+
}
|
|
334
|
+
/** Hide the input entirely when there is nothing left to do: no options remain
|
|
335
|
+
* and free text is not allowed. Readonly fields never show the input. */
|
|
336
|
+
get _showInput() {
|
|
337
|
+
return !this.readonly && (this.allowCustom || this._availableOptionCount > 0);
|
|
338
|
+
}
|
|
339
|
+
/** Whether an options menu is slotted — drives the picker button. Free-text-only
|
|
340
|
+
* fields (e.g. e-mail addresses) have no menu and get no picker. */
|
|
341
|
+
get _hasMenu() {
|
|
342
|
+
return this._menu !== null;
|
|
343
|
+
}
|
|
344
|
+
/** Show the picker only while there are still options left to pick. Once every
|
|
345
|
+
* menu item sits in the field there is nothing to open, so it disappears.
|
|
346
|
+
* Readonly fields never show the picker. */
|
|
347
|
+
get _showPicker() {
|
|
348
|
+
return !this.readonly && this._hasMenu && this._availableOptionCount > 0;
|
|
349
|
+
}
|
|
350
|
+
_labelFor(value) {
|
|
351
|
+
// Scope to the options menu (a direct-child nldd-menu); this deliberately
|
|
352
|
+
// skips nldd-menu-items inside the token-menu template prototypes.
|
|
353
|
+
for (const el of this.querySelectorAll(':scope > nldd-menu nldd-menu-item')) {
|
|
354
|
+
const item = el;
|
|
355
|
+
if ((item.value || item.text) === value) {
|
|
356
|
+
return item.text || item.textContent?.trim() || value;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return value;
|
|
360
|
+
}
|
|
361
|
+
/** The action menu for a value's token (token-control="menu"): a clone of the
|
|
362
|
+
* matching `nldd-token[slot="template"][data-value]` prototype's `nldd-menu`, else
|
|
363
|
+
* the shared keyless prototype's. Cloned once per value and reused. Only the
|
|
364
|
+
* prototype's nested menu is read today; its other props are ignored. */
|
|
365
|
+
_tokenMenuFor(value) {
|
|
366
|
+
const cached = this._tokenMenuCache.get(value);
|
|
367
|
+
if (cached)
|
|
368
|
+
return cached;
|
|
369
|
+
const clone = this._cloneTokenMenu(value);
|
|
370
|
+
if (clone)
|
|
371
|
+
this._tokenMenuCache.set(value, clone);
|
|
372
|
+
return clone;
|
|
373
|
+
}
|
|
374
|
+
_cloneTokenMenu(value) {
|
|
375
|
+
let shared = null;
|
|
376
|
+
let match = null;
|
|
377
|
+
for (const proto of this.querySelectorAll('nldd-token[slot="template"]')) {
|
|
378
|
+
if (proto.dataset.value === value) {
|
|
379
|
+
match = proto;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
if (!proto.hasAttribute('data-value'))
|
|
383
|
+
shared ?? (shared = proto);
|
|
384
|
+
}
|
|
385
|
+
const source = (match ?? shared)?.querySelector('nldd-menu[slot="menu"]');
|
|
386
|
+
return source ? source.cloneNode(true) : null;
|
|
387
|
+
}
|
|
388
|
+
/** A change to any `[slot="template"]` prototype (its menu items, their attributes,
|
|
389
|
+
* or an added/removed prototype) invalidates the cloned per-token menus, so they
|
|
390
|
+
* re-clone on the next render. The field only ever *reads* the prototypes — it
|
|
391
|
+
* mutates the options menu and its own shadow DOM — so filtering to template-scoped
|
|
392
|
+
* mutations keeps this from looping with the field's own option hiding. */
|
|
393
|
+
_onTemplateMutation(records) {
|
|
394
|
+
const touchesTemplate = records.some((r) => {
|
|
395
|
+
if (r.target.closest?.('[slot="template"]'))
|
|
396
|
+
return true;
|
|
397
|
+
return [...r.addedNodes, ...r.removedNodes].some((n) => n.nodeType === Node.ELEMENT_NODE && n.matches?.('[slot="template"]'));
|
|
398
|
+
});
|
|
399
|
+
if (!touchesTemplate)
|
|
400
|
+
return;
|
|
401
|
+
this._tokenMenuCache.clear();
|
|
402
|
+
this.requestUpdate();
|
|
403
|
+
}
|
|
404
|
+
_addValue(value) {
|
|
405
|
+
if (!value || this.values.includes(value))
|
|
406
|
+
return; // dedupe
|
|
407
|
+
this.values = [...this.values, value];
|
|
408
|
+
this._emitChange();
|
|
409
|
+
}
|
|
410
|
+
_removeValue(value) {
|
|
411
|
+
if (!this.values.includes(value))
|
|
412
|
+
return;
|
|
413
|
+
this.values = this.values.filter((v) => v !== value);
|
|
414
|
+
this._emitChange();
|
|
415
|
+
}
|
|
416
|
+
_emitChange() {
|
|
417
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
418
|
+
detail: { values: [...this.values] },
|
|
419
|
+
bubbles: true,
|
|
420
|
+
composed: true,
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
// — Input handlers ———————————————————————————————————————————————————————
|
|
424
|
+
_handleInput(e) {
|
|
425
|
+
this._text = e.target.value;
|
|
426
|
+
// A comma commits the text before it as a token (typed or pasted) — the
|
|
427
|
+
// Enter-equivalent for free text. Only meaningful with custom values.
|
|
428
|
+
if (this.allowCustom && this._text.includes(',')) {
|
|
429
|
+
this._commitCommaSeparated();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
this._syncMenuItems();
|
|
433
|
+
if (!this._isOpen)
|
|
434
|
+
this._openMenu();
|
|
435
|
+
this.dispatchEvent(new CustomEvent('input', {
|
|
436
|
+
detail: { value: this._text },
|
|
437
|
+
bubbles: true,
|
|
438
|
+
composed: true,
|
|
439
|
+
}));
|
|
440
|
+
}
|
|
441
|
+
/** Split the input on commas: every complete segment becomes a token; the
|
|
442
|
+
* trailing segment (after the last comma) stays in the input to keep typing.
|
|
443
|
+
* Emits a single change for the batch. */
|
|
444
|
+
_commitCommaSeparated() {
|
|
445
|
+
const parts = this._text.split(',');
|
|
446
|
+
const remainder = parts.pop() ?? '';
|
|
447
|
+
const next = [...this.values];
|
|
448
|
+
for (const part of parts) {
|
|
449
|
+
const value = part.trim();
|
|
450
|
+
if (value && !next.includes(value))
|
|
451
|
+
next.push(value);
|
|
452
|
+
}
|
|
453
|
+
if (next.length !== this.values.length) {
|
|
454
|
+
this.values = next;
|
|
455
|
+
this._emitChange();
|
|
456
|
+
}
|
|
457
|
+
this._text = remainder;
|
|
458
|
+
if (this._input)
|
|
459
|
+
this._input.value = remainder;
|
|
460
|
+
this._syncMenuItems();
|
|
461
|
+
this.dispatchEvent(new CustomEvent('input', {
|
|
462
|
+
detail: { value: this._text },
|
|
463
|
+
bubbles: true,
|
|
464
|
+
composed: true,
|
|
465
|
+
}));
|
|
466
|
+
}
|
|
467
|
+
/** Close the menu when focus leaves the field for anything but the menu. */
|
|
468
|
+
_handleBlur(e) {
|
|
469
|
+
const related = e.relatedTarget;
|
|
470
|
+
if (related && this._menu?.contains(related))
|
|
471
|
+
return;
|
|
472
|
+
// Commit any free-typed text when focus leaves, so a value typed without
|
|
473
|
+
// pressing Enter/comma isn't silently dropped — it becomes a visible token
|
|
474
|
+
// and joins the form value. Only with custom values allowed; commit without
|
|
475
|
+
// re-focusing so the focus move isn't fought. `_commitValue` closes the
|
|
476
|
+
// menu, so only close it ourselves when nothing was committed.
|
|
477
|
+
if (this.allowCustom && this._text.trim())
|
|
478
|
+
this._commitValue(this._text.trim(), false);
|
|
479
|
+
else
|
|
480
|
+
this._closeMenu();
|
|
481
|
+
}
|
|
482
|
+
_handleKeydown(e) {
|
|
483
|
+
switch (e.key) {
|
|
484
|
+
case 'ArrowDown':
|
|
485
|
+
e.preventDefault();
|
|
486
|
+
if (!this._isOpen) {
|
|
487
|
+
this._syncMenuItems();
|
|
488
|
+
this._openMenu();
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
this._menu?.moveHighlight('next');
|
|
492
|
+
this._updateActiveDescendant();
|
|
493
|
+
}
|
|
494
|
+
break;
|
|
495
|
+
case 'ArrowUp':
|
|
496
|
+
if (!this._isOpen)
|
|
497
|
+
return;
|
|
498
|
+
e.preventDefault();
|
|
499
|
+
this._menu?.moveHighlight('prev');
|
|
500
|
+
this._updateActiveDescendant();
|
|
501
|
+
break;
|
|
502
|
+
case 'Enter': {
|
|
503
|
+
// A highlighted option wins; otherwise commit the typed text as a
|
|
504
|
+
// custom token. Works whether the menu is open or not — with no
|
|
505
|
+
// matching options the menu is closed, but Enter should still add
|
|
506
|
+
// the free-text value. preventDefault only when we actually act, so
|
|
507
|
+
// a no-op Enter can still submit an enclosing form.
|
|
508
|
+
const highlighted = this._isOpen ? (this._menu?.getHighlighted() ?? null) : null;
|
|
509
|
+
if (highlighted) {
|
|
510
|
+
e.preventDefault();
|
|
511
|
+
highlighted.select(); // routes through _handleMenuSelect
|
|
512
|
+
}
|
|
513
|
+
else if (this.allowCustom && this._text.trim()) {
|
|
514
|
+
e.preventDefault();
|
|
515
|
+
this._commitValue(this._text.trim());
|
|
516
|
+
}
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
case 'Escape':
|
|
520
|
+
if (!this._isOpen)
|
|
521
|
+
return;
|
|
522
|
+
e.preventDefault();
|
|
523
|
+
this._closeMenu();
|
|
524
|
+
break;
|
|
525
|
+
case 'ArrowLeft':
|
|
526
|
+
// At the very start of the input, step left into the tokens.
|
|
527
|
+
if (this._caretAtStart() && this._tokens.length > 0) {
|
|
528
|
+
e.preventDefault();
|
|
529
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
530
|
+
}
|
|
531
|
+
break;
|
|
532
|
+
case 'Backspace':
|
|
533
|
+
// Empty input: step focus onto the last token first; a second
|
|
534
|
+
// Backspace (now on the focused token) deletes it.
|
|
535
|
+
if (this._text === '' && this._tokens.length > 0) {
|
|
536
|
+
e.preventDefault();
|
|
537
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
538
|
+
}
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
_caretAtStart() {
|
|
543
|
+
const input = this._input;
|
|
544
|
+
if (!input)
|
|
545
|
+
return false;
|
|
546
|
+
// type="email" / "number" etc. don't expose a caret (selectionStart is null),
|
|
547
|
+
// so an empty value is the only reliable "at the start" signal for those.
|
|
548
|
+
if (input.selectionStart === null)
|
|
549
|
+
return input.value === '';
|
|
550
|
+
return input.selectionStart === 0 && input.selectionEnd === 0;
|
|
551
|
+
}
|
|
552
|
+
// — Token roving navigation ————————————————————————————————————————————————
|
|
553
|
+
get _tokens() {
|
|
554
|
+
return Array.from(this.shadowRoot?.querySelectorAll('nldd-token') ?? []);
|
|
555
|
+
}
|
|
556
|
+
/** Focus the token at `index` (clamped); focus the input when there are none. */
|
|
557
|
+
_focusTokenAt(index) {
|
|
558
|
+
const tokens = this._tokens;
|
|
559
|
+
if (tokens.length === 0) {
|
|
560
|
+
this._input?.focus();
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const clamped = Math.max(0, Math.min(index, tokens.length - 1));
|
|
564
|
+
this._rovingIndex = clamped;
|
|
565
|
+
tokens[clamped].focus();
|
|
566
|
+
}
|
|
567
|
+
/** After removing the token at `index`, move focus to the token that shifted into
|
|
568
|
+
* its slot (the one that was to its right). If the last token was removed, hand
|
|
569
|
+
* focus to the input, or to the new last token when the input is hidden. */
|
|
570
|
+
_focusAfterRemoval(index) {
|
|
571
|
+
if (this._tokens.length === 0) {
|
|
572
|
+
this._input?.focus();
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (index < this._tokens.length)
|
|
576
|
+
this._focusTokenAt(index);
|
|
577
|
+
else if (this._showInput)
|
|
578
|
+
this._input?.focus();
|
|
579
|
+
else
|
|
580
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
581
|
+
}
|
|
582
|
+
/** Arrow keys move between tokens; ArrowRight past the last returns to the
|
|
583
|
+
* input; Backspace/Delete removes the token and steps focus onto the next one.
|
|
584
|
+
* A disabled field is inert — no roving, no keyboard removal. */
|
|
585
|
+
_handleTokenKeydown(e, index) {
|
|
586
|
+
if (this.disabled)
|
|
587
|
+
return;
|
|
588
|
+
switch (e.key) {
|
|
589
|
+
case 'ArrowLeft':
|
|
590
|
+
e.preventDefault();
|
|
591
|
+
this._focusTokenAt(index - 1);
|
|
592
|
+
break;
|
|
593
|
+
case 'ArrowRight':
|
|
594
|
+
e.preventDefault();
|
|
595
|
+
if (index >= this._tokens.length - 1)
|
|
596
|
+
this._input?.focus();
|
|
597
|
+
else
|
|
598
|
+
this._focusTokenAt(index + 1);
|
|
599
|
+
break;
|
|
600
|
+
case 'Home':
|
|
601
|
+
e.preventDefault();
|
|
602
|
+
this._focusTokenAt(0);
|
|
603
|
+
break;
|
|
604
|
+
case 'End':
|
|
605
|
+
e.preventDefault();
|
|
606
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
607
|
+
break;
|
|
608
|
+
case 'Backspace':
|
|
609
|
+
case 'Delete':
|
|
610
|
+
// Remove the token and mark its slot; updated() then steps focus onto the
|
|
611
|
+
// token that took this one's place (or the input), so repeated Backspace
|
|
612
|
+
// walks the row and focus never drops to the body.
|
|
613
|
+
e.preventDefault();
|
|
614
|
+
this._removeValue(this.values[index]);
|
|
615
|
+
this._removalFocusIndex = index;
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
/** Clicking empty space in the field (not a token or the picker) focuses the
|
|
620
|
+
* input, or — when it is hidden — the last token, so a click after the tokens
|
|
621
|
+
* lets you rove them with the arrow keys. The menu opens deliberately via the
|
|
622
|
+
* picker, typing, or ArrowDown, not by clicking the field. */
|
|
623
|
+
_handleFieldClick(e) {
|
|
624
|
+
const target = e.target;
|
|
625
|
+
if (target.closest('nldd-token') || target.closest('.token-field__picker'))
|
|
626
|
+
return;
|
|
627
|
+
if (this._showInput)
|
|
628
|
+
this._input?.focus();
|
|
629
|
+
else
|
|
630
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
631
|
+
}
|
|
632
|
+
/** The ✕ dismiss control: remove the value and mark its slot so updated() steps
|
|
633
|
+
* focus onto the token that takes its place (or the input). */
|
|
634
|
+
_handleTokenDismiss(value, index) {
|
|
635
|
+
this._removeValue(value);
|
|
636
|
+
this._removalFocusIndex = index;
|
|
637
|
+
}
|
|
638
|
+
/** A token's menu action was chosen (token-control="menu"): report which token
|
|
639
|
+
* and which action and let the app decide what happens (remove, edit, …). The
|
|
640
|
+
* token owns closing the menu and returning focus to its chevron. When the app
|
|
641
|
+
* handles the action synchronously by removing this token, mark its slot so
|
|
642
|
+
* updated() re-homes focus (the closing menu has left focus adrift by then). */
|
|
643
|
+
_handleTokenAction(e, value) {
|
|
644
|
+
const item = e.target;
|
|
645
|
+
const action = item.value || item.text;
|
|
646
|
+
const index = this.values.indexOf(value);
|
|
647
|
+
this.dispatchEvent(new CustomEvent('token-action', {
|
|
648
|
+
detail: { value, action },
|
|
649
|
+
bubbles: true,
|
|
650
|
+
composed: true,
|
|
651
|
+
}));
|
|
652
|
+
if (index !== -1 && !this.values.includes(value))
|
|
653
|
+
this._removalFocusIndex = index;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* The picker (a real button) toggles the menu. Because it opens on `click`
|
|
657
|
+
* (after the gesture's pointerdown), the auto-popover isn't light-dismissed by
|
|
658
|
+
* the opening gesture. When the menu is already open, this same gesture's
|
|
659
|
+
* pointerdown light-dismisses it; the flag makes the trailing click a no-op so
|
|
660
|
+
* it doesn't flicker back open. Mirrors the combo-box picker.
|
|
661
|
+
*/
|
|
662
|
+
_handlePickerPointerdown() {
|
|
663
|
+
if (this._isOpen)
|
|
664
|
+
this._pickerPointerdownWhileOpen = true;
|
|
665
|
+
}
|
|
666
|
+
_togglePicker() {
|
|
667
|
+
this._input?.focus();
|
|
668
|
+
if (this._pickerPointerdownWhileOpen) {
|
|
669
|
+
this._pickerPointerdownWhileOpen = false;
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
if (this._isOpen) {
|
|
673
|
+
this._closeMenu();
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
this._syncMenuItems();
|
|
677
|
+
this._openMenu();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
// — Menu wiring ——————————————————————————————————————————————————————————
|
|
681
|
+
_onSlotChange() {
|
|
682
|
+
this.requestUpdate(); // re-render token labels when options change
|
|
683
|
+
const slot = this.shadowRoot?.querySelector('slot');
|
|
684
|
+
const menu = slot
|
|
685
|
+
?.assignedElements({ flatten: true })
|
|
686
|
+
.find((el) => el.tagName.toLowerCase() === 'nldd-menu');
|
|
687
|
+
if (!menu)
|
|
688
|
+
return;
|
|
689
|
+
if (menu === this._menu)
|
|
690
|
+
return;
|
|
691
|
+
this._menu = menu;
|
|
692
|
+
menu.id = this._menuId;
|
|
693
|
+
menu.anchorElement = this;
|
|
694
|
+
menu.placement = 'bottom-start';
|
|
695
|
+
menu.variant = 'listbox';
|
|
696
|
+
menu.addEventListener('toggle', this._handleMenuToggle);
|
|
697
|
+
menu.addEventListener('select', this._handleMenuSelect);
|
|
698
|
+
menu.addEventListener('keydown', this._handleMenuKeydown);
|
|
699
|
+
this._updateMenuWidth();
|
|
700
|
+
this._hideSelectedMenuItems();
|
|
701
|
+
// Options may be added/removed after this (async framework rendering).
|
|
702
|
+
// Watch child changes only — not attributes — so the field's own hidden/
|
|
703
|
+
// query toggles on items don't loop. childList picks up added menu-items.
|
|
704
|
+
this._menuObserver?.disconnect();
|
|
705
|
+
this._menuObserver = new MutationObserver(() => {
|
|
706
|
+
this._hideSelectedMenuItems();
|
|
707
|
+
this.requestUpdate();
|
|
708
|
+
});
|
|
709
|
+
this._menuObserver.observe(menu, { childList: true, subtree: true });
|
|
710
|
+
}
|
|
711
|
+
/** Pin the menu to the native input's width (its anchor) so it lines up under
|
|
712
|
+
* the input and never extends past it. */
|
|
713
|
+
_updateMenuWidth() {
|
|
714
|
+
if (!this._menu)
|
|
715
|
+
return;
|
|
716
|
+
const rect = (this._inputArea ?? this._input ?? this).getBoundingClientRect();
|
|
717
|
+
this._menu.width = `${rect.width}px`;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Add a value, clear the input, and close the menu — focus returns to the empty
|
|
721
|
+
* input. The menu only reopens on a deliberate action (typing, ArrowDown, or the
|
|
722
|
+
* picker), so a focused empty field behaves the same whether it was just focused
|
|
723
|
+
* or a value was just committed.
|
|
724
|
+
*/
|
|
725
|
+
_commitValue(value, refocus = true) {
|
|
726
|
+
this._addValue(value);
|
|
727
|
+
this._resetInputText();
|
|
728
|
+
this._closeMenu();
|
|
729
|
+
// On blur we commit but must NOT pull focus back — the user is leaving the
|
|
730
|
+
// field (e.g. onto a submit button); re-focusing would fight that move.
|
|
731
|
+
if (!refocus)
|
|
732
|
+
return;
|
|
733
|
+
// After the last value the input disappears (no custom, no options left); put
|
|
734
|
+
// focus on the last token instead of dropping it to the body.
|
|
735
|
+
void this.updateComplete.then(() => {
|
|
736
|
+
if (this._showInput)
|
|
737
|
+
this._input?.focus();
|
|
738
|
+
else
|
|
739
|
+
this._focusTokenAt(this._tokens.length - 1);
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
_openMenu() {
|
|
743
|
+
if (!this._menu || this.disabled)
|
|
744
|
+
return;
|
|
745
|
+
if (!('showPopover' in this._menu))
|
|
746
|
+
return;
|
|
747
|
+
// Nothing to show (all options selected / filtered out) — don't open an
|
|
748
|
+
// empty menu. Callers sync the items first, so the count is current.
|
|
749
|
+
if (this._visibleOptionCount === 0)
|
|
750
|
+
return;
|
|
751
|
+
// Guard on the real popover state, not `_isOpen`: the popover toggle event
|
|
752
|
+
// that drives `_isOpen` is async, so right after a menu-item hides the
|
|
753
|
+
// popover `_isOpen` is still stale-true — guarding on it would wrongly skip
|
|
754
|
+
// the reopen. `:popover-open` also prevents the throw on double-show.
|
|
755
|
+
if (this._menu.matches(':popover-open'))
|
|
756
|
+
return;
|
|
757
|
+
// Anchor to the input + picker wrapper so the menu lines up under the whole
|
|
758
|
+
// field row (including the picker), wherever it sits after the tokens.
|
|
759
|
+
this._menu.anchorElement = this._inputArea ?? this._input ?? this;
|
|
760
|
+
this._updateMenuWidth();
|
|
761
|
+
this._menu.showPopover();
|
|
762
|
+
}
|
|
763
|
+
_closeMenu() {
|
|
764
|
+
if (!this._menu)
|
|
765
|
+
return;
|
|
766
|
+
if (!this._menu.matches(':popover-open'))
|
|
767
|
+
return;
|
|
768
|
+
this._menu.hidePopover();
|
|
769
|
+
}
|
|
770
|
+
_updateActiveDescendant() {
|
|
771
|
+
this._highlightedId = this._menu?.getHighlightedId() ?? '';
|
|
772
|
+
}
|
|
773
|
+
_resetInputText() {
|
|
774
|
+
this._text = '';
|
|
775
|
+
if (this._input)
|
|
776
|
+
this._input.value = '';
|
|
777
|
+
}
|
|
778
|
+
/** Options currently shown in the menu (matching the filter and not already
|
|
779
|
+
* selected). Zero means there is nothing worth opening the menu for. */
|
|
780
|
+
get _visibleOptionCount() {
|
|
781
|
+
if (!this._menu)
|
|
782
|
+
return 0;
|
|
783
|
+
return this._menu.querySelectorAll('nldd-menu-item:not([hidden])').length;
|
|
784
|
+
}
|
|
785
|
+
/** Apply the text filter, then hide options already selected. Used after
|
|
786
|
+
* typing, selecting, and whenever `values` changes. */
|
|
787
|
+
_syncMenuItems() {
|
|
788
|
+
if (!this._menu)
|
|
789
|
+
return;
|
|
790
|
+
this._menu.filter(this._text);
|
|
791
|
+
this._hideSelectedMenuItems();
|
|
792
|
+
this._updateActiveDescendant();
|
|
793
|
+
// Don't leave an empty menu open. Without options the empty-state dialog is
|
|
794
|
+
// noise — especially with allow-custom, where the user just types instead.
|
|
795
|
+
if (this._isOpen && this._visibleOptionCount === 0)
|
|
796
|
+
this._closeMenu();
|
|
797
|
+
}
|
|
798
|
+
/** Hide every option whose value is already a token. The text filter unhides
|
|
799
|
+
* matches, so this runs after it. Moves the highlight off an item it hides. */
|
|
800
|
+
_hideSelectedMenuItems() {
|
|
801
|
+
if (!this._menu)
|
|
802
|
+
return;
|
|
803
|
+
const selected = new Set(this.values);
|
|
804
|
+
let reseat = false;
|
|
805
|
+
for (const el of this._menu.querySelectorAll('nldd-menu-item')) {
|
|
806
|
+
const item = el;
|
|
807
|
+
if (selected.has(item.value || item.text)) {
|
|
808
|
+
if (item.hasAttribute('highlighted'))
|
|
809
|
+
reseat = true;
|
|
810
|
+
item.setAttribute('hidden', '');
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (reseat)
|
|
814
|
+
this._menu.moveHighlight('next');
|
|
815
|
+
}
|
|
816
|
+
render() {
|
|
817
|
+
return tokenFieldTemplate(this);
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
NLDDTokenField.formAssociated = true;
|
|
821
|
+
NLDDTokenField.styles = tokenFieldStyles;
|
|
822
|
+
NLDDTokenField._idCounter = 0;
|
|
823
|
+
__decorate([
|
|
824
|
+
property({
|
|
825
|
+
converter: {
|
|
826
|
+
fromAttribute: (value) => value ? value.split(',').map((v) => v.trim()).filter(Boolean) : [],
|
|
827
|
+
toAttribute: () => null,
|
|
828
|
+
},
|
|
829
|
+
})
|
|
830
|
+
], NLDDTokenField.prototype, "values", null);
|
|
831
|
+
__decorate([
|
|
832
|
+
property({ type: String })
|
|
833
|
+
], NLDDTokenField.prototype, "placeholder", void 0);
|
|
834
|
+
__decorate([
|
|
835
|
+
property({ type: String })
|
|
836
|
+
], NLDDTokenField.prototype, "type", void 0);
|
|
837
|
+
__decorate([
|
|
838
|
+
property({ type: String })
|
|
839
|
+
], NLDDTokenField.prototype, "autocomplete", void 0);
|
|
840
|
+
__decorate([
|
|
841
|
+
property({ type: String, attribute: 'accessible-label' })
|
|
842
|
+
], NLDDTokenField.prototype, "accessibleLabel", void 0);
|
|
843
|
+
__decorate([
|
|
844
|
+
property({ type: Boolean, reflect: true, attribute: 'allow-custom' })
|
|
845
|
+
], NLDDTokenField.prototype, "allowCustom", void 0);
|
|
846
|
+
__decorate([
|
|
847
|
+
property({ type: Boolean, reflect: true })
|
|
848
|
+
], NLDDTokenField.prototype, "valid", void 0);
|
|
849
|
+
__decorate([
|
|
850
|
+
property({ type: Boolean, reflect: true })
|
|
851
|
+
], NLDDTokenField.prototype, "invalid", void 0);
|
|
852
|
+
__decorate([
|
|
853
|
+
property({ type: Boolean, reflect: true, attribute: 'no-spellcheck' })
|
|
854
|
+
], NLDDTokenField.prototype, "noSpellcheck", void 0);
|
|
855
|
+
__decorate([
|
|
856
|
+
property({ type: Boolean, reflect: true })
|
|
857
|
+
], NLDDTokenField.prototype, "readonly", void 0);
|
|
858
|
+
__decorate([
|
|
859
|
+
property({ type: Boolean, reflect: true })
|
|
860
|
+
], NLDDTokenField.prototype, "required", void 0);
|
|
861
|
+
__decorate([
|
|
862
|
+
property({ type: Boolean, reflect: true })
|
|
863
|
+
], NLDDTokenField.prototype, "disabled", void 0);
|
|
864
|
+
__decorate([
|
|
865
|
+
property({ attribute: 'token-control' })
|
|
866
|
+
], NLDDTokenField.prototype, "tokenControl", void 0);
|
|
867
|
+
__decorate([
|
|
868
|
+
property({ type: String })
|
|
869
|
+
], NLDDTokenField.prototype, "name", void 0);
|
|
870
|
+
__decorate([
|
|
871
|
+
property({ type: Object })
|
|
872
|
+
], NLDDTokenField.prototype, "translations", void 0);
|
|
873
|
+
__decorate([
|
|
874
|
+
state()
|
|
875
|
+
], NLDDTokenField.prototype, "_text", void 0);
|
|
876
|
+
__decorate([
|
|
877
|
+
state()
|
|
878
|
+
], NLDDTokenField.prototype, "_isOpen", void 0);
|
|
879
|
+
__decorate([
|
|
880
|
+
state()
|
|
881
|
+
], NLDDTokenField.prototype, "_highlightedId", void 0);
|
|
882
|
+
__decorate([
|
|
883
|
+
state()
|
|
884
|
+
], NLDDTokenField.prototype, "_rovingIndex", void 0);
|
|
885
|
+
NLDDTokenField = NLDDTokenField_1 = __decorate([
|
|
886
|
+
customElement('nldd-token-field')
|
|
887
|
+
], NLDDTokenField);
|
|
888
|
+
export { NLDDTokenField };
|
|
889
|
+
//# sourceMappingURL=token-field.js.map
|