@chenzy-design/core 0.1.0
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/LICENSE +21 -0
- package/dist/back-top.d.ts +16 -0
- package/dist/back-top.d.ts.map +1 -0
- package/dist/back-top.js +29 -0
- package/dist/back-top.js.map +1 -0
- package/dist/back-top.test.d.ts +2 -0
- package/dist/back-top.test.d.ts.map +1 -0
- package/dist/back-top.test.js +44 -0
- package/dist/back-top.test.js.map +1 -0
- package/dist/banner.d.ts +19 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +20 -0
- package/dist/banner.js.map +1 -0
- package/dist/banner.test.d.ts +2 -0
- package/dist/banner.test.d.ts.map +1 -0
- package/dist/banner.test.js +29 -0
- package/dist/banner.test.js.map +1 -0
- package/dist/breakpoints.d.ts +30 -0
- package/dist/breakpoints.d.ts.map +1 -0
- package/dist/breakpoints.js +45 -0
- package/dist/breakpoints.js.map +1 -0
- package/dist/breakpoints.test.d.ts +2 -0
- package/dist/breakpoints.test.d.ts.map +1 -0
- package/dist/breakpoints.test.js +46 -0
- package/dist/breakpoints.test.js.map +1 -0
- package/dist/calendar.d.ts +63 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +94 -0
- package/dist/calendar.js.map +1 -0
- package/dist/calendar.test.d.ts +2 -0
- package/dist/calendar.test.d.ts.map +1 -0
- package/dist/calendar.test.js +88 -0
- package/dist/calendar.test.js.map +1 -0
- package/dist/cascader.d.ts +64 -0
- package/dist/cascader.d.ts.map +1 -0
- package/dist/cascader.js +79 -0
- package/dist/cascader.js.map +1 -0
- package/dist/cascader.test.d.ts +2 -0
- package/dist/cascader.test.d.ts.map +1 -0
- package/dist/cascader.test.js +107 -0
- package/dist/cascader.test.js.map +1 -0
- package/dist/color.d.ts +70 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +217 -0
- package/dist/color.js.map +1 -0
- package/dist/color.test.d.ts +2 -0
- package/dist/color.test.d.ts.map +1 -0
- package/dist/color.test.js +161 -0
- package/dist/color.test.js.map +1 -0
- package/dist/config-provider.d.ts +57 -0
- package/dist/config-provider.d.ts.map +1 -0
- package/dist/config-provider.js +49 -0
- package/dist/config-provider.js.map +1 -0
- package/dist/config-provider.test.d.ts +2 -0
- package/dist/config-provider.test.d.ts.map +1 -0
- package/dist/config-provider.test.js +76 -0
- package/dist/config-provider.test.js.map +1 -0
- package/dist/copyable.d.ts +43 -0
- package/dist/copyable.d.ts.map +1 -0
- package/dist/copyable.js +102 -0
- package/dist/copyable.js.map +1 -0
- package/dist/copyable.test.d.ts +2 -0
- package/dist/copyable.test.d.ts.map +1 -0
- package/dist/copyable.test.js +97 -0
- package/dist/copyable.test.js.map +1 -0
- package/dist/date.d.ts +86 -0
- package/dist/date.d.ts.map +1 -0
- package/dist/date.js +226 -0
- package/dist/date.js.map +1 -0
- package/dist/date.test.d.ts +2 -0
- package/dist/date.test.d.ts.map +1 -0
- package/dist/date.test.js +171 -0
- package/dist/date.test.js.map +1 -0
- package/dist/dismiss.d.ts +28 -0
- package/dist/dismiss.d.ts.map +1 -0
- package/dist/dismiss.js +42 -0
- package/dist/dismiss.js.map +1 -0
- package/dist/editable.d.ts +59 -0
- package/dist/editable.d.ts.map +1 -0
- package/dist/editable.js +85 -0
- package/dist/editable.js.map +1 -0
- package/dist/editable.test.d.ts +2 -0
- package/dist/editable.test.d.ts.map +1 -0
- package/dist/editable.test.js +111 -0
- package/dist/editable.test.js.map +1 -0
- package/dist/ellipsis.d.ts +76 -0
- package/dist/ellipsis.d.ts.map +1 -0
- package/dist/ellipsis.js +99 -0
- package/dist/ellipsis.js.map +1 -0
- package/dist/ellipsis.test.d.ts +2 -0
- package/dist/ellipsis.test.d.ts.map +1 -0
- package/dist/ellipsis.test.js +94 -0
- package/dist/ellipsis.test.js.map +1 -0
- package/dist/floating.d.ts +78 -0
- package/dist/floating.d.ts.map +1 -0
- package/dist/floating.js +169 -0
- package/dist/floating.js.map +1 -0
- package/dist/floating.test.d.ts +2 -0
- package/dist/floating.test.d.ts.map +1 -0
- package/dist/floating.test.js +169 -0
- package/dist/floating.test.js.map +1 -0
- package/dist/focus-trap.d.ts +24 -0
- package/dist/focus-trap.d.ts.map +1 -0
- package/dist/focus-trap.js +64 -0
- package/dist/focus-trap.js.map +1 -0
- package/dist/form.d.ts +131 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +257 -0
- package/dist/form.js.map +1 -0
- package/dist/form.test.d.ts +2 -0
- package/dist/form.test.d.ts.map +1 -0
- package/dist/form.test.js +323 -0
- package/dist/form.test.js.map +1 -0
- package/dist/highlight.d.ts +57 -0
- package/dist/highlight.d.ts.map +1 -0
- package/dist/highlight.js +124 -0
- package/dist/highlight.js.map +1 -0
- package/dist/highlight.test.d.ts +2 -0
- package/dist/highlight.test.d.ts.map +1 -0
- package/dist/highlight.test.js +155 -0
- package/dist/highlight.test.js.map +1 -0
- package/dist/id.d.ts +4 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +14 -0
- package/dist/id.js.map +1 -0
- package/dist/id.test.d.ts +2 -0
- package/dist/id.test.d.ts.map +1 -0
- package/dist/id.test.js +13 -0
- package/dist/id.test.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/inert-background.d.ts +27 -0
- package/dist/inert-background.d.ts.map +1 -0
- package/dist/inert-background.js +92 -0
- package/dist/inert-background.js.map +1 -0
- package/dist/inert-background.test.d.ts +2 -0
- package/dist/inert-background.test.d.ts.map +1 -0
- package/dist/inert-background.test.js +62 -0
- package/dist/inert-background.test.js.map +1 -0
- package/dist/input-number.d.ts +34 -0
- package/dist/input-number.d.ts.map +1 -0
- package/dist/input-number.js +69 -0
- package/dist/input-number.js.map +1 -0
- package/dist/input-number.test.d.ts +2 -0
- package/dist/input-number.test.d.ts.map +1 -0
- package/dist/input-number.test.js +74 -0
- package/dist/input-number.test.js.map +1 -0
- package/dist/list-selection.d.ts +38 -0
- package/dist/list-selection.d.ts.map +1 -0
- package/dist/list-selection.js +61 -0
- package/dist/list-selection.js.map +1 -0
- package/dist/list-selection.test.d.ts +2 -0
- package/dist/list-selection.test.d.ts.map +1 -0
- package/dist/list-selection.test.js +61 -0
- package/dist/list-selection.test.js.map +1 -0
- package/dist/live-announcer.d.ts +38 -0
- package/dist/live-announcer.d.ts.map +1 -0
- package/dist/live-announcer.js +89 -0
- package/dist/live-announcer.js.map +1 -0
- package/dist/live-announcer.test.d.ts +2 -0
- package/dist/live-announcer.test.d.ts.map +1 -0
- package/dist/live-announcer.test.js +70 -0
- package/dist/live-announcer.test.js.map +1 -0
- package/dist/lottie-icon.d.ts +88 -0
- package/dist/lottie-icon.d.ts.map +1 -0
- package/dist/lottie-icon.js +84 -0
- package/dist/lottie-icon.js.map +1 -0
- package/dist/lottie-icon.test.d.ts +2 -0
- package/dist/lottie-icon.test.d.ts.map +1 -0
- package/dist/lottie-icon.test.js +88 -0
- package/dist/lottie-icon.test.js.map +1 -0
- package/dist/notification.d.ts +61 -0
- package/dist/notification.d.ts.map +1 -0
- package/dist/notification.js +133 -0
- package/dist/notification.js.map +1 -0
- package/dist/notification.test.d.ts +2 -0
- package/dist/notification.test.d.ts.map +1 -0
- package/dist/notification.test.js +103 -0
- package/dist/notification.test.js.map +1 -0
- package/dist/overflow-list.d.ts +102 -0
- package/dist/overflow-list.d.ts.map +1 -0
- package/dist/overflow-list.js +159 -0
- package/dist/overflow-list.js.map +1 -0
- package/dist/overflow-list.test.d.ts +2 -0
- package/dist/overflow-list.test.d.ts.map +1 -0
- package/dist/overflow-list.test.js +223 -0
- package/dist/overflow-list.test.js.map +1 -0
- package/dist/pagination.d.ts +51 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +127 -0
- package/dist/pagination.js.map +1 -0
- package/dist/pagination.test.d.ts +2 -0
- package/dist/pagination.test.d.ts.map +1 -0
- package/dist/pagination.test.js +147 -0
- package/dist/pagination.test.js.map +1 -0
- package/dist/progress.d.ts +64 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +92 -0
- package/dist/progress.js.map +1 -0
- package/dist/progress.test.d.ts +2 -0
- package/dist/progress.test.d.ts.map +1 -0
- package/dist/progress.test.js +79 -0
- package/dist/progress.test.js.map +1 -0
- package/dist/resize-observer.d.ts +133 -0
- package/dist/resize-observer.d.ts.map +1 -0
- package/dist/resize-observer.js +358 -0
- package/dist/resize-observer.js.map +1 -0
- package/dist/resize-observer.test.d.ts +2 -0
- package/dist/resize-observer.test.d.ts.map +1 -0
- package/dist/resize-observer.test.js +377 -0
- package/dist/resize-observer.test.js.map +1 -0
- package/dist/roving.d.ts +26 -0
- package/dist/roving.d.ts.map +1 -0
- package/dist/roving.js +61 -0
- package/dist/roving.js.map +1 -0
- package/dist/roving.test.d.ts +2 -0
- package/dist/roving.test.d.ts.map +1 -0
- package/dist/roving.test.js +48 -0
- package/dist/roving.test.js.map +1 -0
- package/dist/scroll-list.d.ts +81 -0
- package/dist/scroll-list.d.ts.map +1 -0
- package/dist/scroll-list.js +175 -0
- package/dist/scroll-list.js.map +1 -0
- package/dist/scroll-list.test.d.ts +2 -0
- package/dist/scroll-list.test.d.ts.map +1 -0
- package/dist/scroll-list.test.js +135 -0
- package/dist/scroll-list.test.js.map +1 -0
- package/dist/scroll-lock.d.ts +11 -0
- package/dist/scroll-lock.d.ts.map +1 -0
- package/dist/scroll-lock.js +45 -0
- package/dist/scroll-lock.js.map +1 -0
- package/dist/scroll-lock.test.d.ts +2 -0
- package/dist/scroll-lock.test.d.ts.map +1 -0
- package/dist/scroll-lock.test.js +55 -0
- package/dist/scroll-lock.test.js.map +1 -0
- package/dist/sider.d.ts +26 -0
- package/dist/sider.d.ts.map +1 -0
- package/dist/sider.js +55 -0
- package/dist/sider.js.map +1 -0
- package/dist/sider.test.d.ts +2 -0
- package/dist/sider.test.d.ts.map +1 -0
- package/dist/sider.test.js +29 -0
- package/dist/sider.test.js.map +1 -0
- package/dist/spin.d.ts +25 -0
- package/dist/spin.d.ts.map +1 -0
- package/dist/spin.js +96 -0
- package/dist/spin.js.map +1 -0
- package/dist/spin.test.d.ts +2 -0
- package/dist/spin.test.d.ts.map +1 -0
- package/dist/spin.test.js +80 -0
- package/dist/spin.test.js.map +1 -0
- package/dist/table.d.ts +101 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +244 -0
- package/dist/table.js.map +1 -0
- package/dist/table.test.d.ts +2 -0
- package/dist/table.test.d.ts.map +1 -0
- package/dist/table.test.js +184 -0
- package/dist/table.test.js.map +1 -0
- package/dist/textarea.d.ts +48 -0
- package/dist/textarea.d.ts.map +1 -0
- package/dist/textarea.js +76 -0
- package/dist/textarea.js.map +1 -0
- package/dist/textarea.test.d.ts +2 -0
- package/dist/textarea.test.d.ts.map +1 -0
- package/dist/textarea.test.js +77 -0
- package/dist/textarea.test.js.map +1 -0
- package/dist/time.d.ts +93 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +181 -0
- package/dist/time.js.map +1 -0
- package/dist/time.test.d.ts +2 -0
- package/dist/time.test.d.ts.map +1 -0
- package/dist/time.test.js +159 -0
- package/dist/time.test.js.map +1 -0
- package/dist/toast.d.ts +60 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +135 -0
- package/dist/toast.js.map +1 -0
- package/dist/toast.test.d.ts +2 -0
- package/dist/toast.test.d.ts.map +1 -0
- package/dist/toast.test.js +127 -0
- package/dist/toast.test.js.map +1 -0
- package/dist/tree.d.ts +129 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +351 -0
- package/dist/tree.js.map +1 -0
- package/dist/tree.test.d.ts +2 -0
- package/dist/tree.test.d.ts.map +1 -0
- package/dist/tree.test.js +291 -0
- package/dist/tree.test.js.map +1 -0
- package/dist/upload.d.ts +62 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +85 -0
- package/dist/upload.js.map +1 -0
- package/dist/upload.test.d.ts +2 -0
- package/dist/upload.test.d.ts.map +1 -0
- package/dist/upload.test.js +169 -0
- package/dist/upload.test.js.map +1 -0
- package/dist/virtual-list.d.ts +83 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +143 -0
- package/dist/virtual-list.js.map +1 -0
- package/dist/virtual-list.test.d.ts +2 -0
- package/dist/virtual-list.test.d.ts.map +1 -0
- package/dist/virtual-list.test.js +148 -0
- package/dist/virtual-list.test.js.map +1 -0
- package/package.json +22 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useLiveAnnouncer — 全库通用的单例 ARIA live region 播报原语。
|
|
3
|
+
*
|
|
4
|
+
* 动态状态变化(排序/筛选/翻页/越界/选择…)需要让屏幕阅读器播报,但若每个
|
|
5
|
+
* 组件各自渲染 `aria-live` 容器,会出现重复/竞争且难以统一。本原语在 body 上
|
|
6
|
+
* 命令式挂载两个全局唯一的 region(polite + assertive),所有组件复用同一对节点。
|
|
7
|
+
*
|
|
8
|
+
* - 红线 #3:region DOM 命令式创建/挂载 + 命令式写入 + cleanup;模块级单例复用,
|
|
9
|
+
* 不依赖任何框架 effect。客户端 only(守 `document`,SSR 下静默 no-op)。
|
|
10
|
+
* - region 视觉隐藏(sr-only:absolute + 1px + clip),不可用 display:none /
|
|
11
|
+
* visibility:hidden(会被辅助技术忽略)。
|
|
12
|
+
* - 级别策略(WAI-ARIA APG):polite 排队播报(默认,状态结果类);assertive
|
|
13
|
+
* 立即打断(错误/紧急)。
|
|
14
|
+
* - 同一文案连续两次也能被重播:先清空再写入,触发新一次 AT 播报。
|
|
15
|
+
*
|
|
16
|
+
* 文案由调用方在组件层经 `@chenzy-design/locale` 本地化后传入(本原语不含文案)。
|
|
17
|
+
*
|
|
18
|
+
* 参考 packages/svelte/src/toast/live-region.ts(Toast 自带的 region 范式),
|
|
19
|
+
* 但本原语放在 core,供全库组件复用。Toast/Notification 仍用各自既有 region。
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const announcer = useLiveAnnouncer();
|
|
23
|
+
* announcer.announce('已按名称升序排序'); // polite
|
|
24
|
+
* announcer.announce('表单提交失败', 'assertive'); // 立即打断
|
|
25
|
+
*/
|
|
26
|
+
// 模块级单例:整库共享同一对 region 节点。
|
|
27
|
+
let regions = null;
|
|
28
|
+
function makeRegion(politeness) {
|
|
29
|
+
const el = document.createElement('div');
|
|
30
|
+
// role=status 隐含 polite;role=alert 隐含 assertive。同时显式标注更稳。
|
|
31
|
+
el.setAttribute('role', politeness === 'assertive' ? 'alert' : 'status');
|
|
32
|
+
el.setAttribute('aria-live', politeness);
|
|
33
|
+
el.setAttribute('aria-atomic', 'true');
|
|
34
|
+
el.className = 'cd-live-region';
|
|
35
|
+
// 视觉隐藏但对辅助技术可见(不可用 display:none / visibility:hidden)。
|
|
36
|
+
const s = el.style;
|
|
37
|
+
s.position = 'absolute';
|
|
38
|
+
s.width = '1px';
|
|
39
|
+
s.height = '1px';
|
|
40
|
+
s.margin = '-1px';
|
|
41
|
+
s.padding = '0';
|
|
42
|
+
s.overflow = 'hidden';
|
|
43
|
+
s.clip = 'rect(0 0 0 0)';
|
|
44
|
+
s.clipPath = 'inset(50%)';
|
|
45
|
+
s.whiteSpace = 'nowrap';
|
|
46
|
+
s.border = '0';
|
|
47
|
+
return el;
|
|
48
|
+
}
|
|
49
|
+
function ensureRegions() {
|
|
50
|
+
if (typeof document === 'undefined')
|
|
51
|
+
return null;
|
|
52
|
+
if (!regions) {
|
|
53
|
+
const polite = makeRegion('polite');
|
|
54
|
+
const assertive = makeRegion('assertive');
|
|
55
|
+
document.body.appendChild(polite);
|
|
56
|
+
document.body.appendChild(assertive);
|
|
57
|
+
regions = { polite, assertive };
|
|
58
|
+
}
|
|
59
|
+
return regions;
|
|
60
|
+
}
|
|
61
|
+
function announce(message, politeness = 'polite') {
|
|
62
|
+
// 空消息直接 no-op:不挂载 region(懒挂载,仅真正播报时才创建)。
|
|
63
|
+
if (!message)
|
|
64
|
+
return;
|
|
65
|
+
const r = ensureRegions();
|
|
66
|
+
if (!r)
|
|
67
|
+
return;
|
|
68
|
+
const target = politeness === 'assertive' ? r.assertive : r.polite;
|
|
69
|
+
// 先清空,确保重复文案也会触发新一次播报。
|
|
70
|
+
target.textContent = '';
|
|
71
|
+
// 同步写入即可被 AT 捕获;保持纯命令式、无 effect。
|
|
72
|
+
target.textContent = message;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 获取全局单例播报器。多次调用返回等价 API(共享同一对 region 节点),
|
|
76
|
+
* 首次写入时才惰性挂载 region(SSR 下不挂载)。
|
|
77
|
+
*/
|
|
78
|
+
export function useLiveAnnouncer() {
|
|
79
|
+
return { announce };
|
|
80
|
+
}
|
|
81
|
+
/** 测试 only:移除单例 region 并复位模块状态。 */
|
|
82
|
+
export function __resetLiveAnnouncer() {
|
|
83
|
+
if (regions) {
|
|
84
|
+
regions.polite.remove();
|
|
85
|
+
regions.assertive.remove();
|
|
86
|
+
regions = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=live-announcer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-announcer.js","sourceRoot":"","sources":["../src/live-announcer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAcH,2BAA2B;AAC3B,IAAI,OAAO,GAAuB,IAAI,CAAC;AAEvC,SAAS,UAAU,CAAC,UAAsB;IACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,0DAA0D;IAC1D,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzE,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACzC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACvC,EAAE,CAAC,SAAS,GAAG,gBAAgB,CAAC;IAChC,sDAAsD;IACtD,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;IACnB,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC;IACxB,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC;IAChB,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACtB,CAAC,CAAC,IAAI,GAAG,eAAe,CAAC;IACzB,CAAC,CAAC,QAAQ,GAAG,YAAY,CAAC;IAC1B,CAAC,CAAC,UAAU,GAAG,QAAQ,CAAC;IACxB,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;IACf,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,aAAyB,QAAQ;IAClE,yCAAyC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,IAAI,CAAC,CAAC;QAAE,OAAO;IACf,MAAM,MAAM,GAAG,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,uBAAuB;IACvB,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,iCAAiC;IACjC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,oBAAoB;IAClC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-announcer.test.d.ts","sourceRoot":"","sources":["../src/live-announcer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
3
|
+
import { useLiveAnnouncer, __resetLiveAnnouncer } from './live-announcer.js';
|
|
4
|
+
afterEach(() => {
|
|
5
|
+
__resetLiveAnnouncer();
|
|
6
|
+
});
|
|
7
|
+
function regions() {
|
|
8
|
+
return Array.from(document.querySelectorAll('.cd-live-region'));
|
|
9
|
+
}
|
|
10
|
+
describe('useLiveAnnouncer', () => {
|
|
11
|
+
it('lazily mounts a pair of polite + assertive regions on first announce', () => {
|
|
12
|
+
expect(regions()).toHaveLength(0);
|
|
13
|
+
const a = useLiveAnnouncer();
|
|
14
|
+
a.announce('hello');
|
|
15
|
+
const els = regions();
|
|
16
|
+
expect(els).toHaveLength(2);
|
|
17
|
+
const polite = els.find((e) => e.getAttribute('aria-live') === 'polite');
|
|
18
|
+
const assertive = els.find((e) => e.getAttribute('aria-live') === 'assertive');
|
|
19
|
+
expect(polite).toBeTruthy();
|
|
20
|
+
expect(assertive).toBeTruthy();
|
|
21
|
+
expect(polite.getAttribute('role')).toBe('status');
|
|
22
|
+
expect(assertive.getAttribute('role')).toBe('alert');
|
|
23
|
+
expect(polite.getAttribute('aria-atomic')).toBe('true');
|
|
24
|
+
});
|
|
25
|
+
it('reuses the same singleton region across multiple useLiveAnnouncer() calls', () => {
|
|
26
|
+
useLiveAnnouncer().announce('a');
|
|
27
|
+
useLiveAnnouncer().announce('b');
|
|
28
|
+
expect(regions()).toHaveLength(2);
|
|
29
|
+
});
|
|
30
|
+
it('defaults to polite and writes the message into the polite region', () => {
|
|
31
|
+
const a = useLiveAnnouncer();
|
|
32
|
+
a.announce('sorted by name');
|
|
33
|
+
const polite = regions().find((e) => e.getAttribute('aria-live') === 'polite');
|
|
34
|
+
const assertive = regions().find((e) => e.getAttribute('aria-live') === 'assertive');
|
|
35
|
+
expect(polite.textContent).toBe('sorted by name');
|
|
36
|
+
expect(assertive.textContent).toBe('');
|
|
37
|
+
});
|
|
38
|
+
it('routes assertive announcements to the assertive region', () => {
|
|
39
|
+
const a = useLiveAnnouncer();
|
|
40
|
+
a.announce('submit failed', 'assertive');
|
|
41
|
+
const polite = regions().find((e) => e.getAttribute('aria-live') === 'polite');
|
|
42
|
+
const assertive = regions().find((e) => e.getAttribute('aria-live') === 'assertive');
|
|
43
|
+
expect(assertive.textContent).toBe('submit failed');
|
|
44
|
+
expect(polite.textContent).toBe('');
|
|
45
|
+
});
|
|
46
|
+
it('re-announces identical consecutive messages by clearing first', () => {
|
|
47
|
+
const a = useLiveAnnouncer();
|
|
48
|
+
const polite = () => regions().find((e) => e.getAttribute('aria-live') === 'polite');
|
|
49
|
+
a.announce('page 2');
|
|
50
|
+
expect(polite().textContent).toBe('page 2');
|
|
51
|
+
// simulate AT reading + DOM still holding the text, then same message again
|
|
52
|
+
a.announce('page 2');
|
|
53
|
+
expect(polite().textContent).toBe('page 2');
|
|
54
|
+
});
|
|
55
|
+
it('is a no-op for empty messages and does not mount regions', () => {
|
|
56
|
+
const a = useLiveAnnouncer();
|
|
57
|
+
a.announce('');
|
|
58
|
+
expect(regions()).toHaveLength(0);
|
|
59
|
+
});
|
|
60
|
+
it('__resetLiveAnnouncer removes the regions and resets the singleton', () => {
|
|
61
|
+
useLiveAnnouncer().announce('x');
|
|
62
|
+
expect(regions()).toHaveLength(2);
|
|
63
|
+
__resetLiveAnnouncer();
|
|
64
|
+
expect(regions()).toHaveLength(0);
|
|
65
|
+
// a fresh announce re-mounts
|
|
66
|
+
useLiveAnnouncer().announce('y');
|
|
67
|
+
expect(regions()).toHaveLength(2);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=live-announcer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-announcer.test.js","sourceRoot":"","sources":["../src/live-announcer.test.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE7E,SAAS,CAAC,GAAG,EAAE;IACb,oBAAoB,EAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,SAAS,OAAO;IACd,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAc,iBAAiB,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;QAC7B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,WAAW,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC;QAC5B,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,SAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,CAAC,MAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,gBAAgB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;QAC7B,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAE,CAAC;QAChF,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,WAAW,CAAE,CAAC;QACtF,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;QAC7B,CAAC,CAAC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAE,CAAC;QAChF,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,WAAW,CAAE,CAAC;QACtF,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,GAAG,EAAE,CAClB,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAE,CAAC;QACnE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,4EAA4E;QAC5E,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,GAAG,gBAAgB,EAAE,CAAC;QAC7B,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACf,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,gBAAgB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,oBAAoB,EAAE,CAAC;QACvB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,6BAA6B;QAC7B,gBAAgB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createLottieIcon helpers — framework-agnostic Lottie icon logic.
|
|
3
|
+
* Pure decision functions (reduced-motion resolution, size mapping, autoplay
|
|
4
|
+
* gating) plus a player-adapter interface so the library never hard-depends on
|
|
5
|
+
* lottie-web — consumers inject any player. The svelte layer owns the mount
|
|
6
|
+
* node + adapter lifecycle. See specs/components/other/LottieIcon.spec.md §3
|
|
7
|
+
* (dependency-injected adapter; src fetch / visible / segments deferred).
|
|
8
|
+
*/
|
|
9
|
+
export type LottieTrigger = 'auto' | 'hover' | 'manual';
|
|
10
|
+
export type LottieSize = 'small' | 'default' | 'large';
|
|
11
|
+
/**
|
|
12
|
+
* Render backend the injected player should use. Mirrors lottie-web's
|
|
13
|
+
* `renderer` option ('svg' | 'canvas' | 'html'). Optional everywhere so legacy
|
|
14
|
+
* factories that ignore it keep their default ('svg') behaviour.
|
|
15
|
+
*/
|
|
16
|
+
export type LottieRenderer = 'svg' | 'canvas' | 'html';
|
|
17
|
+
/**
|
|
18
|
+
* Frame segment to play: a `[start, end]` frame pair, or a named marker string
|
|
19
|
+
* resolved against the animation data's `markers`. See `resolveSegments`.
|
|
20
|
+
*/
|
|
21
|
+
export type LottieSegments = [number, number] | string;
|
|
22
|
+
/** Minimal player adapter the host injects (e.g. wrapping lottie-web). */
|
|
23
|
+
export interface LottiePlayerAdapter {
|
|
24
|
+
play(): void;
|
|
25
|
+
pause(): void;
|
|
26
|
+
stop(): void;
|
|
27
|
+
/** jump to a specific frame and hold (used for reduced-motion static frame) */
|
|
28
|
+
goToFrame?(frame: number): void;
|
|
29
|
+
/**
|
|
30
|
+
* Play a resolved `[start, end]` frame segment. Optional: when the injected
|
|
31
|
+
* player lacks it, the host falls back to `play()`. The svelte layer always
|
|
32
|
+
* passes a numeric pair (named markers resolved via `resolveSegments`).
|
|
33
|
+
*/
|
|
34
|
+
playSegments?(segments: [number, number]): void;
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
37
|
+
/** Factory the host passes: builds an adapter for the given container + data. */
|
|
38
|
+
export type LottiePlayerFactory = (config: {
|
|
39
|
+
container: HTMLElement;
|
|
40
|
+
data: unknown;
|
|
41
|
+
loop: boolean | number;
|
|
42
|
+
autoplay: boolean;
|
|
43
|
+
speed: number;
|
|
44
|
+
/** Resolved initial `[start, end]` frame segment, when `segments` is set. */
|
|
45
|
+
segment?: [number, number];
|
|
46
|
+
/**
|
|
47
|
+
* Render backend ('svg' | 'canvas' | 'html'), forwarded to e.g. lottie-web's
|
|
48
|
+
* `renderer` option. Optional & backward-compatible: omitted when the host's
|
|
49
|
+
* `canvas`/`renderer` prop is unset, so legacy factories default to 'svg'.
|
|
50
|
+
*/
|
|
51
|
+
renderer?: LottieRenderer;
|
|
52
|
+
}) => LottiePlayerAdapter;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the host `canvas` / `renderer` prop into a concrete renderer backend
|
|
55
|
+
* for the factory (pure). `renderer` (explicit string) wins; otherwise
|
|
56
|
+
* `canvas === true` → 'canvas'. Returns `undefined` when neither is set so the
|
|
57
|
+
* host omits `renderer` entirely and legacy factories keep their 'svg' default.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveRenderer(canvas: boolean | undefined, renderer: LottieRenderer | undefined): LottieRenderer | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a `segments` prop into a concrete `[start, end]` frame pair.
|
|
62
|
+
* - `[start, end]` numeric pair → returned as-is.
|
|
63
|
+
* - marker name string → looked up in the data's `markers` (`cm` name,
|
|
64
|
+
* `tm` start time, `dr` duration); resolves to `[tm, tm + dr]`.
|
|
65
|
+
* Returns `null` when unresolvable (no markers / name not found / bad input)
|
|
66
|
+
* so the host can fall back to playing the whole animation.
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveSegments(segments: LottieSegments | undefined, data: unknown): [number, number] | null;
|
|
69
|
+
/**
|
|
70
|
+
* Is `src` a usable animation source URL (non-empty string). Pure guard used
|
|
71
|
+
* by the host to decide whether to kick off a fetch.
|
|
72
|
+
*/
|
|
73
|
+
export declare function isLottieSrc(src: unknown): src is string;
|
|
74
|
+
/** Map a size token (or raw px number) to a pixel value. */
|
|
75
|
+
export declare function resolveSize(size: LottieSize | number): number;
|
|
76
|
+
/**
|
|
77
|
+
* Resolve whether animation should run: an explicit `reducedMotion` prop wins;
|
|
78
|
+
* otherwise follow the system `prefers-reduced-motion`. Returns true when
|
|
79
|
+
* animation is ALLOWED (i.e. NOT reduced).
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveAnimated(reducedMotionProp: boolean | undefined, systemReduced: boolean): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Should the icon start playing on mount, given trigger + autoplay + whether
|
|
84
|
+
* animation is allowed (reduced-motion). Only `auto` honors autoplay; hover &
|
|
85
|
+
* manual never autoplay.
|
|
86
|
+
*/
|
|
87
|
+
export declare function shouldAutoplay(trigger: LottieTrigger, autoplay: boolean, animated: boolean): boolean;
|
|
88
|
+
//# sourceMappingURL=lottie-icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lottie-icon.d.ts","sourceRoot":"","sources":["../src/lottie-icon.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AACxD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,+EAA+E;IAC/E,SAAS,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAChD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE;IACzC,SAAS,EAAE,WAAW,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,KAAK,mBAAmB,CAAC;AAE1B;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,QAAQ,EAAE,cAAc,GAAG,SAAS,GACnC,cAAc,GAAG,SAAS,CAI5B;AASD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,GAAG,SAAS,EACpC,IAAI,EAAE,OAAO,GACZ,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAiBzB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAEvD;AAID,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,iBAAiB,EAAE,OAAO,GAAG,SAAS,EACtC,aAAa,EAAE,OAAO,GACrB,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAGT"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createLottieIcon helpers — framework-agnostic Lottie icon logic.
|
|
3
|
+
* Pure decision functions (reduced-motion resolution, size mapping, autoplay
|
|
4
|
+
* gating) plus a player-adapter interface so the library never hard-depends on
|
|
5
|
+
* lottie-web — consumers inject any player. The svelte layer owns the mount
|
|
6
|
+
* node + adapter lifecycle. See specs/components/other/LottieIcon.spec.md §3
|
|
7
|
+
* (dependency-injected adapter; src fetch / visible / segments deferred).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the host `canvas` / `renderer` prop into a concrete renderer backend
|
|
11
|
+
* for the factory (pure). `renderer` (explicit string) wins; otherwise
|
|
12
|
+
* `canvas === true` → 'canvas'. Returns `undefined` when neither is set so the
|
|
13
|
+
* host omits `renderer` entirely and legacy factories keep their 'svg' default.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveRenderer(canvas, renderer) {
|
|
16
|
+
if (renderer != null)
|
|
17
|
+
return renderer;
|
|
18
|
+
if (canvas === true)
|
|
19
|
+
return 'canvas';
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a `segments` prop into a concrete `[start, end]` frame pair.
|
|
24
|
+
* - `[start, end]` numeric pair → returned as-is.
|
|
25
|
+
* - marker name string → looked up in the data's `markers` (`cm` name,
|
|
26
|
+
* `tm` start time, `dr` duration); resolves to `[tm, tm + dr]`.
|
|
27
|
+
* Returns `null` when unresolvable (no markers / name not found / bad input)
|
|
28
|
+
* so the host can fall back to playing the whole animation.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveSegments(segments, data) {
|
|
31
|
+
if (segments == null)
|
|
32
|
+
return null;
|
|
33
|
+
if (Array.isArray(segments)) {
|
|
34
|
+
const [start, end] = segments;
|
|
35
|
+
if (typeof start === 'number' && typeof end === 'number' && Number.isFinite(start) && Number.isFinite(end)) {
|
|
36
|
+
return [start, end];
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (typeof segments !== 'string')
|
|
41
|
+
return null;
|
|
42
|
+
const markers = data?.markers;
|
|
43
|
+
if (!Array.isArray(markers))
|
|
44
|
+
return null;
|
|
45
|
+
const marker = markers.find((m) => m && m.cm === segments);
|
|
46
|
+
if (!marker || typeof marker.tm !== 'number')
|
|
47
|
+
return null;
|
|
48
|
+
const start = marker.tm;
|
|
49
|
+
const end = start + (typeof marker.dr === 'number' ? marker.dr : 0);
|
|
50
|
+
return [start, end];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Is `src` a usable animation source URL (non-empty string). Pure guard used
|
|
54
|
+
* by the host to decide whether to kick off a fetch.
|
|
55
|
+
*/
|
|
56
|
+
export function isLottieSrc(src) {
|
|
57
|
+
return typeof src === 'string' && src.trim().length > 0;
|
|
58
|
+
}
|
|
59
|
+
const SIZE_PX = { small: 16, default: 20, large: 24 };
|
|
60
|
+
/** Map a size token (or raw px number) to a pixel value. */
|
|
61
|
+
export function resolveSize(size) {
|
|
62
|
+
return typeof size === 'number' ? size : SIZE_PX[size];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve whether animation should run: an explicit `reducedMotion` prop wins;
|
|
66
|
+
* otherwise follow the system `prefers-reduced-motion`. Returns true when
|
|
67
|
+
* animation is ALLOWED (i.e. NOT reduced).
|
|
68
|
+
*/
|
|
69
|
+
export function resolveAnimated(reducedMotionProp, systemReduced) {
|
|
70
|
+
if (reducedMotionProp !== undefined)
|
|
71
|
+
return !reducedMotionProp;
|
|
72
|
+
return !systemReduced;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Should the icon start playing on mount, given trigger + autoplay + whether
|
|
76
|
+
* animation is allowed (reduced-motion). Only `auto` honors autoplay; hover &
|
|
77
|
+
* manual never autoplay.
|
|
78
|
+
*/
|
|
79
|
+
export function shouldAutoplay(trigger, autoplay, animated) {
|
|
80
|
+
if (!animated)
|
|
81
|
+
return false;
|
|
82
|
+
return trigger === 'auto' && autoplay;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=lottie-icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lottie-icon.js","sourceRoot":"","sources":["../src/lottie-icon.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmDH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,QAAoC;IAEpC,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IACtC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,QAAQ,CAAC;IACrC,OAAO,SAAS,CAAC;AACnB,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAoC,EACpC,IAAa;IAEb,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC;QAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3G,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,OAAO,GAAI,IAAwD,EAAE,OAAO,CAAC;IACnF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;IACxB,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,GAA+B,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAElF,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,IAAyB;IACnD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,iBAAsC,EACtC,aAAsB;IAEtB,IAAI,iBAAiB,KAAK,SAAS;QAAE,OAAO,CAAC,iBAAiB,CAAC;IAC/D,OAAO,CAAC,aAAa,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAsB,EACtB,QAAiB,EACjB,QAAiB;IAEjB,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,OAAO,OAAO,KAAK,MAAM,IAAI,QAAQ,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lottie-icon.test.d.ts","sourceRoot":"","sources":["../src/lottie-icon.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { resolveSize, resolveAnimated, shouldAutoplay, resolveSegments, isLottieSrc, resolveRenderer, } from './lottie-icon.js';
|
|
3
|
+
describe('resolveSize', () => {
|
|
4
|
+
it('maps size tokens to px', () => {
|
|
5
|
+
expect(resolveSize('small')).toBe(16);
|
|
6
|
+
expect(resolveSize('default')).toBe(20);
|
|
7
|
+
expect(resolveSize('large')).toBe(24);
|
|
8
|
+
});
|
|
9
|
+
it('passes through raw numbers', () => {
|
|
10
|
+
expect(resolveSize(48)).toBe(48);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
describe('resolveAnimated', () => {
|
|
14
|
+
it('explicit reducedMotion prop wins over system', () => {
|
|
15
|
+
expect(resolveAnimated(true, false)).toBe(false); // forced reduce → not animated
|
|
16
|
+
expect(resolveAnimated(false, true)).toBe(true); // forced motion → animated despite system
|
|
17
|
+
});
|
|
18
|
+
it('follows system when prop is undefined', () => {
|
|
19
|
+
expect(resolveAnimated(undefined, false)).toBe(true); // system not reduced → animated
|
|
20
|
+
expect(resolveAnimated(undefined, true)).toBe(false); // system reduced → not animated
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('shouldAutoplay', () => {
|
|
24
|
+
it('auto + autoplay + animated → true', () => {
|
|
25
|
+
expect(shouldAutoplay('auto', true, true)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('not animated (reduced-motion) → never autoplay', () => {
|
|
28
|
+
expect(shouldAutoplay('auto', true, false)).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
it('autoplay=false → no autoplay', () => {
|
|
31
|
+
expect(shouldAutoplay('auto', false, true)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it('hover/manual triggers never autoplay', () => {
|
|
34
|
+
expect(shouldAutoplay('hover', true, true)).toBe(false);
|
|
35
|
+
expect(shouldAutoplay('manual', true, true)).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe('resolveSegments', () => {
|
|
39
|
+
it('passes through a numeric frame pair', () => {
|
|
40
|
+
expect(resolveSegments([10, 60], null)).toEqual([10, 60]);
|
|
41
|
+
});
|
|
42
|
+
it('returns null for undefined / invalid pairs', () => {
|
|
43
|
+
expect(resolveSegments(undefined, null)).toBeNull();
|
|
44
|
+
// @ts-expect-error invalid tuple
|
|
45
|
+
expect(resolveSegments(['a', 'b'], null)).toBeNull();
|
|
46
|
+
expect(resolveSegments([NaN, 5], null)).toBeNull();
|
|
47
|
+
});
|
|
48
|
+
it('resolves a named marker against data.markers (tm + dr)', () => {
|
|
49
|
+
const data = { markers: [{ cm: 'hover', tm: 30, dr: 20 }, { cm: 'idle', tm: 0, dr: 30 }] };
|
|
50
|
+
expect(resolveSegments('hover', data)).toEqual([30, 50]);
|
|
51
|
+
expect(resolveSegments('idle', data)).toEqual([0, 30]);
|
|
52
|
+
});
|
|
53
|
+
it('returns null when marker missing or no markers', () => {
|
|
54
|
+
expect(resolveSegments('nope', { markers: [{ cm: 'x', tm: 1, dr: 1 }] })).toBeNull();
|
|
55
|
+
expect(resolveSegments('x', {})).toBeNull();
|
|
56
|
+
expect(resolveSegments('x', null)).toBeNull();
|
|
57
|
+
});
|
|
58
|
+
it('treats marker without dr as a zero-length point', () => {
|
|
59
|
+
expect(resolveSegments('p', { markers: [{ cm: 'p', tm: 12 }] })).toEqual([12, 12]);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('isLottieSrc', () => {
|
|
63
|
+
it('true for non-empty strings', () => {
|
|
64
|
+
expect(isLottieSrc('https://x/a.json')).toBe(true);
|
|
65
|
+
expect(isLottieSrc(' /local.json ')).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it('false for empty / non-string', () => {
|
|
68
|
+
expect(isLottieSrc('')).toBe(false);
|
|
69
|
+
expect(isLottieSrc(' ')).toBe(false);
|
|
70
|
+
expect(isLottieSrc(undefined)).toBe(false);
|
|
71
|
+
expect(isLottieSrc({})).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('resolveRenderer', () => {
|
|
75
|
+
it('explicit renderer wins over canvas', () => {
|
|
76
|
+
expect(resolveRenderer(true, 'html')).toBe('html');
|
|
77
|
+
expect(resolveRenderer(false, 'svg')).toBe('svg');
|
|
78
|
+
expect(resolveRenderer(undefined, 'canvas')).toBe('canvas');
|
|
79
|
+
});
|
|
80
|
+
it('canvas=true maps to canvas when no explicit renderer', () => {
|
|
81
|
+
expect(resolveRenderer(true, undefined)).toBe('canvas');
|
|
82
|
+
});
|
|
83
|
+
it('undefined (omitted) for default svg / backward compat', () => {
|
|
84
|
+
expect(resolveRenderer(false, undefined)).toBeUndefined();
|
|
85
|
+
expect(resolveRenderer(undefined, undefined)).toBeUndefined();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=lottie-icon.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lottie-icon.test.js","sourceRoot":"","sources":["../src/lottie-icon.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type NotificationType = 'default' | 'success' | 'info' | 'warning' | 'error';
|
|
2
|
+
export type NotificationPlacement = 'topLeft' | 'top' | 'topRight' | 'bottomLeft' | 'bottom' | 'bottomRight';
|
|
3
|
+
export type NotificationCloseReason = 'timeout' | 'manual' | 'replace' | 'destroyAll';
|
|
4
|
+
export type NotificationTheme = 'light' | 'dark';
|
|
5
|
+
export type NotificationDirection = 'ltr' | 'rtl';
|
|
6
|
+
export interface NotificationOptions {
|
|
7
|
+
id?: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
content?: string;
|
|
10
|
+
type?: NotificationType;
|
|
11
|
+
/** auto-dismiss seconds; 0 = persist */
|
|
12
|
+
duration?: number;
|
|
13
|
+
placement?: NotificationPlacement;
|
|
14
|
+
closable?: boolean;
|
|
15
|
+
pauseOnHover?: boolean;
|
|
16
|
+
/** show a countdown progress bar that tracks the remaining auto-dismiss time */
|
|
17
|
+
showProgress?: boolean;
|
|
18
|
+
/** visual theme of the card */
|
|
19
|
+
theme?: NotificationTheme;
|
|
20
|
+
/** writing direction; 'rtl' mirrors the card layout and swaps left/right placement */
|
|
21
|
+
direction?: NotificationDirection;
|
|
22
|
+
/**
|
|
23
|
+
* footer action area. Opaque to core (framework-agnostic) — the render layer
|
|
24
|
+
* (svelte) treats it as a Snippet. Typed `unknown` here to avoid a framework dep.
|
|
25
|
+
*/
|
|
26
|
+
footer?: unknown;
|
|
27
|
+
onClose?: (id: string, reason: NotificationCloseReason) => void;
|
|
28
|
+
}
|
|
29
|
+
export interface NotificationItem {
|
|
30
|
+
id: string;
|
|
31
|
+
title: string;
|
|
32
|
+
content: string;
|
|
33
|
+
type: NotificationType;
|
|
34
|
+
duration: number;
|
|
35
|
+
placement: NotificationPlacement;
|
|
36
|
+
closable: boolean;
|
|
37
|
+
pauseOnHover: boolean;
|
|
38
|
+
showProgress: boolean;
|
|
39
|
+
theme: NotificationTheme;
|
|
40
|
+
direction: NotificationDirection;
|
|
41
|
+
footer: unknown;
|
|
42
|
+
onClose: ((id: string, reason: NotificationCloseReason) => void) | undefined;
|
|
43
|
+
}
|
|
44
|
+
export interface NotificationStoreOptions {
|
|
45
|
+
maxCount?: number;
|
|
46
|
+
defaultDuration?: number;
|
|
47
|
+
/** default writing direction applied to items that don't specify one */
|
|
48
|
+
defaultDirection?: NotificationDirection;
|
|
49
|
+
}
|
|
50
|
+
export interface NotificationStore {
|
|
51
|
+
getItems(): NotificationItem[];
|
|
52
|
+
subscribe(listener: (items: NotificationItem[]) => void): () => void;
|
|
53
|
+
open(options: NotificationOptions): string;
|
|
54
|
+
close(id: string, reason?: NotificationCloseReason): void;
|
|
55
|
+
destroyAll(placement?: NotificationPlacement): void;
|
|
56
|
+
pause(id: string): void;
|
|
57
|
+
resume(id: string): void;
|
|
58
|
+
destroy(): void;
|
|
59
|
+
}
|
|
60
|
+
export declare function createNotificationStore(storeOptions?: NotificationStoreOptions): NotificationStore;
|
|
61
|
+
//# sourceMappingURL=notification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AACpF,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,KAAK,GACL,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,aAAa,CAAC;AAClB,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;AACtF,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,CAAC;AACjD,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,sFAAsF;IACtF,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,qBAAqB,CAAC;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,qBAAqB,CAAC;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9E;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,IAAI,gBAAgB,EAAE,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACrE,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAAC;IAC3C,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC1D,UAAU,CAAC,SAAS,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACpD,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,IAAI,IAAI,CAAC;CACjB;AASD,wBAAgB,uBAAuB,CACrC,YAAY,GAAE,wBAA6B,GAC1C,iBAAiB,CA2HnB"}
|