@lilydesignsystem/angular-motion-picker 0.3.0 → 0.3.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/README.md
CHANGED
|
@@ -46,18 +46,18 @@ export class Example {
|
|
|
46
46
|
|
|
47
47
|
## Inputs / Outputs
|
|
48
48
|
|
|
49
|
-
| Name | Type
|
|
50
|
-
| -------------- |
|
|
51
|
-
| `label` | `string`
|
|
52
|
-
| `motions` | `string[]`
|
|
53
|
-
| `value` | `string` (model)
|
|
54
|
-
| `defaultValue` | `string`
|
|
55
|
-
| `storageKey` | `string`
|
|
56
|
-
| `name` | `string`
|
|
57
|
-
| `target` | `HTMLElement \| null`
|
|
58
|
-
| `motionLabels` | `Record<string,string>`
|
|
59
|
-
| `className` | `string`
|
|
60
|
-
| `motionChange` | `output<string>`
|
|
49
|
+
| Name | Type | Required | Description |
|
|
50
|
+
| -------------- | ----------------------- | -------- | -------------------------------------------------------- |
|
|
51
|
+
| `label` | `string` | yes | Accessible name (`aria-label`) for the button + listbox. |
|
|
52
|
+
| `motions` | `string[]` | yes | Available motion slugs. |
|
|
53
|
+
| `value` | `string` (model) | no | Selected slug. Two-way bindable via `[(value)]`. |
|
|
54
|
+
| `defaultValue` | `string` | no | Initial slug when nothing else is supplied. |
|
|
55
|
+
| `storageKey` | `string` | no | If set, persist the slug to `localStorage`. |
|
|
56
|
+
| `name` | `string` | no | `name` of the hidden input (default `"motion"`). |
|
|
57
|
+
| `target` | `HTMLElement \| null` | no | Element to receive `data-motion`. Default `<html>`. |
|
|
58
|
+
| `motionLabels` | `Record<string,string>` | no | Pretty labels per slug. |
|
|
59
|
+
| `className` | `string` | no | Extra CSS class on the root. |
|
|
60
|
+
| `motionChange` | `output<string>` | — | Emits after a new motion preference is applied. |
|
|
61
61
|
|
|
62
62
|
## Behaviour
|
|
63
63
|
|
|
@@ -25,7 +25,7 @@ var MotionPickerIcon = class MotionPickerIcon {
|
|
|
25
25
|
static {
|
|
26
26
|
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
27
27
|
minVersion: "12.0.0",
|
|
28
|
-
version: "22.2.
|
|
28
|
+
version: "22.2.4",
|
|
29
29
|
ngImport: i0,
|
|
30
30
|
type: MotionPickerIcon,
|
|
31
31
|
deps: [],
|
|
@@ -35,7 +35,7 @@ var MotionPickerIcon = class MotionPickerIcon {
|
|
|
35
35
|
static {
|
|
36
36
|
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
37
37
|
minVersion: "14.0.0",
|
|
38
|
-
version: "22.2.
|
|
38
|
+
version: "22.2.4",
|
|
39
39
|
type: MotionPickerIcon,
|
|
40
40
|
isStandalone: true,
|
|
41
41
|
selector: "ng-template[lilyMotionPickerIcon]",
|
|
@@ -45,7 +45,7 @@ var MotionPickerIcon = class MotionPickerIcon {
|
|
|
45
45
|
};
|
|
46
46
|
i0.ɵɵngDeclareClassMetadata({
|
|
47
47
|
minVersion: "12.0.0",
|
|
48
|
-
version: "22.2.
|
|
48
|
+
version: "22.2.4",
|
|
49
49
|
ngImport: i0,
|
|
50
50
|
type: MotionPickerIcon,
|
|
51
51
|
decorators: [{
|
|
@@ -229,7 +229,7 @@ var MotionPicker = class MotionPicker {
|
|
|
229
229
|
static {
|
|
230
230
|
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
231
231
|
minVersion: "12.0.0",
|
|
232
|
-
version: "22.2.
|
|
232
|
+
version: "22.2.4",
|
|
233
233
|
ngImport: i0,
|
|
234
234
|
type: MotionPicker,
|
|
235
235
|
deps: [],
|
|
@@ -239,7 +239,7 @@ var MotionPicker = class MotionPicker {
|
|
|
239
239
|
static {
|
|
240
240
|
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
241
241
|
minVersion: "17.0.0",
|
|
242
|
-
version: "22.2.
|
|
242
|
+
version: "22.2.4",
|
|
243
243
|
type: MotionPicker,
|
|
244
244
|
isStandalone: true,
|
|
245
245
|
selector: "lily-motion-picker",
|
|
@@ -504,7 +504,7 @@ var MotionPicker = class MotionPicker {
|
|
|
504
504
|
};
|
|
505
505
|
i0.ɵɵngDeclareClassMetadata({
|
|
506
506
|
minVersion: "12.0.0",
|
|
507
|
-
version: "22.2.
|
|
507
|
+
version: "22.2.4",
|
|
508
508
|
ngImport: i0,
|
|
509
509
|
type: MotionPicker,
|
|
510
510
|
decorators: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lilydesignsystem-angular-motion-picker.mjs","names":[],"sources":["../../motion-picker.component.ts"],"sourcesContent":["import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n contentChild,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n model,\n output,\n signal,\n TemplateRef,\n viewChild,\n} from \"@angular/core\";\nimport { IconButton, Listbox } from \"@lilydesignsystem/angular-headless\";\n\n/**\n * Default button icon: a bundled SVG (two pause bars), not a Unicode\n * character. Reversed 2026-09-16 from the font-dependent-glyph\n * convention (was U+23F8 PAUSE SIGN + U+FE0E, exported as `PAUSE_SIGN`\n * — removed, not renamed). \"Stop the moving parts\" still reads\n * directly from two bars; a bundled outline SVG matches the other four\n * picker icons as one consistent visual family regardless of the\n * consumer's fonts.\n */\n\n/** Context passed to a custom icon `<ng-template>` (the button icon). */\nexport type ChildArgs = {\n /** Currently selected motion slug. */\n value: string;\n /** Is the listbox open? */\n open: boolean;\n /** Resolve a slug to its display label. */\n labelFor: (motion: string) => string;\n};\n\n/**\n * Resolve a motion slug to its display label: each hyphen-separated\n * word title-cased, so a slug like \"no-preference\" renders as\n * \"No Preference\". Mirrors `sizeName` in text-size-picker and\n * `themeName` in theme-picker.\n */\nexport function motionName(motion: string): string {\n return motion\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/**\n * True when the platform reports a preference for reduced motion.\n * SSR-safe: `window`/`matchMedia` are absent on the server, so this\n * resolves to `false` there and the client re-derives it on mount.\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n try {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n } catch {\n return false;\n }\n}\n\nlet uid = 0;\n/** Stable per-instance id prefix; SSR-safe (no Math.random / Date.now). */\nexport function nextMotionPickerId(): string {\n uid += 1;\n return `motion-picker-${uid}`;\n}\n\n/**\n * Optional marker for the projected icon template. Gives consumers typed\n * `let-` variables:\n *\n * ```html\n * <lily-motion-picker ...>\n * <ng-template lilyMotionPickerIcon let-args>{{ args.labelFor(args.value) }}</ng-template>\n * </lily-motion-picker>\n * ```\n *\n * The component queries any projected `<ng-template>`, so the marker is\n * for type-checking and readability, not for matching.\n */\n@Directive({\n selector: \"ng-template[lilyMotionPickerIcon]\",\n standalone: true,\n})\nexport class MotionPickerIcon {\n static ngTemplateContextGuard(\n _dir: MotionPickerIcon,\n _ctx: unknown,\n ): _ctx is ChildArgs & { $implicit: ChildArgs } {\n return true;\n }\n}\n\n/**\n * MotionPicker — `data-motion` reduced-motion picker.\n *\n * Renders an icon button that opens a WAI-ARIA APG listbox of motion\n * slugs. On every change the component sets `data-motion=\"{slug}\"` on\n * the document root (or on a consumer-supplied target), with optional\n * `localStorage` persistence. Its initial value defers to the\n * platform's `(prefers-reduced-motion: reduce)` media query before\n * falling back to a fixed default — the one behaviour difference from\n * its `theme-picker`/`text-size-picker` siblings. Ships no CSS; the\n * consumer decides what `[data-motion=\"reduce\"]` actually suppresses.\n * See `spec/index.md` for the full contract.\n */\n@Component({\n selector: \"lily-motion-picker\",\n standalone: true,\n imports: [NgTemplateOutlet, IconButton, Listbox],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n \"(document:click)\": \"onDocumentClick($event)\",\n },\n template: `\n <div\n #rootEl\n class=\"motion-picker {{ className() }}\"\n (focusout)=\"onRootFocusOut($event)\"\n >\n <input type=\"hidden\" [name]=\"name()\" [value]=\"value()\" />\n\n <lily-icon-button\n [disabled]=\"disabled()\"\n #buttonEl\n [label]=\"label()\"\n baseClass=\"motion-picker-button\"\n ariaHaspopup=\"listbox\"\n [ariaExpanded]=\"open()\"\n [ariaControls]=\"listId\"\n (click)=\"toggle(); hoverButton.set(false)\"\n (mouseenter)=\"onTooltipButtonEnter()\"\n (mouseleave)=\"hoverButton.set(false)\"\n (focusin)=\"onTooltipButtonFocusIn()\"\n (focusout)=\"onTooltipButtonFocusOut()\"\n (keydown)=\"onButtonKeydown($event); onTooltipKeydown($event)\"\n >\n @if (iconTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"childContext()\"\n />\n } @else {\n <svg\n class=\"motion-picker-icon\"\n viewBox=\"0 0 16 16\"\n width=\"1.05rem\"\n height=\"1.05rem\"\n aria-hidden=\"true\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.6\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M5 3v10M11 3v10\" />\n </svg>\n }\n </lily-icon-button>\n\n <!-- Purely visual: the same text is already the button's aria-label,\n so it is not wired with aria-describedby (that would announce\n the name twice). -->\n <div\n class=\"motion-picker-tooltip\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.hidden]=\"tooltipVisible() ? null : ''\"\n (mouseenter)=\"hoverTooltip.set(true)\"\n (mouseleave)=\"hoverTooltip.set(false)\"\n >{{ label() }}</div>\n\n <lily-listbox\n #listEl\n [label]=\"label()\"\n baseClass=\"motion-picker-list\"\n [elementId]=\"listId\"\n navigation=\"active-descendant\"\n [clamp]=\"true\"\n [typeahead]=\"true\"\n [pageSize]=\"10\"\n [(activeIndex)]=\"activeIndex\"\n [hidden]=\"!open()\"\n (activate)=\"choose($event)\"\n (escape)=\"closeList()\"\n (tabOut)=\"onListTabOut()\"\n >\n @for (motion of motions(); track motion; let i = $index) {\n <li\n class=\"motion-picker-option\"\n [id]=\"optionId(i)\"\n role=\"option\"\n [attr.aria-selected]=\"motion === value()\"\n [attr.data-active]=\"i === activeIndex() ? '' : null\"\n (click)=\"choose(i)\"\n >\n {{ labelFor(motion) }}\n </li>\n }\n </lily-listbox>\n </div>\n `,\n})\nexport class MotionPicker {\n readonly label = input.required<string>();\n readonly motions = input.required<string[]>();\n readonly value = model<string>(\"\");\n readonly defaultValue = input<string>(\"\");\n readonly storageKey = input<string>(\"\");\n readonly name = input<string>(\"motion\");\n readonly target = input<HTMLElement | null>(null);\n readonly motionLabels = input<Record<string, string>>({});\n readonly className = input<string>(\"\");\n readonly motionChange = output<string>();\n\n /** Projected icon template; replaces the default icon when supplied. */\n protected readonly iconTemplate = contentChild(TemplateRef);\n\n private readonly rootRef =\n viewChild.required<ElementRef<HTMLDivElement>>(\"rootEl\");\n // Angular resolves a template-ref-variable on a component tag to the\n // component INSTANCE by default (not its ElementRef) — exactly what's\n // needed to call the headless components' own public `focus()` methods.\n private readonly buttonRef = viewChild.required<IconButton>(\"buttonEl\");\n private readonly listRef = viewChild.required<Listbox>(\"listEl\");\n\n private readonly baseId = nextMotionPickerId();\n protected readonly listId = `${this.baseId}-list`;\n\n /** Is the popup open? Two-way bindable: `[(open)]`; `openChange` fires for each change. */\n readonly open = model<boolean>(false);\n /** Disables the button; an open popup closes. */\n readonly disabled = input<boolean>(false);\n private readonly closeWhenDisabled = effect(() => {\n if (this.disabled() && this.open()) this.open.set(false);\n });\n\n // Tooltip: shown while the pointer is over the button or the tooltip\n // itself (hoverable, WCAG 1.4.13) or while the button has keyboard\n // focus; Escape dismisses it without moving focus; never shown while\n // the popup is open, since the popup then explains the control.\n protected readonly tooltipId = `${this.baseId}-tooltip`;\n protected readonly hoverButton = signal(false);\n protected readonly hoverTooltip = signal(false);\n protected readonly focusButton = signal(false);\n protected readonly dismissed = signal(false);\n protected readonly tooltipVisible = computed(\n () =>\n !this.open() &&\n !this.dismissed() &&\n (this.hoverButton() || this.hoverTooltip() || this.focusButton()),\n );\n\n protected onTooltipButtonEnter(): void {\n this.hoverButton.set(true);\n this.dismissed.set(false);\n }\n\n protected onTooltipButtonFocusIn(): void {\n // Keyboard focus only: a mouse click also focuses the button in\n // Chromium, and the tooltip should not stick after a click.\n try {\n this.focusButton.set(\n this.buttonRef().element?.matches(\":focus-visible\") ?? false,\n );\n } catch {\n this.focusButton.set(true); // engine without :focus-visible — err towards showing\n }\n }\n\n protected onTooltipButtonFocusOut(): void {\n this.focusButton.set(false);\n this.dismissed.set(false);\n }\n\n protected onTooltipKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\" && this.tooltipVisible()) this.dismissed.set(true);\n }\n\n // WCAG 1.4.13 \"dismissable\": while the tooltip is visible, Escape works\n // wherever focus is (hover-only tooltips have focus elsewhere). The\n // listener exists only while visible; the effect cleanup removes it on\n // hide and on destroy. No preventDefault/stopPropagation, focus untouched.\n private readonly tooltipEscapeListener = effect((onCleanup) => {\n if (!this.tooltipVisible() || typeof document === \"undefined\") return;\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") this.dismissed.set(true);\n };\n document.addEventListener(\"keydown\", onKey);\n onCleanup(() => document.removeEventListener(\"keydown\", onKey));\n });\n protected readonly activeIndex = signal(-1);\n\n protected readonly childContext = computed(() => {\n const args: ChildArgs = {\n value: this.value(),\n open: this.open(),\n labelFor: (motion: string) => this.labelFor(motion),\n };\n return { $implicit: args, ...args };\n });\n\n private initialised = false;\n\n constructor() {\n effect(() => {\n const current = this.value();\n\n if (!this.initialised) {\n this.initialised = true;\n let initial = current;\n\n const sk = this.storageKey();\n if (!initial && sk) {\n try {\n initial =\n (typeof localStorage !== \"undefined\"\n ? localStorage.getItem(sk)\n : null) ?? \"\";\n } catch {\n // ignore privacy errors\n }\n }\n\n if (!initial) {\n // Unlike text-size-picker's \"medium\" default, motion has a\n // real external signal to defer to: the platform's own\n // (prefers-reduced-motion: reduce) media query.\n const motions = this.motions();\n const dv = this.defaultValue();\n const osPreferred = prefersReducedMotion() ? \"reduce\" : \"no-preference\";\n initial =\n dv ||\n (motions.includes(osPreferred) ? osPreferred : undefined) ||\n motions[0] ||\n \"\";\n }\n\n if (initial && initial !== current) {\n this.value.set(initial);\n return;\n }\n }\n\n if (current) this.applyMotion(current);\n });\n }\n\n protected optionId(index: number): string {\n return `${this.baseId}-option-${index}`;\n }\n\n labelFor(motion: string): string {\n const labels = this.motionLabels();\n if (motion in labels) return labels[motion];\n return motionName(motion);\n }\n\n // ---------------------------------------------------------------\n // Open / close\n // ---------------------------------------------------------------\n\n /** Under zoneless change detection the signal write that un-hides the\n * list has not reached the DOM when a microtask runs, so focusing the\n * still-hidden list fails silently and Escape lands on the button.\n * Flushing detection first is the Angular equivalent of Svelte's\n * synchronous update (same fix the date-time-picker port recorded). */\n private readonly cdr = inject(ChangeDetectorRef);\n\n protected toggle(): void {\n if (this.open()) this.closeList();\n else this.openList();\n }\n\n /** Open the listbox, activating `startIndex` (default: the selection). */\n openList(startIndex?: number): void {\n const selected = this.motions().indexOf(this.value());\n // An empty list has no option to activate; -1 keeps\n // aria-activedescendant off rather than pointing at an id that\n // does not exist.\n this.activeIndex.set(\n this.motions().length === 0\n ? -1\n : (startIndex ?? (selected >= 0 ? selected : 0)),\n );\n this.open.set(true);\n // Focus moves to the listbox; the active option is conveyed via\n // aria-activedescendant, per the APG listbox pattern.\n this.cdr.detectChanges();\n queueMicrotask(() => {\n this.listRef().focus({ preventScroll: true });\n this.scrollActiveIntoView();\n });\n }\n\n /** Close the listbox; `refocus` returns focus to the button. */\n closeList(refocus = true): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeIndex.set(-1);\n if (refocus) queueMicrotask(() => this.buttonRef().focus({ preventScroll: true }));\n }\n\n protected choose(index: number): void {\n const slug = this.motions()[index];\n if (slug) this.value.set(slug);\n this.closeList();\n }\n\n private scrollActiveIntoView(): void {\n const i = this.activeIndex();\n if (i < 0) return;\n // getElementById rather than reaching into the composed Listbox's\n // DOM: Listbox exposes behaviour (focus()) and state (activeIndex),\n // not its rendered children, the same \"consumer owns the option\n // elements\" division of responsibility the headless component\n // documents for itself.\n const el = document.getElementById(this.optionId(i));\n // jsdom does not implement scrollIntoView; call it only if present.\n el?.scrollIntoView?.({ block: \"nearest\" });\n }\n\n // Arrow/Home/End/PageUp/PageDown/typeahead/Escape/Tab keyboard handling\n // inside the open list is owned by the composed `lily-listbox`'s\n // `navigation=\"active-descendant\"` mode (see\n // @lilydesignsystem/angular-headless); this component only decides\n // what open/close/choose/scroll mean, and keeps the highlighted option\n // in view whenever activeIndex changes.\n private readonly scrollOnActiveIndexChange = effect(() => {\n this.activeIndex();\n this.scrollActiveIntoView();\n });\n\n // ---------------------------------------------------------------\n // Keyboard\n // ---------------------------------------------------------------\n\n protected onButtonKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case \"ArrowDown\":\n case \"Enter\":\n case \" \":\n event.preventDefault();\n this.openList();\n break;\n case \"ArrowUp\":\n event.preventDefault();\n this.openList(this.motions().length - 1);\n break;\n }\n }\n\n /** `lily-listbox` Tab handling never prevents the key — focus goes to\n * the button FIRST so the browser's default Tab move computes from\n * the picker's position rather than from <body> (hiding the focused\n * list drops focus there, and the browser would otherwise compute the\n * default Tab move from the top of the document). */\n protected onListTabOut(): void {\n this.buttonRef().focus({ preventScroll: true });\n this.closeList(false);\n }\n\n protected onRootFocusOut(event: FocusEvent): void {\n const next = event.relatedTarget as Node | null;\n if (next && this.rootRef().nativeElement.contains(next)) return;\n this.closeList(false);\n }\n\n protected onDocumentClick(event: Event): void {\n if (!this.open()) return;\n const t = event.target as Node | null;\n if (t && !this.rootRef().nativeElement.contains(t)) this.closeList(false);\n }\n\n // ---------------------------------------------------------------\n // Apply\n // ---------------------------------------------------------------\n\n private applyMotion(slug: string): void {\n if (typeof document === \"undefined\" || !slug) return;\n (this.target() ?? document.documentElement).setAttribute(\n \"data-motion\",\n slug,\n );\n\n const sk = this.storageKey();\n if (sk) {\n try {\n localStorage.setItem(sk, slug);\n } catch {\n // ignore quota / privacy errors\n }\n }\n this.motionChange.emit(slug);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lilydesignsystem-angular-motion-picker.mjs","names":[],"sources":["../../motion-picker.component.ts"],"sourcesContent":["import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n contentChild,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n model,\n output,\n signal,\n TemplateRef,\n viewChild,\n} from \"@angular/core\";\nimport { IconButton, Listbox } from \"@lilydesignsystem/angular-headless\";\n\n/**\n * Default button icon: a bundled SVG (two pause bars), not a Unicode\n * character. Reversed 2026-09-16 from the font-dependent-glyph\n * convention (was U+23F8 PAUSE SIGN + U+FE0E, exported as `PAUSE_SIGN`\n * — removed, not renamed). \"Stop the moving parts\" still reads\n * directly from two bars; a bundled outline SVG matches the other four\n * picker icons as one consistent visual family regardless of the\n * consumer's fonts.\n */\n\n/** Context passed to a custom icon `<ng-template>` (the button icon). */\nexport type ChildArgs = {\n /** Currently selected motion slug. */\n value: string;\n /** Is the listbox open? */\n open: boolean;\n /** Resolve a slug to its display label. */\n labelFor: (motion: string) => string;\n};\n\n/**\n * Resolve a motion slug to its display label: each hyphen-separated\n * word title-cased, so a slug like \"no-preference\" renders as\n * \"No Preference\". Mirrors `sizeName` in text-size-picker and\n * `themeName` in theme-picker.\n */\nexport function motionName(motion: string): string {\n return motion\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/**\n * True when the platform reports a preference for reduced motion.\n * SSR-safe: `window`/`matchMedia` are absent on the server, so this\n * resolves to `false` there and the client re-derives it on mount.\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") {\n return false;\n }\n try {\n return window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n } catch {\n return false;\n }\n}\n\nlet uid = 0;\n/** Stable per-instance id prefix; SSR-safe (no Math.random / Date.now). */\nexport function nextMotionPickerId(): string {\n uid += 1;\n return `motion-picker-${uid}`;\n}\n\n/**\n * Optional marker for the projected icon template. Gives consumers typed\n * `let-` variables:\n *\n * ```html\n * <lily-motion-picker ...>\n * <ng-template lilyMotionPickerIcon let-args>{{ args.labelFor(args.value) }}</ng-template>\n * </lily-motion-picker>\n * ```\n *\n * The component queries any projected `<ng-template>`, so the marker is\n * for type-checking and readability, not for matching.\n */\n@Directive({\n selector: \"ng-template[lilyMotionPickerIcon]\",\n standalone: true,\n})\nexport class MotionPickerIcon {\n static ngTemplateContextGuard(\n _dir: MotionPickerIcon,\n _ctx: unknown,\n ): _ctx is ChildArgs & { $implicit: ChildArgs } {\n return true;\n }\n}\n\n/**\n * MotionPicker — `data-motion` reduced-motion picker.\n *\n * Renders an icon button that opens a WAI-ARIA APG listbox of motion\n * slugs. On every change the component sets `data-motion=\"{slug}\"` on\n * the document root (or on a consumer-supplied target), with optional\n * `localStorage` persistence. Its initial value defers to the\n * platform's `(prefers-reduced-motion: reduce)` media query before\n * falling back to a fixed default — the one behaviour difference from\n * its `theme-picker`/`text-size-picker` siblings. Ships no CSS; the\n * consumer decides what `[data-motion=\"reduce\"]` actually suppresses.\n * See `spec/index.md` for the full contract.\n */\n@Component({\n selector: \"lily-motion-picker\",\n standalone: true,\n imports: [NgTemplateOutlet, IconButton, Listbox],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n \"(document:click)\": \"onDocumentClick($event)\",\n },\n template: `\n <div\n #rootEl\n class=\"motion-picker {{ className() }}\"\n (focusout)=\"onRootFocusOut($event)\"\n >\n <input type=\"hidden\" [name]=\"name()\" [value]=\"value()\" />\n\n <lily-icon-button\n [disabled]=\"disabled()\"\n #buttonEl\n [label]=\"label()\"\n baseClass=\"motion-picker-button\"\n ariaHaspopup=\"listbox\"\n [ariaExpanded]=\"open()\"\n [ariaControls]=\"listId\"\n (click)=\"toggle(); hoverButton.set(false)\"\n (mouseenter)=\"onTooltipButtonEnter()\"\n (mouseleave)=\"hoverButton.set(false)\"\n (focusin)=\"onTooltipButtonFocusIn()\"\n (focusout)=\"onTooltipButtonFocusOut()\"\n (keydown)=\"onButtonKeydown($event); onTooltipKeydown($event)\"\n >\n @if (iconTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"childContext()\"\n />\n } @else {\n <svg\n class=\"motion-picker-icon\"\n viewBox=\"0 0 16 16\"\n width=\"1.05rem\"\n height=\"1.05rem\"\n aria-hidden=\"true\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.6\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M5 3v10M11 3v10\" />\n </svg>\n }\n </lily-icon-button>\n\n <!-- Purely visual: the same text is already the button's aria-label,\n so it is not wired with aria-describedby (that would announce\n the name twice). -->\n <div\n class=\"motion-picker-tooltip\"\n role=\"tooltip\"\n [id]=\"tooltipId\"\n [attr.hidden]=\"tooltipVisible() ? null : ''\"\n (mouseenter)=\"hoverTooltip.set(true)\"\n (mouseleave)=\"hoverTooltip.set(false)\"\n >{{ label() }}</div>\n\n <lily-listbox\n #listEl\n [label]=\"label()\"\n baseClass=\"motion-picker-list\"\n [elementId]=\"listId\"\n navigation=\"active-descendant\"\n [clamp]=\"true\"\n [typeahead]=\"true\"\n [pageSize]=\"10\"\n [(activeIndex)]=\"activeIndex\"\n [hidden]=\"!open()\"\n (activate)=\"choose($event)\"\n (escape)=\"closeList()\"\n (tabOut)=\"onListTabOut()\"\n >\n @for (motion of motions(); track motion; let i = $index) {\n <li\n class=\"motion-picker-option\"\n [id]=\"optionId(i)\"\n role=\"option\"\n [attr.aria-selected]=\"motion === value()\"\n [attr.data-active]=\"i === activeIndex() ? '' : null\"\n (click)=\"choose(i)\"\n >\n {{ labelFor(motion) }}\n </li>\n }\n </lily-listbox>\n </div>\n `,\n})\nexport class MotionPicker {\n readonly label = input.required<string>();\n readonly motions = input.required<string[]>();\n readonly value = model<string>(\"\");\n readonly defaultValue = input<string>(\"\");\n readonly storageKey = input<string>(\"\");\n readonly name = input<string>(\"motion\");\n readonly target = input<HTMLElement | null>(null);\n readonly motionLabels = input<Record<string, string>>({});\n readonly className = input<string>(\"\");\n readonly motionChange = output<string>();\n\n /** Projected icon template; replaces the default icon when supplied. */\n protected readonly iconTemplate = contentChild(TemplateRef);\n\n private readonly rootRef = viewChild.required<ElementRef<HTMLDivElement>>(\"rootEl\");\n // Angular resolves a template-ref-variable on a component tag to the\n // component INSTANCE by default (not its ElementRef) — exactly what's\n // needed to call the headless components' own public `focus()` methods.\n private readonly buttonRef = viewChild.required<IconButton>(\"buttonEl\");\n private readonly listRef = viewChild.required<Listbox>(\"listEl\");\n\n private readonly baseId = nextMotionPickerId();\n protected readonly listId = `${this.baseId}-list`;\n\n /** Is the popup open? Two-way bindable: `[(open)]`; `openChange` fires for each change. */\n readonly open = model<boolean>(false);\n /** Disables the button; an open popup closes. */\n readonly disabled = input<boolean>(false);\n private readonly closeWhenDisabled = effect(() => {\n if (this.disabled() && this.open()) this.open.set(false);\n });\n\n // Tooltip: shown while the pointer is over the button or the tooltip\n // itself (hoverable, WCAG 1.4.13) or while the button has keyboard\n // focus; Escape dismisses it without moving focus; never shown while\n // the popup is open, since the popup then explains the control.\n protected readonly tooltipId = `${this.baseId}-tooltip`;\n protected readonly hoverButton = signal(false);\n protected readonly hoverTooltip = signal(false);\n protected readonly focusButton = signal(false);\n protected readonly dismissed = signal(false);\n protected readonly tooltipVisible = computed(\n () =>\n !this.open() &&\n !this.dismissed() &&\n (this.hoverButton() || this.hoverTooltip() || this.focusButton()),\n );\n\n protected onTooltipButtonEnter(): void {\n this.hoverButton.set(true);\n this.dismissed.set(false);\n }\n\n protected onTooltipButtonFocusIn(): void {\n // Keyboard focus only: a mouse click also focuses the button in\n // Chromium, and the tooltip should not stick after a click.\n try {\n this.focusButton.set(this.buttonRef().element?.matches(\":focus-visible\") ?? false);\n } catch {\n this.focusButton.set(true); // engine without :focus-visible — err towards showing\n }\n }\n\n protected onTooltipButtonFocusOut(): void {\n this.focusButton.set(false);\n this.dismissed.set(false);\n }\n\n protected onTooltipKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\" && this.tooltipVisible()) this.dismissed.set(true);\n }\n\n // WCAG 1.4.13 \"dismissable\": while the tooltip is visible, Escape works\n // wherever focus is (hover-only tooltips have focus elsewhere). The\n // listener exists only while visible; the effect cleanup removes it on\n // hide and on destroy. No preventDefault/stopPropagation, focus untouched.\n private readonly tooltipEscapeListener = effect((onCleanup) => {\n if (!this.tooltipVisible() || typeof document === \"undefined\") return;\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") this.dismissed.set(true);\n };\n document.addEventListener(\"keydown\", onKey);\n onCleanup(() => document.removeEventListener(\"keydown\", onKey));\n });\n protected readonly activeIndex = signal(-1);\n\n protected readonly childContext = computed(() => {\n const args: ChildArgs = {\n value: this.value(),\n open: this.open(),\n labelFor: (motion: string) => this.labelFor(motion),\n };\n return { $implicit: args, ...args };\n });\n\n private initialised = false;\n\n constructor() {\n effect(() => {\n const current = this.value();\n\n if (!this.initialised) {\n this.initialised = true;\n let initial = current;\n\n const sk = this.storageKey();\n if (!initial && sk) {\n try {\n initial =\n (typeof localStorage !== \"undefined\"\n ? localStorage.getItem(sk)\n : null) ?? \"\";\n } catch {\n // ignore privacy errors\n }\n }\n\n if (!initial) {\n // Unlike text-size-picker's \"medium\" default, motion has a\n // real external signal to defer to: the platform's own\n // (prefers-reduced-motion: reduce) media query.\n const motions = this.motions();\n const dv = this.defaultValue();\n const osPreferred = prefersReducedMotion() ? \"reduce\" : \"no-preference\";\n initial =\n dv ||\n (motions.includes(osPreferred) ? osPreferred : undefined) ||\n motions[0] ||\n \"\";\n }\n\n if (initial && initial !== current) {\n this.value.set(initial);\n return;\n }\n }\n\n if (current) this.applyMotion(current);\n });\n }\n\n protected optionId(index: number): string {\n return `${this.baseId}-option-${index}`;\n }\n\n labelFor(motion: string): string {\n const labels = this.motionLabels();\n if (motion in labels) return labels[motion];\n return motionName(motion);\n }\n\n // ---------------------------------------------------------------\n // Open / close\n // ---------------------------------------------------------------\n\n /** Under zoneless change detection the signal write that un-hides the\n * list has not reached the DOM when a microtask runs, so focusing the\n * still-hidden list fails silently and Escape lands on the button.\n * Flushing detection first is the Angular equivalent of Svelte's\n * synchronous update (same fix the date-time-picker port recorded). */\n private readonly cdr = inject(ChangeDetectorRef);\n\n protected toggle(): void {\n if (this.open()) this.closeList();\n else this.openList();\n }\n\n /** Open the listbox, activating `startIndex` (default: the selection). */\n openList(startIndex?: number): void {\n const selected = this.motions().indexOf(this.value());\n // An empty list has no option to activate; -1 keeps\n // aria-activedescendant off rather than pointing at an id that\n // does not exist.\n this.activeIndex.set(\n this.motions().length === 0 ? -1 : (startIndex ?? (selected >= 0 ? selected : 0)),\n );\n this.open.set(true);\n // Focus moves to the listbox; the active option is conveyed via\n // aria-activedescendant, per the APG listbox pattern.\n this.cdr.detectChanges();\n queueMicrotask(() => {\n this.listRef().focus({ preventScroll: true });\n this.scrollActiveIntoView();\n });\n }\n\n /** Close the listbox; `refocus` returns focus to the button. */\n closeList(refocus = true): void {\n if (!this.open()) return;\n this.open.set(false);\n this.activeIndex.set(-1);\n if (refocus) queueMicrotask(() => this.buttonRef().focus({ preventScroll: true }));\n }\n\n protected choose(index: number): void {\n const slug = this.motions()[index];\n if (slug) this.value.set(slug);\n this.closeList();\n }\n\n private scrollActiveIntoView(): void {\n const i = this.activeIndex();\n if (i < 0) return;\n // getElementById rather than reaching into the composed Listbox's\n // DOM: Listbox exposes behaviour (focus()) and state (activeIndex),\n // not its rendered children, the same \"consumer owns the option\n // elements\" division of responsibility the headless component\n // documents for itself.\n const el = document.getElementById(this.optionId(i));\n // jsdom does not implement scrollIntoView; call it only if present.\n el?.scrollIntoView?.({ block: \"nearest\" });\n }\n\n // Arrow/Home/End/PageUp/PageDown/typeahead/Escape/Tab keyboard handling\n // inside the open list is owned by the composed `lily-listbox`'s\n // `navigation=\"active-descendant\"` mode (see\n // @lilydesignsystem/angular-headless); this component only decides\n // what open/close/choose/scroll mean, and keeps the highlighted option\n // in view whenever activeIndex changes.\n private readonly scrollOnActiveIndexChange = effect(() => {\n this.activeIndex();\n this.scrollActiveIntoView();\n });\n\n // ---------------------------------------------------------------\n // Keyboard\n // ---------------------------------------------------------------\n\n protected onButtonKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case \"ArrowDown\":\n case \"Enter\":\n case \" \":\n event.preventDefault();\n this.openList();\n break;\n case \"ArrowUp\":\n event.preventDefault();\n this.openList(this.motions().length - 1);\n break;\n }\n }\n\n /** `lily-listbox` Tab handling never prevents the key — focus goes to\n * the button FIRST so the browser's default Tab move computes from\n * the picker's position rather than from <body> (hiding the focused\n * list drops focus there, and the browser would otherwise compute the\n * default Tab move from the top of the document). */\n protected onListTabOut(): void {\n this.buttonRef().focus({ preventScroll: true });\n this.closeList(false);\n }\n\n protected onRootFocusOut(event: FocusEvent): void {\n const next = event.relatedTarget as Node | null;\n if (next && this.rootRef().nativeElement.contains(next)) return;\n this.closeList(false);\n }\n\n protected onDocumentClick(event: Event): void {\n if (!this.open()) return;\n const t = event.target as Node | null;\n if (t && !this.rootRef().nativeElement.contains(t)) this.closeList(false);\n }\n\n // ---------------------------------------------------------------\n // Apply\n // ---------------------------------------------------------------\n\n private applyMotion(slug: string): void {\n if (typeof document === \"undefined\" || !slug) return;\n (this.target() ?? document.documentElement).setAttribute(\"data-motion\", slug);\n\n const sk = this.storageKey();\n if (sk) {\n try {\n localStorage.setItem(sk, slug);\n } catch {\n // ignore quota / privacy errors\n }\n }\n this.motionChange.emit(slug);\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lilydesignsystem/angular-motion-picker",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"engines": {
|
|
5
|
-
"node": "
|
|
5
|
+
"node": ">=26"
|
|
6
6
|
},
|
|
7
7
|
"description": "Lily Design System Angular 20 motion (reduced-motion) picker: an icon button opening an APG listbox that sets data-motion on the document, defaulting to the OS's own prefers-reduced-motion signal. Headless, SSR-safe, no CSS.",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@lilydesignsystem/angular-headless": "^0.
|
|
9
|
+
"@lilydesignsystem/angular-headless": "^0.8.0",
|
|
10
10
|
"tslib": "^2.3.0"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
|
-
"@angular/
|
|
14
|
-
"@angular/
|
|
13
|
+
"@angular/common": ">=20.0.0 <23.0.0",
|
|
14
|
+
"@angular/core": ">=20.0.0 <23.0.0"
|
|
15
15
|
},
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"keywords": [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lilydesignsystem-angular-motion-picker.d.ts","names":[],"sources":["../../motion-picker.component.ts"],"mappings":";;;;;;;;;;;;KA+BY;;
|
|
1
|
+
{"version":3,"file":"lilydesignsystem-angular-motion-picker.d.ts","names":[],"sources":["../../motion-picker.component.ts"],"mappings":";;;;;;;;;;;;KA+BY;;EAER;;EAEA;;EAEA,WAAW;;;;;;;;wBASC,WAAW;;;;;;wBAYX;;wBAaA;;;;;;;;;;;;;;qBAsBH;SACF,uBACH,MAAM,kBACN,gBACD,QAAQ;IAAc,WAAW;;SAJ3B,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;;;;;;;;;;;;;;;qBAuHA;WACA,0CAAK;WACL,4CAAO;WACP,0CAAK;WACL,iDAAY;WACZ,+CAAU;WACV,yCAAI;WACJ,2CAAM,YAAA;WACN,iDAAY,YAAA;WACZ,8CAAS;WACT,uDAAY;;qBAGF,gFAAY,OAAA;mBAEd;mBAIA;mBACA;mBAEA;qBACE;;WAGV,yCAAI;;WAEJ,6CAAQ;mBACA;qBAQE;qBACA,+EAAW;qBACX,gFAAY;qBACZ,+EAAW;qBACX,6EAAS;qBACT,kFAAc;YAOvB;YAKA;YAUA;YAKA,iBAAiB,OAAO;mBAQjB;qBAQE,+EAAW;qBAEX,gFAAY;;IA1QxB;;IAED;;IAEI,WAAC;;;UA+QH;;YA8CE,SAAS;EAInB,SAAS;;;;;;mBAeQ;YAEP;;EAMV,SAAS;;EAmBT,UAAU;YAOA,OAAO;UAMT;mBAmBS;YASP,gBAAgB,OAAO;;;;;;YAoBvB;YAKA,eAAe,OAAO;YAMtB,gBAAgB,OAAO;UAUzB;SA9QC,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAY;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;IAAA;IAAA;IAAA"}
|