@lilydesignsystem/angular-motion-picker 0.2.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 +83 -0
- package/fesm2022/lilydesignsystem-angular-motion-picker.mjs +48 -8
- package/fesm2022/lilydesignsystem-angular-motion-picker.mjs.map +1 -1
- package/package.json +6 -6
- package/types/lilydesignsystem-angular-motion-picker.d.ts +34 -19
- package/types/lilydesignsystem-angular-motion-picker.d.ts.map +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# MotionPicker (Angular helper)
|
|
2
|
+
|
|
3
|
+
A reusable Angular 20 headless **motion (reduced-motion) picker** — an
|
|
4
|
+
icon button that opens a WAI-ARIA APG listbox of motion-preference
|
|
5
|
+
slugs. On every change it sets `data-motion="{slug}"` on a target
|
|
6
|
+
element (default `document.documentElement`), optionally persisting
|
|
7
|
+
the choice to `localStorage`. Ships no CSS — the consumer decides what
|
|
8
|
+
`data-motion="reduce"` actually suppresses, e.g.:
|
|
9
|
+
|
|
10
|
+
```css
|
|
11
|
+
:root[data-motion="reduce"] * {
|
|
12
|
+
animation-duration: 0.001ms !important;
|
|
13
|
+
animation-iteration-count: 1 !important;
|
|
14
|
+
transition-duration: 0.001ms !important;
|
|
15
|
+
scroll-behavior: auto !important;
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Unlike its `theme-picker` and `text-size-picker` siblings, MotionPicker's
|
|
20
|
+
initial value defers to the platform's own
|
|
21
|
+
`(prefers-reduced-motion: reduce)` media query before falling back to
|
|
22
|
+
an arbitrary default.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { Component } from "@angular/core";
|
|
28
|
+
import { MotionPicker } from "@lilydesignsystem/angular-motion-picker";
|
|
29
|
+
|
|
30
|
+
@Component({
|
|
31
|
+
standalone: true,
|
|
32
|
+
imports: [MotionPicker],
|
|
33
|
+
template: `
|
|
34
|
+
<lily-motion-picker
|
|
35
|
+
label="Motion"
|
|
36
|
+
[motions]="['no-preference', 'reduce']"
|
|
37
|
+
[(value)]="motion"
|
|
38
|
+
storageKey="lily-motion"
|
|
39
|
+
/>
|
|
40
|
+
`,
|
|
41
|
+
})
|
|
42
|
+
export class Example {
|
|
43
|
+
motion = "";
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Inputs / Outputs
|
|
48
|
+
|
|
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
|
+
|
|
62
|
+
## Behaviour
|
|
63
|
+
|
|
64
|
+
Initial value resolves from `value` > storage > `defaultValue` > the
|
|
65
|
+
platform's `(prefers-reduced-motion: reduce)` preference (mapped to
|
|
66
|
+
`"reduce"` / `"no-preference"` if either is in `motions`) > `motions[0]`.
|
|
67
|
+
All DOM writes guard on `typeof document`, so the component is
|
|
68
|
+
SSR-safe.
|
|
69
|
+
|
|
70
|
+
## Accessibility
|
|
71
|
+
|
|
72
|
+
- WCAG 2.2 AAA target; directly supports 2.3.3 (Animation from
|
|
73
|
+
Interactions).
|
|
74
|
+
- APG listbox keyboard contract: arrows (clamped), `Home` / `End`,
|
|
75
|
+
`PageUp` / `PageDown` (by ten), typeahead with same-character
|
|
76
|
+
cycling, `Escape` discards, and `Tab` closes via the button so the
|
|
77
|
+
default Tab proceeds from the picker's position.
|
|
78
|
+
- `aria-label` carries the consumer-supplied accessible name.
|
|
79
|
+
- Default labels title-case the slug.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
Lily™ and Lily Design System™ are trademarks.
|
|
@@ -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: [{
|
|
@@ -92,7 +92,11 @@ var MotionPicker = class MotionPicker {
|
|
|
92
92
|
this.listRef = viewChild.required("listEl", ...ngDevMode ? [{ debugName: "listRef" }] : /* istanbul ignore next */ []);
|
|
93
93
|
this.baseId = nextMotionPickerId();
|
|
94
94
|
this.listId = `${this.baseId}-list`;
|
|
95
|
-
this.open =
|
|
95
|
+
this.open = model(false, ...ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []);
|
|
96
|
+
this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
|
|
97
|
+
this.closeWhenDisabled = effect(() => {
|
|
98
|
+
if (this.disabled() && this.open()) this.open.set(false);
|
|
99
|
+
}, ...ngDevMode ? [{ debugName: "closeWhenDisabled" }] : /* istanbul ignore next */ []);
|
|
96
100
|
this.tooltipId = `${this.baseId}-tooltip`;
|
|
97
101
|
this.hoverButton = signal(false, ...ngDevMode ? [{ debugName: "hoverButton" }] : /* istanbul ignore next */ []);
|
|
98
102
|
this.hoverTooltip = signal(false, ...ngDevMode ? [{ debugName: "hoverTooltip" }] : /* istanbul ignore next */ []);
|
|
@@ -225,7 +229,7 @@ var MotionPicker = class MotionPicker {
|
|
|
225
229
|
static {
|
|
226
230
|
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
227
231
|
minVersion: "12.0.0",
|
|
228
|
-
version: "22.2.
|
|
232
|
+
version: "22.2.4",
|
|
229
233
|
ngImport: i0,
|
|
230
234
|
type: MotionPicker,
|
|
231
235
|
deps: [],
|
|
@@ -235,7 +239,7 @@ var MotionPicker = class MotionPicker {
|
|
|
235
239
|
static {
|
|
236
240
|
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
237
241
|
minVersion: "17.0.0",
|
|
238
|
-
version: "22.2.
|
|
242
|
+
version: "22.2.4",
|
|
239
243
|
type: MotionPicker,
|
|
240
244
|
isStandalone: true,
|
|
241
245
|
selector: "lily-motion-picker",
|
|
@@ -302,11 +306,26 @@ var MotionPicker = class MotionPicker {
|
|
|
302
306
|
isSignal: true,
|
|
303
307
|
isRequired: false,
|
|
304
308
|
transformFunction: null
|
|
309
|
+
},
|
|
310
|
+
open: {
|
|
311
|
+
classPropertyName: "open",
|
|
312
|
+
publicName: "open",
|
|
313
|
+
isSignal: true,
|
|
314
|
+
isRequired: false,
|
|
315
|
+
transformFunction: null
|
|
316
|
+
},
|
|
317
|
+
disabled: {
|
|
318
|
+
classPropertyName: "disabled",
|
|
319
|
+
publicName: "disabled",
|
|
320
|
+
isSignal: true,
|
|
321
|
+
isRequired: false,
|
|
322
|
+
transformFunction: null
|
|
305
323
|
}
|
|
306
324
|
},
|
|
307
325
|
outputs: {
|
|
308
326
|
value: "valueChange",
|
|
309
|
-
motionChange: "motionChange"
|
|
327
|
+
motionChange: "motionChange",
|
|
328
|
+
open: "openChange"
|
|
310
329
|
},
|
|
311
330
|
host: { listeners: { "document:click": "onDocumentClick($event)" } },
|
|
312
331
|
queries: [{
|
|
@@ -349,6 +368,7 @@ var MotionPicker = class MotionPicker {
|
|
|
349
368
|
<input type="hidden" [name]="name()" [value]="value()" />
|
|
350
369
|
|
|
351
370
|
<lily-icon-button
|
|
371
|
+
[disabled]="disabled()"
|
|
352
372
|
#buttonEl
|
|
353
373
|
[label]="label()"
|
|
354
374
|
baseClass="motion-picker-button"
|
|
@@ -484,7 +504,7 @@ var MotionPicker = class MotionPicker {
|
|
|
484
504
|
};
|
|
485
505
|
i0.ɵɵngDeclareClassMetadata({
|
|
486
506
|
minVersion: "12.0.0",
|
|
487
|
-
version: "22.2.
|
|
507
|
+
version: "22.2.4",
|
|
488
508
|
ngImport: i0,
|
|
489
509
|
type: MotionPicker,
|
|
490
510
|
decorators: [{
|
|
@@ -508,6 +528,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
508
528
|
<input type="hidden" [name]="name()" [value]="value()" />
|
|
509
529
|
|
|
510
530
|
<lily-icon-button
|
|
531
|
+
[disabled]="disabled()"
|
|
511
532
|
#buttonEl
|
|
512
533
|
[label]="label()"
|
|
513
534
|
baseClass="motion-picker-button"
|
|
@@ -684,6 +705,25 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
684
705
|
listRef: [{
|
|
685
706
|
type: i0.ViewChild,
|
|
686
707
|
args: ["listEl", { isSignal: true }]
|
|
708
|
+
}],
|
|
709
|
+
open: [{
|
|
710
|
+
type: i0.Input,
|
|
711
|
+
args: [{
|
|
712
|
+
isSignal: true,
|
|
713
|
+
alias: "open",
|
|
714
|
+
required: false
|
|
715
|
+
}]
|
|
716
|
+
}, {
|
|
717
|
+
type: i0.Output,
|
|
718
|
+
args: ["openChange"]
|
|
719
|
+
}],
|
|
720
|
+
disabled: [{
|
|
721
|
+
type: i0.Input,
|
|
722
|
+
args: [{
|
|
723
|
+
isSignal: true,
|
|
724
|
+
alias: "disabled",
|
|
725
|
+
required: false
|
|
726
|
+
}]
|
|
687
727
|
}]
|
|
688
728
|
}
|
|
689
729
|
});
|
|
@@ -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 Directive,\n ElementRef,\n TemplateRef,\n computed,\n contentChild,\n effect,\n inject,\n input,\n model,\n output,\n signal,\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 #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 protected readonly open = signal(false);\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
|
+
"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": [
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "MIT OR Apache-2.0 OR GPL-2.0-only OR GPL-3.0-only OR BSD-3-Clause",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/LilyDesignSystem/lily-design-system
|
|
30
|
+
"url": "git+https://github.com/LilyDesignSystem/lily-design-system.git",
|
|
31
31
|
"directory": "lily-design-system-angular-motion-picker"
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://lilydesignsystem.com/",
|
|
@@ -67,37 +67,41 @@ export declare class MotionPickerIcon {
|
|
|
67
67
|
* See `spec/index.md` for the full contract.
|
|
68
68
|
*/
|
|
69
69
|
export declare class MotionPicker {
|
|
70
|
-
readonly label: import("@angular/core").InputSignal<string>;
|
|
71
|
-
readonly motions: import("@angular/core").InputSignal<string[]>;
|
|
72
|
-
readonly value: import("@angular/core").ModelSignal<string>;
|
|
73
|
-
readonly defaultValue: import("@angular/core").InputSignal<string>;
|
|
74
|
-
readonly storageKey: import("@angular/core").InputSignal<string>;
|
|
75
|
-
readonly name: import("@angular/core").InputSignal<string>;
|
|
76
|
-
readonly target: import("@angular/core").InputSignal<HTMLElement | null>;
|
|
77
|
-
readonly motionLabels: import("@angular/core").InputSignal<Record<string, string>>;
|
|
78
|
-
readonly className: import("@angular/core").InputSignal<string>;
|
|
79
|
-
readonly motionChange: import("@angular/core").OutputEmitterRef<string>;
|
|
70
|
+
readonly label: import("@angular/core/types/core").InputSignal<string>;
|
|
71
|
+
readonly motions: import("@angular/core/types/core").InputSignal<string[]>;
|
|
72
|
+
readonly value: import("@angular/core/types/core").ModelSignal<string>;
|
|
73
|
+
readonly defaultValue: import("@angular/core/types/core").InputSignal<string>;
|
|
74
|
+
readonly storageKey: import("@angular/core/types/core").InputSignal<string>;
|
|
75
|
+
readonly name: import("@angular/core/types/core").InputSignal<string>;
|
|
76
|
+
readonly target: import("@angular/core/types/core").InputSignal<HTMLElement | null>;
|
|
77
|
+
readonly motionLabels: import("@angular/core/types/core").InputSignal<Record<string, string>>;
|
|
78
|
+
readonly className: import("@angular/core/types/core").InputSignal<string>;
|
|
79
|
+
readonly motionChange: import("@angular/core/types/_api-chunk").OutputEmitterRef<string>;
|
|
80
80
|
/** Projected icon template; replaces the default icon when supplied. */
|
|
81
|
-
protected readonly iconTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
81
|
+
protected readonly iconTemplate: import("@angular/core/types/_chrome_dev_tools_performance-chunk").Signal<TemplateRef<any> | undefined>;
|
|
82
82
|
private readonly rootRef;
|
|
83
83
|
private readonly buttonRef;
|
|
84
84
|
private readonly listRef;
|
|
85
85
|
private readonly baseId;
|
|
86
86
|
protected readonly listId: string;
|
|
87
|
-
|
|
87
|
+
/** Is the popup open? Two-way bindable: `[(open)]`; `openChange` fires for each change. */
|
|
88
|
+
readonly open: import("@angular/core/types/core").ModelSignal<boolean>;
|
|
89
|
+
/** Disables the button; an open popup closes. */
|
|
90
|
+
readonly disabled: import("@angular/core/types/core").InputSignal<boolean>;
|
|
91
|
+
private readonly closeWhenDisabled;
|
|
88
92
|
protected readonly tooltipId: string;
|
|
89
|
-
protected readonly hoverButton: import("@angular/core").WritableSignal<boolean>;
|
|
90
|
-
protected readonly hoverTooltip: import("@angular/core").WritableSignal<boolean>;
|
|
91
|
-
protected readonly focusButton: import("@angular/core").WritableSignal<boolean>;
|
|
92
|
-
protected readonly dismissed: import("@angular/core").WritableSignal<boolean>;
|
|
93
|
-
protected readonly tooltipVisible: import("@angular/core").Signal<boolean>;
|
|
93
|
+
protected readonly hoverButton: import("@angular/core/types/_chrome_dev_tools_performance-chunk").WritableSignal<boolean>;
|
|
94
|
+
protected readonly hoverTooltip: import("@angular/core/types/_chrome_dev_tools_performance-chunk").WritableSignal<boolean>;
|
|
95
|
+
protected readonly focusButton: import("@angular/core/types/_chrome_dev_tools_performance-chunk").WritableSignal<boolean>;
|
|
96
|
+
protected readonly dismissed: import("@angular/core/types/_chrome_dev_tools_performance-chunk").WritableSignal<boolean>;
|
|
97
|
+
protected readonly tooltipVisible: import("@angular/core/types/_chrome_dev_tools_performance-chunk").Signal<boolean>;
|
|
94
98
|
protected onTooltipButtonEnter(): void;
|
|
95
99
|
protected onTooltipButtonFocusIn(): void;
|
|
96
100
|
protected onTooltipButtonFocusOut(): void;
|
|
97
101
|
protected onTooltipKeydown(event: KeyboardEvent): void;
|
|
98
102
|
private readonly tooltipEscapeListener;
|
|
99
|
-
protected readonly activeIndex: import("@angular/core").WritableSignal<number>;
|
|
100
|
-
protected readonly childContext: import("@angular/core").Signal<{
|
|
103
|
+
protected readonly activeIndex: import("@angular/core/types/_chrome_dev_tools_performance-chunk").WritableSignal<number>;
|
|
104
|
+
protected readonly childContext: import("@angular/core/types/_chrome_dev_tools_performance-chunk").Signal<{
|
|
101
105
|
/** Currently selected motion slug. */
|
|
102
106
|
value: string;
|
|
103
107
|
/** Is the listbox open? */
|
|
@@ -181,9 +185,20 @@ export declare class MotionPicker {
|
|
|
181
185
|
"required": false;
|
|
182
186
|
"isSignal": true;
|
|
183
187
|
};
|
|
188
|
+
"open": {
|
|
189
|
+
"alias": "open";
|
|
190
|
+
"required": false;
|
|
191
|
+
"isSignal": true;
|
|
192
|
+
};
|
|
193
|
+
"disabled": {
|
|
194
|
+
"alias": "disabled";
|
|
195
|
+
"required": false;
|
|
196
|
+
"isSignal": true;
|
|
197
|
+
};
|
|
184
198
|
}, {
|
|
185
199
|
"value": "valueChange";
|
|
186
200
|
"motionChange": "motionChange";
|
|
201
|
+
"open": "openChange";
|
|
187
202
|
}, ["iconTemplate"], never, true, never>;
|
|
188
203
|
}
|
|
189
204
|
export type { ChildArgs };
|
|
@@ -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"}
|