@adobe/spectrum-wc-core 0.0.0-snapshot.20260922095923
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 +39 -0
- package/dist/_virtual/_@oxc-project_runtime@0.124.0/helpers/decorate.js +9 -0
- package/dist/components/accordion/Accordion.base.d.ts +59 -0
- package/dist/components/accordion/Accordion.base.js +69 -0
- package/dist/components/accordion/Accordion.base.js.map +1 -0
- package/dist/components/accordion/Accordion.types.d.ts +22 -0
- package/dist/components/accordion/Accordion.types.js +21 -0
- package/dist/components/accordion/Accordion.types.js.map +1 -0
- package/dist/components/accordion/AccordionItem.base.d.ts +96 -0
- package/dist/components/accordion/AccordionItem.base.js +93 -0
- package/dist/components/accordion/AccordionItem.base.js.map +1 -0
- package/dist/components/accordion/index.d.ts +14 -0
- package/dist/components/accordion/index.js +4 -0
- package/dist/components/action-button/ActionButton.types.d.ts +15 -0
- package/dist/components/action-button/ActionButton.types.js +12 -0
- package/dist/components/action-button/ActionButton.types.js.map +1 -0
- package/dist/components/action-button/index.d.ts +12 -0
- package/dist/components/action-button/index.js +2 -0
- package/dist/components/action-group/ActionGroup.base.d.ts +108 -0
- package/dist/components/action-group/ActionGroup.base.js +53 -0
- package/dist/components/action-group/ActionGroup.base.js.map +1 -0
- package/dist/components/action-group/ActionGroup.types.d.ts +17 -0
- package/dist/components/action-group/ActionGroup.types.js +12 -0
- package/dist/components/action-group/ActionGroup.types.js.map +1 -0
- package/dist/components/action-group/index.d.ts +13 -0
- package/dist/components/action-group/index.js +3 -0
- package/dist/components/alert-banner/AlertBanner.base.d.ts +36 -0
- package/dist/components/alert-banner/AlertBanner.base.js +57 -0
- package/dist/components/alert-banner/AlertBanner.base.js.map +1 -0
- package/dist/components/alert-banner/AlertBanner.types.d.ts +13 -0
- package/dist/components/alert-banner/AlertBanner.types.js +10 -0
- package/dist/components/alert-banner/AlertBanner.types.js.map +1 -0
- package/dist/components/alert-banner/index.d.ts +13 -0
- package/dist/components/alert-banner/index.js +3 -0
- package/dist/components/asset/Asset.base.d.ts +101 -0
- package/dist/components/asset/Asset.base.js +130 -0
- package/dist/components/asset/Asset.base.js.map +1 -0
- package/dist/components/asset/Asset.types.d.ts +31 -0
- package/dist/components/asset/Asset.types.js +14 -0
- package/dist/components/asset/Asset.types.js.map +1 -0
- package/dist/components/asset/index.d.ts +13 -0
- package/dist/components/asset/index.js +3 -0
- package/dist/components/avatar/Avatar.base.d.ts +53 -0
- package/dist/components/avatar/Avatar.base.js +52 -0
- package/dist/components/avatar/Avatar.base.js.map +1 -0
- package/dist/components/avatar/Avatar.types.d.ts +19 -0
- package/dist/components/avatar/Avatar.types.js +24 -0
- package/dist/components/avatar/Avatar.types.js.map +1 -0
- package/dist/components/avatar/index.d.ts +13 -0
- package/dist/components/avatar/index.js +3 -0
- package/dist/components/badge/Badge.base.d.ts +114 -0
- package/dist/components/badge/Badge.base.js +49 -0
- package/dist/components/badge/Badge.base.js.map +1 -0
- package/dist/components/badge/Badge.types.d.ts +21 -0
- package/dist/components/badge/Badge.types.js +43 -0
- package/dist/components/badge/Badge.types.js.map +1 -0
- package/dist/components/badge/index.d.ts +13 -0
- package/dist/components/badge/index.js +3 -0
- package/dist/components/button/Button.base.d.ts +78 -0
- package/dist/components/button/Button.base.js +51 -0
- package/dist/components/button/Button.base.js.map +1 -0
- package/dist/components/button/Button.types.d.ts +19 -0
- package/dist/components/button/Button.types.js +16 -0
- package/dist/components/button/Button.types.js.map +1 -0
- package/dist/components/button/index.d.ts +13 -0
- package/dist/components/button/index.js +3 -0
- package/dist/components/button-group/ButtonGroup.base.d.ts +89 -0
- package/dist/components/button-group/ButtonGroup.base.js +60 -0
- package/dist/components/button-group/ButtonGroup.base.js.map +1 -0
- package/dist/components/button-group/ButtonGroup.types.d.ts +17 -0
- package/dist/components/button-group/ButtonGroup.types.js +15 -0
- package/dist/components/button-group/ButtonGroup.types.js.map +1 -0
- package/dist/components/button-group/index.d.ts +13 -0
- package/dist/components/button-group/index.js +3 -0
- package/dist/components/card/Card.base.d.ts +172 -0
- package/dist/components/card/Card.base.js +123 -0
- package/dist/components/card/Card.base.js.map +1 -0
- package/dist/components/card/Card.types.d.ts +18 -0
- package/dist/components/card/Card.types.js +21 -0
- package/dist/components/card/Card.types.js.map +1 -0
- package/dist/components/card/index.d.ts +13 -0
- package/dist/components/card/index.js +3 -0
- package/dist/components/color-handle/ColorHandle.base.d.ts +51 -0
- package/dist/components/color-handle/ColorHandle.base.js +39 -0
- package/dist/components/color-handle/ColorHandle.base.js.map +1 -0
- package/dist/components/color-handle/ColorHandle.types.d.ts +30 -0
- package/dist/components/color-handle/color-contrast.d.ts +55 -0
- package/dist/components/color-handle/color-contrast.js +49 -0
- package/dist/components/color-handle/color-contrast.js.map +1 -0
- package/dist/components/color-handle/index.d.ts +14 -0
- package/dist/components/color-handle/index.js +3 -0
- package/dist/components/color-loupe/ColorLoupe.base.d.ts +41 -0
- package/dist/components/color-loupe/ColorLoupe.base.js +21 -0
- package/dist/components/color-loupe/ColorLoupe.base.js.map +1 -0
- package/dist/components/color-loupe/index.d.ts +12 -0
- package/dist/components/color-loupe/index.js +2 -0
- package/dist/components/divider/Divider.base.d.ts +43 -0
- package/dist/components/divider/Divider.base.js +42 -0
- package/dist/components/divider/Divider.base.js.map +1 -0
- package/dist/components/divider/Divider.types.d.ts +15 -0
- package/dist/components/divider/Divider.types.js +10 -0
- package/dist/components/divider/Divider.types.js.map +1 -0
- package/dist/components/divider/index.d.ts +13 -0
- package/dist/components/divider/index.js +3 -0
- package/dist/components/dropzone/Dropzone.base.d.ts +74 -0
- package/dist/components/dropzone/Dropzone.base.js +82 -0
- package/dist/components/dropzone/Dropzone.base.js.map +1 -0
- package/dist/components/dropzone/Dropzone.types.d.ts +43 -0
- package/dist/components/dropzone/Dropzone.types.js +15 -0
- package/dist/components/dropzone/Dropzone.types.js.map +1 -0
- package/dist/components/dropzone/index.d.ts +13 -0
- package/dist/components/dropzone/index.js +3 -0
- package/dist/components/icon/Icon.base.d.ts +36 -0
- package/dist/components/icon/Icon.base.js +28 -0
- package/dist/components/icon/Icon.base.js.map +1 -0
- package/dist/components/icon/Icon.types.d.ts +13 -0
- package/dist/components/icon/Icon.types.js +12 -0
- package/dist/components/icon/Icon.types.js.map +1 -0
- package/dist/components/icon/index.d.ts +13 -0
- package/dist/components/icon/index.js +3 -0
- package/dist/components/illustrated-message/IllustratedMessage.base.d.ts +60 -0
- package/dist/components/illustrated-message/IllustratedMessage.base.js +59 -0
- package/dist/components/illustrated-message/IllustratedMessage.base.js.map +1 -0
- package/dist/components/illustrated-message/IllustratedMessage.types.d.ts +15 -0
- package/dist/components/illustrated-message/IllustratedMessage.types.js +10 -0
- package/dist/components/illustrated-message/IllustratedMessage.types.js.map +1 -0
- package/dist/components/illustrated-message/index.d.ts +13 -0
- package/dist/components/illustrated-message/index.js +3 -0
- package/dist/components/infield-button/InfieldButton.base.d.ts +28 -0
- package/dist/components/infield-button/InfieldButton.base.js +22 -0
- package/dist/components/infield-button/InfieldButton.base.js.map +1 -0
- package/dist/components/infield-button/InfieldButton.types.d.ts +13 -0
- package/dist/components/infield-button/InfieldButton.types.js +11 -0
- package/dist/components/infield-button/InfieldButton.types.js.map +1 -0
- package/dist/components/infield-button/index.d.ts +13 -0
- package/dist/components/infield-button/index.js +3 -0
- package/dist/components/meter/Meter.base.d.ts +40 -0
- package/dist/components/meter/Meter.base.js +32 -0
- package/dist/components/meter/Meter.base.js.map +1 -0
- package/dist/components/meter/Meter.types.d.ts +13 -0
- package/dist/components/meter/Meter.types.js +11 -0
- package/dist/components/meter/Meter.types.js.map +1 -0
- package/dist/components/meter/index.d.ts +13 -0
- package/dist/components/meter/index.js +3 -0
- package/dist/components/popover/Popover.base.d.ts +226 -0
- package/dist/components/popover/Popover.base.js +287 -0
- package/dist/components/popover/Popover.base.js.map +1 -0
- package/dist/components/popover/Popover.types.d.ts +39 -0
- package/dist/components/popover/Popover.types.js +24 -0
- package/dist/components/popover/Popover.types.js.map +1 -0
- package/dist/components/popover/index.d.ts +13 -0
- package/dist/components/popover/index.js +3 -0
- package/dist/components/progress-bar/ProgressBar.base.d.ts +34 -0
- package/dist/components/progress-bar/ProgressBar.base.js +21 -0
- package/dist/components/progress-bar/ProgressBar.base.js.map +1 -0
- package/dist/components/progress-bar/ProgressBar.types.d.ts +12 -0
- package/dist/components/progress-bar/index.d.ts +13 -0
- package/dist/components/progress-bar/index.js +2 -0
- package/dist/components/progress-circle/ProgressCircle.base.d.ts +83 -0
- package/dist/components/progress-circle/ProgressCircle.base.js +77 -0
- package/dist/components/progress-circle/ProgressCircle.base.js.map +1 -0
- package/dist/components/progress-circle/ProgressCircle.types.d.ts +15 -0
- package/dist/components/progress-circle/ProgressCircle.types.js +10 -0
- package/dist/components/progress-circle/ProgressCircle.types.js.map +1 -0
- package/dist/components/progress-circle/index.d.ts +13 -0
- package/dist/components/progress-circle/index.js +3 -0
- package/dist/components/status-light/StatusLight.base.d.ts +69 -0
- package/dist/components/status-light/StatusLight.base.js +32 -0
- package/dist/components/status-light/StatusLight.base.js.map +1 -0
- package/dist/components/status-light/StatusLight.types.d.ts +19 -0
- package/dist/components/status-light/StatusLight.types.js +32 -0
- package/dist/components/status-light/StatusLight.types.js.map +1 -0
- package/dist/components/status-light/index.d.ts +13 -0
- package/dist/components/status-light/index.js +3 -0
- package/dist/components/tabs/Tab.base.d.ts +49 -0
- package/dist/components/tabs/Tab.base.js +39 -0
- package/dist/components/tabs/Tab.base.js.map +1 -0
- package/dist/components/tabs/Tab.types.d.ts +17 -0
- package/dist/components/tabs/TabPanel.base.d.ts +49 -0
- package/dist/components/tabs/TabPanel.base.js +36 -0
- package/dist/components/tabs/TabPanel.base.js.map +1 -0
- package/dist/components/tabs/TabPanel.types.d.ts +17 -0
- package/dist/components/tabs/Tabs.base.d.ts +221 -0
- package/dist/components/tabs/Tabs.base.js +213 -0
- package/dist/components/tabs/Tabs.base.js.map +1 -0
- package/dist/components/tabs/Tabs.types.d.ts +55 -0
- package/dist/components/tabs/Tabs.types.js +6 -0
- package/dist/components/tabs/Tabs.types.js.map +1 -0
- package/dist/components/tabs/index.d.ts +17 -0
- package/dist/components/tabs/index.js +5 -0
- package/dist/components/tooltip/Tooltip.base.d.ts +159 -0
- package/dist/components/tooltip/Tooltip.base.js +198 -0
- package/dist/components/tooltip/Tooltip.base.js.map +1 -0
- package/dist/components/tooltip/Tooltip.types.d.ts +18 -0
- package/dist/components/tooltip/Tooltip.types.js +15 -0
- package/dist/components/tooltip/Tooltip.types.js.map +1 -0
- package/dist/components/tooltip/index.d.ts +13 -0
- package/dist/components/tooltip/index.js +3 -0
- package/dist/controllers/color-controller/index.d.ts +12 -0
- package/dist/controllers/color-controller/index.js +2 -0
- package/dist/controllers/color-controller/src/color-controller.d.ts +226 -0
- package/dist/controllers/color-controller/src/color-controller.js +253 -0
- package/dist/controllers/color-controller/src/color-controller.js.map +1 -0
- package/dist/controllers/drag-and-drop-controller/index.d.ts +12 -0
- package/dist/controllers/drag-and-drop-controller/index.js +2 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.d.ts +68 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js +56 -0
- package/dist/controllers/drag-and-drop-controller/src/drag-and-drop-controller.js.map +1 -0
- package/dist/controllers/focusgroup-navigation-controller/index.d.ts +12 -0
- package/dist/controllers/focusgroup-navigation-controller/index.js +2 -0
- package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.d.ts +496 -0
- package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.js +345 -0
- package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.js.map +1 -0
- package/dist/controllers/hover-controller/index.d.ts +12 -0
- package/dist/controllers/hover-controller/index.js +2 -0
- package/dist/controllers/hover-controller/src/hover-controller.d.ts +118 -0
- package/dist/controllers/hover-controller/src/hover-controller.js +90 -0
- package/dist/controllers/hover-controller/src/hover-controller.js.map +1 -0
- package/dist/controllers/index.d.ts +26 -0
- package/dist/controllers/index.js +18 -0
- package/dist/controllers/language-resolution.d.ts +87 -0
- package/dist/controllers/language-resolution.js +56 -0
- package/dist/controllers/language-resolution.js.map +1 -0
- package/dist/controllers/live-selection-controller/index.d.ts +12 -0
- package/dist/controllers/live-selection-controller/index.js +2 -0
- package/dist/controllers/live-selection-controller/src/live-selection-controller.d.ts +144 -0
- package/dist/controllers/live-selection-controller/src/live-selection-controller.js +36 -0
- package/dist/controllers/live-selection-controller/src/live-selection-controller.js.map +1 -0
- package/dist/controllers/page-scroll-lock-controller/index.d.ts +12 -0
- package/dist/controllers/page-scroll-lock-controller/index.js +2 -0
- package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.d.ts +20 -0
- package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.js +30 -0
- package/dist/controllers/page-scroll-lock-controller/src/page-scroll-lock.js.map +1 -0
- package/dist/controllers/pending-controller/index.d.ts +12 -0
- package/dist/controllers/pending-controller/index.js +2 -0
- package/dist/controllers/pending-controller/src/pending-controller.d.ts +95 -0
- package/dist/controllers/pending-controller/src/pending-controller.js +55 -0
- package/dist/controllers/pending-controller/src/pending-controller.js.map +1 -0
- package/dist/controllers/placement-controller/index.d.ts +12 -0
- package/dist/controllers/placement-controller/index.js +4 -0
- package/dist/controllers/placement-controller/src/fallback-placements.d.ts +9 -0
- package/dist/controllers/placement-controller/src/fallback-placements.js +71 -0
- package/dist/controllers/placement-controller/src/fallback-placements.js.map +1 -0
- package/dist/controllers/placement-controller/src/placement-controller.d.ts +152 -0
- package/dist/controllers/placement-controller/src/placement-controller.js +129 -0
- package/dist/controllers/placement-controller/src/placement-controller.js.map +1 -0
- package/dist/controllers/placement-controller/src/placement-conversion.d.ts +35 -0
- package/dist/controllers/placement-controller/src/placement-conversion.js +54 -0
- package/dist/controllers/placement-controller/src/placement-conversion.js.map +1 -0
- package/dist/controllers/placement-controller/src/types.d.ts +128 -0
- package/dist/controllers/placement-controller/src/types.js +29 -0
- package/dist/controllers/placement-controller/src/types.js.map +1 -0
- package/dist/controllers/slot-attribute-propagation-controller/index.d.ts +12 -0
- package/dist/controllers/slot-attribute-propagation-controller/index.js +2 -0
- package/dist/controllers/slot-attribute-propagation-controller/src/slot-attribute-propagation-controller.d.ts +65 -0
- package/dist/controllers/slot-attribute-propagation-controller/src/slot-attribute-propagation-controller.js +33 -0
- package/dist/controllers/slot-attribute-propagation-controller/src/slot-attribute-propagation-controller.js.map +1 -0
- package/dist/controllers/slot-presence-controller/index.d.ts +12 -0
- package/dist/controllers/slot-presence-controller/index.js +2 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.d.ts +57 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js +44 -0
- package/dist/controllers/slot-presence-controller/src/slot-presence-controller.js.map +1 -0
- package/dist/controllers/slot-text-controller/index.d.ts +12 -0
- package/dist/controllers/slot-text-controller/index.js +2 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.d.ts +92 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.js +53 -0
- package/dist/controllers/slot-text-controller/src/slot-text-controller.js.map +1 -0
- package/dist/directives/index.d.ts +15 -0
- package/dist/directives/index.js +3 -0
- package/dist/directives/pending-spinner/index.d.ts +12 -0
- package/dist/directives/pending-spinner/index.js +1 -0
- package/dist/directives/pending-spinner/src/pending-spinner.d.ts +22 -0
- package/dist/directives/pending-spinner/src/pending-spinner.js +39 -0
- package/dist/directives/pending-spinner/src/pending-spinner.js.map +1 -0
- package/dist/element/define-element.d.ts +16 -0
- package/dist/element/define-element.js +8 -0
- package/dist/element/define-element.js.map +1 -0
- package/dist/element/index.d.ts +14 -0
- package/dist/element/index.js +4 -0
- package/dist/element/spectrum-element.d.ts +69 -0
- package/dist/element/spectrum-element.js +85 -0
- package/dist/element/spectrum-element.js.map +1 -0
- package/dist/element/version.d.ts +19 -0
- package/dist/element/version.js +6 -0
- package/dist/element/version.js.map +1 -0
- package/dist/mixins/disabled-mixin.d.ts +30 -0
- package/dist/mixins/disabled-mixin.js +27 -0
- package/dist/mixins/disabled-mixin.js.map +1 -0
- package/dist/mixins/index.d.ts +16 -0
- package/dist/mixins/index.js +5 -0
- package/dist/mixins/linear-progress-mixin.d.ts +41 -0
- package/dist/mixins/linear-progress-mixin.js +115 -0
- package/dist/mixins/linear-progress-mixin.js.map +1 -0
- package/dist/mixins/pending-mixin.d.ts +45 -0
- package/dist/mixins/pending-mixin.js +50 -0
- package/dist/mixins/pending-mixin.js.map +1 -0
- package/dist/mixins/sized-mixin.d.ts +49 -0
- package/dist/mixins/sized-mixin.js +42 -0
- package/dist/mixins/sized-mixin.js.map +1 -0
- package/dist/utils/actual-placement.d.ts +10 -0
- package/dist/utils/actual-placement.js +8 -0
- package/dist/utils/actual-placement.js.map +1 -0
- package/dist/utils/capitalize.d.ts +26 -0
- package/dist/utils/capitalize.js +8 -0
- package/dist/utils/capitalize.js.map +1 -0
- package/dist/utils/deep-contains.d.ts +26 -0
- package/dist/utils/deep-contains.js +14 -0
- package/dist/utils/deep-contains.js.map +1 -0
- package/dist/utils/dev-validation.d.ts +88 -0
- package/dist/utils/dev-validation.js +33 -0
- package/dist/utils/dev-validation.js.map +1 -0
- package/dist/utils/dismissible-stack.d.ts +26 -0
- package/dist/utils/dismissible-stack.js +16 -0
- package/dist/utils/dismissible-stack.js.map +1 -0
- package/dist/utils/focusable-selectors.d.ts +43 -0
- package/dist/utils/focusable-selectors.js +18 -0
- package/dist/utils/focusable-selectors.js.map +1 -0
- package/dist/utils/get-active-element.d.ts +31 -0
- package/dist/utils/get-active-element.js +11 -0
- package/dist/utils/get-active-element.js.map +1 -0
- package/dist/utils/get-label-from-slot.d.ts +12 -0
- package/dist/utils/get-label-from-slot.js +10 -0
- package/dist/utils/get-label-from-slot.js.map +1 -0
- package/dist/utils/index.d.ts +22 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/is-focus-visible-in-tree.d.ts +33 -0
- package/dist/utils/is-focus-visible-in-tree.js +11 -0
- package/dist/utils/is-focus-visible-in-tree.js.map +1 -0
- package/dist/utils/resolve-trigger.d.ts +42 -0
- package/dist/utils/resolve-trigger.js +23 -0
- package/dist/utils/resolve-trigger.js.map +1 -0
- package/dist/utils/transition.d.ts +53 -0
- package/dist/utils/transition.js +26 -0
- package/dist/utils/transition.js.map +1 -0
- package/package.json +644 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region controllers/drag-and-drop-controller/src/drag-and-drop-controller.ts
|
|
2
|
+
var e = 100, t = class {
|
|
3
|
+
constructor(t, n) {
|
|
4
|
+
this._dragLeaveTimer = null, this._abortController = null, this._onDragOver = (e) => {
|
|
5
|
+
var t, n, r, i, a;
|
|
6
|
+
if (e.preventDefault(), e.dataTransfer) {
|
|
7
|
+
if (this._clearDragLeaveTimer(), ((t = (n = this._options).shouldAccept) == null ? void 0 : t.call(n, e)) === !1) {
|
|
8
|
+
if (e.dataTransfer.dropEffect = "none", this._options.isDragged()) {
|
|
9
|
+
var o, s;
|
|
10
|
+
(o = (s = this._options).onDragLeave) == null || o.call(s, {
|
|
11
|
+
clientX: e.clientX,
|
|
12
|
+
clientY: e.clientY,
|
|
13
|
+
relatedTarget: e.relatedTarget
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (e.dataTransfer.dropEffect = (r = (i = (a = this._options).dropEffect) == null ? void 0 : i.call(a)) == null ? "copy" : r, !this._options.isDragged()) {
|
|
19
|
+
var c, l;
|
|
20
|
+
(c = (l = this._options).onDragEnter) == null || c.call(l, e);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, this._onDragLeave = (t) => {
|
|
24
|
+
if (t.relatedTarget && this._host.contains(t.relatedTarget)) return;
|
|
25
|
+
this._clearDragLeaveTimer();
|
|
26
|
+
let { clientX: n, clientY: r, relatedTarget: i } = t;
|
|
27
|
+
this._dragLeaveTimer = setTimeout(() => {
|
|
28
|
+
var e, t;
|
|
29
|
+
this._dragLeaveTimer = null, (e = (t = this._options).onDragLeave) == null || e.call(t, {
|
|
30
|
+
clientX: n,
|
|
31
|
+
clientY: r,
|
|
32
|
+
relatedTarget: i
|
|
33
|
+
});
|
|
34
|
+
}, e);
|
|
35
|
+
}, this._onDrop = (e) => {
|
|
36
|
+
var t, n;
|
|
37
|
+
e.preventDefault(), this._options.isDragged() && (this._clearDragLeaveTimer(), (t = (n = this._options).onDrop) == null || t.call(n, e));
|
|
38
|
+
}, this._host = t, this._options = n, t.addController(this);
|
|
39
|
+
}
|
|
40
|
+
hostConnected() {
|
|
41
|
+
this._abortController = new AbortController();
|
|
42
|
+
let { signal: e } = this._abortController;
|
|
43
|
+
this._host.addEventListener("dragover", this._onDragOver, { signal: e }), this._host.addEventListener("dragleave", this._onDragLeave, { signal: e }), this._host.addEventListener("drop", this._onDrop, { signal: e });
|
|
44
|
+
}
|
|
45
|
+
hostDisconnected() {
|
|
46
|
+
var e;
|
|
47
|
+
(e = this._abortController) == null || e.abort(), this._abortController = null, this._clearDragLeaveTimer();
|
|
48
|
+
}
|
|
49
|
+
_clearDragLeaveTimer() {
|
|
50
|
+
this._dragLeaveTimer !== null && (clearTimeout(this._dragLeaveTimer), this._dragLeaveTimer = null);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { t as DragAndDropController };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=drag-and-drop-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drag-and-drop-controller.js","names":[],"sources":["../../../../controllers/drag-and-drop-controller/src/drag-and-drop-controller.ts"],"sourcesContent":["/**\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport type { ReactiveController, ReactiveElement } from 'lit';\n\n// ─────────────────────────\n// TYPES\n// ─────────────────────────\n\n/**\n * Snapshot of the fields read from a native `DragEvent` before it's recycled\n * by the browser, safe to read after the debounce in {@link DragAndDropControllerOptions.onDragLeave}.\n */\nexport interface DragLeaveSnapshot {\n clientX: number;\n clientY: number;\n relatedTarget: EventTarget | null;\n}\n\n/** Configuration options for {@link DragAndDropController}. */\nexport interface DragAndDropControllerOptions {\n /**\n * The host's own current \"is a drag over me\" flag. The controller never\n * keeps a copy of this state; it re-reads it on every native event so a\n * host that also exposes this flag as a public, externally-settable\n * property (as `swc-dropzone` does) can never drift out of sync with it.\n */\n isDragged: () => boolean;\n\n /**\n * Return `false` to reject the current drag payload; sets the OS cursor to\n * \"not-allowed\". Called on every native `dragover` tick. Defaults to\n * always-accept.\n */\n shouldAccept?: (event: DragEvent) => boolean;\n\n /** Called once when an accepted drag enters — not on every `dragover` tick. Set `isDragged`'s backing flag to `true` here. */\n onDragEnter?: (event: DragEvent) => void;\n\n /** Called once the accepted drag leaves or becomes rejected. Set `isDragged`'s backing flag to `false` here. */\n onDragLeave?: (snapshot: DragLeaveSnapshot) => void;\n\n /** Called on drop, only when `isDragged()` is currently `true`. */\n onDrop?: (event: DragEvent) => void;\n\n /** OS cursor feedback while an accepted drag hovers. Defaults to `'copy'`. */\n dropEffect?: () => DataTransfer['dropEffect'];\n}\n\n// Long enough that passing over a child element's own dragleave/dragover pair\n// doesn't flicker the state; short enough that leaving the host still reads\n// as immediate.\nconst DRAG_LEAVE_DEBOUNCE_MS = 100;\n\n// ─────────────────────────\n// CONTROLLER\n// ─────────────────────────\n\n/**\n * A Lit {@link ReactiveController} that manages native drag-and-drop event\n * wiring (`dragover` / `dragleave` / `drop`) for a host element: debounces\n * `dragleave` so passing over a child element doesn't flicker the state,\n * de-duplicates entry so `onDragEnter` fires once per hover session rather\n * than on every `dragover` tick, and lets the host veto payloads it doesn't\n * want via `shouldAccept`.\n *\n * The host owns its own \"dragged\" state (via `isDragged`/`onDragEnter`/\n * `onDragLeave`); this controller only drives the timing.\n *\n * @example\n * ```ts\n * const dragAndDrop = new DragAndDropController(this, {\n * isDragged: () => this._dragged,\n * onDragEnter: () => { this._dragged = true; },\n * onDragLeave: () => { this._dragged = false; },\n * onDrop: (event) => this._handleFilesDropped(event.dataTransfer?.files),\n * });\n * ```\n */\nexport class DragAndDropController implements ReactiveController {\n private readonly _host: ReactiveElement;\n private readonly _options: DragAndDropControllerOptions;\n private _dragLeaveTimer: ReturnType<typeof setTimeout> | null = null;\n private _abortController: AbortController | null = null;\n\n constructor(host: ReactiveElement, options: DragAndDropControllerOptions) {\n this._host = host;\n this._options = options;\n host.addController(this);\n }\n\n public hostConnected(): void {\n this._abortController = new AbortController();\n const { signal } = this._abortController;\n this._host.addEventListener('dragover', this._onDragOver as EventListener, {\n signal,\n });\n this._host.addEventListener(\n 'dragleave',\n this._onDragLeave as EventListener,\n { signal }\n );\n this._host.addEventListener('drop', this._onDrop as EventListener, {\n signal,\n });\n }\n\n public hostDisconnected(): void {\n this._abortController?.abort();\n this._abortController = null;\n this._clearDragLeaveTimer();\n }\n\n private readonly _onDragOver = (event: DragEvent): void => {\n event.preventDefault();\n if (!event.dataTransfer) {\n return;\n }\n\n this._clearDragLeaveTimer();\n if (this._options.shouldAccept?.(event) === false) {\n event.dataTransfer.dropEffect = 'none';\n if (this._options.isDragged()) {\n this._options.onDragLeave?.({\n clientX: event.clientX,\n clientY: event.clientY,\n relatedTarget: event.relatedTarget,\n });\n }\n return;\n }\n\n event.dataTransfer.dropEffect = this._options.dropEffect?.() ?? 'copy';\n\n if (!this._options.isDragged()) {\n this._options.onDragEnter?.(event);\n }\n };\n\n private readonly _onDragLeave = (event: DragEvent): void => {\n if (\n event.relatedTarget &&\n this._host.contains(event.relatedTarget as Node)\n ) {\n return;\n }\n\n this._clearDragLeaveTimer();\n // Capture synchronously; browsers recycle DragEvent objects after the\n // synchronous handler returns, so reading them inside setTimeout is unsafe.\n const { clientX, clientY, relatedTarget } = event;\n this._dragLeaveTimer = setTimeout(() => {\n this._dragLeaveTimer = null;\n this._options.onDragLeave?.({ clientX, clientY, relatedTarget });\n }, DRAG_LEAVE_DEBOUNCE_MS);\n };\n\n private readonly _onDrop = (event: DragEvent): void => {\n event.preventDefault();\n if (!this._options.isDragged()) {\n return;\n }\n\n this._clearDragLeaveTimer();\n this._options.onDrop?.(event);\n };\n\n private _clearDragLeaveTimer(): void {\n if (this._dragLeaveTimer !== null) {\n clearTimeout(this._dragLeaveTimer);\n this._dragLeaveTimer = null;\n }\n }\n}\n"],"mappings":";AA6DA,IAAM,IAAyB,KA2BlB,IAAb,MAAiE;CAM/D,YAAY,GAAuB,GAAuC;AAGxE,yBAN8D,8BACb,0BA8BnB,MAA2B;;AACzD,SAAM,gBAAgB,EACjB,EAAM,cAKX;QADA,KAAK,sBAAsB,IAC3B,KAAA,IAAI,KAAK,UAAS,iBAAA,OAAA,KAAA,IAAA,EAAA,KAAA,GAAe,EAAM,MAAK,IAAO;AAEjD,SADA,EAAM,aAAa,aAAa,QAC5B,KAAK,SAAS,WAAW,EAAE;;AAC7B,OAAA,KAAA,IAAA,KAAK,UAAS,gBAAA,QAAA,EAAA,KAAA,GAAc;OAC1B,SAAS,EAAM;OACf,SAAS,EAAM;OACf,eAAe,EAAM;OACtB,CAAC;;AAEJ;;AAKF,QAFA,EAAM,aAAa,cAAA,KAAA,KAAA,IAAa,KAAK,UAAS,eAAA,OAAA,KAAA,IAAA,EAAA,KAAA,EAAc,KAAA,OAAI,SAAJ,GAExD,CAAC,KAAK,SAAS,WAAW,EAAE;;AAC9B,MAAA,KAAA,IAAA,KAAK,UAAS,gBAAA,QAAA,EAAA,KAAA,GAAc,EAAM;;;0BAIL,MAA2B;AAC1D,OACE,EAAM,iBACN,KAAK,MAAM,SAAS,EAAM,cAAsB,CAEhD;AAGF,QAAK,sBAAsB;GAG3B,IAAM,EAAE,YAAS,YAAS,qBAAkB;AAC5C,QAAK,kBAAkB,iBAAiB;;AAEtC,IADA,KAAK,kBAAkB,OACvB,KAAA,IAAA,KAAK,UAAS,gBAAA,QAAA,EAAA,KAAA,GAAc;KAAE;KAAS;KAAS;KAAe,CAAC;MAC/D,EAAuB;qBAGA,MAA2B;;AACrD,KAAM,gBAAgB,EACjB,KAAK,SAAS,WAAW,KAI9B,KAAK,sBAAsB,GAC3B,KAAA,IAAA,KAAK,UAAS,WAAA,QAAA,EAAA,KAAA,GAAS,EAAM;KA9E7B,KAAK,QAAQ,GACb,KAAK,WAAW,GAChB,EAAK,cAAc,KAAK;;CAG1B,gBAA6B;AAC3B,OAAK,mBAAmB,IAAI,iBAAiB;EAC7C,IAAM,EAAE,cAAW,KAAK;AASxB,EARA,KAAK,MAAM,iBAAiB,YAAY,KAAK,aAA8B,EACzE,WACD,CAAC,EACF,KAAK,MAAM,iBACT,aACA,KAAK,cACL,EAAE,WAAQ,CACX,EACD,KAAK,MAAM,iBAAiB,QAAQ,KAAK,SAA0B,EACjE,WACD,CAAC;;CAGJ,mBAAgC;;AAG9B,GAFA,IAAA,KAAK,qBAAA,QAAA,EAAkB,OAAO,EAC9B,KAAK,mBAAmB,MACxB,KAAK,sBAAsB;;CAyD7B,uBAAqC;AACnC,EAAI,KAAK,oBAAoB,SAC3B,aAAa,KAAK,gBAAgB,EAClC,KAAK,kBAAkB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
export { focusgroupNavigationActiveChange, FocusgroupNavigationController, type FocusgroupActiveChangeSource, type FocusgroupDirection, type FocusgroupNavigationActiveChangeDetail, type FocusgroupNavigationOptions, } from './src/focusgroup-navigation-controller.js';
|
package/dist/controllers/focusgroup-navigation-controller/src/focusgroup-navigation-controller.d.ts
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { ReactiveController, ReactiveElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* Spatial mode for arrow-key movement. Aligns with logical axes (inline/block) and a
|
|
4
|
+
* 2D layout mode derived from element geometry.
|
|
5
|
+
*
|
|
6
|
+
* - **horizontal**: Arrow keys on the inline axis move focus (respects `dir`).
|
|
7
|
+
* - **vertical**: Arrow keys on the block axis move focus.
|
|
8
|
+
* - **both**: **ArrowLeft** / **ArrowRight** move along `getItems()` order like **horizontal**
|
|
9
|
+
* (respects `dir`); **ArrowUp** / **ArrowDown** move backward / forward in the same order.
|
|
10
|
+
* - **grid**: Arrow keys move in rows and columns using bounding-rect layout; Ctrl+Home / Ctrl+End
|
|
11
|
+
* jump to the first cell of the first row or the last cell of the last row.
|
|
12
|
+
*/
|
|
13
|
+
export type FocusgroupDirection = 'horizontal' | 'vertical' | 'both' | 'grid';
|
|
14
|
+
/**
|
|
15
|
+
* Options for {@link FocusgroupNavigationController}.
|
|
16
|
+
*/
|
|
17
|
+
export type FocusgroupNavigationOptions = {
|
|
18
|
+
/**
|
|
19
|
+
* Returns the current set of items that participate in roving tabindex and
|
|
20
|
+
* directional navigation. Callers typically close over the host (for example
|
|
21
|
+
* querying slotted or shadow DOM children).
|
|
22
|
+
*/
|
|
23
|
+
getItems: () => HTMLElement[];
|
|
24
|
+
/**
|
|
25
|
+
* Determines which arrow keys move focus and how grid navigation is computed.
|
|
26
|
+
* Use **`both`** when the same linear order should respond to horizontal and vertical arrow keys.
|
|
27
|
+
*/
|
|
28
|
+
direction: FocusgroupDirection;
|
|
29
|
+
/**
|
|
30
|
+
* When true, arrow keys wrap from the last item to the first (and reverse).
|
|
31
|
+
* Defaults to false.
|
|
32
|
+
*/
|
|
33
|
+
wrap?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* When true, restoring focus into the composite (for example with Tab) targets
|
|
36
|
+
* the item that was last focused, if it is still a member of the group.
|
|
37
|
+
* Similar to the default memory behavior described for `focusgroup` in Open UI.
|
|
38
|
+
* Defaults to true.
|
|
39
|
+
*/
|
|
40
|
+
memory?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* When true, both natively `disabled` and `aria-disabled="true"` items are
|
|
43
|
+
* skipped for arrow navigation and are not chosen as the roving tab stop.
|
|
44
|
+
* When false (default), disabled items remain in sequence — useful for
|
|
45
|
+
* patterns such as menus where disabled items may still be focusable per
|
|
46
|
+
* APG guidance.
|
|
47
|
+
*
|
|
48
|
+
* **Note:** Regardless of this flag, natively `disabled` elements are never
|
|
49
|
+
* chosen as the roving tab stop (`tabindex="0"`) because they cannot receive
|
|
50
|
+
* browser focus; see {@link applyRovingTabindex}. A future revision may
|
|
51
|
+
* decouple native `disabled` and `aria-disabled` into separate options if
|
|
52
|
+
* component migrations surface the need.
|
|
53
|
+
*
|
|
54
|
+
* Defaults to false.
|
|
55
|
+
*/
|
|
56
|
+
skipDisabled?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Invoked after the active item changes and `tabindex` values are synchronized.
|
|
59
|
+
* The argument is the new active element, or null when the group has no eligible items.
|
|
60
|
+
*/
|
|
61
|
+
onActiveItemChange?: (active: HTMLElement | null) => void;
|
|
62
|
+
/**
|
|
63
|
+
* When set to a **non-zero** integer, **Page Up** / **Page Down** move focus by that many
|
|
64
|
+
* positions in `getItems()` order for **`horizontal`**, **`vertical`**, and **`both`** modes
|
|
65
|
+
* (respects **`wrap`** the same way as single-step arrows).
|
|
66
|
+
* For **`grid`**, page keys move by that many **rows** (column index is clamped to each row’s
|
|
67
|
+
* length). Omitted, `0`, `NaN`, and non-finite values disable page keys. The sign of the
|
|
68
|
+
* number is ignored; only the magnitude is used.
|
|
69
|
+
*/
|
|
70
|
+
pageStep?: number;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Name of the `CustomEvent` dispatched on the host when the roving tabindex active item changes.
|
|
74
|
+
*
|
|
75
|
+
* The event `bubbles` and is `composed`. Handlers read
|
|
76
|
+
* {@link FocusgroupNavigationActiveChangeDetail} from `event.detail`.
|
|
77
|
+
*/
|
|
78
|
+
export declare const focusgroupNavigationActiveChange = "swc-focusgroup-navigation-active-change";
|
|
79
|
+
/**
|
|
80
|
+
* Describes why the active item changed in a {@link focusgroupNavigationActiveChange} event.
|
|
81
|
+
*
|
|
82
|
+
* - **`keyboard`** — Arrow key, Home, or End navigation moved focus.
|
|
83
|
+
* - **`focus`** — A managed item received DOM focus directly (pointer click or Tab-key entry).
|
|
84
|
+
* - **`refresh`** — {@link FocusgroupNavigationController.refresh} re-parked the roving tab stop.
|
|
85
|
+
* - **`programmatic`** — {@link FocusgroupNavigationController.setActiveItem} or
|
|
86
|
+
* {@link FocusgroupNavigationController.focusFirstItemByTextPrefix} was called directly.
|
|
87
|
+
*/
|
|
88
|
+
export type FocusgroupActiveChangeSource = 'keyboard' | 'focus' | 'refresh' | 'programmatic';
|
|
89
|
+
/**
|
|
90
|
+
* `detail` object for the {@link focusgroupNavigationActiveChange} event.
|
|
91
|
+
*/
|
|
92
|
+
export type FocusgroupNavigationActiveChangeDetail = {
|
|
93
|
+
/**
|
|
94
|
+
* Element that now has `tabindex="0"` among managed items, or null when the group is empty.
|
|
95
|
+
*/
|
|
96
|
+
activeElement: HTMLElement | null;
|
|
97
|
+
/**
|
|
98
|
+
* Why the active item changed. Hosts that implement selection-follows-focus (e.g. automatic
|
|
99
|
+
* activation in a tab list) should react to `'keyboard'` and `'focus'` sources and ignore
|
|
100
|
+
* `'refresh'` and `'programmatic'` to avoid spurious selection changes on mount or when
|
|
101
|
+
* toggling `disabled`.
|
|
102
|
+
*/
|
|
103
|
+
source: FocusgroupActiveChangeSource;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* **FocusgroupNavigation** — implements the roving `tabindex` pattern from the APG
|
|
107
|
+
* keyboard guide and directional navigation similar to the proposed `focusgroup`
|
|
108
|
+
* attribute (Open UI). The exported class name is `FocusgroupNavigationController`.
|
|
109
|
+
*
|
|
110
|
+
* The controller:
|
|
111
|
+
* - Keeps exactly one item in the tab order (`tabindex="0"`) per composite; sets
|
|
112
|
+
* `tabindex="-1"` on other items it manages.
|
|
113
|
+
* - Handles Arrow keys, Home, and End for focus movement (and optionally wrap). **`both`**
|
|
114
|
+
* direction accepts horizontal and vertical arrows on the same `getItems()` sequence.
|
|
115
|
+
* In **`grid`** mode only, **Ctrl+Home** / **Ctrl+End** move to the first cell of the first
|
|
116
|
+
* row or the last cell of the last row (by layout-derived rows).
|
|
117
|
+
* - Optional **`pageStep`**: **Page Up** / **Page Down** move by that many items (linear modes)
|
|
118
|
+
* or rows (**`grid`**).
|
|
119
|
+
* - Optional **`skipDisabled`**: omit **`disabled`** and **`aria-disabled="true"`** items from
|
|
120
|
+
* roving tabindex and arrow navigation.
|
|
121
|
+
* - Supports optional last-focused memory when re-entering via Tab.
|
|
122
|
+
* - Exposes {@link FocusgroupNavigationController.setActiveItem} to choose the roving tab stop
|
|
123
|
+
* without calling `focus()`, and {@link FocusgroupNavigationController.focusFirstItemByTextPrefix}
|
|
124
|
+
* for typeahead-style roving `tabindex` (call {@link FocusgroupNavigationController.getActiveItem}
|
|
125
|
+
* and `focus()` yourself when you want keyboard focus to move). Arrow-key handling calls
|
|
126
|
+
* `setActiveItem` and `focus()` together.
|
|
127
|
+
*
|
|
128
|
+
* Dispatches a bubbling, composed `CustomEvent` named
|
|
129
|
+
* {@link focusgroupNavigationActiveChange} when the active item changes.
|
|
130
|
+
*
|
|
131
|
+
* This is not a browser `focusgroup` implementation; it is a Lit reactive controller
|
|
132
|
+
* for custom elements until native `focusgroup` is available.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* class MyToolbar extends LitElement {
|
|
137
|
+
* private readonly navigation = new FocusgroupNavigationController(this, {
|
|
138
|
+
* direction: 'horizontal',
|
|
139
|
+
* wrap: true,
|
|
140
|
+
* getItems: () =>
|
|
141
|
+
* Array.from(this.renderRoot.querySelectorAll<HTMLElement>('button')),
|
|
142
|
+
* });
|
|
143
|
+
*
|
|
144
|
+
* protected override firstUpdated(): void {
|
|
145
|
+
* super.firstUpdated();
|
|
146
|
+
* this.navigation.refresh();
|
|
147
|
+
* }
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @see https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#keyboardnavigationinsidecomponents
|
|
152
|
+
* @see https://open-ui.org/components/scoped-focusgroup.explainer/
|
|
153
|
+
*
|
|
154
|
+
* **Native `focusgroup` (future):** The comment block immediately below this class lists which
|
|
155
|
+
* parts of this file are the most likely candidates for deprecation or deletion once browsers
|
|
156
|
+
* ship built-in focus-group behavior that covers the same cases (especially roving tabindex and
|
|
157
|
+
* arrow-key focus moves). Some options (for example rect-based **grid**, **pageStep**, or
|
|
158
|
+
* **skipDisabled**) may remain useful longer if the platform surface stays narrower.
|
|
159
|
+
*/
|
|
160
|
+
export declare class FocusgroupNavigationController implements ReactiveController {
|
|
161
|
+
/**
|
|
162
|
+
* Lit reactive host this controller is attached to.
|
|
163
|
+
*/
|
|
164
|
+
private host;
|
|
165
|
+
/**
|
|
166
|
+
* Effective options (defaults merged with the latest `setOptions` / constructor values).
|
|
167
|
+
*/
|
|
168
|
+
private options;
|
|
169
|
+
/**
|
|
170
|
+
* Capture-phase `keydown` listener reference for removal on disconnect.
|
|
171
|
+
*/
|
|
172
|
+
private readonly boundKeydown;
|
|
173
|
+
/**
|
|
174
|
+
* Capture-phase `focusin` listener reference for removal on disconnect.
|
|
175
|
+
*/
|
|
176
|
+
private readonly boundFocusin;
|
|
177
|
+
/**
|
|
178
|
+
* Capture-phase `focusout` listener reference for removal on disconnect.
|
|
179
|
+
*/
|
|
180
|
+
private readonly boundFocusout;
|
|
181
|
+
/**
|
|
182
|
+
* Cached item for {@link FocusgroupNavigationOptions.memory} when the user moves focus
|
|
183
|
+
* inside or out of the composite. Cleared when that node is no longer returned by
|
|
184
|
+
* `getItems` or when the group becomes empty.
|
|
185
|
+
*/
|
|
186
|
+
private lastFocused;
|
|
187
|
+
/**
|
|
188
|
+
* Tracks the previously dispatched active item so that
|
|
189
|
+
* {@link applyRovingTabindex} only fires the active-change event and
|
|
190
|
+
* {@link FocusgroupNavigationOptions.onActiveItemChange} callback when the
|
|
191
|
+
* active item actually changes.
|
|
192
|
+
*/
|
|
193
|
+
private previousActive;
|
|
194
|
+
/**
|
|
195
|
+
* Guard flag set during keyboard navigation so that the `focusin` triggered
|
|
196
|
+
* by `item.focus()` does not redundantly call {@link applyRovingTabindex}.
|
|
197
|
+
*/
|
|
198
|
+
private isNavigating;
|
|
199
|
+
/**
|
|
200
|
+
* Cached result of {@link getEligibleItems}, populated on first access within
|
|
201
|
+
* a refresh cycle and cleared at the start of each entry point
|
|
202
|
+
* ({@link refresh}, {@link handleFocusin}, {@link handleKeydown}).
|
|
203
|
+
*/
|
|
204
|
+
private cachedEligibleItems;
|
|
205
|
+
/**
|
|
206
|
+
* Cached result of {@link buildRows}, populated on first access within a
|
|
207
|
+
* keydown cycle and cleared alongside {@link cachedEligibleItems}.
|
|
208
|
+
*/
|
|
209
|
+
private cachedRows;
|
|
210
|
+
/**
|
|
211
|
+
* Registers this instance on `host` via `addController` and merges `options` with defaults.
|
|
212
|
+
*
|
|
213
|
+
* @param host - Reactive element that owns the composite (arrow keys and tab order apply within its subtree).
|
|
214
|
+
* @param options - `getItems`, `direction`, and optional behavior flags.
|
|
215
|
+
*/
|
|
216
|
+
constructor(host: ReactiveElement, options: FocusgroupNavigationOptions);
|
|
217
|
+
/**
|
|
218
|
+
* Merges `partial` into the current options and reapplies roving `tabindex` to the item set.
|
|
219
|
+
*
|
|
220
|
+
* @param partial - Fields to override; omitted keys keep their previous values.
|
|
221
|
+
*/
|
|
222
|
+
setOptions(partial: Partial<FocusgroupNavigationOptions>): void;
|
|
223
|
+
/**
|
|
224
|
+
* Returns the eligible managed item that currently participates in the sequential focus order
|
|
225
|
+
* (`tabindex="0"`), or null if no eligible item has tab index zero.
|
|
226
|
+
*
|
|
227
|
+
* @returns The active roving item, or null.
|
|
228
|
+
*/
|
|
229
|
+
getActiveItem(): HTMLElement | null;
|
|
230
|
+
/**
|
|
231
|
+
* Re-queries `getItems()`, recomputes eligibility, and syncs roving `tabindex`.
|
|
232
|
+
*
|
|
233
|
+
* Call after the item list or item eligibility changes (for example after Lit
|
|
234
|
+
* `updated()` or slot changes). When {@link FocusgroupNavigationOptions.memory} is true,
|
|
235
|
+
* prefers the stored last-focused item if it is still eligible; otherwise keeps the
|
|
236
|
+
* current active item or falls back to the first eligible item.
|
|
237
|
+
*/
|
|
238
|
+
refresh(): void;
|
|
239
|
+
/**
|
|
240
|
+
* Sets roving `tabindex` so `item` is the active tab stop (`tabindex="0"`) and others in the
|
|
241
|
+
* group are `-1`. Does **not** call `focus()`. When {@link FocusgroupNavigationOptions.memory}
|
|
242
|
+
* is true, updates the stored last-focused item so Tab re-entry can target this item.
|
|
243
|
+
*
|
|
244
|
+
* @param item - Item to mark active; must be returned by `getItems` and pass eligibility checks.
|
|
245
|
+
* @returns False if `item` is not in the current eligible item list.
|
|
246
|
+
*/
|
|
247
|
+
setActiveItem(item: HTMLElement): boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Updates roving `tabindex` so the first **eligible** item (same set as arrow navigation)
|
|
250
|
+
* whose typeahead label starts with `prefix` becomes the active tab stop (`tabindex="0"`).
|
|
251
|
+
* Matching is **case-insensitive**. The label is the first non-empty of: trimmed
|
|
252
|
+
* **`aria-label`**, trimmed text from **`aria-labelledby`** references (in order, space-joined),
|
|
253
|
+
* or trimmed **`textContent`**. Search order matches arrow-key traversal.
|
|
254
|
+
*
|
|
255
|
+
* Does **not** call `focus()`. After this returns `true`, call `focus()` on
|
|
256
|
+
* {@link FocusgroupNavigationController.getActiveItem} (for example `getActiveItem()?.focus()`),
|
|
257
|
+
* often from a **microtask** when the caller runs from a pointer handler so focus is not
|
|
258
|
+
* overwritten by the clicked control.
|
|
259
|
+
*
|
|
260
|
+
* Typical use: menu typeahead; wire `keydown` or `input` at the host and debounce as needed.
|
|
261
|
+
*
|
|
262
|
+
* @param prefix - String to match as a leading substring after `trim`; whitespace-only yields
|
|
263
|
+
* no match and returns `false`.
|
|
264
|
+
* @returns True if a matching item was found and roving tabindex was applied.
|
|
265
|
+
*/
|
|
266
|
+
focusFirstItemByTextPrefix(prefix: string): boolean;
|
|
267
|
+
/**
|
|
268
|
+
* Lit `ReactiveController` hook: registers capture-phase listeners on `host` and runs
|
|
269
|
+
* an initial {@link refresh}.
|
|
270
|
+
*/
|
|
271
|
+
hostConnected(): void;
|
|
272
|
+
/**
|
|
273
|
+
* Lit `ReactiveController` hook: removes listeners registered in {@link hostConnected}.
|
|
274
|
+
*/
|
|
275
|
+
hostDisconnected(): void;
|
|
276
|
+
/**
|
|
277
|
+
* Resolves writing direction from the computed style of the host element.
|
|
278
|
+
*
|
|
279
|
+
* Uses `getComputedStyle` rather than walking `dir` attributes so that
|
|
280
|
+
* CSS-inherited direction (the gen2 default) is correctly detected.
|
|
281
|
+
*
|
|
282
|
+
* @returns True when horizontal arrow directions should follow RTL semantics.
|
|
283
|
+
*/
|
|
284
|
+
private isRtl;
|
|
285
|
+
/**
|
|
286
|
+
* Whether `node` is the host or reachable from it by walking `parentNode` and
|
|
287
|
+
* `ShadowRoot.host` (so shadow descendants count, including nested shadow roots).
|
|
288
|
+
*
|
|
289
|
+
* `Element.contains()` is not used because it returns false for nodes inside the
|
|
290
|
+
* host's shadow tree, which would drop every item for typical Lit components.
|
|
291
|
+
*
|
|
292
|
+
* @param node - Node to test (may be null).
|
|
293
|
+
* @returns True if `node` is in the host's shadow-inclusive subtree.
|
|
294
|
+
*/
|
|
295
|
+
private isNodeWithinHostScope;
|
|
296
|
+
/**
|
|
297
|
+
* Items returned by `getItems` that lie within `host` (shadow-inclusive tree).
|
|
298
|
+
*
|
|
299
|
+
* @returns Candidates before eligibility filtering.
|
|
300
|
+
*/
|
|
301
|
+
private getRawItems;
|
|
302
|
+
/**
|
|
303
|
+
* {@link getRawItems} filtered by {@link isNavigableItem}.
|
|
304
|
+
*
|
|
305
|
+
* @returns Items that participate in roving tabindex and arrow navigation.
|
|
306
|
+
*/
|
|
307
|
+
private getEligibleItems;
|
|
308
|
+
/**
|
|
309
|
+
* {@link buildRows} with per-cycle caching, cleared alongside
|
|
310
|
+
* {@link cachedEligibleItems}.
|
|
311
|
+
*
|
|
312
|
+
* @param items - Eligible items to lay out as a grid.
|
|
313
|
+
* @returns Cached row-major array of rows.
|
|
314
|
+
*/
|
|
315
|
+
private getRows;
|
|
316
|
+
/**
|
|
317
|
+
* Whether `el` may participate in the focus group (connected, visible, not inert,
|
|
318
|
+
* and not skipped when {@link FocusgroupNavigationOptions.skipDisabled} is true).
|
|
319
|
+
*
|
|
320
|
+
* @param el - Candidate from `getItems`.
|
|
321
|
+
* @returns True if the element counts as navigable for this controller.
|
|
322
|
+
*/
|
|
323
|
+
private isNavigableItem;
|
|
324
|
+
/**
|
|
325
|
+
* Whether `el` should be treated as disabled for {@link FocusgroupNavigationOptions.skipDisabled}.
|
|
326
|
+
*
|
|
327
|
+
* @param el - Element to test.
|
|
328
|
+
* @returns True if the native `disabled` property is true or `aria-disabled` is `"true"`.
|
|
329
|
+
*/
|
|
330
|
+
private isDisabledForSkip;
|
|
331
|
+
/**
|
|
332
|
+
* String used for {@link focusFirstItemByTextPrefix}: prefers **`aria-label`**, then text from
|
|
333
|
+
* **`aria-labelledby`** (IDs resolved in the shadow root or document), else **`textContent`**.
|
|
334
|
+
* All branches are trimmed; empty strings fall through to the next source.
|
|
335
|
+
*/
|
|
336
|
+
private getItemTypeaheadLabel;
|
|
337
|
+
/**
|
|
338
|
+
* Whether `el` is natively disabled and therefore unable to receive focus
|
|
339
|
+
* regardless of its `tabindex` value.
|
|
340
|
+
*/
|
|
341
|
+
private isNativelyDisabled;
|
|
342
|
+
/**
|
|
343
|
+
* Sets `tabindex="-1"` on ineligible raw items, then assigns `tabindex="0"` to
|
|
344
|
+
* `active` (or the first eligible item if `active` is not eligible) and `-1` to the rest.
|
|
345
|
+
*
|
|
346
|
+
* When `skipDisabled` is false, natively disabled items remain in the eligible list
|
|
347
|
+
* for arrow navigation but are never chosen as the roving tab stop because they
|
|
348
|
+
* cannot receive focus. The tab stop falls through to the nearest non-disabled item.
|
|
349
|
+
*
|
|
350
|
+
* Dispatches the active-change event and {@link FocusgroupNavigationOptions.onActiveItemChange}.
|
|
351
|
+
*
|
|
352
|
+
* @param active - Preferred item to mark as the single tab stop when eligible.
|
|
353
|
+
* @param source - Why the active item is changing; included in the dispatched event detail.
|
|
354
|
+
*/
|
|
355
|
+
private applyRovingTabindex;
|
|
356
|
+
/**
|
|
357
|
+
* Dispatches {@link focusgroupNavigationActiveChange} on the reactive host with the given detail.
|
|
358
|
+
*
|
|
359
|
+
* @param activeElement - New active item, or null when clearing selection.
|
|
360
|
+
* @param source - Why the active item changed.
|
|
361
|
+
*/
|
|
362
|
+
private dispatchActiveChange;
|
|
363
|
+
/**
|
|
364
|
+
* Resolves the managed item that actually received focus inside the shadow tree.
|
|
365
|
+
*
|
|
366
|
+
* Same retargeting problem as {@link resolveManagedKeydownTarget}: listeners on
|
|
367
|
+
* the shadow host see `event.target` retargeted to the host when focus lands on a
|
|
368
|
+
* descendant inside the shadow root. Walk `composedPath()` and fall back to
|
|
369
|
+
* `shadowRoot.activeElement` to find the real focused managed item.
|
|
370
|
+
*
|
|
371
|
+
* @param event - Focus event dispatched while focus moves into the composite.
|
|
372
|
+
* @param items - Current eligible items from {@link getEligibleItems}.
|
|
373
|
+
* @returns The managed element that received focus, or null.
|
|
374
|
+
*/
|
|
375
|
+
private resolveManagedFocusTarget;
|
|
376
|
+
/**
|
|
377
|
+
* Capture-phase `focusin` handler: syncs roving `tabindex` when focus moves to a managed item
|
|
378
|
+
* (for example via pointer), and updates memory when enabled.
|
|
379
|
+
*
|
|
380
|
+
* @param event - Focus event whose target may be a group item.
|
|
381
|
+
*/
|
|
382
|
+
private handleFocusin;
|
|
383
|
+
/**
|
|
384
|
+
* Capture-phase `focusout` handler: when focus leaves the host subtree, stores the
|
|
385
|
+
* previous target for {@link FocusgroupNavigationOptions.memory}.
|
|
386
|
+
*
|
|
387
|
+
* @param event - Focus event; `relatedTarget` stays inside the host when moving between items.
|
|
388
|
+
*/
|
|
389
|
+
private handleFocusout;
|
|
390
|
+
/**
|
|
391
|
+
* Resolves which managed item should receive arrow, Home, End, or grid Ctrl+Home / Ctrl+End
|
|
392
|
+
* handling for this key event.
|
|
393
|
+
*
|
|
394
|
+
* Listeners on the shadow **host** often see a **retargeted** {@link KeyboardEvent.target}
|
|
395
|
+
* (the host) while focus is on a descendant inside the shadow tree, so matching
|
|
396
|
+
* `event.target` against `getItems()` fails. {@link Event.composedPath} still includes the
|
|
397
|
+
* focused node; we also fall back to {@link ShadowRoot.activeElement} when needed.
|
|
398
|
+
*
|
|
399
|
+
* @param event - Keyboard event dispatched while focus is in this composite.
|
|
400
|
+
* @param items - Current eligible items from {@link getEligibleItems}.
|
|
401
|
+
* @returns The managed element to treat as keydown target, or null.
|
|
402
|
+
*/
|
|
403
|
+
private resolveManagedKeydownTarget;
|
|
404
|
+
/**
|
|
405
|
+
* Capture-phase `keydown` handler: arrow keys and Home/End move focus among eligible items
|
|
406
|
+
* when the event target is managed; calls `preventDefault` when handling navigation.
|
|
407
|
+
*
|
|
408
|
+
* When {@link FocusgroupDirection | `direction`} is **`both`**, **ArrowLeft** / **ArrowRight**
|
|
409
|
+
* and **ArrowUp** / **ArrowDown** all participate (see {@link navigateBothAxes}).
|
|
410
|
+
*
|
|
411
|
+
* When {@link FocusgroupDirection | `direction`} is **`grid`**, **Ctrl+Home** focuses the
|
|
412
|
+
* first cell in the first row and **Ctrl+End** focuses the last cell in the last row (from
|
|
413
|
+
* {@link buildRows}); other modifier combinations are ignored except plain Home/End.
|
|
414
|
+
*
|
|
415
|
+
* When {@link FocusgroupNavigationOptions.pageStep} is a non-zero finite number, **Page Up**
|
|
416
|
+
* and **Page Down** are handled before arrow keys (see {@link navigatePage}).
|
|
417
|
+
*
|
|
418
|
+
* @param event - Keyboard event from the focused element inside the host.
|
|
419
|
+
*/
|
|
420
|
+
private handleKeydown;
|
|
421
|
+
/**
|
|
422
|
+
* Applies roving tabindex to `item` and moves DOM focus; used for keyboard navigation only.
|
|
423
|
+
*/
|
|
424
|
+
private moveKeyNavigationFocusTo;
|
|
425
|
+
/**
|
|
426
|
+
* Positive step count for {@link FocusgroupNavigationOptions.pageStep}, or null when page keys
|
|
427
|
+
* are disabled.
|
|
428
|
+
*/
|
|
429
|
+
private getEffectivePageMagnitude;
|
|
430
|
+
/**
|
|
431
|
+
* Target for **Page Up** / **Page Down** when {@link getEffectivePageMagnitude} is set.
|
|
432
|
+
*
|
|
433
|
+
* @param items - Eligible items.
|
|
434
|
+
* @param current - Focused item.
|
|
435
|
+
* @param signedDelta - `+magnitude` for Page Down or `-magnitude` for Page Up (items for
|
|
436
|
+
* linear modes, rows for `grid`).
|
|
437
|
+
*/
|
|
438
|
+
private navigatePage;
|
|
439
|
+
/**
|
|
440
|
+
* Page Up/Down along `getItems()` order (used for `horizontal`, `vertical`, and `both`).
|
|
441
|
+
*/
|
|
442
|
+
private navigatePageLinearItems;
|
|
443
|
+
/**
|
|
444
|
+
* Page Up/Down by whole rows in `grid` mode (column clamped per {@link navigateGrid}).
|
|
445
|
+
*/
|
|
446
|
+
private navigatePageGridRows;
|
|
447
|
+
/**
|
|
448
|
+
* Computes the next focus target for linear {@link FocusgroupDirection} modes.
|
|
449
|
+
*
|
|
450
|
+
* @param items - Eligible items in traversal order.
|
|
451
|
+
* @param current - Currently focused item.
|
|
452
|
+
* @param key - `KeyboardEvent.key` value.
|
|
453
|
+
* @param mode - `horizontal` (inline axis) or `vertical` (block axis).
|
|
454
|
+
* @param rtl - When true, horizontal Left/Right swap forward/backward.
|
|
455
|
+
* @returns Next item, or null if the key is not a navigation key or movement is blocked.
|
|
456
|
+
*/
|
|
457
|
+
private navigateLinear;
|
|
458
|
+
/**
|
|
459
|
+
* Computes the next focus target when {@link FocusgroupDirection | `direction`} is **`both`**:
|
|
460
|
+
* inline arrows use the same deltas as {@link navigateLinear} `horizontal` mode; **ArrowUp** /
|
|
461
|
+
* **ArrowDown** step backward / forward in `getItems()` order (not flipped by `dir`).
|
|
462
|
+
*
|
|
463
|
+
* @param items - Eligible items in traversal order.
|
|
464
|
+
* @param current - Currently focused item.
|
|
465
|
+
* @param key - `KeyboardEvent.key` value.
|
|
466
|
+
* @param rtl - When true, horizontal Left/Right swap forward/backward.
|
|
467
|
+
* @returns Next item, or null if the key is not handled or movement is blocked.
|
|
468
|
+
*/
|
|
469
|
+
private navigateBothAxes;
|
|
470
|
+
/**
|
|
471
|
+
* Computes the next focus target for `grid` {@link FocusgroupDirection} mode using
|
|
472
|
+
* row clustering and column indices.
|
|
473
|
+
*
|
|
474
|
+
* @param current - Currently focused item.
|
|
475
|
+
* @param key - `KeyboardEvent.key` value.
|
|
476
|
+
* @param rtl - When true, horizontal Left/Right swap column direction within a row.
|
|
477
|
+
* @param grid - Pre-built row grid from {@link buildRows}.
|
|
478
|
+
* @returns Next cell item, or null if the key is not handled or movement is blocked.
|
|
479
|
+
*/
|
|
480
|
+
private navigateGrid;
|
|
481
|
+
/**
|
|
482
|
+
* Groups `items` into rows by similar `getBoundingClientRect().top`, then sorts each row by `left`.
|
|
483
|
+
*
|
|
484
|
+
* @param items - Eligible elements to lay out as a grid.
|
|
485
|
+
* @returns Row-major array of rows; each row is left-to-right.
|
|
486
|
+
*/
|
|
487
|
+
private buildRows;
|
|
488
|
+
/**
|
|
489
|
+
* Locates `el` in a row-major grid built by {@link buildRows}.
|
|
490
|
+
*
|
|
491
|
+
* @param grid - Rows of elements.
|
|
492
|
+
* @param el - Element to find.
|
|
493
|
+
* @returns Row and column indices, or null if absent.
|
|
494
|
+
*/
|
|
495
|
+
private findGridIndex;
|
|
496
|
+
}
|