@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,184 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { nextSortOrder, toggleSort, applySort, paginate, pageCount, selectAllState, toggleSelectAll, toggleRow, flattenTreeRows, conductRows, normalizeRowsToLeaves, toggleRowCheck, } from './table.js';
|
|
3
|
+
describe('sort cycling', () => {
|
|
4
|
+
it('cycles none β ascend β descend β none', () => {
|
|
5
|
+
expect(nextSortOrder(null)).toBe('ascend');
|
|
6
|
+
expect(nextSortOrder('ascend')).toBe('descend');
|
|
7
|
+
expect(nextSortOrder('descend')).toBe(null);
|
|
8
|
+
});
|
|
9
|
+
it('toggleSort starts a new column at ascend', () => {
|
|
10
|
+
const s = { key: 'a', order: 'descend' };
|
|
11
|
+
expect(toggleSort(s, 'b')).toEqual({ key: 'b', order: 'ascend' });
|
|
12
|
+
});
|
|
13
|
+
it('toggleSort cycles the same column and clears key at none', () => {
|
|
14
|
+
expect(toggleSort({ key: 'a', order: null }, 'a')).toEqual({ key: 'a', order: 'ascend' });
|
|
15
|
+
expect(toggleSort({ key: 'a', order: 'ascend' }, 'a')).toEqual({ key: 'a', order: 'descend' });
|
|
16
|
+
expect(toggleSort({ key: 'a', order: 'descend' }, 'a')).toEqual({ key: null, order: null });
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
describe('applySort', () => {
|
|
20
|
+
const data = [
|
|
21
|
+
{ id: 1, n: 3 },
|
|
22
|
+
{ id: 2, n: 1 },
|
|
23
|
+
{ id: 3, n: 1 },
|
|
24
|
+
{ id: 4, n: 2 },
|
|
25
|
+
];
|
|
26
|
+
const cmp = (a, b) => a.n - b.n;
|
|
27
|
+
it('returns a copy unchanged when order is null', () => {
|
|
28
|
+
const out = applySort(data, null, cmp);
|
|
29
|
+
expect(out).toEqual(data);
|
|
30
|
+
expect(out).not.toBe(data);
|
|
31
|
+
});
|
|
32
|
+
it('sorts ascending', () => {
|
|
33
|
+
expect(applySort(data, 'ascend', cmp).map((d) => d.id)).toEqual([2, 3, 4, 1]);
|
|
34
|
+
});
|
|
35
|
+
it('sorts descending', () => {
|
|
36
|
+
expect(applySort(data, 'descend', cmp).map((d) => d.id)).toEqual([1, 4, 2, 3]);
|
|
37
|
+
});
|
|
38
|
+
it('is stable for equal keys (ascend keeps original order)', () => {
|
|
39
|
+
// ids 2 and 3 both have n=1 β stay in original relative order
|
|
40
|
+
expect(applySort(data, 'ascend', cmp).slice(0, 2).map((d) => d.id)).toEqual([2, 3]);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('pagination', () => {
|
|
44
|
+
const data = Array.from({ length: 23 }, (_, i) => i + 1);
|
|
45
|
+
it('slices the right page', () => {
|
|
46
|
+
expect(paginate(data, 1, 10)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
47
|
+
expect(paginate(data, 3, 10)).toEqual([21, 22, 23]);
|
|
48
|
+
});
|
|
49
|
+
it('computes page count', () => {
|
|
50
|
+
expect(pageCount(23, 10)).toBe(3);
|
|
51
|
+
expect(pageCount(0, 10)).toBe(1);
|
|
52
|
+
expect(pageCount(20, 10)).toBe(2);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('selection', () => {
|
|
56
|
+
const keys = ['a', 'b', 'c', 'd'];
|
|
57
|
+
it('select-all state: none / some / all', () => {
|
|
58
|
+
expect(selectAllState(keys, new Set())).toEqual({ checked: false, indeterminate: false });
|
|
59
|
+
expect(selectAllState(keys, new Set(['a']))).toEqual({ checked: false, indeterminate: true });
|
|
60
|
+
expect(selectAllState(keys, new Set(keys))).toEqual({ checked: true, indeterminate: false });
|
|
61
|
+
});
|
|
62
|
+
it('excludes disabled rows from the all-computation', () => {
|
|
63
|
+
// d disabled; selecting a,b,c counts as "all selectable"
|
|
64
|
+
const st = selectAllState(keys, new Set(['a', 'b', 'c']), new Set(['d']));
|
|
65
|
+
expect(st).toEqual({ checked: true, indeterminate: false });
|
|
66
|
+
});
|
|
67
|
+
it('toggleSelectAll selects all selectable then clears', () => {
|
|
68
|
+
const on = toggleSelectAll(keys, new Set(), new Set(['d']));
|
|
69
|
+
expect([...on].sort()).toEqual(['a', 'b', 'c']); // d never auto-selected
|
|
70
|
+
const off = toggleSelectAll(keys, on, new Set(['d']));
|
|
71
|
+
expect(off.size).toBe(0);
|
|
72
|
+
});
|
|
73
|
+
it('toggleSelectAll preserves a pre-selected disabled row', () => {
|
|
74
|
+
const off = toggleSelectAll(keys, new Set(['a', 'b', 'c', 'd']), new Set(['d']));
|
|
75
|
+
expect([...off]).toEqual(['d']); // selectable cleared, disabled d kept
|
|
76
|
+
});
|
|
77
|
+
it('toggleRow flips a single row', () => {
|
|
78
|
+
expect([...toggleRow(new Set(), 'a')]).toEqual(['a']);
|
|
79
|
+
expect([...toggleRow(new Set(['a']), 'a')]).toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('flattenTreeRows', () => {
|
|
83
|
+
const data = [
|
|
84
|
+
{
|
|
85
|
+
id: 1,
|
|
86
|
+
children: [{ id: 11 }, { id: 12, children: [{ id: 121 }] }],
|
|
87
|
+
},
|
|
88
|
+
{ id: 2 },
|
|
89
|
+
{ id: 3, children: [{ id: 31 }] },
|
|
90
|
+
];
|
|
91
|
+
const getKey = (r) => r.id;
|
|
92
|
+
const getChildren = (r) => r.children;
|
|
93
|
+
it('shows only top-level rows when nothing is expanded', () => {
|
|
94
|
+
const flat = flattenTreeRows(data, new Set(), getKey, getChildren);
|
|
95
|
+
expect(flat.map((r) => r.key)).toEqual([1, 2, 3]);
|
|
96
|
+
expect(flat.every((r) => r.level === 0)).toBe(true);
|
|
97
|
+
expect(flat.map((r) => r.hasChildren)).toEqual([true, false, true]);
|
|
98
|
+
expect(flat.map((r) => r.topIndex)).toEqual([0, 1, 2]);
|
|
99
|
+
});
|
|
100
|
+
it('reveals children of expanded rows with incremented level', () => {
|
|
101
|
+
const flat = flattenTreeRows(data, new Set([1]), getKey, getChildren);
|
|
102
|
+
expect(flat.map((r) => r.key)).toEqual([1, 11, 12, 2, 3]);
|
|
103
|
+
const r12 = flat.find((r) => r.key === 12);
|
|
104
|
+
expect(r12.level).toBe(1);
|
|
105
|
+
expect(r12.parentKey).toBe(1);
|
|
106
|
+
expect(r12.hasChildren).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
it('recurses into nested expanded rows and carries topIndex', () => {
|
|
109
|
+
const flat = flattenTreeRows(data, new Set([1, 12]), getKey, getChildren);
|
|
110
|
+
expect(flat.map((r) => r.key)).toEqual([1, 11, 12, 121, 2, 3]);
|
|
111
|
+
const deep = flat.find((r) => r.key === 121);
|
|
112
|
+
expect(deep.level).toBe(2);
|
|
113
|
+
expect(deep.parentKey).toBe(12);
|
|
114
|
+
expect(deep.topIndex).toBe(0);
|
|
115
|
+
});
|
|
116
|
+
it('does not expand a key with no children', () => {
|
|
117
|
+
const flat = flattenTreeRows(data, new Set([2]), getKey, getChildren);
|
|
118
|
+
expect(flat.map((r) => r.key)).toEqual([1, 2, 3]);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('tree row selection conduction', () => {
|
|
122
|
+
// 1 β 11
|
|
123
|
+
// β 12 β 121
|
|
124
|
+
// β 122
|
|
125
|
+
// 2
|
|
126
|
+
const data = [
|
|
127
|
+
{
|
|
128
|
+
id: 1,
|
|
129
|
+
children: [
|
|
130
|
+
{ id: 11 },
|
|
131
|
+
{ id: 12, children: [{ id: 121 }, { id: 122 }] },
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{ id: 2 },
|
|
135
|
+
];
|
|
136
|
+
const getKey = (r) => r.id;
|
|
137
|
+
const getChildren = (r) => r.children;
|
|
138
|
+
const isDisabled = (r) => !!r.disabled;
|
|
139
|
+
it('conductRows: checking a parent fully checks descendants', () => {
|
|
140
|
+
const { checked, half } = conductRows(data, new Set([1]), getKey, getChildren);
|
|
141
|
+
expect([...checked].sort((a, b) => Number(a) - Number(b))).toEqual([1, 11, 12, 121, 122]);
|
|
142
|
+
expect(half.size).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
it('conductRows: partial children make ancestors half', () => {
|
|
145
|
+
const { checked, half } = conductRows(data, new Set([121]), getKey, getChildren);
|
|
146
|
+
expect([...checked]).toEqual([121]);
|
|
147
|
+
expect([...half].sort((a, b) => Number(a) - Number(b))).toEqual([1, 12]);
|
|
148
|
+
});
|
|
149
|
+
it('conductRows: all leaves of a parent β parent checked, not half', () => {
|
|
150
|
+
const { checked, half } = conductRows(data, new Set([121, 122]), getKey, getChildren);
|
|
151
|
+
expect(checked.has(12)).toBe(true);
|
|
152
|
+
expect(half.has(12)).toBe(false); // 12 fully checked, not half
|
|
153
|
+
expect(half.has(1)).toBe(true); // 1 still partial (11 unchecked)
|
|
154
|
+
});
|
|
155
|
+
it('conductRows: disabled leaf excluded from parent computation', () => {
|
|
156
|
+
const withDisabled = [
|
|
157
|
+
{ id: 1, children: [{ id: 11 }, { id: 12, disabled: true }] },
|
|
158
|
+
];
|
|
159
|
+
// check only 11; 12 is disabled so 1 counts only the enabled leaf β checked
|
|
160
|
+
const { checked, half } = conductRows(withDisabled, new Set([11]), getKey, getChildren, isDisabled);
|
|
161
|
+
expect(checked.has(1)).toBe(true);
|
|
162
|
+
expect(half.has(1)).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
it('toggleRowCheck: toggling a parent adds/removes all leaves', () => {
|
|
165
|
+
const on = toggleRowCheck(data, new Set(), 1, getKey, getChildren);
|
|
166
|
+
expect([...on].sort((a, b) => Number(a) - Number(b))).toEqual([11, 121, 122]); // leaf-level base
|
|
167
|
+
const off = toggleRowCheck(data, on, 1, getKey, getChildren);
|
|
168
|
+
expect(off.size).toBe(0);
|
|
169
|
+
});
|
|
170
|
+
it('toggleRowCheck: round-trips conductRows output (parent keys)', () => {
|
|
171
|
+
// feed conduct output (contains parent keys) back through toggle
|
|
172
|
+
const { checked } = conductRows(data, new Set([1]), getKey, getChildren);
|
|
173
|
+
const off = toggleRowCheck(data, checked, 12, getKey, getChildren);
|
|
174
|
+
// toggling 12 off should remove its leaves only, keep 11
|
|
175
|
+
expect(off.has(11)).toBe(true);
|
|
176
|
+
expect(off.has(121)).toBe(false);
|
|
177
|
+
expect(off.has(122)).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
it('normalizeRowsToLeaves: expands parents to leaves, drops unknown keys', () => {
|
|
180
|
+
const out = normalizeRowsToLeaves(data, new Set([1, 999]), getKey, getChildren);
|
|
181
|
+
expect([...out].sort((a, b) => Number(a) - Number(b))).toEqual([11, 121, 122]);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=table.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.test.js","sourceRoot":"","sources":["../src/table.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* textarea β framework-agnostic autosize height math for <textarea>.
|
|
3
|
+
* Pure: given the measured scrollHeight (with box-sizing: border-box, i.e. the
|
|
4
|
+
* content height the browser reports) plus the row metrics, returns the height
|
|
5
|
+
* to apply and whether vertical scrolling is needed (maxRows reached). No DOM.
|
|
6
|
+
* The render layer measures scrollHeight and applies the result.
|
|
7
|
+
* See specs/components/input/Input.spec.md (TextArea autosize).
|
|
8
|
+
*/
|
|
9
|
+
export interface AutosizeInput {
|
|
10
|
+
/** measured content height (px), e.g. textarea.scrollHeight with border-box */
|
|
11
|
+
scrollHeight: number;
|
|
12
|
+
/** single line height (px), from computed line-height */
|
|
13
|
+
lineHeight: number;
|
|
14
|
+
/** total vertical padding (top + bottom, px) */
|
|
15
|
+
verticalPadding: number;
|
|
16
|
+
/** total vertical border (top + bottom, px) */
|
|
17
|
+
verticalBorder: number;
|
|
18
|
+
/** minimum visible rows (default 1) */
|
|
19
|
+
minRows?: number;
|
|
20
|
+
/** maximum visible rows before scrolling (default Infinity) */
|
|
21
|
+
maxRows?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface AutosizeResult {
|
|
24
|
+
/** height (px) to apply to the textarea (border-box) */
|
|
25
|
+
height: number;
|
|
26
|
+
/** whether content exceeds maxRows and vertical scroll is needed */
|
|
27
|
+
overflow: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compute the autosize height. Clamps the content-driven height into
|
|
31
|
+
* [minRows, maxRows]; sets overflow=true only when the natural content exceeds
|
|
32
|
+
* the maxRows cap (so the caller can switch overflow-y to auto).
|
|
33
|
+
*/
|
|
34
|
+
export declare function computeAutosizeHeight(input: AutosizeInput): AutosizeResult;
|
|
35
|
+
/**
|
|
36
|
+
* Count the visible characters of a string. Pure (no DOM).
|
|
37
|
+
*
|
|
38
|
+
* - `graphemes: false` (default) β spread-based code-point count (`[...s].length`),
|
|
39
|
+
* matching the existing behaviour; zero extra cost.
|
|
40
|
+
* - `graphemes: true` β counts user-perceived characters via `Intl.Segmenter`
|
|
41
|
+
* (correctly handles emoji, ZWJ sequences, combining marks, flags). Falls back
|
|
42
|
+
* to the code-point count when `Intl.Segmenter` is unavailable.
|
|
43
|
+
*/
|
|
44
|
+
export declare function countCharacters(value: string, options?: {
|
|
45
|
+
graphemes?: boolean;
|
|
46
|
+
locale?: string;
|
|
47
|
+
}): number;
|
|
48
|
+
//# sourceMappingURL=textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../src/textarea.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAYD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAiB1E;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,MAAM,CAUR"}
|
package/dist/textarea.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* textarea β framework-agnostic autosize height math for <textarea>.
|
|
3
|
+
* Pure: given the measured scrollHeight (with box-sizing: border-box, i.e. the
|
|
4
|
+
* content height the browser reports) plus the row metrics, returns the height
|
|
5
|
+
* to apply and whether vertical scrolling is needed (maxRows reached). No DOM.
|
|
6
|
+
* The render layer measures scrollHeight and applies the result.
|
|
7
|
+
* See specs/components/input/Input.spec.md (TextArea autosize).
|
|
8
|
+
*/
|
|
9
|
+
/** border-box height for a given number of text rows. */
|
|
10
|
+
function heightForRows(rows, lineHeight, verticalPadding, verticalBorder) {
|
|
11
|
+
return rows * lineHeight + verticalPadding + verticalBorder;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compute the autosize height. Clamps the content-driven height into
|
|
15
|
+
* [minRows, maxRows]; sets overflow=true only when the natural content exceeds
|
|
16
|
+
* the maxRows cap (so the caller can switch overflow-y to auto).
|
|
17
|
+
*/
|
|
18
|
+
export function computeAutosizeHeight(input) {
|
|
19
|
+
const { scrollHeight, lineHeight, verticalPadding, verticalBorder } = input;
|
|
20
|
+
const minRows = input.minRows ?? 1;
|
|
21
|
+
const maxRows = input.maxRows ?? Number.POSITIVE_INFINITY;
|
|
22
|
+
const minHeight = heightForRows(minRows, lineHeight, verticalPadding, verticalBorder);
|
|
23
|
+
const maxHeight = Number.isFinite(maxRows)
|
|
24
|
+
? heightForRows(maxRows, lineHeight, verticalPadding, verticalBorder)
|
|
25
|
+
: Number.POSITIVE_INFINITY;
|
|
26
|
+
// scrollHeight already includes padding (border-box reporting); it is the
|
|
27
|
+
// natural content height. Clamp it into [minHeight, maxHeight].
|
|
28
|
+
const natural = scrollHeight;
|
|
29
|
+
const overflow = natural > maxHeight;
|
|
30
|
+
const height = Math.min(Math.max(natural, minHeight), maxHeight);
|
|
31
|
+
return { height, overflow };
|
|
32
|
+
}
|
|
33
|
+
// --- character counting -----------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Lazily-built, locale-keyed cache of `Intl.Segmenter` instances. The Segmenter
|
|
36
|
+
* is only constructed when grapheme counting is actually requested (perf budget:
|
|
37
|
+
* default length counting has zero extra cost). One instance per locale is reused.
|
|
38
|
+
*/
|
|
39
|
+
const segmenterCache = new Map();
|
|
40
|
+
function getGraphemeSegmenter(locale) {
|
|
41
|
+
const key = locale ?? '';
|
|
42
|
+
if (segmenterCache.has(key))
|
|
43
|
+
return segmenterCache.get(key) ?? null;
|
|
44
|
+
let seg = null;
|
|
45
|
+
// Intl.Segmenter is widely supported but guard for older runtimes/SSR.
|
|
46
|
+
if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
|
|
47
|
+
seg = new Intl.Segmenter(locale, { granularity: 'grapheme' });
|
|
48
|
+
}
|
|
49
|
+
segmenterCache.set(key, seg);
|
|
50
|
+
return seg;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Count the visible characters of a string. Pure (no DOM).
|
|
54
|
+
*
|
|
55
|
+
* - `graphemes: false` (default) β spread-based code-point count (`[...s].length`),
|
|
56
|
+
* matching the existing behaviour; zero extra cost.
|
|
57
|
+
* - `graphemes: true` β counts user-perceived characters via `Intl.Segmenter`
|
|
58
|
+
* (correctly handles emoji, ZWJ sequences, combining marks, flags). Falls back
|
|
59
|
+
* to the code-point count when `Intl.Segmenter` is unavailable.
|
|
60
|
+
*/
|
|
61
|
+
export function countCharacters(value, options) {
|
|
62
|
+
if (!value)
|
|
63
|
+
return 0;
|
|
64
|
+
if (!options?.graphemes)
|
|
65
|
+
return [...value].length;
|
|
66
|
+
const seg = getGraphemeSegmenter(options.locale);
|
|
67
|
+
if (!seg)
|
|
68
|
+
return [...value].length;
|
|
69
|
+
let n = 0;
|
|
70
|
+
// Iterate segments; the iterator yields one entry per grapheme cluster.
|
|
71
|
+
const iter = seg.segment(value)[Symbol.iterator]();
|
|
72
|
+
while (!iter.next().done)
|
|
73
|
+
n++;
|
|
74
|
+
return n;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../src/textarea.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwBH,yDAAyD;AACzD,SAAS,aAAa,CACpB,IAAY,EACZ,UAAkB,EAClB,eAAuB,EACvB,cAAsB;IAEtB,OAAO,IAAI,GAAG,UAAU,GAAG,eAAe,GAAG,cAAc,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAoB;IACxD,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;IAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,iBAAiB,CAAC;IAE1D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;IACtF,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,CAAC;QACrE,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAE7B,0EAA0E;IAC1E,gEAAgE;IAChE,MAAM,OAAO,GAAG,YAAY,CAAC;IAC7B,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IAEjE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,cAAc,GAAG,IAAI,GAAG,EAAiC,CAAC;AAEhE,SAAS,oBAAoB,CAAC,MAAe;IAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC;IACzB,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACpE,IAAI,GAAG,GAA0B,IAAI,CAAC;IACtC,uEAAuE;IACvE,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;QACxE,GAAG,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,OAAkD;IAElD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,CAAC,OAAO,EAAE,SAAS;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,wEAAwE;IACxE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI;QAAE,CAAC,EAAE,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.test.d.ts","sourceRoot":"","sources":["../src/textarea.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { computeAutosizeHeight, countCharacters } from './textarea.js';
|
|
3
|
+
// row metrics: line 20px, padding 8px (4+4), border 2px (1+1).
|
|
4
|
+
// 1 row = 20 + 8 + 2 = 30; 3 rows = 60 + 10 = 70; 5 rows = 100 + 10 = 110.
|
|
5
|
+
const metrics = { lineHeight: 20, verticalPadding: 8, verticalBorder: 2 };
|
|
6
|
+
describe('computeAutosizeHeight', () => {
|
|
7
|
+
it('grows to fit content between min and max', () => {
|
|
8
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 70, minRows: 1, maxRows: 5 });
|
|
9
|
+
expect(r.height).toBe(70); // 3 rows worth of content
|
|
10
|
+
expect(r.overflow).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
it('clamps up to minRows when content is shorter', () => {
|
|
13
|
+
// content 30px (1 row) but minRows 2 β 2 rows = 40 + 10 = 50
|
|
14
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 30, minRows: 2, maxRows: 6 });
|
|
15
|
+
expect(r.height).toBe(50);
|
|
16
|
+
expect(r.overflow).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
it('caps at maxRows and flags overflow when content exceeds it', () => {
|
|
19
|
+
// content 200px but maxRows 5 β cap 110, overflow true
|
|
20
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 200, minRows: 1, maxRows: 5 });
|
|
21
|
+
expect(r.height).toBe(110);
|
|
22
|
+
expect(r.overflow).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
it('does not overflow when content exactly fills maxRows', () => {
|
|
25
|
+
// exactly 5 rows = 110
|
|
26
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 110, minRows: 1, maxRows: 5 });
|
|
27
|
+
expect(r.height).toBe(110);
|
|
28
|
+
expect(r.overflow).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
it('defaults minRows=1 and maxRows=Infinity (no cap, never overflow)', () => {
|
|
31
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 1000 });
|
|
32
|
+
expect(r.height).toBe(1000);
|
|
33
|
+
expect(r.overflow).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
it('respects minRows even with default (Infinity) maxRows', () => {
|
|
36
|
+
const r = computeAutosizeHeight({ ...metrics, scrollHeight: 20, minRows: 3 });
|
|
37
|
+
expect(r.height).toBe(70); // 3 rows
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('countCharacters', () => {
|
|
41
|
+
it('returns 0 for empty string', () => {
|
|
42
|
+
expect(countCharacters('')).toBe(0);
|
|
43
|
+
expect(countCharacters('', { graphemes: true })).toBe(0);
|
|
44
|
+
});
|
|
45
|
+
it('counts ASCII identically in both modes', () => {
|
|
46
|
+
expect(countCharacters('hello')).toBe(5);
|
|
47
|
+
expect(countCharacters('hello', { graphemes: true })).toBe(5);
|
|
48
|
+
});
|
|
49
|
+
it('counts CJK by code point in default mode', () => {
|
|
50
|
+
expect(countCharacters('δ½ ε₯½δΈη')).toBe(4);
|
|
51
|
+
});
|
|
52
|
+
it('default mode counts a single emoji by code point (spread)', () => {
|
|
53
|
+
// π is one code point β spread length 1
|
|
54
|
+
expect(countCharacters('π')).toBe(1);
|
|
55
|
+
});
|
|
56
|
+
it('default mode splits ZWJ emoji into multiple code points', () => {
|
|
57
|
+
// π¨βπ©βπ§ = man + ZWJ + woman + ZWJ + girl β 5 code points via spread
|
|
58
|
+
expect(countCharacters('π¨βπ©βπ§')).toBe(5);
|
|
59
|
+
});
|
|
60
|
+
it('grapheme mode counts a ZWJ family emoji as one character', () => {
|
|
61
|
+
expect(countCharacters('π¨βπ©βπ§', { graphemes: true })).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
it('grapheme mode counts a flag emoji as one character', () => {
|
|
64
|
+
// π¨π³ is two regional-indicator code points β 1 grapheme
|
|
65
|
+
expect(countCharacters('π¨π³', { graphemes: true })).toBe(1);
|
|
66
|
+
});
|
|
67
|
+
it('grapheme mode counts combining marks as one character', () => {
|
|
68
|
+
// 'e' + combining acute accent β 1 grapheme, 2 code points
|
|
69
|
+
expect(countCharacters('eΜ')).toBe(2);
|
|
70
|
+
expect(countCharacters('eΜ', { graphemes: true })).toBe(1);
|
|
71
|
+
});
|
|
72
|
+
it('grapheme mode counts mixed text correctly', () => {
|
|
73
|
+
// a + family emoji + b β 3 graphemes
|
|
74
|
+
expect(countCharacters('aπ¨βπ©βπ§b', { graphemes: true })).toBe(3);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=textarea.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.test.js","sourceRoot":"","sources":["../src/textarea.test.ts"],"names":[],"mappings":"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"}
|
package/dist/time.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic time-column utilities for TimePicker.
|
|
3
|
+
* No DOM, no framework deps. See specs/components/input/TimePicker.spec.md Β§3/Β§4.
|
|
4
|
+
* Pure column math only β display formatting is the render layer's job (Intl).
|
|
5
|
+
*/
|
|
6
|
+
/** AM/PM meridiem in 12-hour mode. */
|
|
7
|
+
export type Meridiem = 'am' | 'pm';
|
|
8
|
+
/** A single selectable option in a time column. */
|
|
9
|
+
export interface TimeOption {
|
|
10
|
+
/** the underlying numeric value (hour 0-23 / 1-12, minute/second 0-59) */
|
|
11
|
+
value: number;
|
|
12
|
+
/** true when the value is disabled (placed by disabledXxx) */
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Disabled-providers passed straight through from the component props. */
|
|
16
|
+
export interface DisabledTime {
|
|
17
|
+
disabledHours?: () => number[];
|
|
18
|
+
disabledMinutes?: (hour: number) => number[];
|
|
19
|
+
disabledSeconds?: (hour: number, minute: number) => number[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build a stepped numeric range `[0, max)`.
|
|
23
|
+
* step β€ 0 is treated as 1.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildRange(max: number, step: number): number[];
|
|
26
|
+
/** Convert a 24-hour hour (0-23) to its 12-hour display hour (1-12). */
|
|
27
|
+
export declare function to12Hour(hour24: number): number;
|
|
28
|
+
/** Derive the meridiem ('am' | 'pm') of a 24-hour hour. */
|
|
29
|
+
export declare function meridiemOf(hour24: number): Meridiem;
|
|
30
|
+
/**
|
|
31
|
+
* Convert a 12-hour display hour (1-12) + meridiem back to a 24-hour hour (0-23).
|
|
32
|
+
* Boundary rules: 12 AM β 0, 12 PM β 12.
|
|
33
|
+
*/
|
|
34
|
+
export declare function from12Hour(hour12: number, meridiem: Meridiem): number;
|
|
35
|
+
/**
|
|
36
|
+
* Build the hour column options.
|
|
37
|
+
* 24h mode: stepped values 0-23.
|
|
38
|
+
* 12h mode: stepped values 1-12 (uses `to12Hour`/`from12Hour` semantics; value is the display hour).
|
|
39
|
+
* `disabledHours` returns 24-hour numbers; in 12h mode it is mapped via the active meridiem.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildHourOptions(step: number, use12Hours: boolean, meridiem: Meridiem, disabledHours?: () => number[]): TimeOption[];
|
|
42
|
+
/** Build the minute column options for a given (24-hour) hour. */
|
|
43
|
+
export declare function buildMinuteOptions(step: number, hour24: number, disabledMinutes?: (hour: number) => number[]): TimeOption[];
|
|
44
|
+
/** Build the second column options for a given (24-hour) hour + minute. */
|
|
45
|
+
export declare function buildSecondOptions(step: number, hour24: number, minute: number, disabledSeconds?: (hour: number, minute: number) => number[]): TimeOption[];
|
|
46
|
+
/**
|
|
47
|
+
* Drop disabled options when `hideDisabledOptions` is on; otherwise keep them all.
|
|
48
|
+
* Pure: returns a new array.
|
|
49
|
+
*/
|
|
50
|
+
export declare function applyHideDisabled(options: TimeOption[], hideDisabledOptions: boolean): TimeOption[];
|
|
51
|
+
/** true if the given 24-hour time is (partially) disabled by any provider. */
|
|
52
|
+
export declare function isTimeDisabled(hour24: number, minute: number, second: number, d: DisabledTime): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* A simple time triple in 24-hour internal representation.
|
|
55
|
+
* Shared by the format string parse/serialize helpers below.
|
|
56
|
+
*/
|
|
57
|
+
export interface TimeParts {
|
|
58
|
+
hour: number;
|
|
59
|
+
minute: number;
|
|
60
|
+
second: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Which columns a `format` string drives, plus whether AM/PM (12h) is requested.
|
|
64
|
+
* Derived purely from the token string β the render layer uses this to decide
|
|
65
|
+
* which columns to show instead of the boolean `showSecond` / `use12Hours` props.
|
|
66
|
+
*/
|
|
67
|
+
export interface FormatSpec {
|
|
68
|
+
showHour: boolean;
|
|
69
|
+
showMinute: boolean;
|
|
70
|
+
showSecond: boolean;
|
|
71
|
+
use12Hours: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse a format string (e.g. 'HH:mm', 'hh:mm A', 'HH:mm:ss') into a column spec.
|
|
75
|
+
* Recognized tokens: H/HH (24h hour), h/hh (12h hour), m/mm (minute), s/ss (second),
|
|
76
|
+
* A/a (AM/PM meridiem). Lowercase `h` or an `A`/`a` token implies 12-hour mode.
|
|
77
|
+
* Tokens inside any other characters (':', ' ', etc.) are treated as literals.
|
|
78
|
+
*/
|
|
79
|
+
export declare function parseFormatSpec(format: string): FormatSpec;
|
|
80
|
+
/**
|
|
81
|
+
* Serialize a time triple to a string per the given format.
|
|
82
|
+
* Token semantics: HH/H 24h hour (HH zero-padded), hh/h 12h hour, mm/m minute,
|
|
83
|
+
* ss/s second, A β 'AM'/'PM', a β 'am'/'pm'. Unrecognized characters pass through.
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatTime(parts: TimeParts, format: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Parse a time string into a 24-hour {hour,minute,second} triple, or null when
|
|
88
|
+
* unparseable. Tolerant: accepts 'HH:mm', 'HH:mm:ss', optional leading zeros, and
|
|
89
|
+
* a trailing AM/PM marker (case-insensitive, e.g. '12:30 pm', '1:05:09AM').
|
|
90
|
+
* When a meridiem is present the leading number is treated as a 12-hour hour.
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseTimeString(input: string): TimeParts | null;
|
|
93
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,sCAAsC;AACtC,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IAC7C,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CAC9D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAK9D;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAGnD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAIrE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,QAAQ,EAAE,QAAQ,EAClB,aAAa,CAAC,EAAE,MAAM,MAAM,EAAE,GAC7B,UAAU,EAAE,CAYd;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,GAC3C,UAAU,EAAE,CAGd;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,GAC3D,UAAU,EAAE,CAGd;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,mBAAmB,EAAE,OAAO,GAAG,UAAU,EAAE,CAEnG;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CAKvG;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CA8B1D;AAMD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAwBnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAgB/D"}
|