@signality/cdk-interop 0.0.1-alpha.2 → 0.0.1-alpha.4
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/fesm2022/signality-cdk-interop-focus-monitor.mjs +2 -2
- package/fesm2022/signality-cdk-interop-focus-monitor.mjs.map +1 -1
- package/fesm2022/signality-cdk-interop-live-announcer.mjs +2 -2
- package/fesm2022/signality-cdk-interop-live-announcer.mjs.map +1 -1
- package/focus-monitor/index.d.ts +23 -5
- package/live-announcer/index.d.ts +30 -6
- package/package.json +3 -3
|
@@ -4,7 +4,7 @@ import { onDisconnect } from '@signality/core';
|
|
|
4
4
|
import { setupContext, NOOP_FN, constSignal, toElement } from '@signality/core/internal';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Signal-based wrapper around the [Angular CDK](https://material.angular.io/cdk/a11y/overview)
|
|
7
|
+
* Signal-based wrapper around the [Angular CDK FocusMonitor](https://material.angular.io/cdk/a11y/overview#focusmonitor).
|
|
8
8
|
*
|
|
9
9
|
* @param target - Target element to monitor
|
|
10
10
|
* @param options - Optional configuration
|
|
@@ -57,7 +57,7 @@ function focusMonitor(target, options) {
|
|
|
57
57
|
cdkMonitor.stopMonitoring(el);
|
|
58
58
|
};
|
|
59
59
|
const focusVia = (origin, options) => {
|
|
60
|
-
const el = toElement(target);
|
|
60
|
+
const el = toElement.untracked(target);
|
|
61
61
|
if (!el) {
|
|
62
62
|
if (ngDevMode) {
|
|
63
63
|
console.warn('[focusMonitor] Cannot focus: element is not available');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signality-cdk-interop-focus-monitor.mjs","sources":["../../../projects/cdk-interop/focus-monitor/index.ts","../../../projects/cdk-interop/focus-monitor/signality-cdk-interop-focus-monitor.ts"],"sourcesContent":["import {\n afterRenderEffect,\n type EffectCleanupRegisterFn,\n inject,\n type Signal,\n signal,\n} from '@angular/core';\nimport { FocusMonitor, type FocusOrigin } from '@angular/cdk/a11y';\nimport type { Subscription } from 'rxjs';\nimport { MaybeElementSignal, onDisconnect, WithInjector } from '@signality/core';\nimport { constSignal, NOOP_FN, setupContext, toElement } from '@signality/core/internal';\n\nexport interface FocusMonitorOptions extends WithInjector {\n /**\n *
|
|
1
|
+
{"version":3,"file":"signality-cdk-interop-focus-monitor.mjs","sources":["../../../projects/cdk-interop/focus-monitor/index.ts","../../../projects/cdk-interop/focus-monitor/signality-cdk-interop-focus-monitor.ts"],"sourcesContent":["import {\n afterRenderEffect,\n type EffectCleanupRegisterFn,\n inject,\n type Signal,\n signal,\n} from '@angular/core';\nimport { FocusMonitor, type FocusOrigin } from '@angular/cdk/a11y';\nimport type { Subscription } from 'rxjs';\nimport { MaybeElementSignal, onDisconnect, WithInjector } from '@signality/core';\nimport { constSignal, NOOP_FN, setupContext, toElement } from '@signality/core/internal';\n\nexport interface FocusMonitorOptions extends WithInjector {\n /**\n * Whether to also monitor focus changes within child elements of the target.\n *\n * @default false\n * @see [FocusMonitor on Angular CDK](https://material.angular.io/cdk/a11y/overview#focusmonitor)\n */\n readonly checkChildren?: boolean;\n}\n\nexport interface FocusMonitorRef {\n /**\n * Whether the target element (or any of its children when `checkChildren` is `true`) is focused.\n */\n readonly isFocused: Signal<boolean>;\n\n /**\n * How the element received focus. One of:\n * - `'mouse'` — focused via mouse click\n * - `'keyboard'` — focused via keyboard navigation\n * - `'touch'` — focused via touch interaction\n * - `'program'` — focused programmatically (e.g. via `focusVia`)\n * - `null` — element is not focused\n *\n * @see [FocusOrigin on Angular CDK](https://material.angular.io/cdk/a11y/api#FocusOrigin)\n */\n readonly origin: Signal<FocusOrigin>;\n\n /**\n * Programmatically focus the target element with a specific origin.\n * The `origin` will be reflected in the `origin` signal after focusing.\n *\n * @see [FocusMonitor.focusVia() on Angular CDK](https://material.angular.io/cdk/a11y/api#FocusMonitor)\n */\n readonly focusVia: (origin: FocusOrigin, options?: FocusOptions) => void;\n}\n\n/**\n * Signal-based wrapper around the [Angular CDK FocusMonitor](https://material.angular.io/cdk/a11y/overview#focusmonitor).\n *\n * @param target - Target element to monitor\n * @param options - Optional configuration\n * @returns A FocusMonitorRef with focus state signals and control methods\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <button #btn [class.focused]=\"focus.isFocused()\">\n * Click me\n * @if (focus.origin(); as origin) {\n * <span>({{ origin }})</span>\n * }\n * </button>\n * <button (click)=\"focus.focusVia('program')\">Focus programmatically</button>\n * `\n * })\n * class FocusComponent {\n * readonly btn = viewChild<ElementRef>('btn');\n * readonly focus = focusMonitor(this.btn);\n * }\n * ```\n */\nexport function focusMonitor(\n target: MaybeElementSignal<HTMLElement>,\n options?: FocusMonitorOptions\n): FocusMonitorRef {\n const { runInContext } = setupContext(options?.injector, focusMonitor);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return {\n origin: constSignal(null),\n isFocused: constSignal(false),\n focusVia: NOOP_FN,\n };\n }\n\n const cdkMonitor = inject(FocusMonitor);\n\n const origin = signal<FocusOrigin>(null);\n const isFocused = signal(false);\n\n let subscription: Subscription | undefined;\n\n const startMonitoring = (el: HTMLElement) => {\n subscription?.unsubscribe();\n\n subscription = cdkMonitor.monitor(el, options?.checkChildren).subscribe(focusOrigin => {\n origin.set(focusOrigin);\n isFocused.set(focusOrigin !== null);\n });\n };\n\n const stopMonitoring = (el: HTMLElement) => {\n origin.set(null);\n isFocused.set(false);\n subscription?.unsubscribe();\n cdkMonitor.stopMonitoring(el);\n };\n\n const focusVia = (origin: FocusOrigin, options?: FocusOptions) => {\n const el = toElement.untracked(target);\n\n if (!el) {\n if (ngDevMode) {\n console.warn('[focusMonitor] Cannot focus: element is not available');\n }\n return;\n }\n\n cdkMonitor.focusVia(el, origin, options);\n };\n\n const setupMonitoring = (onCleanup: EffectCleanupRegisterFn) => {\n const el = toElement(target);\n\n if (el) {\n startMonitoring(el);\n onCleanup(() => stopMonitoring(el));\n }\n };\n\n onCleanup(() => subscription?.unsubscribe());\n\n afterRenderEffect({ read: setupMonitoring });\n\n onDisconnect(target, stopMonitoring);\n\n return {\n origin: origin.asReadonly(),\n isFocused: isFocused.asReadonly(),\n focusVia,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAiDA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AACG,SAAU,YAAY,CAC1B,MAAuC,EACvC,OAA6B,EAAA;AAE7B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC;IAEtE,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;YACZ,OAAO;AACL,gBAAA,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC;AACzB,gBAAA,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;AAC7B,gBAAA,QAAQ,EAAE,OAAO;aAClB;QACH;AAEA,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC;AAEvC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAc,IAAI,kDAAC;AACxC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC;AAE/B,QAAA,IAAI,YAAsC;AAE1C,QAAA,MAAM,eAAe,GAAG,CAAC,EAAe,KAAI;YAC1C,YAAY,EAAE,WAAW,EAAE;AAE3B,YAAA,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,SAAS,CAAC,WAAW,IAAG;AACpF,gBAAA,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;AACvB,gBAAA,SAAS,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC;AACrC,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;AAED,QAAA,MAAM,cAAc,GAAG,CAAC,EAAe,KAAI;AACzC,YAAA,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;AAChB,YAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YACpB,YAAY,EAAE,WAAW,EAAE;AAC3B,YAAA,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;AAC/B,QAAA,CAAC;AAED,QAAA,MAAM,QAAQ,GAAG,CAAC,MAAmB,EAAE,OAAsB,KAAI;YAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC;YAEtC,IAAI,CAAC,EAAE,EAAE;gBACP,IAAI,SAAS,EAAE;AACb,oBAAA,OAAO,CAAC,IAAI,CAAC,uDAAuD,CAAC;gBACvE;gBACA;YACF;YAEA,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC;AAC1C,QAAA,CAAC;AAED,QAAA,MAAM,eAAe,GAAG,CAAC,SAAkC,KAAI;AAC7D,YAAA,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC;YAE5B,IAAI,EAAE,EAAE;gBACN,eAAe,CAAC,EAAE,CAAC;gBACnB,SAAS,CAAC,MAAM,cAAc,CAAC,EAAE,CAAC,CAAC;YACrC;AACF,QAAA,CAAC;QAED,SAAS,CAAC,MAAM,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5C,QAAA,iBAAiB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;AAE5C,QAAA,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC;QAEpC,OAAO;AACL,YAAA,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE;AAC3B,YAAA,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE;YACjC,QAAQ;SACT;AACH,IAAA,CAAC,CAAC;AACJ;;ACnJA;;AAEG;;;;"}
|
|
@@ -3,7 +3,7 @@ import { LiveAnnouncer } from '@angular/cdk/a11y';
|
|
|
3
3
|
import { setupContext, NOOP_FN, constSignal } from '@signality/core/internal';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Signal-based wrapper around the [Angular CDK](https://material.angular.io/cdk/a11y/overview)
|
|
6
|
+
* Signal-based wrapper around the [Angular CDK LiveAnnouncer](https://material.angular.io/cdk/a11y/overview#liveannouncer).
|
|
7
7
|
*
|
|
8
8
|
* @param options - Optional configuration
|
|
9
9
|
* @returns A LiveAnnouncerRef with announcement methods and last message signal
|
|
@@ -21,7 +21,7 @@ import { setupContext, NOOP_FN, constSignal } from '@signality/core/internal';
|
|
|
21
21
|
* </div>
|
|
22
22
|
* `
|
|
23
23
|
* })
|
|
24
|
-
* class
|
|
24
|
+
* class ShoppingCart {
|
|
25
25
|
* readonly announcer = liveAnnouncer();
|
|
26
26
|
*
|
|
27
27
|
* addToCart() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signality-cdk-interop-live-announcer.mjs","sources":["../../../projects/cdk-interop/live-announcer/index.ts","../../../projects/cdk-interop/live-announcer/signality-cdk-interop-live-announcer.ts"],"sourcesContent":["import { inject, signal, type Signal } from '@angular/core';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { WithInjector } from '@signality/core';\nimport { constSignal, NOOP_FN, setupContext } from '@signality/core/internal';\n\nexport type AriaLivePoliteness = 'polite' | 'assertive' | 'off';\n\nexport interface LiveAnnouncerOptions extends WithInjector {\n /**\n * Default politeness level
|
|
1
|
+
{"version":3,"file":"signality-cdk-interop-live-announcer.mjs","sources":["../../../projects/cdk-interop/live-announcer/index.ts","../../../projects/cdk-interop/live-announcer/signality-cdk-interop-live-announcer.ts"],"sourcesContent":["import { inject, signal, type Signal } from '@angular/core';\nimport { LiveAnnouncer } from '@angular/cdk/a11y';\nimport { WithInjector } from '@signality/core';\nimport { constSignal, NOOP_FN, setupContext } from '@signality/core/internal';\n\n/**\n * Controls how urgently a screen reader will announce a message.\n *\n * - `'polite'` — waits for the user to be idle before announcing (recommended default).\n * - `'assertive'` — announces immediately, interrupting any speech in progress.\n * - `'off'` — no announcement; `announce()` is a no-op when this level is used.\n *\n * @see [aria-live on MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live)\n * @see [AriaLivePoliteness on Angular CDK](https://material.angular.io/cdk/a11y/api#AriaLivePoliteness)\n */\nexport type AriaLivePoliteness = 'polite' | 'assertive' | 'off';\n\nexport interface LiveAnnouncerOptions extends WithInjector {\n /**\n * Default politeness level applied when `announce()` is called without an explicit level.\n *\n * @default 'polite'\n * @see [LiveAnnouncer on Angular CDK](https://material.angular.io/cdk/a11y/overview#liveannouncer)\n */\n readonly defaultPoliteness?: AriaLivePoliteness;\n}\n\nexport interface LiveAnnouncerRef {\n /**\n * The last message successfully announced to screen readers.\n * `null` before any announcement or after `clear()` is called.\n */\n readonly lastMessage: Signal<string | null>;\n\n /**\n * Announce a message to screen readers via an ARIA live region.\n * No-op when `politeness` resolves to `'off'`.\n *\n * @see [LiveAnnouncer.announce() on Angular CDK](https://material.angular.io/cdk/a11y/api#LiveAnnouncer)\n */\n readonly announce: (message: string, politeness?: AriaLivePoliteness) => void;\n\n /**\n * Clear all pending announcements from the ARIA live region and reset `lastMessage` to `null`.\n *\n * @see [LiveAnnouncer.clear() on Angular CDK](https://material.angular.io/cdk/a11y/api#LiveAnnouncer)\n */\n readonly clear: () => void;\n}\n\n/**\n * Signal-based wrapper around the [Angular CDK LiveAnnouncer](https://material.angular.io/cdk/a11y/overview#liveannouncer).\n *\n * @param options - Optional configuration\n * @returns A LiveAnnouncerRef with announcement methods and last message signal\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <button (click)=\"addToCart()\">Add to cart</button>\n * <button (click)=\"announcer.clear()\">Clear Announcements</button>\n * @if (announcer.lastMessage(); as message) {\n * <p>Last: {{ message }}</p>\n * }\n * </div>\n * `\n * })\n * class ShoppingCart {\n * readonly announcer = liveAnnouncer();\n *\n * addToCart() {\n * this.announcer.announce('Item added to cart', 'polite');\n * }\n * }\n * ```\n */\nexport function liveAnnouncer(options?: LiveAnnouncerOptions): LiveAnnouncerRef {\n const { runInContext } = setupContext(options?.injector, liveAnnouncer);\n\n return runInContext(({ isServer }) => {\n if (isServer) {\n return {\n lastMessage: constSignal(null),\n announce: NOOP_FN,\n clear: NOOP_FN,\n };\n }\n\n const cdkLiveAnnouncer = inject(LiveAnnouncer);\n const defaultPoliteness = options?.defaultPoliteness ?? 'polite';\n\n const lastMessage = signal<string | null>(null);\n\n const announce = (message: string, politeness?: AriaLivePoliteness) => {\n const politenessLevel = politeness ?? defaultPoliteness;\n\n if (politenessLevel === 'off') {\n return;\n }\n\n cdkLiveAnnouncer.announce(message, politenessLevel as 'polite' | 'assertive').then(() => {\n lastMessage.set(message);\n });\n };\n\n const clear = () => {\n cdkLiveAnnouncer.clear();\n lastMessage.set(null);\n };\n\n return {\n lastMessage: lastMessage.asReadonly(),\n announce,\n clear,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAkDA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;AACG,SAAU,aAAa,CAAC,OAA8B,EAAA;AAC1D,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC;AAEvE,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;QACnC,IAAI,QAAQ,EAAE;YACZ,OAAO;AACL,gBAAA,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC;AAC9B,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,KAAK,EAAE,OAAO;aACf;QACH;AAEA,QAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,aAAa,CAAC;AAC9C,QAAA,MAAM,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,IAAI,QAAQ;AAEhE,QAAA,MAAM,WAAW,GAAG,MAAM,CAAgB,IAAI,uDAAC;AAE/C,QAAA,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,UAA+B,KAAI;AACpE,YAAA,MAAM,eAAe,GAAG,UAAU,IAAI,iBAAiB;AAEvD,YAAA,IAAI,eAAe,KAAK,KAAK,EAAE;gBAC7B;YACF;YAEA,gBAAgB,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAyC,CAAC,CAAC,IAAI,CAAC,MAAK;AACtF,gBAAA,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1B,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;QAED,MAAM,KAAK,GAAG,MAAK;YACjB,gBAAgB,CAAC,KAAK,EAAE;AACxB,YAAA,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AACvB,QAAA,CAAC;QAED,OAAO;AACL,YAAA,WAAW,EAAE,WAAW,CAAC,UAAU,EAAE;YACrC,QAAQ;YACR,KAAK;SACN;AACH,IAAA,CAAC,CAAC;AACJ;;ACtHA;;AAEG;;;;"}
|
package/focus-monitor/index.d.ts
CHANGED
|
@@ -3,21 +3,39 @@ import { type FocusOrigin } from '@angular/cdk/a11y';
|
|
|
3
3
|
import { MaybeElementSignal, WithInjector } from '@signality/core';
|
|
4
4
|
export interface FocusMonitorOptions extends WithInjector {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Whether to also monitor focus changes within child elements of the target.
|
|
7
|
+
*
|
|
7
8
|
* @default false
|
|
9
|
+
* @see [FocusMonitor on Angular CDK](https://material.angular.io/cdk/a11y/overview#focusmonitor)
|
|
8
10
|
*/
|
|
9
11
|
readonly checkChildren?: boolean;
|
|
10
12
|
}
|
|
11
13
|
export interface FocusMonitorRef {
|
|
12
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Whether the target element (or any of its children when `checkChildren` is `true`) is focused.
|
|
16
|
+
*/
|
|
13
17
|
readonly isFocused: Signal<boolean>;
|
|
14
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* How the element received focus. One of:
|
|
20
|
+
* - `'mouse'` — focused via mouse click
|
|
21
|
+
* - `'keyboard'` — focused via keyboard navigation
|
|
22
|
+
* - `'touch'` — focused via touch interaction
|
|
23
|
+
* - `'program'` — focused programmatically (e.g. via `focusVia`)
|
|
24
|
+
* - `null` — element is not focused
|
|
25
|
+
*
|
|
26
|
+
* @see [FocusOrigin on Angular CDK](https://material.angular.io/cdk/a11y/api#FocusOrigin)
|
|
27
|
+
*/
|
|
15
28
|
readonly origin: Signal<FocusOrigin>;
|
|
16
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Programmatically focus the target element with a specific origin.
|
|
31
|
+
* The `origin` will be reflected in the `origin` signal after focusing.
|
|
32
|
+
*
|
|
33
|
+
* @see [FocusMonitor.focusVia() on Angular CDK](https://material.angular.io/cdk/a11y/api#FocusMonitor)
|
|
34
|
+
*/
|
|
17
35
|
readonly focusVia: (origin: FocusOrigin, options?: FocusOptions) => void;
|
|
18
36
|
}
|
|
19
37
|
/**
|
|
20
|
-
* Signal-based wrapper around the [Angular CDK](https://material.angular.io/cdk/a11y/overview)
|
|
38
|
+
* Signal-based wrapper around the [Angular CDK FocusMonitor](https://material.angular.io/cdk/a11y/overview#focusmonitor).
|
|
21
39
|
*
|
|
22
40
|
* @param target - Target element to monitor
|
|
23
41
|
* @param options - Optional configuration
|
|
@@ -1,23 +1,47 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
2
|
import { WithInjector } from '@signality/core';
|
|
3
|
+
/**
|
|
4
|
+
* Controls how urgently a screen reader will announce a message.
|
|
5
|
+
*
|
|
6
|
+
* - `'polite'` — waits for the user to be idle before announcing (recommended default).
|
|
7
|
+
* - `'assertive'` — announces immediately, interrupting any speech in progress.
|
|
8
|
+
* - `'off'` — no announcement; `announce()` is a no-op when this level is used.
|
|
9
|
+
*
|
|
10
|
+
* @see [aria-live on MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-live)
|
|
11
|
+
* @see [AriaLivePoliteness on Angular CDK](https://material.angular.io/cdk/a11y/api#AriaLivePoliteness)
|
|
12
|
+
*/
|
|
3
13
|
export type AriaLivePoliteness = 'polite' | 'assertive' | 'off';
|
|
4
14
|
export interface LiveAnnouncerOptions extends WithInjector {
|
|
5
15
|
/**
|
|
6
|
-
* Default politeness level
|
|
16
|
+
* Default politeness level applied when `announce()` is called without an explicit level.
|
|
17
|
+
*
|
|
7
18
|
* @default 'polite'
|
|
19
|
+
* @see [LiveAnnouncer on Angular CDK](https://material.angular.io/cdk/a11y/overview#liveannouncer)
|
|
8
20
|
*/
|
|
9
21
|
readonly defaultPoliteness?: AriaLivePoliteness;
|
|
10
22
|
}
|
|
11
23
|
export interface LiveAnnouncerRef {
|
|
12
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The last message successfully announced to screen readers.
|
|
26
|
+
* `null` before any announcement or after `clear()` is called.
|
|
27
|
+
*/
|
|
13
28
|
readonly lastMessage: Signal<string | null>;
|
|
14
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Announce a message to screen readers via an ARIA live region.
|
|
31
|
+
* No-op when `politeness` resolves to `'off'`.
|
|
32
|
+
*
|
|
33
|
+
* @see [LiveAnnouncer.announce() on Angular CDK](https://material.angular.io/cdk/a11y/api#LiveAnnouncer)
|
|
34
|
+
*/
|
|
15
35
|
readonly announce: (message: string, politeness?: AriaLivePoliteness) => void;
|
|
16
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Clear all pending announcements from the ARIA live region and reset `lastMessage` to `null`.
|
|
38
|
+
*
|
|
39
|
+
* @see [LiveAnnouncer.clear() on Angular CDK](https://material.angular.io/cdk/a11y/api#LiveAnnouncer)
|
|
40
|
+
*/
|
|
17
41
|
readonly clear: () => void;
|
|
18
42
|
}
|
|
19
43
|
/**
|
|
20
|
-
* Signal-based wrapper around the [Angular CDK](https://material.angular.io/cdk/a11y/overview)
|
|
44
|
+
* Signal-based wrapper around the [Angular CDK LiveAnnouncer](https://material.angular.io/cdk/a11y/overview#liveannouncer).
|
|
21
45
|
*
|
|
22
46
|
* @param options - Optional configuration
|
|
23
47
|
* @returns A LiveAnnouncerRef with announcement methods and last message signal
|
|
@@ -35,7 +59,7 @@ export interface LiveAnnouncerRef {
|
|
|
35
59
|
* </div>
|
|
36
60
|
* `
|
|
37
61
|
* })
|
|
38
|
-
* class
|
|
62
|
+
* class ShoppingCart {
|
|
39
63
|
* readonly announcer = liveAnnouncer();
|
|
40
64
|
*
|
|
41
65
|
* addToCart() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signality/cdk-interop",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Vyacheslav Borodin <https://github.com/vs-borodin>",
|
|
6
6
|
"description": "Signal-based utilities for Angular CDK",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"homepage": "https://signality.dev",
|
|
22
22
|
"sideEffects": false,
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@angular/core": ">=
|
|
25
|
-
"@angular/cdk": ">=
|
|
24
|
+
"@angular/core": ">=20.0.0",
|
|
25
|
+
"@angular/cdk": ">=20.0.0",
|
|
26
26
|
"@signality/core": ">=0.0.1-alpha.1",
|
|
27
27
|
"rxjs": ">=7.8.1"
|
|
28
28
|
},
|