igniteui-webcomponents 7.3.0-beta.0 → 7.3.0-beta.1
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/CHANGELOG.md +20 -0
- package/animations/player.d.ts +7 -2
- package/animations/player.js +1 -2
- package/animations/player.js.map +1 -1
- package/components/accordion/accordion.js +4 -16
- package/components/accordion/accordion.js.map +1 -1
- package/components/avatar/avatar.d.ts +0 -1
- package/components/avatar/avatar.js +5 -9
- package/components/avatar/avatar.js.map +1 -1
- package/components/badge/badge.d.ts +1 -3
- package/components/badge/badge.js +4 -8
- package/components/badge/badge.js.map +1 -1
- package/components/banner/banner.d.ts +6 -5
- package/components/banner/banner.js +19 -17
- package/components/banner/banner.js.map +1 -1
- package/components/button/button-base.d.ts +1 -1
- package/components/button/button-base.js.map +1 -1
- package/components/button-group/button-group.d.ts +0 -1
- package/components/button-group/button-group.js +12 -17
- package/components/button-group/button-group.js.map +1 -1
- package/components/calendar/base.d.ts +3 -13
- package/components/calendar/base.js +10 -31
- package/components/calendar/base.js.map +1 -1
- package/components/calendar/calendar.d.ts +2 -2
- package/components/calendar/months-view/months-view.d.ts +1 -1
- package/components/calendar/months-view/months-view.js.map +1 -1
- package/components/carousel/carousel-indicator.d.ts +1 -1
- package/components/carousel/carousel-indicator.js +13 -13
- package/components/carousel/carousel-indicator.js.map +1 -1
- package/components/carousel/carousel-slide.d.ts +0 -2
- package/components/carousel/carousel-slide.js +7 -9
- package/components/carousel/carousel-slide.js.map +1 -1
- package/components/carousel/carousel.d.ts +52 -35
- package/components/carousel/carousel.js +136 -122
- package/components/carousel/carousel.js.map +1 -1
- package/components/carousel/themes/carousel.base.css.js +1 -1
- package/components/carousel/themes/carousel.base.css.js.map +1 -1
- package/components/chat/chat-input.d.ts +1 -1
- package/components/chat/chat-input.js +21 -21
- package/components/chat/chat-input.js.map +1 -1
- package/components/chat/chat.d.ts +0 -2
- package/components/chat/chat.js +6 -12
- package/components/chat/chat.js.map +1 -1
- package/components/checkbox/checkbox-base.d.ts +1 -1
- package/components/checkbox/checkbox.d.ts +3 -5
- package/components/checkbox/checkbox.js +33 -44
- package/components/checkbox/checkbox.js.map +1 -1
- package/components/checkbox/switch.d.ts +1 -1
- package/components/checkbox/switch.js +23 -34
- package/components/checkbox/switch.js.map +1 -1
- package/components/chip/chip.d.ts +1 -14
- package/components/chip/chip.js +12 -33
- package/components/chip/chip.js.map +1 -1
- package/components/combo/combo-item.d.ts +1 -3
- package/components/combo/combo-item.js +5 -12
- package/components/combo/combo-item.js.map +1 -1
- package/components/combo/combo.d.ts +7 -20
- package/components/combo/combo.js +59 -81
- package/components/combo/combo.js.map +1 -1
- package/components/date-picker/date-picker.base.d.ts +12 -9
- package/components/date-picker/date-picker.base.js +24 -31
- package/components/date-picker/date-picker.base.js.map +1 -1
- package/components/date-picker/date-picker.d.ts +1 -1
- package/components/date-picker/date-picker.js +3 -5
- package/components/date-picker/date-picker.js.map +1 -1
- package/components/date-range-picker/date-range-input.d.ts +2 -4
- package/components/date-range-picker/date-range-input.js +6 -37
- package/components/date-range-picker/date-range-input.js.map +1 -1
- package/components/date-range-picker/date-range-picker.d.ts +2 -5
- package/components/date-range-picker/date-range-picker.js +15 -28
- package/components/date-range-picker/date-range-picker.js.map +1 -1
- package/components/date-range-picker/predefined-ranges-area.d.ts +2 -2
- package/components/date-range-picker/predefined-ranges-area.js +4 -6
- package/components/date-range-picker/predefined-ranges-area.js.map +1 -1
- package/components/date-range-picker/validators.d.ts +1 -1
- package/components/date-range-picker/validators.js +5 -18
- package/components/date-range-picker/validators.js.map +1 -1
- package/components/date-time-input/date-part.d.ts +2 -1
- package/components/date-time-input/date-part.js +38 -75
- package/components/date-time-input/date-part.js.map +1 -1
- package/components/date-time-input/date-time-input.base.d.ts +31 -12
- package/components/date-time-input/date-time-input.base.js +43 -11
- package/components/date-time-input/date-time-input.base.js.map +1 -1
- package/components/date-time-input/date-time-input.d.ts +1 -3
- package/components/date-time-input/date-time-input.js +7 -40
- package/components/date-time-input/date-time-input.js.map +1 -1
- package/components/date-time-input/datetime-mask-parser.d.ts +8 -0
- package/components/date-time-input/datetime-mask-parser.js +8 -8
- package/components/date-time-input/datetime-mask-parser.js.map +1 -1
- package/components/date-time-input/validators.js +3 -14
- package/components/date-time-input/validators.js.map +1 -1
- package/components/dialog/dialog.d.ts +6 -7
- package/components/dialog/dialog.js +21 -26
- package/components/dialog/dialog.js.map +1 -1
- package/components/divider/divider.d.ts +1 -4
- package/components/divider/divider.js +8 -17
- package/components/divider/divider.js.map +1 -1
- package/components/dropdown/dropdown-group.js +1 -6
- package/components/dropdown/dropdown-group.js.map +1 -1
- package/components/expansion-panel/expansion-panel.d.ts +15 -5
- package/components/expansion-panel/expansion-panel.js +23 -34
- package/components/expansion-panel/expansion-panel.js.map +1 -1
- package/components/file-input/file-input.d.ts +2 -14
- package/components/file-input/file-input.js +5 -23
- package/components/file-input/file-input.js.map +1 -1
- package/components/highlight/highlight.d.ts +6 -8
- package/components/highlight/highlight.js +12 -20
- package/components/highlight/highlight.js.map +1 -1
- package/components/icon/icon.d.ts +1 -1
- package/components/icon/registry/types.d.ts +1 -1
- package/components/icon/registry/types.js.map +1 -1
- package/components/input/input.d.ts +9 -19
- package/components/input/input.js +30 -60
- package/components/input/input.js.map +1 -1
- package/components/mask-input/mask-input.d.ts +1 -1
- package/components/mask-input/mask-input.js +2 -4
- package/components/mask-input/mask-input.js.map +1 -1
- package/components/nav-drawer/nav-drawer.d.ts +7 -7
- package/components/nav-drawer/nav-drawer.js +12 -23
- package/components/nav-drawer/nav-drawer.js.map +1 -1
- package/components/progress/base.d.ts +4 -7
- package/components/progress/base.js +21 -45
- package/components/progress/base.js.map +1 -1
- package/components/qr-code/qr-code.d.ts +1 -1
- package/components/qr-code/qr-code.js +3 -2
- package/components/qr-code/qr-code.js.map +1 -1
- package/components/qr-code/types.d.ts +1 -1
- package/components/qr-code/types.js.map +1 -1
- package/components/radio/controller.d.ts +2 -30
- package/components/radio/controller.js +8 -94
- package/components/radio/controller.js.map +1 -1
- package/components/radio/radio.d.ts +5 -5
- package/components/radio/radio.js +48 -58
- package/components/radio/radio.js.map +1 -1
- package/components/radio-group/radio-group.d.ts +1 -2
- package/components/radio-group/radio-group.js +2 -9
- package/components/radio-group/radio-group.js.map +1 -1
- package/components/rating/rating.d.ts +24 -12
- package/components/rating/rating.js +79 -73
- package/components/rating/rating.js.map +1 -1
- package/components/resize-container/default-ghost.js +4 -3
- package/components/resize-container/default-ghost.js.map +1 -1
- package/components/resize-container/resize-container.d.ts +1 -1
- package/components/resize-container/resize-container.js +5 -3
- package/components/resize-container/resize-container.js.map +1 -1
- package/components/resize-container/resize-controller.js +4 -3
- package/components/resize-container/resize-controller.js.map +1 -1
- package/components/select/select-group.d.ts +2 -1
- package/components/select/select-group.js +7 -11
- package/components/select/select-group.js.map +1 -1
- package/components/select/select.d.ts +3 -4
- package/components/select/select.js +23 -28
- package/components/select/select.js.map +1 -1
- package/components/slider/range-slider.d.ts +3 -2
- package/components/slider/range-slider.js +22 -70
- package/components/slider/range-slider.js.map +1 -1
- package/components/slider/slider-base.d.ts +9 -6
- package/components/slider/slider-base.js +27 -28
- package/components/slider/slider-base.js.map +1 -1
- package/components/slider/slider.js +9 -5
- package/components/slider/slider.js.map +1 -1
- package/components/splitter/splitter.d.ts +1 -1
- package/components/splitter/splitter.js.map +1 -1
- package/components/stepper/step.d.ts +3 -0
- package/components/stepper/step.js +9 -5
- package/components/stepper/step.js.map +1 -1
- package/components/stepper/stepper.d.ts +0 -11
- package/components/stepper/stepper.js +21 -86
- package/components/stepper/stepper.js.map +1 -1
- package/components/tabs/tab.d.ts +1 -1
- package/components/tabs/tab.js +6 -5
- package/components/tabs/tab.js.map +1 -1
- package/components/tabs/tabs.d.ts +1 -5
- package/components/tabs/tabs.js +12 -34
- package/components/tabs/tabs.js.map +1 -1
- package/components/textarea/textarea.d.ts +6 -7
- package/components/textarea/textarea.js +3 -10
- package/components/textarea/textarea.js.map +1 -1
- package/components/theme-provider/theme-provider.d.ts +2 -4
- package/components/theme-provider/theme-provider.js +11 -21
- package/components/theme-provider/theme-provider.js.map +1 -1
- package/components/tile-manager/tile-manager.d.ts +10 -21
- package/components/tile-manager/tile-manager.js +43 -74
- package/components/tile-manager/tile-manager.js.map +1 -1
- package/components/tile-manager/tile.d.ts +10 -18
- package/components/tile-manager/tile.js +50 -67
- package/components/tile-manager/tile.js.map +1 -1
- package/components/tooltip/tooltip.d.ts +4 -7
- package/components/tooltip/tooltip.js +20 -28
- package/components/tooltip/tooltip.js.map +1 -1
- package/components/tree/tree.d.ts +1 -14
- package/components/tree/tree.js +5 -23
- package/components/tree/tree.js.map +1 -1
- package/components/tree/tree.navigation.d.ts +1 -1
- package/components/tree/tree.navigation.js.map +1 -1
- package/components/validation-container/validation-container.d.ts +1 -2
- package/components/validation-container/validation-container.js.map +1 -1
- package/components/virtualization/engine.d.ts +40 -38
- package/components/virtualization/engine.js.map +1 -1
- package/components/virtualization/types.d.ts +6 -5
- package/components/virtualization/types.js.map +1 -1
- package/components/virtualization/virtualization.d.ts +94 -80
- package/components/virtualization/virtualization.js +10 -2
- package/components/virtualization/virtualization.js.map +1 -1
- package/custom-elements.json +9940 -7738
- package/igniteui-webcomponents.css-data.json +1 -1
- package/igniteui-webcomponents.html-data.json +1 -1
- package/internals/controllers/aria-projection.d.ts +6 -6
- package/internals/controllers/aria-projection.js.map +1 -1
- package/internals/controllers/context-provider.d.ts +48 -0
- package/internals/controllers/context-provider.js +29 -0
- package/internals/controllers/context-provider.js.map +1 -0
- package/internals/controllers/drag.js +6 -6
- package/internals/controllers/drag.js.map +1 -1
- package/internals/controllers/gestures.js +3 -0
- package/internals/controllers/gestures.js.map +1 -1
- package/internals/controllers/group.d.ts +64 -0
- package/internals/controllers/group.js +104 -0
- package/internals/controllers/group.js.map +1 -0
- package/internals/controllers/internals.d.ts +16 -3
- package/internals/controllers/internals.js +10 -3
- package/internals/controllers/internals.js.map +1 -1
- package/internals/controllers/key-bindings.d.ts +6 -0
- package/internals/controllers/key-bindings.js +3 -0
- package/internals/controllers/key-bindings.js.map +1 -1
- package/internals/controllers/roving-focus.d.ts +72 -0
- package/internals/controllers/roving-focus.js +61 -0
- package/internals/controllers/roving-focus.js.map +1 -0
- package/internals/controllers/slot.d.ts +8 -0
- package/internals/controllers/slot.js +4 -0
- package/internals/controllers/slot.js.map +1 -1
- package/internals/controllers/toggle.d.ts +96 -0
- package/internals/controllers/toggle.js +65 -0
- package/internals/controllers/toggle.js.map +1 -0
- package/internals/date/converters.js +2 -5
- package/internals/date/converters.js.map +1 -1
- package/internals/date/model.d.ts +4 -0
- package/internals/date/model.js +6 -0
- package/internals/date/model.js.map +1 -1
- package/internals/decorators/coerced-property.d.ts +47 -0
- package/internals/decorators/coerced-property.js +36 -0
- package/internals/decorators/coerced-property.js.map +1 -0
- package/internals/i18n/i18n-controller.d.ts +22 -3
- package/internals/i18n/i18n-controller.js +28 -6
- package/internals/i18n/i18n-controller.js.map +1 -1
- package/internals/mixins/alert.d.ts +1 -1
- package/internals/mixins/alert.js +5 -3
- package/internals/mixins/alert.js.map +1 -1
- package/internals/mixins/combo-box.d.ts +3 -12
- package/internals/mixins/combo-box.js +6 -32
- package/internals/mixins/combo-box.js.map +1 -1
- package/internals/mixins/forms/associated.js +18 -0
- package/internals/mixins/forms/associated.js.map +1 -1
- package/internals/mixins/forms/types.d.ts +20 -1
- package/internals/mixins/forms/types.js.map +1 -1
- package/internals/mixins/i18n.d.ts +31 -0
- package/internals/mixins/i18n.js +36 -0
- package/internals/mixins/i18n.js.map +1 -0
- package/internals/mixins/mask-behavior.d.ts +6 -5
- package/internals/mixins/mask-behavior.js +1 -2
- package/internals/mixins/mask-behavior.js.map +1 -1
- package/internals/mixins/option.js +4 -2
- package/internals/mixins/option.js.map +1 -1
- package/internals/templates/masked-input.d.ts +1 -1
- package/internals/templates/masked-input.js.map +1 -1
- package/internals/templates/slotted-icon.d.ts +32 -0
- package/internals/templates/slotted-icon.js +19 -0
- package/internals/templates/slotted-icon.js.map +1 -0
- package/internals/templates/toggle-shell.d.ts +46 -0
- package/internals/templates/toggle-shell.js +38 -0
- package/internals/templates/toggle-shell.js.map +1 -0
- package/internals/timing.d.ts +32 -0
- package/internals/timing.js +20 -0
- package/internals/timing.js.map +1 -0
- package/internals/utils/arrays.d.ts +2 -2
- package/internals/utils/arrays.js.map +1 -1
- package/internals/utils/dom.d.ts +22 -0
- package/internals/utils/dom.js +15 -1
- package/internals/utils/dom.js.map +1 -1
- package/internals/utils/math.d.ts +1 -1
- package/internals/utils/math.js.map +1 -1
- package/internals/utils/types.d.ts +1 -1
- package/internals/utils/types.js.map +1 -1
- package/internals/validators.d.ts +23 -0
- package/internals/validators.js +21 -0
- package/internals/validators.js.map +1 -1
- package/package.json +1 -1
- package/theming/theming-controller.d.ts +3 -3
- package/theming/theming-controller.js.map +1 -1
- package/web-types.json +2 -2
- package/internals/decorators/watch.d.ts +0 -5
- package/internals/decorators/watch.js +0 -19
- package/internals/decorators/watch.js.map +0 -1
|
@@ -7,7 +7,7 @@ type ControllerHost = ReactiveControllerHost & LitElement;
|
|
|
7
7
|
*
|
|
8
8
|
* The host cannot publish these itself: it delegates focus, so the native
|
|
9
9
|
* editor inside the input component's shadow root is what assistive technology
|
|
10
|
-
* lands on and reports. All relations travel as element references
|
|
10
|
+
* lands on and reports. All relations travel as element references - an IDREF
|
|
11
11
|
* cannot cross a shadow boundary, while ARIA element reflection resolves into
|
|
12
12
|
* ancestor tree scopes.
|
|
13
13
|
*/
|
|
@@ -60,7 +60,7 @@ export type ResolvedARIABindings = {
|
|
|
60
60
|
* component. Holds the state a composite host currently projects and resolves
|
|
61
61
|
* it against the component's own ARIA when the native editor is rendered.
|
|
62
62
|
*
|
|
63
|
-
* Not a reactive controller
|
|
63
|
+
* Not a reactive controller - it needs no lifecycle hooks, only a render
|
|
64
64
|
* scheduled on the host when the projected state changes.
|
|
65
65
|
*/
|
|
66
66
|
declare class AriaTargetController {
|
|
@@ -88,14 +88,14 @@ declare class AriaTargetController {
|
|
|
88
88
|
* Projected labels take precedence over the component's own. The editor's
|
|
89
89
|
* description stays a same-root IDREF ({@link ResolvedARIABindings.describedByRef})
|
|
90
90
|
* while nothing is projected; once a host projects a description, the whole
|
|
91
|
-
* relation switches to element references
|
|
92
|
-
* coexist
|
|
91
|
+
* relation switches to element references - attribute and reflection cannot
|
|
92
|
+
* coexist - with the editor's own description element joining the projected
|
|
93
93
|
* ones.
|
|
94
94
|
*/
|
|
95
95
|
resolveBindings(): ResolvedARIABindings;
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
* Applies {@link ResolvedARIABindings} onto the native editor element
|
|
98
|
+
* Applies {@link ResolvedARIABindings} onto the native editor element -
|
|
99
99
|
* relations on every render, scalar attributes only when they changed.
|
|
100
100
|
*/
|
|
101
101
|
declare class AriaBindingsDirective extends Directive {
|
|
@@ -132,7 +132,7 @@ declare class AriaProjectorController implements ReactiveController {
|
|
|
132
132
|
/**
|
|
133
133
|
* Creates and adds an {@link AriaTargetController} to an input-shaped
|
|
134
134
|
* component, making its native editor a valid target for
|
|
135
|
-
* {@link addAriaProjector}
|
|
135
|
+
* {@link addAriaProjector} - the editor is what assistive technology lands on
|
|
136
136
|
* and reports once the component's host delegates focus to it.
|
|
137
137
|
*/
|
|
138
138
|
export declare function addAriaTarget(host: ControllerHost, config: AriaTargetConfig): AriaTargetController;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aria-projection.js","sourceRoot":"","sources":["../../../src/internals/controllers/aria-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type LitElement,\n noChange,\n type ReactiveController,\n type ReactiveControllerHost,\n} from 'lit';\nimport {\n Directive,\n type DirectiveParameters,\n directive,\n type ElementPart,\n type PartInfo,\n PartType,\n} from 'lit/directive.js';\n\ntype ControllerHost = ReactiveControllerHost & LitElement;\n\n/**\n * ARIA semantics a composite host projects onto the native editor of an\n * input-shaped component.\n *\n * The host cannot publish these itself: it delegates focus, so the native\n * editor inside the input component's shadow root is what assistive technology\n * lands on and reports. All relations travel as element references — an IDREF\n * cannot cross a shadow boundary, while ARIA element reflection resolves into\n * ancestor tree scopes.\n */\nexport type ProjectedARIA = {\n role?: string;\n hasPopup?: string;\n expanded?: string;\n disabled?: string;\n label?: string;\n controls?: ReadonlyArray<Element> | null;\n describedBy?: ReadonlyArray<Element> | null;\n labelledBy?: ReadonlyArray<Element> | null;\n activeDescendant?: Element | null;\n};\n\n/** Configuration for the {@link AriaTargetController}. */\ntype AriaTargetConfig = {\n /** Resolves the component's own `ElementInternals` labels. */\n labels: () => ReadonlyArray<Element> | null;\n /**\n * Resolves the component's own description element (its helper-text\n * container), or `null` when it currently renders no description content.\n */\n description: () => Element | null;\n};\n\n/**\n * Binding values for a native editor element, resolved from the projected\n * state merged with the editor's own ARIA. Applied onto the editor with the\n * {@link ariaBindings} directive: scalars bind as attributes, relations bind\n * through the ARIA element-reflection properties.\n */\nexport type ResolvedARIABindings = {\n role?: string;\n hasPopup?: string;\n expanded?: string;\n disabled?: string;\n label?: string;\n /**\n * Same-root IDREF for the editor's own description, applied while no\n * description is projected. Unlike element reflection, a content attribute\n * stays visible to tooling that only reads attributes (e.g. axe).\n */\n describedByRef?: string;\n labelledBy: ReadonlyArray<Element> | null;\n controls: ReadonlyArray<Element> | null;\n describedBy: ReadonlyArray<Element> | null;\n activeDescendant: Element | null;\n};\n\n/**\n * Internal registry resolving an input-shaped component to its ARIA target\n * controller, so composite hosts can project state without the component\n * exposing a public member for it.\n */\nconst targets = new WeakMap<Element, AriaTargetController>();\n\nfunction elementsEqual(\n a: ReadonlyArray<Element> | null | undefined,\n b: ReadonlyArray<Element> | null | undefined\n): boolean {\n if (a == null || b == null) {\n return a == null && b == null;\n }\n\n return a.length === b.length && a.every((element, i) => element === b[i]);\n}\n\nfunction projectionsEqual(a: ProjectedARIA, b: ProjectedARIA): boolean {\n return (\n a.role === b.role &&\n a.hasPopup === b.hasPopup &&\n a.expanded === b.expanded &&\n a.disabled === b.disabled &&\n a.label === b.label &&\n (a.activeDescendant ?? null) === (b.activeDescendant ?? null) &&\n elementsEqual(a.controls, b.controls) &&\n elementsEqual(a.describedBy, b.describedBy) &&\n elementsEqual(a.labelledBy, b.labelledBy)\n );\n}\n\n/**\n * The receiving end of an ARIA projection, added by every input-shaped\n * component. Holds the state a composite host currently projects and resolves\n * it against the component's own ARIA when the native editor is rendered.\n *\n * Not a reactive controller — it needs no lifecycle hooks, only a render\n * scheduled on the host when the projected state changes.\n */\nclass AriaTargetController {\n private readonly _host: ControllerHost;\n private readonly _config: AriaTargetConfig;\n private _projected: ProjectedARIA = {};\n\n constructor(host: ControllerHost, config: AriaTargetConfig) {\n this._host = host;\n this._config = config;\n targets.set(host, this);\n }\n\n /**\n * Replaces the projected state, scheduling a host render only when it\n * actually changed so projecting on every host update stays cheap.\n */\n public setProjected(state: ProjectedARIA): void {\n if (!projectionsEqual(this._projected, state)) {\n this._projected = state;\n this._reflectStylingHooks();\n this._host.requestUpdate();\n }\n }\n\n /**\n * Mirrors the projected `role`/`hasPopup` as `data-role`/`data-haspopup`\n * attributes on the component itself. The input themes style anchors of\n * composite widgets differently and key off these; the ARIA itself lives on\n * the native editor inside the shadow root, where `:host()` selectors\n * cannot observe it.\n */\n private _reflectStylingHooks(): void {\n const host = this._host;\n const { role, hasPopup } = this._projected;\n\n role\n ? host.setAttribute('data-role', role)\n : host.removeAttribute('data-role');\n hasPopup\n ? host.setAttribute('data-haspopup', hasPopup)\n : host.removeAttribute('data-haspopup');\n }\n\n /**\n * Resolves the binding values for the native editor element by merging the\n * projected state with the editor's own ARIA.\n *\n * Projected labels take precedence over the component's own. The editor's\n * description stays a same-root IDREF ({@link ResolvedARIABindings.describedByRef})\n * while nothing is projected; once a host projects a description, the whole\n * relation switches to element references — attribute and reflection cannot\n * coexist — with the editor's own description element joining the projected\n * ones.\n */\n public resolveBindings(): ResolvedARIABindings {\n const projected = this._projected;\n const description = this._config.description();\n\n return {\n role: projected.role,\n hasPopup: projected.hasPopup,\n expanded: projected.expanded,\n disabled: projected.disabled,\n label: projected.label,\n labelledBy: projected.labelledBy ?? this._config.labels(),\n controls: projected.controls ?? null,\n describedBy: projected.describedBy\n ? description\n ? [description, ...projected.describedBy]\n : projected.describedBy\n : null,\n describedByRef: projected.describedBy\n ? undefined\n : description?.id || undefined,\n activeDescendant: projected.activeDescendant ?? null,\n };\n }\n}\n\nconst scalarBindings = [\n ['role', 'role'],\n ['hasPopup', 'aria-haspopup'],\n ['expanded', 'aria-expanded'],\n ['disabled', 'aria-disabled'],\n ['label', 'aria-label'],\n ['describedByRef', 'aria-describedby'],\n] as const;\n\n/**\n * Applies {@link ResolvedARIABindings} onto the native editor element —\n * relations on every render, scalar attributes only when they changed.\n */\nclass AriaBindingsDirective extends Directive {\n private _previous?: ResolvedARIABindings;\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n\n if (partInfo.type !== PartType.ELEMENT) {\n throw new Error(\n '`ariaBindings()` can only be used as an element expression.'\n );\n }\n }\n\n public override render(_: ResolvedARIABindings): unknown {\n return noChange;\n }\n\n public override update(\n part: ElementPart,\n [bindings]: DirectiveParameters<this>\n ): unknown {\n const element = part.element;\n const previous = this._previous;\n this._previous = bindings;\n\n // Relations are re-asserted on every render: element references assigned\n // while the editor is detached (its first render commits inside the\n // template fragment) are dropped by the browser, so memoizing them here\n // would leave the associations permanently missing.\n // Assigning them first also means the scalar pass below always observes\n // the final state, since a reflection property detaches the corresponding\n // content attribute.\n element.ariaLabelledByElements = bindings.labelledBy;\n element.ariaControlsElements = bindings.controls;\n element.ariaDescribedByElements = bindings.describedBy;\n element.ariaActiveDescendantElement = bindings.activeDescendant;\n\n for (const [key, attribute] of scalarBindings) {\n const value = bindings[key];\n\n if (!previous || previous[key] !== value) {\n value != null\n ? element.setAttribute(attribute, value)\n : element.removeAttribute(attribute);\n }\n }\n\n return noChange;\n }\n}\n\n/**\n * Binds resolved ARIA state onto a native editor element as a single element\n * expression, e.g. `<input ${ariaBindings(aria)} />`.\n */\nexport const ariaBindings = directive(AriaBindingsDirective);\n\n/** Configuration for the {@link AriaProjectorController}. */\ntype AriaProjectorConfig = {\n /** Resolves the input-shaped component the ARIA state is projected onto. */\n target: () => Element | null | undefined;\n /** Computes the ARIA state to project. Invoked after every host update. */\n state: () => ProjectedARIA;\n};\n\n/**\n * The sending end of an ARIA projection, added by composite hosts\n * (e.g. `igc-select`). After every host update it pushes the computed ARIA\n * state onto the target component's {@link AriaTargetController}.\n */\nclass AriaProjectorController implements ReactiveController {\n private readonly _host: ControllerHost;\n private readonly _config: AriaProjectorConfig;\n private _retryScheduled = false;\n\n constructor(host: ControllerHost, config: AriaProjectorConfig) {\n this._host = host;\n this._config = config;\n host.addController(this);\n }\n\n /** @internal */\n public hostUpdated(): void {\n const element = this._config.target();\n\n if (!element) {\n return;\n }\n\n const target = targets.get(element);\n\n if (target) {\n target.setProjected(this._config.state());\n return;\n }\n\n // The target exists but has no controller yet - it is not upgraded on the\n // host's first render when definitions register late. Re-project once its\n // definition resolves.\n if (!this._retryScheduled) {\n this._retryScheduled = true;\n\n customElements.whenDefined(element.localName).then(() => {\n this._retryScheduled = false;\n this._host.requestUpdate();\n });\n }\n }\n}\n\n/**\n * Creates and adds an {@link AriaTargetController} to an input-shaped\n * component, making its native editor a valid target for\n * {@link addAriaProjector} — the editor is what assistive technology lands on\n * and reports once the component's host delegates focus to it.\n */\nexport function addAriaTarget(\n host: ControllerHost,\n config: AriaTargetConfig\n): AriaTargetController {\n return new AriaTargetController(host, config);\n}\n\n/**\n * Creates and adds an {@link AriaProjectorController} to a composite host,\n * projecting ARIA semantics onto the native editor of the target component.\n */\nexport function addAriaProjector(\n host: ControllerHost,\n config: AriaProjectorConfig\n): AriaProjectorController {\n return new AriaProjectorController(host, config);\n}\n\nexport type { AriaProjectorController, AriaTargetController };\n"]}
|
|
1
|
+
{"version":3,"file":"aria-projection.js","sourceRoot":"","sources":["../../../src/internals/controllers/aria-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type LitElement,\n noChange,\n type ReactiveController,\n type ReactiveControllerHost,\n} from 'lit';\nimport {\n Directive,\n type DirectiveParameters,\n directive,\n type ElementPart,\n type PartInfo,\n PartType,\n} from 'lit/directive.js';\n\ntype ControllerHost = ReactiveControllerHost & LitElement;\n\n/**\n * ARIA semantics a composite host projects onto the native editor of an\n * input-shaped component.\n *\n * The host cannot publish these itself: it delegates focus, so the native\n * editor inside the input component's shadow root is what assistive technology\n * lands on and reports. All relations travel as element references - an IDREF\n * cannot cross a shadow boundary, while ARIA element reflection resolves into\n * ancestor tree scopes.\n */\nexport type ProjectedARIA = {\n role?: string;\n hasPopup?: string;\n expanded?: string;\n disabled?: string;\n label?: string;\n controls?: ReadonlyArray<Element> | null;\n describedBy?: ReadonlyArray<Element> | null;\n labelledBy?: ReadonlyArray<Element> | null;\n activeDescendant?: Element | null;\n};\n\n/** Configuration for the {@link AriaTargetController}. */\ntype AriaTargetConfig = {\n /** Resolves the component's own `ElementInternals` labels. */\n labels: () => ReadonlyArray<Element> | null;\n /**\n * Resolves the component's own description element (its helper-text\n * container), or `null` when it currently renders no description content.\n */\n description: () => Element | null;\n};\n\n/**\n * Binding values for a native editor element, resolved from the projected\n * state merged with the editor's own ARIA. Applied onto the editor with the\n * {@link ariaBindings} directive: scalars bind as attributes, relations bind\n * through the ARIA element-reflection properties.\n */\nexport type ResolvedARIABindings = {\n role?: string;\n hasPopup?: string;\n expanded?: string;\n disabled?: string;\n label?: string;\n /**\n * Same-root IDREF for the editor's own description, applied while no\n * description is projected. Unlike element reflection, a content attribute\n * stays visible to tooling that only reads attributes (e.g. axe).\n */\n describedByRef?: string;\n labelledBy: ReadonlyArray<Element> | null;\n controls: ReadonlyArray<Element> | null;\n describedBy: ReadonlyArray<Element> | null;\n activeDescendant: Element | null;\n};\n\n/**\n * Internal registry resolving an input-shaped component to its ARIA target\n * controller, so composite hosts can project state without the component\n * exposing a public member for it.\n */\nconst targets = new WeakMap<Element, AriaTargetController>();\n\nfunction elementsEqual(\n a: ReadonlyArray<Element> | null | undefined,\n b: ReadonlyArray<Element> | null | undefined\n): boolean {\n if (a == null || b == null) {\n return a == null && b == null;\n }\n\n return a.length === b.length && a.every((element, i) => element === b[i]);\n}\n\nfunction projectionsEqual(a: ProjectedARIA, b: ProjectedARIA): boolean {\n return (\n a.role === b.role &&\n a.hasPopup === b.hasPopup &&\n a.expanded === b.expanded &&\n a.disabled === b.disabled &&\n a.label === b.label &&\n (a.activeDescendant ?? null) === (b.activeDescendant ?? null) &&\n elementsEqual(a.controls, b.controls) &&\n elementsEqual(a.describedBy, b.describedBy) &&\n elementsEqual(a.labelledBy, b.labelledBy)\n );\n}\n\n/**\n * The receiving end of an ARIA projection, added by every input-shaped\n * component. Holds the state a composite host currently projects and resolves\n * it against the component's own ARIA when the native editor is rendered.\n *\n * Not a reactive controller - it needs no lifecycle hooks, only a render\n * scheduled on the host when the projected state changes.\n */\nclass AriaTargetController {\n private readonly _host: ControllerHost;\n private readonly _config: AriaTargetConfig;\n private _projected: ProjectedARIA = {};\n\n constructor(host: ControllerHost, config: AriaTargetConfig) {\n this._host = host;\n this._config = config;\n targets.set(host, this);\n }\n\n /**\n * Replaces the projected state, scheduling a host render only when it\n * actually changed so projecting on every host update stays cheap.\n */\n public setProjected(state: ProjectedARIA): void {\n if (!projectionsEqual(this._projected, state)) {\n this._projected = state;\n this._reflectStylingHooks();\n this._host.requestUpdate();\n }\n }\n\n /**\n * Mirrors the projected `role`/`hasPopup` as `data-role`/`data-haspopup`\n * attributes on the component itself. The input themes style anchors of\n * composite widgets differently and key off these; the ARIA itself lives on\n * the native editor inside the shadow root, where `:host()` selectors\n * cannot observe it.\n */\n private _reflectStylingHooks(): void {\n const host = this._host;\n const { role, hasPopup } = this._projected;\n\n role\n ? host.setAttribute('data-role', role)\n : host.removeAttribute('data-role');\n hasPopup\n ? host.setAttribute('data-haspopup', hasPopup)\n : host.removeAttribute('data-haspopup');\n }\n\n /**\n * Resolves the binding values for the native editor element by merging the\n * projected state with the editor's own ARIA.\n *\n * Projected labels take precedence over the component's own. The editor's\n * description stays a same-root IDREF ({@link ResolvedARIABindings.describedByRef})\n * while nothing is projected; once a host projects a description, the whole\n * relation switches to element references - attribute and reflection cannot\n * coexist - with the editor's own description element joining the projected\n * ones.\n */\n public resolveBindings(): ResolvedARIABindings {\n const projected = this._projected;\n const description = this._config.description();\n\n return {\n role: projected.role,\n hasPopup: projected.hasPopup,\n expanded: projected.expanded,\n disabled: projected.disabled,\n label: projected.label,\n labelledBy: projected.labelledBy ?? this._config.labels(),\n controls: projected.controls ?? null,\n describedBy: projected.describedBy\n ? description\n ? [description, ...projected.describedBy]\n : projected.describedBy\n : null,\n describedByRef: projected.describedBy\n ? undefined\n : description?.id || undefined,\n activeDescendant: projected.activeDescendant ?? null,\n };\n }\n}\n\nconst scalarBindings = [\n ['role', 'role'],\n ['hasPopup', 'aria-haspopup'],\n ['expanded', 'aria-expanded'],\n ['disabled', 'aria-disabled'],\n ['label', 'aria-label'],\n ['describedByRef', 'aria-describedby'],\n] as const;\n\n/**\n * Applies {@link ResolvedARIABindings} onto the native editor element -\n * relations on every render, scalar attributes only when they changed.\n */\nclass AriaBindingsDirective extends Directive {\n private _previous?: ResolvedARIABindings;\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n\n if (partInfo.type !== PartType.ELEMENT) {\n throw new Error(\n '`ariaBindings()` can only be used as an element expression.'\n );\n }\n }\n\n public override render(_: ResolvedARIABindings): unknown {\n return noChange;\n }\n\n public override update(\n part: ElementPart,\n [bindings]: DirectiveParameters<this>\n ): unknown {\n const element = part.element;\n const previous = this._previous;\n this._previous = bindings;\n\n // Relations are re-asserted on every render: element references assigned\n // while the editor is detached (its first render commits inside the\n // template fragment) are dropped by the browser, so memoizing them here\n // would leave the associations permanently missing.\n // Assigning them first also means the scalar pass below always observes\n // the final state, since a reflection property detaches the corresponding\n // content attribute.\n element.ariaLabelledByElements = bindings.labelledBy;\n element.ariaControlsElements = bindings.controls;\n element.ariaDescribedByElements = bindings.describedBy;\n element.ariaActiveDescendantElement = bindings.activeDescendant;\n\n for (const [key, attribute] of scalarBindings) {\n const value = bindings[key];\n\n if (!previous || previous[key] !== value) {\n value != null\n ? element.setAttribute(attribute, value)\n : element.removeAttribute(attribute);\n }\n }\n\n return noChange;\n }\n}\n\n/**\n * Binds resolved ARIA state onto a native editor element as a single element\n * expression, e.g. `<input ${ariaBindings(aria)} />`.\n */\nexport const ariaBindings = directive(AriaBindingsDirective);\n\n/** Configuration for the {@link AriaProjectorController}. */\ntype AriaProjectorConfig = {\n /** Resolves the input-shaped component the ARIA state is projected onto. */\n target: () => Element | null | undefined;\n /** Computes the ARIA state to project. Invoked after every host update. */\n state: () => ProjectedARIA;\n};\n\n/**\n * The sending end of an ARIA projection, added by composite hosts\n * (e.g. `igc-select`). After every host update it pushes the computed ARIA\n * state onto the target component's {@link AriaTargetController}.\n */\nclass AriaProjectorController implements ReactiveController {\n private readonly _host: ControllerHost;\n private readonly _config: AriaProjectorConfig;\n private _retryScheduled = false;\n\n constructor(host: ControllerHost, config: AriaProjectorConfig) {\n this._host = host;\n this._config = config;\n host.addController(this);\n }\n\n /** @internal */\n public hostUpdated(): void {\n const element = this._config.target();\n\n if (!element) {\n return;\n }\n\n const target = targets.get(element);\n\n if (target) {\n target.setProjected(this._config.state());\n return;\n }\n\n // The target exists but has no controller yet - it is not upgraded on the\n // host's first render when definitions register late. Re-project once its\n // definition resolves.\n if (!this._retryScheduled) {\n this._retryScheduled = true;\n\n customElements.whenDefined(element.localName).then(() => {\n this._retryScheduled = false;\n this._host.requestUpdate();\n });\n }\n }\n}\n\n/**\n * Creates and adds an {@link AriaTargetController} to an input-shaped\n * component, making its native editor a valid target for\n * {@link addAriaProjector} - the editor is what assistive technology lands on\n * and reports once the component's host delegates focus to it.\n */\nexport function addAriaTarget(\n host: ControllerHost,\n config: AriaTargetConfig\n): AriaTargetController {\n return new AriaTargetController(host, config);\n}\n\n/**\n * Creates and adds an {@link AriaProjectorController} to a composite host,\n * projecting ARIA semantics onto the native editor of the target component.\n */\nexport function addAriaProjector(\n host: ControllerHost,\n config: AriaProjectorConfig\n): AriaProjectorController {\n return new AriaProjectorController(host, config);\n}\n\nexport type { AriaProjectorController, AriaTargetController };\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Context, type ContextType } from '@lit/context';
|
|
2
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
3
|
+
type ProviderHost = ReactiveControllerHost & HTMLElement;
|
|
4
|
+
type ContextProviderControllerOptions<C extends Context<unknown, unknown>, H extends ProviderHost> = {
|
|
5
|
+
/** The context to provide. */
|
|
6
|
+
context: C;
|
|
7
|
+
/** Computes the context value published to subscribers. */
|
|
8
|
+
value: () => ContextType<C>;
|
|
9
|
+
/**
|
|
10
|
+
* Host properties whose changes republish the context. Anything else that must
|
|
11
|
+
* republish calls {@link ContextProviderController.publish}.
|
|
12
|
+
*/
|
|
13
|
+
watch?: readonly (keyof H)[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Provides a context from the host and keeps subscribers current: the value
|
|
17
|
+
* is published when the host connects, republished before an update whenever
|
|
18
|
+
* one of the watched host properties has changed, and on demand via
|
|
19
|
+
* {@link ContextProviderController.publish}.
|
|
20
|
+
*
|
|
21
|
+
* Every publish notifies subscribers, also when the value keeps its identity -
|
|
22
|
+
* hosts that share one mutable context object still propagate their changes.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* private readonly _provider = addContextProvider(this, {
|
|
27
|
+
* context: themeContext,
|
|
28
|
+
* watch: ['theme', 'variant'],
|
|
29
|
+
* value: () => ({ theme: this.theme, variant: this.variant }),
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare class ContextProviderController<C extends Context<unknown, unknown>, H extends ProviderHost> implements ReactiveController {
|
|
34
|
+
private readonly _host;
|
|
35
|
+
private readonly _options;
|
|
36
|
+
private readonly _provider;
|
|
37
|
+
private readonly _snapshot;
|
|
38
|
+
constructor(host: H, options: ContextProviderControllerOptions<C, H>);
|
|
39
|
+
/** @internal */
|
|
40
|
+
hostConnected(): void;
|
|
41
|
+
/** @internal */
|
|
42
|
+
hostUpdate(): void;
|
|
43
|
+
/** Publishes the current value to the subscribers. */
|
|
44
|
+
publish(): void;
|
|
45
|
+
}
|
|
46
|
+
/** Creates and adds a {@link ContextProviderController} to the given host. */
|
|
47
|
+
export declare function addContextProvider<C extends Context<unknown, unknown>, H extends ProviderHost>(host: H, options: ContextProviderControllerOptions<C, H>): ContextProviderController<C, H>;
|
|
48
|
+
export type { ContextProviderController, ContextProviderControllerOptions };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ContextProvider } from '@lit/context';
|
|
2
|
+
class ContextProviderController {
|
|
3
|
+
constructor(host, options) {
|
|
4
|
+
this._snapshot = new Map();
|
|
5
|
+
this._host = host;
|
|
6
|
+
this._options = options;
|
|
7
|
+
this._provider = new ContextProvider(host, { context: options.context });
|
|
8
|
+
host.addController(this);
|
|
9
|
+
}
|
|
10
|
+
hostConnected() {
|
|
11
|
+
this.publish();
|
|
12
|
+
}
|
|
13
|
+
hostUpdate() {
|
|
14
|
+
const watched = this._options.watch;
|
|
15
|
+
if (watched?.some((key) => this._host[key] !== this._snapshot.get(key))) {
|
|
16
|
+
this.publish();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
publish() {
|
|
20
|
+
for (const key of this._options.watch ?? []) {
|
|
21
|
+
this._snapshot.set(key, this._host[key]);
|
|
22
|
+
}
|
|
23
|
+
this._provider.setValue(this._options.value.call(this._host), true);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function addContextProvider(host, options) {
|
|
27
|
+
return new ContextProviderController(host, options);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=context-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-provider.js","sourceRoot":"","sources":["../../../src/internals/controllers/context-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,eAAe,EAAoB,MAAM,cAAc,CAAC;AAsC/E,MAAM,yBAAyB;IAS7B,YAAY,IAAO,EAAE,OAA+C;QAFnD,cAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;QAGvD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAGM,aAAa;QAClB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAGM,UAAU;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAEpC,IAAI,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAGM,OAAO;QACZ,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC;CACF;AAGD,MAAM,UAAU,kBAAkB,CAIhC,IAAO,EACP,OAA+C;IAE/C,OAAO,IAAI,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC","sourcesContent":["import { type Context, ContextProvider, type ContextType } from '@lit/context';\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\n\ntype ProviderHost = ReactiveControllerHost & HTMLElement;\n\ntype ContextProviderControllerOptions<\n C extends Context<unknown, unknown>,\n H extends ProviderHost,\n> = {\n /** The context to provide. */\n context: C;\n /** Computes the context value published to subscribers. */\n value: () => ContextType<C>;\n /**\n * Host properties whose changes republish the context. Anything else that must\n * republish calls {@link ContextProviderController.publish}.\n */\n watch?: readonly (keyof H)[];\n};\n\n/**\n * Provides a context from the host and keeps subscribers current: the value\n * is published when the host connects, republished before an update whenever\n * one of the watched host properties has changed, and on demand via\n * {@link ContextProviderController.publish}.\n *\n * Every publish notifies subscribers, also when the value keeps its identity -\n * hosts that share one mutable context object still propagate their changes.\n *\n * @example\n * ```typescript\n * private readonly _provider = addContextProvider(this, {\n * context: themeContext,\n * watch: ['theme', 'variant'],\n * value: () => ({ theme: this.theme, variant: this.variant }),\n * });\n * ```\n */\nclass ContextProviderController<\n C extends Context<unknown, unknown>,\n H extends ProviderHost,\n> implements ReactiveController {\n private readonly _host: H;\n private readonly _options: ContextProviderControllerOptions<C, H>;\n private readonly _provider: ContextProvider<C, H>;\n private readonly _snapshot = new Map<keyof H, unknown>();\n\n constructor(host: H, options: ContextProviderControllerOptions<C, H>) {\n this._host = host;\n this._options = options;\n this._provider = new ContextProvider(host, { context: options.context });\n\n host.addController(this);\n }\n\n /** @internal */\n public hostConnected(): void {\n this.publish();\n }\n\n /** @internal */\n public hostUpdate(): void {\n const watched = this._options.watch;\n\n if (watched?.some((key) => this._host[key] !== this._snapshot.get(key))) {\n this.publish();\n }\n }\n\n /** Publishes the current value to the subscribers. */\n public publish(): void {\n for (const key of this._options.watch ?? []) {\n this._snapshot.set(key, this._host[key]);\n }\n\n this._provider.setValue(this._options.value.call(this._host), true);\n }\n}\n\n/** Creates and adds a {@link ContextProviderController} to the given host. */\nexport function addContextProvider<\n C extends Context<unknown, unknown>,\n H extends ProviderHost,\n>(\n host: H,\n options: ContextProviderControllerOptions<C, H>\n): ContextProviderController<C, H> {\n return new ContextProviderController(host, options);\n}\n\nexport type { ContextProviderController, ContextProviderControllerOptions };\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getDefaultLayer } from '../../components/resize-container/default-ghost.js';
|
|
2
2
|
import { createAbortHandle } from '../abort-handler.js';
|
|
3
|
-
import { getRoot, isLTR, roundByDPR } from '../utils/dom.js';
|
|
3
|
+
import { getRoot, isLTR, roundByDPR, setStyles } from '../utils/dom.js';
|
|
4
4
|
import { getElementFromPath } from '../utils/events.js';
|
|
5
|
+
import { escapeKey, isKey } from './key-bindings.js';
|
|
5
6
|
const additionalEvents = [
|
|
6
7
|
'pointermove',
|
|
7
8
|
'lostpointercapture',
|
|
@@ -134,8 +135,7 @@ class DragController {
|
|
|
134
135
|
this.dispose();
|
|
135
136
|
}
|
|
136
137
|
_handleCancel(event) {
|
|
137
|
-
|
|
138
|
-
if (this._hasPointerCapture && key === 'escape') {
|
|
138
|
+
if (this._hasPointerCapture && isKey(event, escapeKey)) {
|
|
139
139
|
this._options.cancel?.call(this._host, this._stateParameters);
|
|
140
140
|
}
|
|
141
141
|
}
|
|
@@ -164,7 +164,7 @@ class DragController {
|
|
|
164
164
|
_setDragState(enabled = true) {
|
|
165
165
|
this._hasPointerCapture = enabled;
|
|
166
166
|
const cssValue = enabled ? 'none' : '';
|
|
167
|
-
|
|
167
|
+
setStyles(this._element, {
|
|
168
168
|
touchAction: cssValue,
|
|
169
169
|
userSelect: cssValue,
|
|
170
170
|
webkitUserSelect: cssValue,
|
|
@@ -266,13 +266,13 @@ class DragController {
|
|
|
266
266
|
}
|
|
267
267
|
function createDefaultDragGhost({ x, y, width, height }) {
|
|
268
268
|
const element = document.createElement('div');
|
|
269
|
-
|
|
269
|
+
setStyles(element, {
|
|
270
270
|
position: 'absolute',
|
|
271
271
|
left: `${x}px`,
|
|
272
272
|
top: `${y}px`,
|
|
273
273
|
width: `${width}px`,
|
|
274
274
|
height: `${height}px`,
|
|
275
|
-
zIndex: 1000,
|
|
275
|
+
zIndex: '1000',
|
|
276
276
|
background: 'gold',
|
|
277
277
|
});
|
|
278
278
|
return element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drag.js","sourceRoot":"","sources":["../../../src/internals/controllers/drag.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LitElement,\n ReactiveController,\n ReactiveControllerHost,\n} from 'lit';\nimport type { Ref } from 'lit/directives/ref.js';\n\nimport { getDefaultLayer } from '../../components/resize-container/default-ghost.js';\nimport { createAbortHandle } from '../abort-handler.js';\nimport { getRoot, isLTR, roundByDPR } from '../utils/dom.js';\nimport { getElementFromPath } from '../utils/events.js';\n\ntype DragCallback = (parameters: DragCallbackParameters) => unknown;\ntype DragCancelCallback = (state: DragState) => unknown;\n\nexport type DragCallbackParameters = {\n event: PointerEvent;\n state: DragState;\n};\n\ntype State = {\n initial: DOMRect;\n current: DOMRect;\n position: { x: number; y: number };\n offset: { x: number; y: number };\n pointerState: {\n previous: { x: number; y: number };\n current: { x: number; y: number };\n direction: Direction;\n };\n};\n\ntype DragState = State & {\n ghost: HTMLElement | null;\n element: Element | null;\n};\n\ntype Direction = 'start' | 'end' | 'bottom' | 'top';\n\ntype DragControllerConfiguration = {\n /** Whether the drag feature is enabled for the current host. */\n enabled?: boolean;\n /**\n * The mode of the drag operation.\n *\n * Deferred will create a ghost element and keep the original element\n * at its place until the operation completes successfully.\n */\n mode?: 'immediate' | 'deferred';\n /**\n * Whether starting a drag operation should snap the dragged item's top left corner\n * to the cursor position.\n */\n snapToCursor?: boolean;\n /**\n * Guard function invoked during the `start` callback.\n * Returning a truthy value will stop the current drag operation.\n */\n skip?: (event: PointerEvent) => boolean;\n\n matchTarget?: (target: Element) => boolean;\n /**\n *\n */\n trigger?: () => HTMLElement;\n /**\n * Contain drag operations to the scope of the passed DOM element.\n */\n container?: Ref<HTMLElement>;\n /**\n * The DOM element that will \"host\" the ghost drag element when the controller\n * is set to **deferred**.\n *\n * @remarks\n * In **immediate** mode, this property is ignored.\n */\n layer?: () => HTMLElement;\n\n ghost?: () => HTMLElement;\n\n /** Callback invoked at the beginning of a drag operation. */\n start?: DragCallback;\n /** Callback invoked while dragging the target element. */\n move?: DragCallback;\n\n enter?: DragCallback;\n\n leave?: DragCallback;\n\n over?: DragCallback;\n\n /** Callback invoked during a drop operation. */\n end?: DragCallback;\n /** Callback invoked when a drag is cancelled */\n cancel?: DragCancelCallback;\n};\n\nconst additionalEvents = [\n 'pointermove',\n 'lostpointercapture',\n 'contextmenu',\n] as const;\n\nclass DragController implements ReactiveController {\n private readonly _host: ReactiveControllerHost & LitElement;\n private readonly _options: DragControllerConfiguration = {\n enabled: true,\n mode: 'deferred',\n snapToCursor: false,\n layer: getDefaultLayer,\n };\n\n private readonly _abortHandle = createAbortHandle();\n\n private _state!: State;\n\n private _matchedElement!: Element | null;\n\n private _id = -1;\n private _hasPointerCapture = false;\n\n private _ghost: HTMLElement | null = null;\n\n /** Whether `snapToCursor` is enabled for the controller. */\n private get _hasSnapping(): boolean {\n return Boolean(this._options.snapToCursor);\n }\n\n /** Whether the current drag mode is deferred. */\n private get _isDeferred(): boolean {\n return this._options.mode === 'deferred';\n }\n\n /**\n * The source element which will capture pointer events and initiate drag mode.\n *\n * @remarks\n * By default that will be the host element itself, unless `trigger` is passed in.\n */\n private get _element(): HTMLElement {\n return this._options.trigger?.() ?? this._host;\n }\n\n /**\n * The element being dragged.\n *\n * @remarks\n * When in **deferred** mode this returns a reference to the drag ghost element,\n * otherwise it is the host element.\n */\n private get _dragItem(): HTMLElement {\n return this._isDeferred ? this._ghost! : this._host;\n }\n\n /**\n * The DOM element that will \"host\" the ghost drag element when the controller\n * is set to **deferred**.\n *\n * @remarks\n * In **immediate** mode, this property is ignored.\n */\n private get _layer(): HTMLElement {\n if (!this._isDeferred) {\n return this._host;\n }\n\n return this._options.layer?.() ?? this._host;\n }\n\n private get _stateParameters(): DragState {\n return {\n ...this._state,\n ghost: this._ghost,\n element: this._matchedElement,\n };\n }\n\n constructor(\n host: ReactiveControllerHost & LitElement,\n options?: DragControllerConfiguration\n ) {\n this._host = host;\n this._host.addController(this);\n this.set(options);\n }\n\n // #region Public API\n\n /** Whether the drag controller is enabled. */\n public get enabled(): boolean {\n return Boolean(this._options.enabled);\n }\n\n /** Updates the drag controller configuration. */\n public set(options?: DragControllerConfiguration): void {\n Object.assign(this._options, options);\n }\n\n /** Stops any drag operation and cleans up state, additional event listeners and elements. */\n public dispose(): void {\n this._matchedElement = null;\n this._removeGhost();\n this._setDragState(false);\n }\n\n /** @internal */\n public hostConnected(): void {\n const { signal } = this._abortHandle;\n\n this._host.addEventListener('dragstart', this, { signal });\n this._host.addEventListener('touchstart', this, { passive: false, signal });\n this._host.addEventListener('pointerdown', this, { signal });\n }\n\n /** @internal */\n public hostDisconnected(): void {\n this._abortHandle.abort();\n this._setDragCancelListener(false);\n this._removeGhost();\n }\n\n /** @internal */\n public handleEvent(event: PointerEvent & KeyboardEvent): void {\n if (!this.enabled) {\n return;\n }\n\n switch (event.type) {\n case 'touchstart':\n case 'dragstart':\n // Prevent contextmenu default behavior during drag\n case 'contextmenu':\n event.preventDefault();\n break;\n case 'keydown':\n this._handleCancel(event);\n break;\n case 'pointerdown':\n this._handlePointerDown(event);\n break;\n case 'pointermove':\n this._handlePointerMove(event);\n break;\n case 'lostpointercapture':\n this._handlePointerEnd(event);\n break;\n }\n }\n\n // #endregion\n\n // #region Event handlers\n\n private _handlePointerDown(event: PointerEvent): void {\n if (this._shouldSkip(event)) {\n return;\n }\n\n this._setInitialState(event);\n this._createDragGhost();\n this._updatePosition(event);\n\n const parameters = {\n event,\n state: this._stateParameters,\n };\n\n if (this._options.start?.call(this._host, parameters) === false) {\n this.dispose();\n return;\n }\n\n this._assignPosition(this._dragItem);\n this._setDragState();\n }\n\n private _handlePointerMove(event: PointerEvent): void {\n if (!this._hasPointerCapture) {\n return;\n }\n\n this._updatePosition(event);\n this._updatePointerState(event);\n this._updateMatcher(event);\n\n const parameters = {\n event,\n state: this._stateParameters,\n };\n\n this._options.move?.call(this._host, parameters);\n\n this._assignPosition(this._dragItem);\n }\n\n private _handlePointerEnd(event: PointerEvent): void {\n this._options.end?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n this.dispose();\n }\n\n private _handleCancel(event: KeyboardEvent): void {\n const key = event.key.toLowerCase();\n\n if (this._hasPointerCapture && key === 'escape') {\n // Reset state\n this._options.cancel?.call(this._host, this._stateParameters);\n }\n }\n\n // #endregion\n\n private _setDragCancelListener(enabled = true): void {\n enabled\n ? globalThis.addEventListener('keydown', this)\n : globalThis.removeEventListener('keydown', this);\n }\n\n private _setInitialState({\n pointerId,\n clientX,\n clientY,\n }: PointerEvent): void {\n const rect = this._host.getBoundingClientRect();\n const position = { x: rect.x, y: rect.y };\n const offset = { x: rect.x - clientX, y: rect.y - clientY };\n\n this._id = pointerId;\n this._state = {\n initial: rect,\n current: structuredClone(rect),\n position,\n offset,\n pointerState: {\n previous: { x: clientX, y: clientY },\n current: { x: clientX, y: clientY },\n direction: 'end',\n },\n };\n }\n\n private _setDragState(enabled = true): void {\n this._hasPointerCapture = enabled;\n const cssValue = enabled ? 'none' : '';\n\n Object.assign(this._element.style, {\n touchAction: cssValue,\n userSelect: cssValue,\n webkitUserSelect: cssValue,\n });\n\n this._toggleTextSelection(enabled);\n\n enabled\n ? this._element.setPointerCapture(this._id)\n : this._element.releasePointerCapture(this._id);\n\n this._setDragCancelListener(enabled);\n\n // Toggle additional events\n for (const type of additionalEvents) {\n enabled\n ? this._host.addEventListener(type, this)\n : this._host.removeEventListener(type, this);\n }\n }\n\n /**\n * Toggles text selection for the duration of a drag operation.\n *\n * @remarks\n * Disabling `user-select` only on the dragged element is not enough, since browsers\n * (notably Safari) will still create a text selection in whatever elements sit under\n * the pointer while dragging. Applying it to the owner document's body prevents that\n * across the page for the active drag and is reverted once the operation completes.\n */\n private _toggleTextSelection(disabled: boolean): void {\n const value = disabled ? 'none' : '';\n const { style } = this._host.ownerDocument.body;\n\n style.userSelect = value;\n style.webkitUserSelect = value;\n\n if (disabled) {\n this._host.ownerDocument.getSelection()?.removeAllRanges();\n }\n }\n\n private _updateMatcher(event: PointerEvent) {\n if (!this._options.matchTarget) {\n return;\n }\n\n const match = getRoot(this._host)\n .elementsFromPoint(event.clientX, event.clientY)\n .find((element) => this._options.matchTarget!.call(this._host, element));\n\n if (match && !this._matchedElement) {\n this._matchedElement = match;\n this._options.enter?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n return;\n }\n\n if (!match && this._matchedElement) {\n this._options.leave?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n this._matchedElement = null;\n return;\n }\n\n if (match && match === this._matchedElement) {\n this._options.over?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n }\n }\n\n private _updatePosition({ clientX, clientY }: PointerEvent): void {\n const { x, y } = this._state.offset;\n const { x: layerX, y: layerY } = this._isDeferred\n ? this._layer.getBoundingClientRect()\n : this._state.initial;\n\n const posX = this._hasSnapping ? clientX - layerX : clientX - layerX + x;\n const posY = this._hasSnapping ? clientY - layerY : clientY - layerY + y;\n\n this._state.position = { x: posX, y: posY };\n }\n\n private _updatePointerState({ clientX, clientY }: PointerEvent): void {\n const state = this._state.pointerState;\n\n state.previous = { ...state.current };\n state.current = { x: clientX, y: clientY };\n\n const dx = state.current.x - state.previous.x;\n const dy = state.current.y - state.previous.y;\n\n if (Math.abs(dx) >= Math.abs(dy)) {\n const swapHorizontal = isLTR(this._host) ? dx >= 0 : dx <= 0;\n state.direction = swapHorizontal ? 'end' : 'start';\n } else {\n state.direction = dy >= 0 ? 'bottom' : 'top';\n }\n }\n\n private _assignPosition(element: HTMLElement): void {\n element.style.transform = `translate3d(${roundByDPR(this._state.position.x)}px,${roundByDPR(this._state.position.y)}px,0)`;\n }\n\n private _createDragGhost(): void {\n if (!this._isDeferred) {\n return;\n }\n\n this._ghost =\n this._options.ghost?.call(this._host) ??\n createDefaultDragGhost(this._host.getBoundingClientRect());\n\n this._layer.append(this._ghost);\n }\n\n private _removeGhost(): void {\n this._ghost?.remove();\n this._ghost = null;\n }\n\n private _shouldSkip(event: PointerEvent): boolean {\n return (\n Boolean(event.button) ||\n this._options.skip?.call(this._host, event) ||\n !getElementFromPath((e) => e === this._element, event)\n );\n }\n}\n\nfunction createDefaultDragGhost({ x, y, width, height }: DOMRect): HTMLElement {\n const element = document.createElement('div');\n\n Object.assign(element.style, {\n position: 'absolute',\n left: `${x}px`,\n top: `${y}px`,\n width: `${width}px`,\n height: `${height}px`,\n zIndex: 1000,\n background: 'gold',\n });\n\n return element;\n}\n\n/**\n * Adds a drag and drop controller to the given host\n */\nexport function addDragController(\n host: ReactiveControllerHost & LitElement,\n options?: DragControllerConfiguration\n): DragController {\n return new DragController(host, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"drag.js","sourceRoot":"","sources":["../../../src/internals/controllers/drag.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LitElement,\n ReactiveController,\n ReactiveControllerHost,\n} from 'lit';\nimport type { Ref } from 'lit/directives/ref.js';\n\nimport { getDefaultLayer } from '../../components/resize-container/default-ghost.js';\nimport { createAbortHandle } from '../abort-handler.js';\nimport { getRoot, isLTR, roundByDPR, setStyles } from '../utils/dom.js';\nimport { getElementFromPath } from '../utils/events.js';\nimport { escapeKey, isKey } from './key-bindings.js';\n\ntype DragCallback = (parameters: DragCallbackParameters) => unknown;\ntype DragCancelCallback = (state: DragState) => unknown;\n\nexport type DragCallbackParameters = {\n event: PointerEvent;\n state: DragState;\n};\n\ntype State = {\n initial: DOMRect;\n current: DOMRect;\n position: { x: number; y: number };\n offset: { x: number; y: number };\n pointerState: {\n previous: { x: number; y: number };\n current: { x: number; y: number };\n direction: Direction;\n };\n};\n\ntype DragState = State & {\n ghost: HTMLElement | null;\n element: Element | null;\n};\n\ntype Direction = 'start' | 'end' | 'bottom' | 'top';\n\ntype DragControllerConfiguration = {\n /** Whether the drag feature is enabled for the current host. */\n enabled?: boolean;\n /**\n * The mode of the drag operation.\n *\n * Deferred will create a ghost element and keep the original element\n * at its place until the operation completes successfully.\n */\n mode?: 'immediate' | 'deferred';\n /**\n * Whether starting a drag operation should snap the dragged item's top left corner\n * to the cursor position.\n */\n snapToCursor?: boolean;\n /**\n * Guard function invoked during the `start` callback.\n * Returning a truthy value will stop the current drag operation.\n */\n skip?: (event: PointerEvent) => boolean;\n\n matchTarget?: (target: Element) => boolean;\n /**\n *\n */\n trigger?: () => HTMLElement;\n /**\n * Contain drag operations to the scope of the passed DOM element.\n */\n container?: Ref<HTMLElement>;\n /**\n * The DOM element that will \"host\" the ghost drag element when the controller\n * is set to **deferred**.\n *\n * @remarks\n * In **immediate** mode, this property is ignored.\n */\n layer?: () => HTMLElement;\n\n ghost?: () => HTMLElement;\n\n /** Callback invoked at the beginning of a drag operation. */\n start?: DragCallback;\n /** Callback invoked while dragging the target element. */\n move?: DragCallback;\n\n enter?: DragCallback;\n\n leave?: DragCallback;\n\n over?: DragCallback;\n\n /** Callback invoked during a drop operation. */\n end?: DragCallback;\n /** Callback invoked when a drag is cancelled */\n cancel?: DragCancelCallback;\n};\n\nconst additionalEvents = [\n 'pointermove',\n 'lostpointercapture',\n 'contextmenu',\n] as const;\n\nclass DragController implements ReactiveController {\n private readonly _host: ReactiveControllerHost & LitElement;\n private readonly _options: DragControllerConfiguration = {\n enabled: true,\n mode: 'deferred',\n snapToCursor: false,\n layer: getDefaultLayer,\n };\n\n private readonly _abortHandle = createAbortHandle();\n\n private _state!: State;\n\n private _matchedElement!: Element | null;\n\n private _id = -1;\n private _hasPointerCapture = false;\n\n private _ghost: HTMLElement | null = null;\n\n /** Whether `snapToCursor` is enabled for the controller. */\n private get _hasSnapping(): boolean {\n return Boolean(this._options.snapToCursor);\n }\n\n /** Whether the current drag mode is deferred. */\n private get _isDeferred(): boolean {\n return this._options.mode === 'deferred';\n }\n\n /**\n * The source element which will capture pointer events and initiate drag mode.\n *\n * @remarks\n * By default that will be the host element itself, unless `trigger` is passed in.\n */\n private get _element(): HTMLElement {\n return this._options.trigger?.() ?? this._host;\n }\n\n /**\n * The element being dragged.\n *\n * @remarks\n * When in **deferred** mode this returns a reference to the drag ghost element,\n * otherwise it is the host element.\n */\n private get _dragItem(): HTMLElement {\n return this._isDeferred ? this._ghost! : this._host;\n }\n\n /**\n * The DOM element that will \"host\" the ghost drag element when the controller\n * is set to **deferred**.\n *\n * @remarks\n * In **immediate** mode, this property is ignored.\n */\n private get _layer(): HTMLElement {\n if (!this._isDeferred) {\n return this._host;\n }\n\n return this._options.layer?.() ?? this._host;\n }\n\n private get _stateParameters(): DragState {\n return {\n ...this._state,\n ghost: this._ghost,\n element: this._matchedElement,\n };\n }\n\n constructor(\n host: ReactiveControllerHost & LitElement,\n options?: DragControllerConfiguration\n ) {\n this._host = host;\n this._host.addController(this);\n this.set(options);\n }\n\n // #region Public API\n\n /** Whether the drag controller is enabled. */\n public get enabled(): boolean {\n return Boolean(this._options.enabled);\n }\n\n /** Updates the drag controller configuration. */\n public set(options?: DragControllerConfiguration): void {\n Object.assign(this._options, options);\n }\n\n /** Stops any drag operation and cleans up state, additional event listeners and elements. */\n public dispose(): void {\n this._matchedElement = null;\n this._removeGhost();\n this._setDragState(false);\n }\n\n /** @internal */\n public hostConnected(): void {\n const { signal } = this._abortHandle;\n\n this._host.addEventListener('dragstart', this, { signal });\n this._host.addEventListener('touchstart', this, { passive: false, signal });\n this._host.addEventListener('pointerdown', this, { signal });\n }\n\n /** @internal */\n public hostDisconnected(): void {\n this._abortHandle.abort();\n this._setDragCancelListener(false);\n this._removeGhost();\n }\n\n /** @internal */\n public handleEvent(event: PointerEvent & KeyboardEvent): void {\n if (!this.enabled) {\n return;\n }\n\n switch (event.type) {\n case 'touchstart':\n case 'dragstart':\n // Prevent contextmenu default behavior during drag\n case 'contextmenu':\n event.preventDefault();\n break;\n case 'keydown':\n this._handleCancel(event);\n break;\n case 'pointerdown':\n this._handlePointerDown(event);\n break;\n case 'pointermove':\n this._handlePointerMove(event);\n break;\n case 'lostpointercapture':\n this._handlePointerEnd(event);\n break;\n }\n }\n\n // #endregion\n\n // #region Event handlers\n\n private _handlePointerDown(event: PointerEvent): void {\n if (this._shouldSkip(event)) {\n return;\n }\n\n this._setInitialState(event);\n this._createDragGhost();\n this._updatePosition(event);\n\n const parameters = {\n event,\n state: this._stateParameters,\n };\n\n if (this._options.start?.call(this._host, parameters) === false) {\n this.dispose();\n return;\n }\n\n this._assignPosition(this._dragItem);\n this._setDragState();\n }\n\n private _handlePointerMove(event: PointerEvent): void {\n if (!this._hasPointerCapture) {\n return;\n }\n\n this._updatePosition(event);\n this._updatePointerState(event);\n this._updateMatcher(event);\n\n const parameters = {\n event,\n state: this._stateParameters,\n };\n\n this._options.move?.call(this._host, parameters);\n\n this._assignPosition(this._dragItem);\n }\n\n private _handlePointerEnd(event: PointerEvent): void {\n this._options.end?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n this.dispose();\n }\n\n private _handleCancel(event: KeyboardEvent): void {\n if (this._hasPointerCapture && isKey(event, escapeKey)) {\n // Reset state\n this._options.cancel?.call(this._host, this._stateParameters);\n }\n }\n\n // #endregion\n\n private _setDragCancelListener(enabled = true): void {\n enabled\n ? globalThis.addEventListener('keydown', this)\n : globalThis.removeEventListener('keydown', this);\n }\n\n private _setInitialState({\n pointerId,\n clientX,\n clientY,\n }: PointerEvent): void {\n const rect = this._host.getBoundingClientRect();\n const position = { x: rect.x, y: rect.y };\n const offset = { x: rect.x - clientX, y: rect.y - clientY };\n\n this._id = pointerId;\n this._state = {\n initial: rect,\n current: structuredClone(rect),\n position,\n offset,\n pointerState: {\n previous: { x: clientX, y: clientY },\n current: { x: clientX, y: clientY },\n direction: 'end',\n },\n };\n }\n\n private _setDragState(enabled = true): void {\n this._hasPointerCapture = enabled;\n const cssValue = enabled ? 'none' : '';\n\n setStyles(this._element, {\n touchAction: cssValue,\n userSelect: cssValue,\n webkitUserSelect: cssValue,\n });\n\n this._toggleTextSelection(enabled);\n\n enabled\n ? this._element.setPointerCapture(this._id)\n : this._element.releasePointerCapture(this._id);\n\n this._setDragCancelListener(enabled);\n\n // Toggle additional events\n for (const type of additionalEvents) {\n enabled\n ? this._host.addEventListener(type, this)\n : this._host.removeEventListener(type, this);\n }\n }\n\n /**\n * Toggles text selection for the duration of a drag operation.\n *\n * @remarks\n * Disabling `user-select` only on the dragged element is not enough, since browsers\n * (notably Safari) will still create a text selection in whatever elements sit under\n * the pointer while dragging. Applying it to the owner document's body prevents that\n * across the page for the active drag and is reverted once the operation completes.\n */\n private _toggleTextSelection(disabled: boolean): void {\n const value = disabled ? 'none' : '';\n const { style } = this._host.ownerDocument.body;\n\n style.userSelect = value;\n style.webkitUserSelect = value;\n\n if (disabled) {\n this._host.ownerDocument.getSelection()?.removeAllRanges();\n }\n }\n\n private _updateMatcher(event: PointerEvent) {\n if (!this._options.matchTarget) {\n return;\n }\n\n const match = getRoot(this._host)\n .elementsFromPoint(event.clientX, event.clientY)\n .find((element) => this._options.matchTarget!.call(this._host, element));\n\n if (match && !this._matchedElement) {\n this._matchedElement = match;\n this._options.enter?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n return;\n }\n\n if (!match && this._matchedElement) {\n this._options.leave?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n this._matchedElement = null;\n return;\n }\n\n if (match && match === this._matchedElement) {\n this._options.over?.call(this._host, {\n event,\n state: this._stateParameters,\n });\n }\n }\n\n private _updatePosition({ clientX, clientY }: PointerEvent): void {\n const { x, y } = this._state.offset;\n const { x: layerX, y: layerY } = this._isDeferred\n ? this._layer.getBoundingClientRect()\n : this._state.initial;\n\n const posX = this._hasSnapping ? clientX - layerX : clientX - layerX + x;\n const posY = this._hasSnapping ? clientY - layerY : clientY - layerY + y;\n\n this._state.position = { x: posX, y: posY };\n }\n\n private _updatePointerState({ clientX, clientY }: PointerEvent): void {\n const state = this._state.pointerState;\n\n state.previous = { ...state.current };\n state.current = { x: clientX, y: clientY };\n\n const dx = state.current.x - state.previous.x;\n const dy = state.current.y - state.previous.y;\n\n if (Math.abs(dx) >= Math.abs(dy)) {\n const swapHorizontal = isLTR(this._host) ? dx >= 0 : dx <= 0;\n state.direction = swapHorizontal ? 'end' : 'start';\n } else {\n state.direction = dy >= 0 ? 'bottom' : 'top';\n }\n }\n\n private _assignPosition(element: HTMLElement): void {\n element.style.transform = `translate3d(${roundByDPR(this._state.position.x)}px,${roundByDPR(this._state.position.y)}px,0)`;\n }\n\n private _createDragGhost(): void {\n if (!this._isDeferred) {\n return;\n }\n\n this._ghost =\n this._options.ghost?.call(this._host) ??\n createDefaultDragGhost(this._host.getBoundingClientRect());\n\n this._layer.append(this._ghost);\n }\n\n private _removeGhost(): void {\n this._ghost?.remove();\n this._ghost = null;\n }\n\n private _shouldSkip(event: PointerEvent): boolean {\n return (\n Boolean(event.button) ||\n this._options.skip?.call(this._host, event) ||\n !getElementFromPath((e) => e === this._element, event)\n );\n }\n}\n\nfunction createDefaultDragGhost({ x, y, width, height }: DOMRect): HTMLElement {\n const element = document.createElement('div');\n\n setStyles(element, {\n position: 'absolute',\n left: `${x}px`,\n top: `${y}px`,\n width: `${width}px`,\n height: `${height}px`,\n zIndex: '1000',\n background: 'gold',\n });\n\n return element;\n}\n\n/**\n * Adds a drag and drop controller to the given host\n */\nexport function addDragController(\n host: ReactiveControllerHost & LitElement,\n options?: DragControllerConfiguration\n): DragController {\n return new DragController(host, options);\n}\n"]}
|
|
@@ -62,6 +62,9 @@ class GesturesController extends EventTarget {
|
|
|
62
62
|
hostConnected() {
|
|
63
63
|
const { signal } = this._abortHandle;
|
|
64
64
|
this._host.updateComplete.then(() => {
|
|
65
|
+
if (signal.aborted || !this._element) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
65
68
|
for (const event of Events) {
|
|
66
69
|
this._element.addEventListener(event, this, { passive: true, signal });
|
|
67
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gestures.js","sourceRoot":"","sources":["../../../src/internals/controllers/gestures.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { Ref } from 'lit/directives/ref.js';\nimport { createAbortHandle } from '../abort-handler.js';\n\nconst Events = [\n 'pointerdown',\n 'pointermove',\n 'lostpointercapture',\n 'pointercancel',\n] as const;\nconst defaultState: GestureState = Object.freeze({ x: 0, y: 0, time: 0 });\n\n/**\n * Configuration object for a {@link GesturesController} instance.\n * @hidden\n */\nexport interface GesturesOptions {\n /**\n * By default, the controller listens for pointer/touch events in the context of the host element.\n * If you pass a `ref`, you can limit the observation to a certain DOM part of the host scope.\n */\n ref?: Ref<HTMLElement>;\n /**\n * The maximum amount of milliseconds between the start and end of a gesture combination\n * before it is recognized as such.\n */\n thresholdTime?: number;\n /**\n * The minimum amount a \"pointer\" should travel in pixels, before being recognized as a\n * gesture.\n */\n thresholdDistance?: number;\n /**\n * When enabled, the controller will skip events generated by a mouse device.\n */\n touchOnly?: boolean;\n}\n\ntype GestureState = {\n x: number;\n y: number;\n time: number;\n};\n\ntype GestureDirection = 'left' | 'up' | 'right' | 'down';\ntype SwipeEvents =\n | 'swipe'\n | 'swipe-left'\n | 'swipe-up'\n | 'swipe-right'\n | 'swipe-down';\n\nexport type GestureData = {\n direction: GestureDirection;\n type: string;\n xStart: number;\n xEnd: number;\n yStart: number;\n yEnd: number;\n};\n\n/* blazorSuppress */\nexport class SwipeEvent extends Event {\n public readonly data: GestureData;\n public readonly name: string;\n\n constructor(name: string, data: GestureData, initOptions?: EventInit) {\n super(name, initOptions);\n this.name = name;\n this.data = data;\n }\n}\n\nclass GesturesController extends EventTarget implements ReactiveController {\n private readonly _host: ReactiveControllerHost & HTMLElement;\n private readonly _ref?: Ref<HTMLElement>;\n private readonly _abortHandle = createAbortHandle();\n\n private _options: GesturesOptions = {\n thresholdDistance: 100,\n thresholdTime: 500,\n touchOnly: false,\n };\n\n private _pointerState = {\n captured: false,\n start: defaultState,\n current: defaultState,\n };\n\n protected get _element() {\n return this._ref ? this._ref.value! : this._host;\n }\n\n /** Get the current configuration object */\n public get options(): GesturesOptions {\n return this._options;\n }\n\n constructor(\n host: ReactiveControllerHost & HTMLElement,\n options?: GesturesOptions\n ) {\n super();\n\n Object.assign(this._options, options);\n this._ref = this._options.ref;\n\n this._host = host;\n this._host.addController(this);\n }\n\n /**\n * Add an event listener for a given swipe event.\n */\n public set(\n type: SwipeEvents,\n callback: (event: SwipeEvent) => void,\n options?: AddEventListenerOptions\n ): this {\n const bound = callback.bind(this._host) as EventListener;\n\n this.addEventListener(type, bound, options);\n return this;\n }\n\n /** @internal */\n public handleEvent(event: PointerEvent): void {\n if (this._options.touchOnly && event.pointerType === 'mouse') {\n return;\n }\n\n switch (event.type) {\n case 'pointerdown':\n this._handlePointerDown(event);\n break;\n case 'pointermove':\n this._handlePointerMove(event);\n break;\n case 'lostpointercapture':\n case 'pointercancel':\n this._handleLostPointerCapture(event);\n }\n }\n\n /** @internal */\n public hostConnected(): void {\n const { signal } = this._abortHandle;\n\n this._host.updateComplete.then(() => {\n for (const event of Events) {\n this._element.addEventListener(event, this, { passive: true, signal });\n }\n });\n }\n\n /** @internal */\n public hostDisconnected(): void {\n this._abortHandle.abort();\n }\n\n /** Updates the configuration of the controller */\n public updateOptions(options: Omit<GesturesOptions, 'ref'>): void {\n Object.assign(this._options, options);\n }\n\n private _getGestureState({\n clientX: x,\n clientY: y,\n }: PointerEvent): GestureState {\n return { x, y, time: Date.now() };\n }\n\n private _setTouchActionState(disabled: boolean) {\n this._element.style.touchAction = disabled ? 'none' : '';\n }\n\n private _resetState() {\n this._pointerState.start = defaultState;\n this._pointerState.current = defaultState;\n }\n\n private _setPointerCaptureState(event: PointerEvent, state: boolean) {\n this._pointerState.captured = state;\n state\n ? this._element.setPointerCapture(event.pointerId)\n : this._element.releasePointerCapture(event.pointerId);\n }\n\n private _handlePointerDown(event: PointerEvent) {\n const state = this._getGestureState(event);\n\n this._setTouchActionState(true);\n // Seeded so that a press without any movement resolves to a zero delta\n // instead of being measured against the zeroed default state.\n this._pointerState.start = state;\n this._pointerState.current = state;\n this._setPointerCaptureState(event, true);\n }\n\n private _handlePointerMove(event: PointerEvent) {\n if (this._pointerState.captured) {\n this._pointerState.current = this._getGestureState(event);\n }\n }\n\n private _emit(name: SwipeEvents, data: GestureData) {\n return this.dispatchEvent(new SwipeEvent(name, data));\n }\n\n private _createEventArgs() {\n const { start, current } = this._pointerState;\n\n return {\n xStart: start.x,\n xEnd: current.x,\n yStart: start.y,\n yEnd: current.y,\n };\n }\n\n protected _recognize(): GestureDirection | false {\n const { start, current } = this._pointerState;\n\n const dt = current.time - start.time;\n const dx = current.x - start.x;\n const dy = current.y - start.y;\n\n const time = this._options.thresholdTime ?? 500;\n const distance = this._options.thresholdDistance ?? 100;\n\n if (dt > time) {\n return false;\n }\n\n if (dx > distance && Math.abs(dy) < distance) {\n return 'right';\n }\n\n if (-dx > distance && Math.abs(dy) < distance) {\n return 'left';\n }\n\n if (dy > distance && Math.abs(dx) < distance) {\n return 'down';\n }\n\n if (-dy > distance && Math.abs(dx) < distance) {\n return 'up';\n }\n\n return false;\n }\n\n private _handleLostPointerCapture(event: PointerEvent) {\n this._setPointerCaptureState(event, false);\n const state = this._recognize();\n\n if (state) {\n const args: GestureData = Object.assign(this._createEventArgs(), {\n type: event.pointerType,\n direction: state,\n });\n\n this._emit('swipe', args);\n this._emit(`swipe-${state}`, args);\n }\n\n this._resetState();\n this._setTouchActionState(false);\n }\n}\n\n/**\n * Adds a {@link GesturesController} responsible for managing gesture behaviors\n * for the given host element.\n */\nexport function addGesturesController(\n host: ReactiveControllerHost & HTMLElement,\n options?: GesturesOptions\n) {\n return new GesturesController(host, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gestures.js","sourceRoot":"","sources":["../../../src/internals/controllers/gestures.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,MAAM,GAAG;IACb,aAAa;IACb,aAAa;IACb,oBAAoB;IACpB,eAAe;CACP,CAAC;AACX,MAAM,YAAY,GAAiB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;AAoD1E,MAAM,OAAO,UAAW,SAAQ,KAAK;IAInC,YAAY,IAAY,EAAE,IAAiB,EAAE,WAAuB;QAClE,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,kBAAmB,SAAQ,WAAW;IAiB1C,IAAc,QAAQ;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACnD,CAAC;IAGD,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,YACE,IAA0C,EAC1C,OAAyB;QAEzB,KAAK,EAAE,CAAC;QA3BO,iBAAY,GAAG,iBAAiB,EAAE,CAAC;QAE5C,aAAQ,GAAoB;YAClC,iBAAiB,EAAE,GAAG;YACtB,aAAa,EAAE,GAAG;YAClB,SAAS,EAAE,KAAK;SACjB,CAAC;QAEM,kBAAa,GAAG;YACtB,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,YAAY;SACtB,CAAC;QAiBA,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAE9B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAKM,GAAG,CACR,IAAiB,EACjB,QAAqC,EACrC,OAAiC;QAEjC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAkB,CAAC;QAEzD,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAGM,WAAW,CAAC,KAAmB;QACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,aAAa;gBAChB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC/B,MAAM;YACR,KAAK,aAAa;gBAChB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC/B,MAAM;YACR,KAAK,oBAAoB,CAAC;YAC1B,KAAK,eAAe;gBAClB,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAGM,aAAa;QAClB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC;QAErC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAClC,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAGM,gBAAgB;QACrB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAGM,aAAa,CAAC,OAAqC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAEO,gBAAgB,CAAC,EACvB,OAAO,EAAE,CAAC,EACV,OAAO,EAAE,CAAC,GACG;QACb,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACpC,CAAC;IAEO,oBAAoB,CAAC,QAAiB;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IAEO,WAAW;QACjB,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,YAAY,CAAC;QACxC,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,YAAY,CAAC;IAC5C,CAAC;IAEO,uBAAuB,CAAC,KAAmB,EAAE,KAAc;QACjE,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC;QACpC,KAAK;YACH,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC;YAClD,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;IAEO,kBAAkB,CAAC,KAAmB;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAE3C,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAGhC,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC;QACjC,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAEO,kBAAkB,CAAC,KAAmB;QAC5C,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAiB,EAAE,IAAiB;QAChD,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IAEO,gBAAgB;QACtB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAE9C,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,CAAC;YACf,IAAI,EAAE,OAAO,CAAC,CAAC;YACf,MAAM,EAAE,KAAK,CAAC,CAAC;YACf,IAAI,EAAE,OAAO,CAAC,CAAC;SAChB,CAAC;IACJ,CAAC;IAES,UAAU;QAClB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;QAE9C,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACrC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAE/B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,GAAG,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,GAAG,CAAC;QAExD,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC;YAC7C,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC;YAC9C,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC;YAC7C,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,yBAAyB,CAAC,KAAmB;QACnD,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAEhC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAgB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE;gBAC/D,IAAI,EAAE,KAAK,CAAC,WAAW;gBACvB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;CACF;AAMD,MAAM,UAAU,qBAAqB,CACnC,IAA0C,EAC1C,OAAyB;IAEzB,OAAO,IAAI,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { Ref } from 'lit/directives/ref.js';\nimport { createAbortHandle } from '../abort-handler.js';\n\nconst Events = [\n 'pointerdown',\n 'pointermove',\n 'lostpointercapture',\n 'pointercancel',\n] as const;\nconst defaultState: GestureState = Object.freeze({ x: 0, y: 0, time: 0 });\n\n/**\n * Configuration object for a {@link GesturesController} instance.\n * @hidden\n */\nexport interface GesturesOptions {\n /**\n * By default, the controller listens for pointer/touch events in the context of the host element.\n * If you pass a `ref`, you can limit the observation to a certain DOM part of the host scope.\n */\n ref?: Ref<HTMLElement>;\n /**\n * The maximum amount of milliseconds between the start and end of a gesture combination\n * before it is recognized as such.\n */\n thresholdTime?: number;\n /**\n * The minimum amount a \"pointer\" should travel in pixels, before being recognized as a\n * gesture.\n */\n thresholdDistance?: number;\n /**\n * When enabled, the controller will skip events generated by a mouse device.\n */\n touchOnly?: boolean;\n}\n\ntype GestureState = {\n x: number;\n y: number;\n time: number;\n};\n\ntype GestureDirection = 'left' | 'up' | 'right' | 'down';\ntype SwipeEvents =\n | 'swipe'\n | 'swipe-left'\n | 'swipe-up'\n | 'swipe-right'\n | 'swipe-down';\n\nexport type GestureData = {\n direction: GestureDirection;\n type: string;\n xStart: number;\n xEnd: number;\n yStart: number;\n yEnd: number;\n};\n\n/* blazorSuppress */\nexport class SwipeEvent extends Event {\n public readonly data: GestureData;\n public readonly name: string;\n\n constructor(name: string, data: GestureData, initOptions?: EventInit) {\n super(name, initOptions);\n this.name = name;\n this.data = data;\n }\n}\n\nclass GesturesController extends EventTarget implements ReactiveController {\n private readonly _host: ReactiveControllerHost & HTMLElement;\n private readonly _ref?: Ref<HTMLElement>;\n private readonly _abortHandle = createAbortHandle();\n\n private _options: GesturesOptions = {\n thresholdDistance: 100,\n thresholdTime: 500,\n touchOnly: false,\n };\n\n private _pointerState = {\n captured: false,\n start: defaultState,\n current: defaultState,\n };\n\n protected get _element() {\n return this._ref ? this._ref.value! : this._host;\n }\n\n /** Get the current configuration object */\n public get options(): GesturesOptions {\n return this._options;\n }\n\n constructor(\n host: ReactiveControllerHost & HTMLElement,\n options?: GesturesOptions\n ) {\n super();\n\n Object.assign(this._options, options);\n this._ref = this._options.ref;\n\n this._host = host;\n this._host.addController(this);\n }\n\n /**\n * Add an event listener for a given swipe event.\n */\n public set(\n type: SwipeEvents,\n callback: (event: SwipeEvent) => void,\n options?: AddEventListenerOptions\n ): this {\n const bound = callback.bind(this._host) as EventListener;\n\n this.addEventListener(type, bound, options);\n return this;\n }\n\n /** @internal */\n public handleEvent(event: PointerEvent): void {\n if (this._options.touchOnly && event.pointerType === 'mouse') {\n return;\n }\n\n switch (event.type) {\n case 'pointerdown':\n this._handlePointerDown(event);\n break;\n case 'pointermove':\n this._handlePointerMove(event);\n break;\n case 'lostpointercapture':\n case 'pointercancel':\n this._handleLostPointerCapture(event);\n }\n }\n\n /** @internal */\n public hostConnected(): void {\n const { signal } = this._abortHandle;\n\n this._host.updateComplete.then(() => {\n if (signal.aborted || !this._element) {\n return;\n }\n\n for (const event of Events) {\n this._element.addEventListener(event, this, { passive: true, signal });\n }\n });\n }\n\n /** @internal */\n public hostDisconnected(): void {\n this._abortHandle.abort();\n }\n\n /** Updates the configuration of the controller */\n public updateOptions(options: Omit<GesturesOptions, 'ref'>): void {\n Object.assign(this._options, options);\n }\n\n private _getGestureState({\n clientX: x,\n clientY: y,\n }: PointerEvent): GestureState {\n return { x, y, time: Date.now() };\n }\n\n private _setTouchActionState(disabled: boolean) {\n this._element.style.touchAction = disabled ? 'none' : '';\n }\n\n private _resetState() {\n this._pointerState.start = defaultState;\n this._pointerState.current = defaultState;\n }\n\n private _setPointerCaptureState(event: PointerEvent, state: boolean) {\n this._pointerState.captured = state;\n state\n ? this._element.setPointerCapture(event.pointerId)\n : this._element.releasePointerCapture(event.pointerId);\n }\n\n private _handlePointerDown(event: PointerEvent) {\n const state = this._getGestureState(event);\n\n this._setTouchActionState(true);\n // Seeded so that a press without any movement resolves to a zero delta\n // instead of being measured against the zeroed default state.\n this._pointerState.start = state;\n this._pointerState.current = state;\n this._setPointerCaptureState(event, true);\n }\n\n private _handlePointerMove(event: PointerEvent) {\n if (this._pointerState.captured) {\n this._pointerState.current = this._getGestureState(event);\n }\n }\n\n private _emit(name: SwipeEvents, data: GestureData) {\n return this.dispatchEvent(new SwipeEvent(name, data));\n }\n\n private _createEventArgs() {\n const { start, current } = this._pointerState;\n\n return {\n xStart: start.x,\n xEnd: current.x,\n yStart: start.y,\n yEnd: current.y,\n };\n }\n\n protected _recognize(): GestureDirection | false {\n const { start, current } = this._pointerState;\n\n const dt = current.time - start.time;\n const dx = current.x - start.x;\n const dy = current.y - start.y;\n\n const time = this._options.thresholdTime ?? 500;\n const distance = this._options.thresholdDistance ?? 100;\n\n if (dt > time) {\n return false;\n }\n\n if (dx > distance && Math.abs(dy) < distance) {\n return 'right';\n }\n\n if (-dx > distance && Math.abs(dy) < distance) {\n return 'left';\n }\n\n if (dy > distance && Math.abs(dx) < distance) {\n return 'down';\n }\n\n if (-dy > distance && Math.abs(dx) < distance) {\n return 'up';\n }\n\n return false;\n }\n\n private _handleLostPointerCapture(event: PointerEvent) {\n this._setPointerCaptureState(event, false);\n const state = this._recognize();\n\n if (state) {\n const args: GestureData = Object.assign(this._createEventArgs(), {\n type: event.pointerType,\n direction: state,\n });\n\n this._emit('swipe', args);\n this._emit(`swipe-${state}`, args);\n }\n\n this._resetState();\n this._setTouchActionState(false);\n }\n}\n\n/**\n * Adds a {@link GesturesController} responsible for managing gesture behaviors\n * for the given host element.\n */\nexport function addGesturesController(\n host: ReactiveControllerHost & HTMLElement,\n options?: GesturesOptions\n) {\n return new GesturesController(host, options);\n}\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
type GroupHost = ReactiveControllerHost & Element;
|
|
3
|
+
/** The object a group's identity is bound to - a root node, a container element. */
|
|
4
|
+
type GroupScope = object;
|
|
5
|
+
type GroupRegistryConfig<T extends GroupHost, S> = {
|
|
6
|
+
/**
|
|
7
|
+
* The group key of a host. Together with the scope it forms the identity of
|
|
8
|
+
* a group. A host with an empty key stays on its own.
|
|
9
|
+
*/
|
|
10
|
+
keyOf: (host: T) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Derives the group-wide state that each member receives on sync, from the
|
|
13
|
+
* current members of the group.
|
|
14
|
+
*/
|
|
15
|
+
deriveState: (members: T[]) => S;
|
|
16
|
+
/**
|
|
17
|
+
* The scope the group identity is bound to. Defaults to the host's root
|
|
18
|
+
* node (document or shadow root).
|
|
19
|
+
*/
|
|
20
|
+
scopeOf?: (host: T) => GroupScope;
|
|
21
|
+
};
|
|
22
|
+
/** The membership of one host, attached to it as a reactive controller. */
|
|
23
|
+
interface GroupMemberController<T extends GroupHost> extends ReactiveController {
|
|
24
|
+
/** The hosts of this member's group, in DOM order. A host with no group is on its own. */
|
|
25
|
+
readonly members: T[];
|
|
26
|
+
/**
|
|
27
|
+
* Moves the host to the group of its current scope and key. Does nothing
|
|
28
|
+
* while both stay the same. If not, the group that the host joins and the
|
|
29
|
+
* group that it leaves both update their state.
|
|
30
|
+
*/
|
|
31
|
+
updateMembership(): void;
|
|
32
|
+
/** Updates the state of the host group. */
|
|
33
|
+
sync(): void;
|
|
34
|
+
}
|
|
35
|
+
interface GroupRegistry<T extends GroupHost, S> {
|
|
36
|
+
/** Creates and attaches a membership controller to the host. */
|
|
37
|
+
attach(host: T, onSync: (state: S) => void): GroupMemberController<T>;
|
|
38
|
+
/** Returns the hosts of the group of `member`, in DOM order. */
|
|
39
|
+
membersOf(member: T): T[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates a registry of groups whose members discover each other through a
|
|
43
|
+
* shared scope and key instead of a common parent element - the way native
|
|
44
|
+
* radio buttons group by their `name` within a form root.
|
|
45
|
+
*
|
|
46
|
+
* Each member holds its own entry for its life-cycle, so that a group read
|
|
47
|
+
* reflects the actual membership and the members that stay behind derive their
|
|
48
|
+
* state again when one leaves - a change a member cannot see on its own.
|
|
49
|
+
*
|
|
50
|
+
* One registry holds one kind of group; create it at module level:
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const radioGroups = createGroupRegistry<IgcRadioComponent, boolean>({
|
|
55
|
+
* keyOf: (radio) => radio.name || '',
|
|
56
|
+
* deriveState: (radios) => radios.some((radio) => radio.checked),
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // In the component:
|
|
60
|
+
* private readonly _group = radioGroups.attach(this, (state) => { ... });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function createGroupRegistry<T extends GroupHost, S>(config: GroupRegistryConfig<T, S>): GroupRegistry<T, S>;
|
|
64
|
+
export type { GroupMemberController, GroupRegistry, GroupRegistryConfig };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { isEmpty } from '../utils/arrays.js';
|
|
2
|
+
import { getRoot } from '../utils/dom.js';
|
|
3
|
+
function byDocumentOrder(a, b) {
|
|
4
|
+
if (a === b) {
|
|
5
|
+
return 0;
|
|
6
|
+
}
|
|
7
|
+
return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING
|
|
8
|
+
? -1
|
|
9
|
+
: 1;
|
|
10
|
+
}
|
|
11
|
+
export function createGroupRegistry(config) {
|
|
12
|
+
const groups = new WeakMap();
|
|
13
|
+
const controllers = new WeakMap();
|
|
14
|
+
function scopeOf(host) {
|
|
15
|
+
return config.scopeOf?.(host) ?? getRoot(host);
|
|
16
|
+
}
|
|
17
|
+
function syncGroup(group) {
|
|
18
|
+
const members = Array.from(group);
|
|
19
|
+
const state = config.deriveState(members.map((member) => member.host));
|
|
20
|
+
for (const member of members) {
|
|
21
|
+
member.onSync(state);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
class Member {
|
|
25
|
+
get _isCurrent() {
|
|
26
|
+
return (config.keyOf(this.host) === this._key &&
|
|
27
|
+
scopeOf(this.host) === this._scope);
|
|
28
|
+
}
|
|
29
|
+
get _group() {
|
|
30
|
+
const entries = this._scope
|
|
31
|
+
? Array.from(groups.get(this._scope)?.get(this._key) ?? [])
|
|
32
|
+
: [];
|
|
33
|
+
const members = entries.filter((member) => member._isCurrent);
|
|
34
|
+
return isEmpty(members)
|
|
35
|
+
? [this]
|
|
36
|
+
: members.sort((a, b) => byDocumentOrder(a.host, b.host));
|
|
37
|
+
}
|
|
38
|
+
get members() {
|
|
39
|
+
return this._group.map((member) => member.host);
|
|
40
|
+
}
|
|
41
|
+
constructor(host, onSync) {
|
|
42
|
+
this._scope = null;
|
|
43
|
+
this._key = '';
|
|
44
|
+
this.host = host;
|
|
45
|
+
this.onSync = onSync;
|
|
46
|
+
controllers.set(host, this);
|
|
47
|
+
host.addController(this);
|
|
48
|
+
}
|
|
49
|
+
hostConnected() {
|
|
50
|
+
this.updateMembership();
|
|
51
|
+
}
|
|
52
|
+
hostDisconnected() {
|
|
53
|
+
this._unregister();
|
|
54
|
+
}
|
|
55
|
+
updateMembership() {
|
|
56
|
+
const scope = this.host.isConnected ? scopeOf(this.host) : null;
|
|
57
|
+
const key = config.keyOf(this.host);
|
|
58
|
+
if (scope === this._scope && key === this._key) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this._unregister();
|
|
62
|
+
if (scope && key) {
|
|
63
|
+
this._scope = scope;
|
|
64
|
+
this._key = key;
|
|
65
|
+
const keys = groups.get(scope) ?? new Map();
|
|
66
|
+
const group = keys.get(key) ?? new Set();
|
|
67
|
+
keys.set(key, group);
|
|
68
|
+
groups.set(scope, keys);
|
|
69
|
+
group.add(this);
|
|
70
|
+
}
|
|
71
|
+
this.sync();
|
|
72
|
+
}
|
|
73
|
+
sync() {
|
|
74
|
+
syncGroup(this._group);
|
|
75
|
+
}
|
|
76
|
+
_unregister() {
|
|
77
|
+
const { _scope: scope, _key: key } = this;
|
|
78
|
+
const keys = scope ? groups.get(scope) : undefined;
|
|
79
|
+
const group = keys?.get(key);
|
|
80
|
+
this._scope = null;
|
|
81
|
+
this._key = '';
|
|
82
|
+
if (!group?.delete(this)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (isEmpty(group)) {
|
|
86
|
+
keys?.delete(key);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
syncGroup(group);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
attach(host, onSync) {
|
|
95
|
+
return new Member(host, onSync);
|
|
96
|
+
},
|
|
97
|
+
membersOf(member) {
|
|
98
|
+
const controller = controllers.get(member);
|
|
99
|
+
controller?.updateMembership();
|
|
100
|
+
return controller?.members ?? [member];
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=group.js.map
|