@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,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createNotificationStore — framework-agnostic singleton notification queue.
|
|
3
|
+
* Same queue + timer model as the toast store, but groups by 6 placements and
|
|
4
|
+
* carries richer data (title/content/footer). Auto-dismiss with hover pause,
|
|
5
|
+
* FIFO maxCount per placement, id-based dedup/update. No DOM, no framework deps.
|
|
6
|
+
* See specs/components/feedback/Notification.spec.md §3.
|
|
7
|
+
*/
|
|
8
|
+
import { useId } from './id.js';
|
|
9
|
+
export function createNotificationStore(storeOptions = {}) {
|
|
10
|
+
const { maxCount = 5, defaultDuration = 4.5, defaultDirection = 'ltr' } = storeOptions;
|
|
11
|
+
let items = [];
|
|
12
|
+
const timers = new Map();
|
|
13
|
+
const listeners = new Set();
|
|
14
|
+
function emit() {
|
|
15
|
+
const snapshot = items.slice();
|
|
16
|
+
for (const l of listeners)
|
|
17
|
+
l(snapshot);
|
|
18
|
+
}
|
|
19
|
+
function now() {
|
|
20
|
+
return Date.now();
|
|
21
|
+
}
|
|
22
|
+
function clearTimer(id) {
|
|
23
|
+
const rec = timers.get(id);
|
|
24
|
+
if (rec?.timer != null) {
|
|
25
|
+
clearTimeout(rec.timer);
|
|
26
|
+
rec.timer = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function startTimer(id, ms) {
|
|
30
|
+
if (ms <= 0)
|
|
31
|
+
return;
|
|
32
|
+
const rec = { timer: null, remaining: ms, startedAt: now() };
|
|
33
|
+
rec.timer = setTimeout(() => close(id, 'timeout'), ms);
|
|
34
|
+
timers.set(id, rec);
|
|
35
|
+
}
|
|
36
|
+
function close(id, reason = 'manual') {
|
|
37
|
+
const item = items.find((t) => t.id === id);
|
|
38
|
+
if (!item)
|
|
39
|
+
return;
|
|
40
|
+
clearTimer(id);
|
|
41
|
+
timers.delete(id);
|
|
42
|
+
items = items.filter((t) => t.id !== id);
|
|
43
|
+
emit();
|
|
44
|
+
item.onClose?.(id, reason);
|
|
45
|
+
}
|
|
46
|
+
function open(options) {
|
|
47
|
+
const id = options.id ?? useId('cd-notification');
|
|
48
|
+
const placement = options.placement ?? 'topRight';
|
|
49
|
+
const item = {
|
|
50
|
+
id,
|
|
51
|
+
title: options.title ?? '',
|
|
52
|
+
content: options.content ?? '',
|
|
53
|
+
type: options.type ?? 'default',
|
|
54
|
+
duration: options.duration ?? defaultDuration,
|
|
55
|
+
placement,
|
|
56
|
+
closable: options.closable ?? true,
|
|
57
|
+
pauseOnHover: options.pauseOnHover ?? true,
|
|
58
|
+
showProgress: options.showProgress ?? false,
|
|
59
|
+
theme: options.theme ?? 'light',
|
|
60
|
+
direction: options.direction ?? defaultDirection,
|
|
61
|
+
footer: options.footer,
|
|
62
|
+
onClose: options.onClose,
|
|
63
|
+
};
|
|
64
|
+
const existingIndex = items.findIndex((t) => t.id === id);
|
|
65
|
+
if (existingIndex >= 0) {
|
|
66
|
+
clearTimer(id);
|
|
67
|
+
timers.delete(id);
|
|
68
|
+
items = items.map((t, i) => (i === existingIndex ? item : t));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
items = [...items, item];
|
|
72
|
+
// FIFO per placement
|
|
73
|
+
const samePlacement = items.filter((t) => t.placement === placement);
|
|
74
|
+
if (samePlacement.length > maxCount) {
|
|
75
|
+
const oldest = samePlacement[0];
|
|
76
|
+
clearTimer(oldest.id);
|
|
77
|
+
timers.delete(oldest.id);
|
|
78
|
+
items = items.filter((t) => t.id !== oldest.id);
|
|
79
|
+
oldest.onClose?.(oldest.id, 'replace');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
emit();
|
|
83
|
+
startTimer(id, item.duration * 1000);
|
|
84
|
+
return id;
|
|
85
|
+
}
|
|
86
|
+
function destroyAll(placement) {
|
|
87
|
+
const targets = placement ? items.filter((t) => t.placement === placement) : items.slice();
|
|
88
|
+
for (const t of targets) {
|
|
89
|
+
clearTimer(t.id);
|
|
90
|
+
timers.delete(t.id);
|
|
91
|
+
}
|
|
92
|
+
const ids = new Set(targets.map((t) => t.id));
|
|
93
|
+
items = items.filter((t) => !ids.has(t.id));
|
|
94
|
+
emit();
|
|
95
|
+
for (const t of targets)
|
|
96
|
+
t.onClose?.(t.id, 'destroyAll');
|
|
97
|
+
}
|
|
98
|
+
function pause(id) {
|
|
99
|
+
const rec = timers.get(id);
|
|
100
|
+
if (!rec || rec.timer == null)
|
|
101
|
+
return;
|
|
102
|
+
clearTimeout(rec.timer);
|
|
103
|
+
rec.remaining = Math.max(0, rec.remaining - (now() - rec.startedAt));
|
|
104
|
+
rec.timer = null;
|
|
105
|
+
}
|
|
106
|
+
function resume(id) {
|
|
107
|
+
const rec = timers.get(id);
|
|
108
|
+
if (!rec || rec.timer != null || rec.remaining <= 0)
|
|
109
|
+
return;
|
|
110
|
+
rec.startedAt = now();
|
|
111
|
+
rec.timer = setTimeout(() => close(id, 'timeout'), rec.remaining);
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
getItems: () => items.slice(),
|
|
115
|
+
subscribe(listener) {
|
|
116
|
+
listeners.add(listener);
|
|
117
|
+
return () => listeners.delete(listener);
|
|
118
|
+
},
|
|
119
|
+
open,
|
|
120
|
+
close,
|
|
121
|
+
destroyAll,
|
|
122
|
+
pause,
|
|
123
|
+
resume,
|
|
124
|
+
destroy() {
|
|
125
|
+
for (const t of items)
|
|
126
|
+
clearTimer(t.id);
|
|
127
|
+
timers.clear();
|
|
128
|
+
items = [];
|
|
129
|
+
listeners.clear();
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=notification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../src/notification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification.test.d.ts","sourceRoot":"","sources":["../src/notification.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { createNotificationStore } from './notification.js';
|
|
3
|
+
describe('createNotificationStore', () => {
|
|
4
|
+
beforeEach(() => vi.useFakeTimers());
|
|
5
|
+
afterEach(() => vi.useRealTimers());
|
|
6
|
+
it('opens a notification and returns its id', () => {
|
|
7
|
+
const s = createNotificationStore();
|
|
8
|
+
const id = s.open({ title: 'Done', content: 'Saved', duration: 0 });
|
|
9
|
+
expect(typeof id).toBe('string');
|
|
10
|
+
expect(s.getItems()[0]?.title).toBe('Done');
|
|
11
|
+
s.destroy();
|
|
12
|
+
});
|
|
13
|
+
it('auto-dismisses after duration (default 4.5s)', () => {
|
|
14
|
+
const s = createNotificationStore();
|
|
15
|
+
s.open({ title: 'x' });
|
|
16
|
+
vi.advanceTimersByTime(4499);
|
|
17
|
+
expect(s.getItems().length).toBe(1);
|
|
18
|
+
vi.advanceTimersByTime(1);
|
|
19
|
+
expect(s.getItems().length).toBe(0);
|
|
20
|
+
s.destroy();
|
|
21
|
+
});
|
|
22
|
+
it('duration 0 persists', () => {
|
|
23
|
+
const s = createNotificationStore();
|
|
24
|
+
s.open({ title: 'stay', duration: 0 });
|
|
25
|
+
vi.advanceTimersByTime(100000);
|
|
26
|
+
expect(s.getItems().length).toBe(1);
|
|
27
|
+
s.destroy();
|
|
28
|
+
});
|
|
29
|
+
it('id dedup updates in place', () => {
|
|
30
|
+
const s = createNotificationStore();
|
|
31
|
+
const id = s.open({ title: 'v1', duration: 0 });
|
|
32
|
+
s.open({ id, title: 'v2', duration: 0 });
|
|
33
|
+
expect(s.getItems().length).toBe(1);
|
|
34
|
+
expect(s.getItems()[0]?.title).toBe('v2');
|
|
35
|
+
s.destroy();
|
|
36
|
+
});
|
|
37
|
+
it('FIFO is per-placement', () => {
|
|
38
|
+
const s = createNotificationStore({ maxCount: 2 });
|
|
39
|
+
s.open({ title: 'a', placement: 'topRight', duration: 0 });
|
|
40
|
+
s.open({ title: 'b', placement: 'topRight', duration: 0 });
|
|
41
|
+
s.open({ title: 'c', placement: 'topRight', duration: 0 });
|
|
42
|
+
// topRight evicts oldest 'a'
|
|
43
|
+
const tr = s.getItems().filter((t) => t.placement === 'topRight');
|
|
44
|
+
expect(tr.map((t) => t.title)).toEqual(['b', 'c']);
|
|
45
|
+
// a different placement is unaffected
|
|
46
|
+
s.open({ title: 'd', placement: 'bottomLeft', duration: 0 });
|
|
47
|
+
expect(s.getItems().filter((t) => t.placement === 'bottomLeft').length).toBe(1);
|
|
48
|
+
s.destroy();
|
|
49
|
+
});
|
|
50
|
+
it('close and destroyAll (optionally by placement)', () => {
|
|
51
|
+
const s = createNotificationStore();
|
|
52
|
+
const a = s.open({ title: 'a', placement: 'topRight', duration: 0 });
|
|
53
|
+
s.open({ title: 'b', placement: 'bottomLeft', duration: 0 });
|
|
54
|
+
s.close(a);
|
|
55
|
+
expect(s.getItems().map((t) => t.title)).toEqual(['b']);
|
|
56
|
+
s.open({ title: 'c', placement: 'topRight', duration: 0 });
|
|
57
|
+
s.destroyAll('topRight'); // only topRight cleared
|
|
58
|
+
expect(s.getItems().map((t) => t.title)).toEqual(['b']);
|
|
59
|
+
s.destroyAll(); // all cleared
|
|
60
|
+
expect(s.getItems().length).toBe(0);
|
|
61
|
+
s.destroy();
|
|
62
|
+
});
|
|
63
|
+
it('pause/resume preserves remaining time', () => {
|
|
64
|
+
const s = createNotificationStore();
|
|
65
|
+
const id = s.open({ title: 'x', duration: 4 });
|
|
66
|
+
vi.advanceTimersByTime(1000);
|
|
67
|
+
s.pause(id);
|
|
68
|
+
vi.advanceTimersByTime(10000);
|
|
69
|
+
expect(s.getItems().length).toBe(1);
|
|
70
|
+
s.resume(id);
|
|
71
|
+
vi.advanceTimersByTime(3000);
|
|
72
|
+
expect(s.getItems().length).toBe(0);
|
|
73
|
+
s.destroy();
|
|
74
|
+
});
|
|
75
|
+
it('default type and placement', () => {
|
|
76
|
+
const s = createNotificationStore();
|
|
77
|
+
s.open({ title: 'x', duration: 0 });
|
|
78
|
+
const item = s.getItems()[0];
|
|
79
|
+
expect(item.type).toBe('default');
|
|
80
|
+
expect(item.placement).toBe('topRight');
|
|
81
|
+
s.destroy();
|
|
82
|
+
});
|
|
83
|
+
it('showProgress/theme/footer default to off/light/undefined', () => {
|
|
84
|
+
const s = createNotificationStore();
|
|
85
|
+
s.open({ title: 'x', duration: 0 });
|
|
86
|
+
const item = s.getItems()[0];
|
|
87
|
+
expect(item.showProgress).toBe(false);
|
|
88
|
+
expect(item.theme).toBe('light');
|
|
89
|
+
expect(item.footer).toBeUndefined();
|
|
90
|
+
s.destroy();
|
|
91
|
+
});
|
|
92
|
+
it('carries showProgress/theme/footer through to the item', () => {
|
|
93
|
+
const s = createNotificationStore();
|
|
94
|
+
const footer = { __snippet: true };
|
|
95
|
+
s.open({ title: 'x', duration: 0, showProgress: true, theme: 'dark', footer });
|
|
96
|
+
const item = s.getItems()[0];
|
|
97
|
+
expect(item.showProgress).toBe(true);
|
|
98
|
+
expect(item.theme).toBe('dark');
|
|
99
|
+
expect(item.footer).toBe(footer);
|
|
100
|
+
s.destroy();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=notification.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification.test.js","sourceRoot":"","sources":["../src/notification.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createOverflowList helpers — framework-agnostic overflow-collapse math.
|
|
3
|
+
* Pure functions only: given measured item widths + container width, compute
|
|
4
|
+
* how many leading items fit before the rest collapse into a "+N" node. No DOM,
|
|
5
|
+
* no framework deps, no internal mutable state — the svelte layer measures DOM
|
|
6
|
+
* (ResizeObserver) and feeds widths in. See specs/components/show/OverflowList.spec.md §3.
|
|
7
|
+
* The fit math is axis-agnostic — horizontal/vertical only changes which DOM
|
|
8
|
+
* dimension the svelte layer measures — and `computeOverflowPartition` adds
|
|
9
|
+
* `collapseFrom: 'start' | 'end'` for head- vs tail-collapse.
|
|
10
|
+
*/
|
|
11
|
+
export interface OverflowComputeInput {
|
|
12
|
+
/** measured main-axis size of each item, in document order */
|
|
13
|
+
itemSizes: readonly number[];
|
|
14
|
+
/** available container main-axis size */
|
|
15
|
+
containerSize: number;
|
|
16
|
+
/** main-axis size of the "+N" overflow node (reserved when collapsing) */
|
|
17
|
+
overflowSize: number;
|
|
18
|
+
/** gap between adjacent items */
|
|
19
|
+
gap: number;
|
|
20
|
+
/** items that must never be collapsed (indexes) */
|
|
21
|
+
alwaysVisible?: readonly number[];
|
|
22
|
+
/** never collapse below this many visible items (prefer overflow instead) */
|
|
23
|
+
minVisibleItems?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface OverflowComputeResult {
|
|
26
|
+
/** number of leading items rendered visibly */
|
|
27
|
+
visibleCount: number;
|
|
28
|
+
/** number of items collapsed into the overflow node */
|
|
29
|
+
overflowCount: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compute how many leading items fit. If all fit, no overflow node is reserved.
|
|
33
|
+
* Otherwise reserve `overflowSize` (+ a gap) and fit as many leading items as
|
|
34
|
+
* possible. `alwaysVisible` indexes and `minVisibleItems` raise the floor.
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeVisibleCount(input: OverflowComputeInput): OverflowComputeResult;
|
|
37
|
+
/** which end the overflow node collapses from: trailing (`end`) or leading (`start`) */
|
|
38
|
+
export type CollapseFrom = 'end' | 'start';
|
|
39
|
+
export interface OverflowPartitionInput extends OverflowComputeInput {
|
|
40
|
+
/** collapse trailing items (`end`, default) or leading items (`start`) */
|
|
41
|
+
collapseFrom?: CollapseFrom;
|
|
42
|
+
}
|
|
43
|
+
export interface OverflowPartitionResult extends OverflowComputeResult {
|
|
44
|
+
/** indexes rendered visibly, in document order */
|
|
45
|
+
visibleIndexes: number[];
|
|
46
|
+
/** indexes collapsed into the overflow node, in document order */
|
|
47
|
+
overflowIndexes: number[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Partition items into visible + overflow honoring `collapseFrom`. The fit math
|
|
51
|
+
* is direction-agnostic (the svelte layer feeds the main-axis sizes regardless
|
|
52
|
+
* of horizontal/vertical), so the same {@link computeVisibleCount} drives both
|
|
53
|
+
* ends — for `start` we mirror the size array, fit the same number of items, and
|
|
54
|
+
* map the kept window back to the trailing positions.
|
|
55
|
+
*
|
|
56
|
+
* `end` → visible = leading [0..k), overflow = trailing [k..count)
|
|
57
|
+
* `start`→ visible = trailing [count-k..count), overflow = leading [0..count-k)
|
|
58
|
+
*
|
|
59
|
+
* `alwaysVisible` indexes and `minVisibleItems` raise the visible-count floor in
|
|
60
|
+
* both directions (mirrored for `start`).
|
|
61
|
+
*/
|
|
62
|
+
export declare function computeOverflowPartition(input: OverflowPartitionInput): OverflowPartitionResult;
|
|
63
|
+
/**
|
|
64
|
+
* Tabs dropdown-overflow partition input. Given measured tab sizes + the bar's
|
|
65
|
+
* available main-axis size, decide which leading tabs render inline and which
|
|
66
|
+
* collapse into a "more" trigger. Pure math: the svelte layer measures DOM
|
|
67
|
+
* (ResizeObserver) and feeds sizes in. The active tab is always kept visible
|
|
68
|
+
* (Semi behavior) — if it would collapse, it is pulled into the visible set so
|
|
69
|
+
* the selected panel's tab is never hidden behind the dropdown.
|
|
70
|
+
*/
|
|
71
|
+
export interface TabOverflowInput {
|
|
72
|
+
/** measured main-axis size of each tab, in document order */
|
|
73
|
+
tabSizes: readonly number[];
|
|
74
|
+
/** available main-axis size of the tab bar (minus reserved chrome) */
|
|
75
|
+
containerSize: number;
|
|
76
|
+
/** main-axis size of the "more" trigger (reserved when collapsing) */
|
|
77
|
+
moreSize: number;
|
|
78
|
+
/** gap between adjacent tabs */
|
|
79
|
+
gap: number;
|
|
80
|
+
/** index of the active tab; always kept in the visible set when valid */
|
|
81
|
+
activeIndex?: number;
|
|
82
|
+
}
|
|
83
|
+
export interface TabOverflowResult {
|
|
84
|
+
/** tab indexes rendered inline, in document order */
|
|
85
|
+
visibleIndexes: number[];
|
|
86
|
+
/** tab indexes collapsed into the "more" dropdown, in document order */
|
|
87
|
+
overflowIndexes: number[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Partition tabs into visible (inline) and overflow (collapsed into "more").
|
|
91
|
+
* Reuses {@link computeVisibleCount} for the leading-fit math, then guarantees
|
|
92
|
+
* the active tab is visible by swapping it into the last visible slot if it
|
|
93
|
+
* landed in the overflow set.
|
|
94
|
+
*/
|
|
95
|
+
export declare function computeTabOverflow(input: TabOverflowInput): TabOverflowResult;
|
|
96
|
+
/**
|
|
97
|
+
* Apply hysteresis: keep the previous visibleCount unless the new computation
|
|
98
|
+
* differs by enough to cross the threshold band, preventing flicker at the
|
|
99
|
+
* boundary width. Returns the count to actually render.
|
|
100
|
+
*/
|
|
101
|
+
export declare function applyHysteresis(prev: number, next: number, prevContainerSize: number, containerSize: number, threshold: number): number;
|
|
102
|
+
//# sourceMappingURL=overflow-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow-list.d.ts","sourceRoot":"","sources":["../src/overflow-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;CACvB;AAWD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAsCtF;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAClE,0EAA0E;IAC1E,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,kDAAkD;IAClD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kEAAkE;IAClE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,sBAAsB,GAC5B,uBAAuB,CAiCzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,wEAAwE;IACxE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAqC7E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,MAAM,CAOR"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createOverflowList helpers — framework-agnostic overflow-collapse math.
|
|
3
|
+
* Pure functions only: given measured item widths + container width, compute
|
|
4
|
+
* how many leading items fit before the rest collapse into a "+N" node. No DOM,
|
|
5
|
+
* no framework deps, no internal mutable state — the svelte layer measures DOM
|
|
6
|
+
* (ResizeObserver) and feeds widths in. See specs/components/show/OverflowList.spec.md §3.
|
|
7
|
+
* The fit math is axis-agnostic — horizontal/vertical only changes which DOM
|
|
8
|
+
* dimension the svelte layer measures — and `computeOverflowPartition` adds
|
|
9
|
+
* `collapseFrom: 'start' | 'end'` for head- vs tail-collapse.
|
|
10
|
+
*/
|
|
11
|
+
/** sum of `n` item sizes plus the gaps between them */
|
|
12
|
+
function rowWidth(sizes, n, gap) {
|
|
13
|
+
if (n <= 0)
|
|
14
|
+
return 0;
|
|
15
|
+
let total = 0;
|
|
16
|
+
for (let i = 0; i < n; i += 1)
|
|
17
|
+
total += sizes[i] ?? 0;
|
|
18
|
+
total += gap * (n - 1);
|
|
19
|
+
return total;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Compute how many leading items fit. If all fit, no overflow node is reserved.
|
|
23
|
+
* Otherwise reserve `overflowSize` (+ a gap) and fit as many leading items as
|
|
24
|
+
* possible. `alwaysVisible` indexes and `minVisibleItems` raise the floor.
|
|
25
|
+
*/
|
|
26
|
+
export function computeVisibleCount(input) {
|
|
27
|
+
const { itemSizes, containerSize, overflowSize, gap, alwaysVisible = [], minVisibleItems = 0, } = input;
|
|
28
|
+
const count = itemSizes.length;
|
|
29
|
+
if (count === 0)
|
|
30
|
+
return { visibleCount: 0, overflowCount: 0 };
|
|
31
|
+
// Everything fits → no collapse.
|
|
32
|
+
if (rowWidth(itemSizes, count, gap) <= containerSize) {
|
|
33
|
+
return { visibleCount: count, overflowCount: 0 };
|
|
34
|
+
}
|
|
35
|
+
// Need to collapse: reserve room for the overflow node.
|
|
36
|
+
const reserved = overflowSize + gap;
|
|
37
|
+
let visible = 0;
|
|
38
|
+
for (let n = 1; n <= count; n += 1) {
|
|
39
|
+
if (rowWidth(itemSizes, n, gap) + reserved <= containerSize) {
|
|
40
|
+
visible = n;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Honor floors: alwaysVisible highest index + 1, and minVisibleItems.
|
|
47
|
+
const maxAlways = alwaysVisible.length ? Math.max(...alwaysVisible) + 1 : 0;
|
|
48
|
+
const floor = Math.min(count, Math.max(visible, maxAlways, minVisibleItems));
|
|
49
|
+
visible = Math.max(visible, floor);
|
|
50
|
+
// If the floor pushed us to render everything, there's no overflow.
|
|
51
|
+
if (visible >= count)
|
|
52
|
+
return { visibleCount: count, overflowCount: 0 };
|
|
53
|
+
return { visibleCount: visible, overflowCount: count - visible };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Partition items into visible + overflow honoring `collapseFrom`. The fit math
|
|
57
|
+
* is direction-agnostic (the svelte layer feeds the main-axis sizes regardless
|
|
58
|
+
* of horizontal/vertical), so the same {@link computeVisibleCount} drives both
|
|
59
|
+
* ends — for `start` we mirror the size array, fit the same number of items, and
|
|
60
|
+
* map the kept window back to the trailing positions.
|
|
61
|
+
*
|
|
62
|
+
* `end` → visible = leading [0..k), overflow = trailing [k..count)
|
|
63
|
+
* `start`→ visible = trailing [count-k..count), overflow = leading [0..count-k)
|
|
64
|
+
*
|
|
65
|
+
* `alwaysVisible` indexes and `minVisibleItems` raise the visible-count floor in
|
|
66
|
+
* both directions (mirrored for `start`).
|
|
67
|
+
*/
|
|
68
|
+
export function computeOverflowPartition(input) {
|
|
69
|
+
const { itemSizes, collapseFrom = 'end', alwaysVisible = [] } = input;
|
|
70
|
+
const count = itemSizes.length;
|
|
71
|
+
if (collapseFrom === 'end') {
|
|
72
|
+
const { visibleCount, overflowCount } = computeVisibleCount(input);
|
|
73
|
+
const visibleIndexes = [];
|
|
74
|
+
const overflowIndexes = [];
|
|
75
|
+
for (let i = 0; i < count; i += 1) {
|
|
76
|
+
if (i < visibleCount)
|
|
77
|
+
visibleIndexes.push(i);
|
|
78
|
+
else
|
|
79
|
+
overflowIndexes.push(i);
|
|
80
|
+
}
|
|
81
|
+
return { visibleCount, overflowCount, visibleIndexes, overflowIndexes };
|
|
82
|
+
}
|
|
83
|
+
// start: mirror so the same leading-fit math keeps the *trailing* window.
|
|
84
|
+
const mirroredSizes = [...itemSizes].reverse();
|
|
85
|
+
// mirror alwaysVisible indexes too (i → count-1-i).
|
|
86
|
+
const mirroredAlways = alwaysVisible.map((i) => count - 1 - i);
|
|
87
|
+
const { visibleCount } = computeVisibleCount({
|
|
88
|
+
...input,
|
|
89
|
+
itemSizes: mirroredSizes,
|
|
90
|
+
alwaysVisible: mirroredAlways,
|
|
91
|
+
});
|
|
92
|
+
const overflowCount = count - visibleCount;
|
|
93
|
+
const firstVisible = overflowCount; // [overflowCount .. count) stay visible
|
|
94
|
+
const visibleIndexes = [];
|
|
95
|
+
const overflowIndexes = [];
|
|
96
|
+
for (let i = 0; i < count; i += 1) {
|
|
97
|
+
if (i < firstVisible)
|
|
98
|
+
overflowIndexes.push(i);
|
|
99
|
+
else
|
|
100
|
+
visibleIndexes.push(i);
|
|
101
|
+
}
|
|
102
|
+
return { visibleCount, overflowCount, visibleIndexes, overflowIndexes };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Partition tabs into visible (inline) and overflow (collapsed into "more").
|
|
106
|
+
* Reuses {@link computeVisibleCount} for the leading-fit math, then guarantees
|
|
107
|
+
* the active tab is visible by swapping it into the last visible slot if it
|
|
108
|
+
* landed in the overflow set.
|
|
109
|
+
*/
|
|
110
|
+
export function computeTabOverflow(input) {
|
|
111
|
+
const { tabSizes, containerSize, moreSize, gap, activeIndex } = input;
|
|
112
|
+
const count = tabSizes.length;
|
|
113
|
+
if (count === 0)
|
|
114
|
+
return { visibleIndexes: [], overflowIndexes: [] };
|
|
115
|
+
const { visibleCount } = computeVisibleCount({
|
|
116
|
+
itemSizes: tabSizes,
|
|
117
|
+
containerSize,
|
|
118
|
+
overflowSize: moreSize,
|
|
119
|
+
gap,
|
|
120
|
+
});
|
|
121
|
+
// Leading tabs are visible by default.
|
|
122
|
+
const visible = new Set();
|
|
123
|
+
for (let i = 0; i < visibleCount; i += 1)
|
|
124
|
+
visible.add(i);
|
|
125
|
+
// Guarantee the active tab is visible: if it overflowed, swap it for the last
|
|
126
|
+
// leading visible tab (which is then pushed into overflow). Keeps the visible
|
|
127
|
+
// count stable so the "more" reservation still holds.
|
|
128
|
+
if (activeIndex !== undefined &&
|
|
129
|
+
activeIndex >= 0 &&
|
|
130
|
+
activeIndex < count &&
|
|
131
|
+
!visible.has(activeIndex) &&
|
|
132
|
+
visibleCount > 0) {
|
|
133
|
+
visible.delete(visibleCount - 1);
|
|
134
|
+
visible.add(activeIndex);
|
|
135
|
+
}
|
|
136
|
+
const visibleIndexes = [];
|
|
137
|
+
const overflowIndexes = [];
|
|
138
|
+
for (let i = 0; i < count; i += 1) {
|
|
139
|
+
if (visible.has(i))
|
|
140
|
+
visibleIndexes.push(i);
|
|
141
|
+
else
|
|
142
|
+
overflowIndexes.push(i);
|
|
143
|
+
}
|
|
144
|
+
return { visibleIndexes, overflowIndexes };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Apply hysteresis: keep the previous visibleCount unless the new computation
|
|
148
|
+
* differs by enough to cross the threshold band, preventing flicker at the
|
|
149
|
+
* boundary width. Returns the count to actually render.
|
|
150
|
+
*/
|
|
151
|
+
export function applyHysteresis(prev, next, prevContainerSize, containerSize, threshold) {
|
|
152
|
+
// Only damp tiny size wobbles; a real resize (beyond threshold) always applies.
|
|
153
|
+
if (Math.abs(containerSize - prevContainerSize) <= threshold && next !== prev) {
|
|
154
|
+
// within the dead-band: prefer keeping more items visible (avoid collapse churn)
|
|
155
|
+
return Math.max(prev, next);
|
|
156
|
+
}
|
|
157
|
+
return next;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=overflow-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow-list.js","sourceRoot":"","sources":["../src/overflow-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow-list.test.d.ts","sourceRoot":"","sources":["../src/overflow-list.test.ts"],"names":[],"mappings":""}
|