@llui/components 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +143 -0
- package/dist/components/accordion.d.ts +115 -0
- package/dist/components/accordion.d.ts.map +1 -0
- package/dist/components/accordion.js +138 -0
- package/dist/components/alert-dialog.d.ts +45 -0
- package/dist/components/alert-dialog.d.ts.map +1 -0
- package/dist/components/alert-dialog.js +12 -0
- package/dist/components/angle-slider.d.ts +121 -0
- package/dist/components/angle-slider.d.ts.map +1 -0
- package/dist/components/angle-slider.js +145 -0
- package/dist/components/async-list.d.ts +104 -0
- package/dist/components/async-list.d.ts.map +1 -0
- package/dist/components/async-list.js +117 -0
- package/dist/components/avatar.d.ts +58 -0
- package/dist/components/avatar.d.ts.map +1 -0
- package/dist/components/avatar.js +43 -0
- package/dist/components/carousel.d.ts +128 -0
- package/dist/components/carousel.d.ts.map +1 -0
- package/dist/components/carousel.js +131 -0
- package/dist/components/cascade-select.d.ts +95 -0
- package/dist/components/cascade-select.d.ts.map +1 -0
- package/dist/components/cascade-select.js +100 -0
- package/dist/components/checkbox.d.ts +74 -0
- package/dist/components/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox.js +73 -0
- package/dist/components/clipboard.d.ts +72 -0
- package/dist/components/clipboard.d.ts.map +1 -0
- package/dist/components/clipboard.js +73 -0
- package/dist/components/collapsible.d.ts +64 -0
- package/dist/components/collapsible.d.ts.map +1 -0
- package/dist/components/collapsible.js +51 -0
- package/dist/components/color-picker.d.ts +125 -0
- package/dist/components/color-picker.d.ts.map +1 -0
- package/dist/components/color-picker.js +169 -0
- package/dist/components/combobox.d.ts +163 -0
- package/dist/components/combobox.d.ts.map +1 -0
- package/dist/components/combobox.js +345 -0
- package/dist/components/context-menu.d.ts +105 -0
- package/dist/components/context-menu.d.ts.map +1 -0
- package/dist/components/context-menu.js +177 -0
- package/dist/components/date-input.d.ts +117 -0
- package/dist/components/date-input.d.ts.map +1 -0
- package/dist/components/date-input.js +149 -0
- package/dist/components/date-picker.d.ts +142 -0
- package/dist/components/date-picker.d.ts.map +1 -0
- package/dist/components/date-picker.js +294 -0
- package/dist/components/dialog.d.ts +152 -0
- package/dist/components/dialog.d.ts.map +1 -0
- package/dist/components/dialog.js +140 -0
- package/dist/components/drawer.d.ts +106 -0
- package/dist/components/drawer.d.ts.map +1 -0
- package/dist/components/drawer.js +136 -0
- package/dist/components/editable.d.ts +92 -0
- package/dist/components/editable.d.ts.map +1 -0
- package/dist/components/editable.js +112 -0
- package/dist/components/file-upload.d.ts +251 -0
- package/dist/components/file-upload.d.ts.map +1 -0
- package/dist/components/file-upload.js +324 -0
- package/dist/components/floating-panel.d.ts +171 -0
- package/dist/components/floating-panel.d.ts.map +1 -0
- package/dist/components/floating-panel.js +198 -0
- package/dist/components/hover-card.d.ts +85 -0
- package/dist/components/hover-card.d.ts.map +1 -0
- package/dist/components/hover-card.js +128 -0
- package/dist/components/image-cropper.d.ts +129 -0
- package/dist/components/image-cropper.d.ts.map +1 -0
- package/dist/components/image-cropper.js +208 -0
- package/dist/components/index.d.ts +109 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +54 -0
- package/dist/components/listbox.d.ts +98 -0
- package/dist/components/listbox.d.ts.map +1 -0
- package/dist/components/listbox.js +174 -0
- package/dist/components/marquee.d.ts +84 -0
- package/dist/components/marquee.d.ts.map +1 -0
- package/dist/components/marquee.js +73 -0
- package/dist/components/menu.d.ts +131 -0
- package/dist/components/menu.d.ts.map +1 -0
- package/dist/components/menu.js +262 -0
- package/dist/components/navigation-menu.d.ts +111 -0
- package/dist/components/navigation-menu.d.ts.map +1 -0
- package/dist/components/navigation-menu.js +102 -0
- package/dist/components/number-input.d.ts +106 -0
- package/dist/components/number-input.d.ts.map +1 -0
- package/dist/components/number-input.js +178 -0
- package/dist/components/pagination.d.ts +113 -0
- package/dist/components/pagination.d.ts.map +1 -0
- package/dist/components/pagination.js +135 -0
- package/dist/components/password-input.d.ts +64 -0
- package/dist/components/password-input.d.ts.map +1 -0
- package/dist/components/password-input.js +52 -0
- package/dist/components/pin-input.d.ts +89 -0
- package/dist/components/pin-input.d.ts.map +1 -0
- package/dist/components/pin-input.js +139 -0
- package/dist/components/popover.d.ts +116 -0
- package/dist/components/popover.d.ts.map +1 -0
- package/dist/components/popover.js +146 -0
- package/dist/components/presence.d.ts +71 -0
- package/dist/components/presence.d.ts.map +1 -0
- package/dist/components/presence.js +57 -0
- package/dist/components/progress.d.ts +74 -0
- package/dist/components/progress.d.ts.map +1 -0
- package/dist/components/progress.js +80 -0
- package/dist/components/qr-code.d.ts +114 -0
- package/dist/components/qr-code.d.ts.map +1 -0
- package/dist/components/qr-code.js +108 -0
- package/dist/components/radio-group.d.ts +89 -0
- package/dist/components/radio-group.d.ts.map +1 -0
- package/dist/components/radio-group.js +161 -0
- package/dist/components/rating-group.d.ts +88 -0
- package/dist/components/rating-group.d.ts.map +1 -0
- package/dist/components/rating-group.js +122 -0
- package/dist/components/scroll-area.d.ts +124 -0
- package/dist/components/scroll-area.d.ts.map +1 -0
- package/dist/components/scroll-area.js +152 -0
- package/dist/components/select.d.ts +161 -0
- package/dist/components/select.d.ts.map +1 -0
- package/dist/components/select.js +333 -0
- package/dist/components/signature-pad.d.ts +138 -0
- package/dist/components/signature-pad.d.ts.map +1 -0
- package/dist/components/signature-pad.js +142 -0
- package/dist/components/slider.d.ts +117 -0
- package/dist/components/slider.d.ts.map +1 -0
- package/dist/components/slider.js +210 -0
- package/dist/components/splitter.d.ts +87 -0
- package/dist/components/splitter.d.ts.map +1 -0
- package/dist/components/splitter.js +119 -0
- package/dist/components/steps.d.ts +104 -0
- package/dist/components/steps.d.ts.map +1 -0
- package/dist/components/steps.js +133 -0
- package/dist/components/switch.d.ts +66 -0
- package/dist/components/switch.d.ts.map +1 -0
- package/dist/components/switch.js +59 -0
- package/dist/components/tabs.d.ts +146 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.js +244 -0
- package/dist/components/tags-input.d.ts +118 -0
- package/dist/components/tags-input.d.ts.map +1 -0
- package/dist/components/tags-input.js +168 -0
- package/dist/components/time-picker.d.ts +121 -0
- package/dist/components/time-picker.d.ts.map +1 -0
- package/dist/components/time-picker.js +147 -0
- package/dist/components/timer.d.ts +131 -0
- package/dist/components/timer.d.ts.map +1 -0
- package/dist/components/timer.js +117 -0
- package/dist/components/toast.d.ts +119 -0
- package/dist/components/toast.d.ts.map +1 -0
- package/dist/components/toast.js +102 -0
- package/dist/components/toc.d.ts +119 -0
- package/dist/components/toc.d.ts.map +1 -0
- package/dist/components/toc.js +107 -0
- package/dist/components/toggle-group.d.ts +80 -0
- package/dist/components/toggle-group.d.ts.map +1 -0
- package/dist/components/toggle-group.js +93 -0
- package/dist/components/toggle.d.ts +47 -0
- package/dist/components/toggle.d.ts.map +1 -0
- package/dist/components/toggle.js +41 -0
- package/dist/components/tooltip.d.ts +92 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip.js +147 -0
- package/dist/components/tour.d.ts +145 -0
- package/dist/components/tour.d.ts.map +1 -0
- package/dist/components/tour.js +133 -0
- package/dist/components/tree-view.d.ts +216 -0
- package/dist/components/tree-view.d.ts.map +1 -0
- package/dist/components/tree-view.js +293 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/patterns/confirm-dialog.d.ts +92 -0
- package/dist/patterns/confirm-dialog.d.ts.map +1 -0
- package/dist/patterns/confirm-dialog.js +92 -0
- package/dist/patterns/index.d.ts +3 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +1 -0
- package/dist/utils/anatomy.d.ts +40 -0
- package/dist/utils/anatomy.d.ts.map +1 -0
- package/dist/utils/anatomy.js +41 -0
- package/dist/utils/aria-hidden.d.ts +12 -0
- package/dist/utils/aria-hidden.d.ts.map +1 -0
- package/dist/utils/aria-hidden.js +72 -0
- package/dist/utils/dismissable.d.ts +25 -0
- package/dist/utils/dismissable.d.ts.map +1 -0
- package/dist/utils/dismissable.js +65 -0
- package/dist/utils/dom.d.ts +8 -0
- package/dist/utils/dom.d.ts.map +1 -0
- package/dist/utils/dom.js +21 -0
- package/dist/utils/floating.d.ts +44 -0
- package/dist/utils/floating.d.ts.map +1 -0
- package/dist/utils/floating.js +44 -0
- package/dist/utils/focus-trap.d.ts +18 -0
- package/dist/utils/focus-trap.d.ts.map +1 -0
- package/dist/utils/focus-trap.js +85 -0
- package/dist/utils/focusables.d.ts +6 -0
- package/dist/utils/focusables.d.ts.map +1 -0
- package/dist/utils/focusables.js +65 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +10 -0
- package/dist/utils/interact-outside.d.ts +26 -0
- package/dist/utils/interact-outside.d.ts.map +1 -0
- package/dist/utils/interact-outside.js +46 -0
- package/dist/utils/remove-scroll.d.ts +8 -0
- package/dist/utils/remove-scroll.d.ts.map +1 -0
- package/dist/utils/remove-scroll.js +37 -0
- package/dist/utils/tree-collection.d.ts +61 -0
- package/dist/utils/tree-collection.d.ts.map +1 -0
- package/dist/utils/tree-collection.js +137 -0
- package/dist/utils/typeahead.d.ts +49 -0
- package/dist/utils/typeahead.d.ts.map +1 -0
- package/dist/utils/typeahead.js +81 -0
- package/package.json +282 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TreeCollection — helper for building tree-view payloads from a nested
|
|
3
|
+
* data structure. Tree-view's state machine only knows about flat lists
|
|
4
|
+
* (visibleItems, visibleLabels) and opaque ids; the collection owns the
|
|
5
|
+
* structure and derives those flat arrays on demand.
|
|
6
|
+
*
|
|
7
|
+
* Typical flow:
|
|
8
|
+
*
|
|
9
|
+
* const col = new TreeCollection(data)
|
|
10
|
+
* state.visibleItems = col.visibleItems(state.expanded)
|
|
11
|
+
* state.visibleLabels = col.visibleLabels(state.expanded)
|
|
12
|
+
*
|
|
13
|
+
* After every `expand` / `collapse` message, the consumer dispatches
|
|
14
|
+
* `setVisibleItems` with the updated arrays. The collection itself is
|
|
15
|
+
* immutable — build a new one when the tree structure changes.
|
|
16
|
+
*/
|
|
17
|
+
export interface TreeNode {
|
|
18
|
+
id: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
children?: TreeNode[];
|
|
22
|
+
}
|
|
23
|
+
export declare class TreeCollection {
|
|
24
|
+
readonly roots: TreeNode[];
|
|
25
|
+
private readonly info;
|
|
26
|
+
constructor(roots: TreeNode | TreeNode[]);
|
|
27
|
+
private index;
|
|
28
|
+
/** All ids in the collection, in depth-first order. */
|
|
29
|
+
get allIds(): string[];
|
|
30
|
+
getNode(id: string): TreeNode | null;
|
|
31
|
+
getLabel(id: string): string;
|
|
32
|
+
getParent(id: string): string | null;
|
|
33
|
+
getDepth(id: string): number;
|
|
34
|
+
getChildren(id: string): string[];
|
|
35
|
+
/** All descendants of id in depth-first order (excluding id itself). */
|
|
36
|
+
getDescendants(id: string): string[];
|
|
37
|
+
isBranch(id: string): boolean;
|
|
38
|
+
isDisabled(id: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The ordered list of visible item ids given a set of expanded branches.
|
|
41
|
+
* A branch's descendants appear only if every ancestor up to a root is
|
|
42
|
+
* in `expanded`.
|
|
43
|
+
*/
|
|
44
|
+
visibleItems(expanded: string[]): string[];
|
|
45
|
+
/** Parallel array of labels for `visibleItems()`, using `label ?? id`. */
|
|
46
|
+
visibleLabels(expanded: string[]): string[];
|
|
47
|
+
/**
|
|
48
|
+
* Ids of all branches in the collection (useful for `expandAll`).
|
|
49
|
+
*/
|
|
50
|
+
get branchIds(): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Compute the indeterminate-set from a set of checked ids: any branch
|
|
53
|
+
* whose descendants are partially — but not fully — checked. Useful as
|
|
54
|
+
* a post-toggleChecked reconciler:
|
|
55
|
+
*
|
|
56
|
+
* const indeterminate = col.computeIndeterminate(new Set(state.checked))
|
|
57
|
+
* send({ type: 'setIndeterminate', ids: indeterminate })
|
|
58
|
+
*/
|
|
59
|
+
computeIndeterminate(checked: Set<string>): string[];
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=tree-collection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-collection.d.ts","sourceRoot":"","sources":["../../src/utils/tree-collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CACtB;AASD,qBAAa,cAAc;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;gBAEhC,KAAK,EAAE,QAAQ,GAAG,QAAQ,EAAE;IAMxC,OAAO,CAAC,KAAK;IAcb,uDAAuD;IACvD,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAED,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAIpC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAK5B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIpC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAI5B,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE;IAIjC,wEAAwE;IACxE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE;IAYpC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI7B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B;;;;OAIG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAe1C,0EAA0E;IAC1E,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAI3C;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,EAAE,CAMxB;IAED;;;;;;;OAOG;IACH,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE;CAYrD"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TreeCollection — helper for building tree-view payloads from a nested
|
|
3
|
+
* data structure. Tree-view's state machine only knows about flat lists
|
|
4
|
+
* (visibleItems, visibleLabels) and opaque ids; the collection owns the
|
|
5
|
+
* structure and derives those flat arrays on demand.
|
|
6
|
+
*
|
|
7
|
+
* Typical flow:
|
|
8
|
+
*
|
|
9
|
+
* const col = new TreeCollection(data)
|
|
10
|
+
* state.visibleItems = col.visibleItems(state.expanded)
|
|
11
|
+
* state.visibleLabels = col.visibleLabels(state.expanded)
|
|
12
|
+
*
|
|
13
|
+
* After every `expand` / `collapse` message, the consumer dispatches
|
|
14
|
+
* `setVisibleItems` with the updated arrays. The collection itself is
|
|
15
|
+
* immutable — build a new one when the tree structure changes.
|
|
16
|
+
*/
|
|
17
|
+
export class TreeCollection {
|
|
18
|
+
roots;
|
|
19
|
+
info;
|
|
20
|
+
constructor(roots) {
|
|
21
|
+
this.roots = Array.isArray(roots) ? roots : [roots];
|
|
22
|
+
this.info = new Map();
|
|
23
|
+
this.index();
|
|
24
|
+
}
|
|
25
|
+
index() {
|
|
26
|
+
const walk = (node, parentId, depth) => {
|
|
27
|
+
const children = node.children ?? [];
|
|
28
|
+
this.info.set(node.id, {
|
|
29
|
+
node,
|
|
30
|
+
parentId,
|
|
31
|
+
depth,
|
|
32
|
+
childIds: children.map((c) => c.id),
|
|
33
|
+
});
|
|
34
|
+
for (const child of children)
|
|
35
|
+
walk(child, node.id, depth + 1);
|
|
36
|
+
};
|
|
37
|
+
for (const root of this.roots)
|
|
38
|
+
walk(root, null, 0);
|
|
39
|
+
}
|
|
40
|
+
/** All ids in the collection, in depth-first order. */
|
|
41
|
+
get allIds() {
|
|
42
|
+
return Array.from(this.info.keys());
|
|
43
|
+
}
|
|
44
|
+
getNode(id) {
|
|
45
|
+
return this.info.get(id)?.node ?? null;
|
|
46
|
+
}
|
|
47
|
+
getLabel(id) {
|
|
48
|
+
const node = this.getNode(id);
|
|
49
|
+
return node?.label ?? id;
|
|
50
|
+
}
|
|
51
|
+
getParent(id) {
|
|
52
|
+
return this.info.get(id)?.parentId ?? null;
|
|
53
|
+
}
|
|
54
|
+
getDepth(id) {
|
|
55
|
+
return this.info.get(id)?.depth ?? 0;
|
|
56
|
+
}
|
|
57
|
+
getChildren(id) {
|
|
58
|
+
return this.info.get(id)?.childIds ?? [];
|
|
59
|
+
}
|
|
60
|
+
/** All descendants of id in depth-first order (excluding id itself). */
|
|
61
|
+
getDescendants(id) {
|
|
62
|
+
const out = [];
|
|
63
|
+
const walk = (current) => {
|
|
64
|
+
for (const childId of this.getChildren(current)) {
|
|
65
|
+
out.push(childId);
|
|
66
|
+
walk(childId);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
walk(id);
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
isBranch(id) {
|
|
73
|
+
return this.getChildren(id).length > 0;
|
|
74
|
+
}
|
|
75
|
+
isDisabled(id) {
|
|
76
|
+
return this.info.get(id)?.node.disabled === true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The ordered list of visible item ids given a set of expanded branches.
|
|
80
|
+
* A branch's descendants appear only if every ancestor up to a root is
|
|
81
|
+
* in `expanded`.
|
|
82
|
+
*/
|
|
83
|
+
visibleItems(expanded) {
|
|
84
|
+
const expandedSet = new Set(expanded);
|
|
85
|
+
const out = [];
|
|
86
|
+
const walk = (nodes) => {
|
|
87
|
+
for (const node of nodes) {
|
|
88
|
+
out.push(node.id);
|
|
89
|
+
if (expandedSet.has(node.id) && node.children) {
|
|
90
|
+
walk(node.children);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
walk(this.roots);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/** Parallel array of labels for `visibleItems()`, using `label ?? id`. */
|
|
98
|
+
visibleLabels(expanded) {
|
|
99
|
+
return this.visibleItems(expanded).map((id) => this.getLabel(id));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Ids of all branches in the collection (useful for `expandAll`).
|
|
103
|
+
*/
|
|
104
|
+
get branchIds() {
|
|
105
|
+
const out = [];
|
|
106
|
+
for (const [id, info] of this.info) {
|
|
107
|
+
if (info.childIds.length > 0)
|
|
108
|
+
out.push(id);
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Compute the indeterminate-set from a set of checked ids: any branch
|
|
114
|
+
* whose descendants are partially — but not fully — checked. Useful as
|
|
115
|
+
* a post-toggleChecked reconciler:
|
|
116
|
+
*
|
|
117
|
+
* const indeterminate = col.computeIndeterminate(new Set(state.checked))
|
|
118
|
+
* send({ type: 'setIndeterminate', ids: indeterminate })
|
|
119
|
+
*/
|
|
120
|
+
computeIndeterminate(checked) {
|
|
121
|
+
const out = [];
|
|
122
|
+
for (const [id, info] of this.info) {
|
|
123
|
+
if (info.childIds.length === 0)
|
|
124
|
+
continue;
|
|
125
|
+
const desc = this.getDescendants(id);
|
|
126
|
+
if (desc.length === 0)
|
|
127
|
+
continue;
|
|
128
|
+
let checkedCount = 0;
|
|
129
|
+
for (const d of desc)
|
|
130
|
+
if (checked.has(d))
|
|
131
|
+
checkedCount++;
|
|
132
|
+
if (checkedCount > 0 && checkedCount < desc.length)
|
|
133
|
+
out.push(id);
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typeahead search — accumulates keystrokes into a query while the user
|
|
3
|
+
* types rapidly, then matches the first item whose label starts with the
|
|
4
|
+
* query. Used by listbox, menu, select, combobox, tree-view to support
|
|
5
|
+
* WAI-ARIA keyboard navigation patterns.
|
|
6
|
+
*
|
|
7
|
+
* Behavior:
|
|
8
|
+
* - If a keystroke arrives within `TYPEAHEAD_TIMEOUT_MS` of the previous
|
|
9
|
+
* one, append to the existing query (so typing "sa" finds "Saturn" even
|
|
10
|
+
* if the highlight is currently on "Jupiter").
|
|
11
|
+
* - Otherwise, start a fresh single-character query.
|
|
12
|
+
* - Single-character queries advance past the current position (jump to
|
|
13
|
+
* the *next* item starting with that letter), which is the standard
|
|
14
|
+
* WAI-ARIA behavior — rapid repeated presses of "s" cycle through
|
|
15
|
+
* items beginning with "s".
|
|
16
|
+
* - Multi-character queries search from the current cursor position
|
|
17
|
+
* (inclusive) so if the cursor is already on a matching item, it
|
|
18
|
+
* stays — typing "ap" while on "apricot" keeps focus on "apricot".
|
|
19
|
+
*/
|
|
20
|
+
export declare const TYPEAHEAD_TIMEOUT_MS = 500;
|
|
21
|
+
/**
|
|
22
|
+
* Advance the typeahead query based on a new keystroke and the previous
|
|
23
|
+
* expiration time. Returns the new query string; callers combine this with
|
|
24
|
+
* `typeaheadMatch()` to produce a new highlight index.
|
|
25
|
+
*/
|
|
26
|
+
export declare function typeaheadAccumulate(prev: string, char: string, now: number, expiresAt: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* Find the first enabled item whose label starts with the query
|
|
29
|
+
* (case-insensitive). `labels` and `disabledMask` are parallel arrays.
|
|
30
|
+
* `startFrom` is the current highlighted index; for single-character
|
|
31
|
+
* queries the search begins at `startFrom + 1` (so repeated "s" keys
|
|
32
|
+
* cycle), for multi-character queries it begins at `startFrom` (inclusive).
|
|
33
|
+
*
|
|
34
|
+
* Returns the matching index, or `null` if no enabled item matches.
|
|
35
|
+
*/
|
|
36
|
+
export declare function typeaheadMatch(labels: string[], disabledMask: boolean[], query: string, startFrom: number | null): number | null;
|
|
37
|
+
/**
|
|
38
|
+
* Convenience: pass a `disabled` list of values instead of a boolean mask.
|
|
39
|
+
* Builds the mask by checking membership via `===` on the raw string values.
|
|
40
|
+
*/
|
|
41
|
+
export declare function typeaheadMatchByItems(items: string[], disabled: readonly string[], query: string, startFrom: number | null): number | null;
|
|
42
|
+
/**
|
|
43
|
+
* Returns true if the key event should trigger a typeahead query — i.e., a
|
|
44
|
+
* single printable character that isn't a modified keyboard shortcut. Use
|
|
45
|
+
* this in `onKeyDown` handlers to decide whether to dispatch a typeahead
|
|
46
|
+
* message.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isTypeaheadKey(e: KeyboardEvent): boolean;
|
|
49
|
+
//# sourceMappingURL=typeahead.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeahead.d.ts","sourceRoot":"","sources":["../../src/utils/typeahead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAEvC;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EAAE,EAChB,YAAY,EAAE,OAAO,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,MAAM,GAAG,IAAI,CAYf;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO,CAOxD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typeahead search — accumulates keystrokes into a query while the user
|
|
3
|
+
* types rapidly, then matches the first item whose label starts with the
|
|
4
|
+
* query. Used by listbox, menu, select, combobox, tree-view to support
|
|
5
|
+
* WAI-ARIA keyboard navigation patterns.
|
|
6
|
+
*
|
|
7
|
+
* Behavior:
|
|
8
|
+
* - If a keystroke arrives within `TYPEAHEAD_TIMEOUT_MS` of the previous
|
|
9
|
+
* one, append to the existing query (so typing "sa" finds "Saturn" even
|
|
10
|
+
* if the highlight is currently on "Jupiter").
|
|
11
|
+
* - Otherwise, start a fresh single-character query.
|
|
12
|
+
* - Single-character queries advance past the current position (jump to
|
|
13
|
+
* the *next* item starting with that letter), which is the standard
|
|
14
|
+
* WAI-ARIA behavior — rapid repeated presses of "s" cycle through
|
|
15
|
+
* items beginning with "s".
|
|
16
|
+
* - Multi-character queries search from the current cursor position
|
|
17
|
+
* (inclusive) so if the cursor is already on a matching item, it
|
|
18
|
+
* stays — typing "ap" while on "apricot" keeps focus on "apricot".
|
|
19
|
+
*/
|
|
20
|
+
export const TYPEAHEAD_TIMEOUT_MS = 500;
|
|
21
|
+
/**
|
|
22
|
+
* Advance the typeahead query based on a new keystroke and the previous
|
|
23
|
+
* expiration time. Returns the new query string; callers combine this with
|
|
24
|
+
* `typeaheadMatch()` to produce a new highlight index.
|
|
25
|
+
*/
|
|
26
|
+
export function typeaheadAccumulate(prev, char, now, expiresAt) {
|
|
27
|
+
return now < expiresAt ? prev + char : char;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Find the first enabled item whose label starts with the query
|
|
31
|
+
* (case-insensitive). `labels` and `disabledMask` are parallel arrays.
|
|
32
|
+
* `startFrom` is the current highlighted index; for single-character
|
|
33
|
+
* queries the search begins at `startFrom + 1` (so repeated "s" keys
|
|
34
|
+
* cycle), for multi-character queries it begins at `startFrom` (inclusive).
|
|
35
|
+
*
|
|
36
|
+
* Returns the matching index, or `null` if no enabled item matches.
|
|
37
|
+
*/
|
|
38
|
+
export function typeaheadMatch(labels, disabledMask, query, startFrom) {
|
|
39
|
+
if (labels.length === 0 || query.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
const q = query.toLowerCase();
|
|
42
|
+
const offset = query.length === 1 ? 1 : 0;
|
|
43
|
+
const n = labels.length;
|
|
44
|
+
const start = startFrom ?? -1;
|
|
45
|
+
for (let i = 0; i < n; i++) {
|
|
46
|
+
const idx = (start + offset + i + n) % n;
|
|
47
|
+
if (disabledMask[idx])
|
|
48
|
+
continue;
|
|
49
|
+
if (labels[idx].toLowerCase().startsWith(q))
|
|
50
|
+
return idx;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Convenience: pass a `disabled` list of values instead of a boolean mask.
|
|
56
|
+
* Builds the mask by checking membership via `===` on the raw string values.
|
|
57
|
+
*/
|
|
58
|
+
export function typeaheadMatchByItems(items, disabled, query, startFrom) {
|
|
59
|
+
const n = items.length;
|
|
60
|
+
const mask = new Array(n);
|
|
61
|
+
for (let i = 0; i < n; i++)
|
|
62
|
+
mask[i] = disabled.includes(items[i]);
|
|
63
|
+
return typeaheadMatch(items, mask, query, startFrom);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns true if the key event should trigger a typeahead query — i.e., a
|
|
67
|
+
* single printable character that isn't a modified keyboard shortcut. Use
|
|
68
|
+
* this in `onKeyDown` handlers to decide whether to dispatch a typeahead
|
|
69
|
+
* message.
|
|
70
|
+
*/
|
|
71
|
+
export function isTypeaheadKey(e) {
|
|
72
|
+
if (e.ctrlKey || e.metaKey || e.altKey)
|
|
73
|
+
return false;
|
|
74
|
+
if (e.key.length !== 1)
|
|
75
|
+
return false;
|
|
76
|
+
// Whitespace isn't a typeahead character in most widgets — Space often
|
|
77
|
+
// activates the highlighted item. Let callers override if needed.
|
|
78
|
+
if (e.key === ' ')
|
|
79
|
+
return false;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@llui/components",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./utils": {
|
|
13
|
+
"import": "./dist/utils/index.js",
|
|
14
|
+
"types": "./dist/utils/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./toggle": {
|
|
17
|
+
"import": "./dist/components/toggle.js",
|
|
18
|
+
"types": "./dist/components/toggle.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./checkbox": {
|
|
21
|
+
"import": "./dist/components/checkbox.js",
|
|
22
|
+
"types": "./dist/components/checkbox.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./accordion": {
|
|
25
|
+
"import": "./dist/components/accordion.js",
|
|
26
|
+
"types": "./dist/components/accordion.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./tabs": {
|
|
29
|
+
"import": "./dist/components/tabs.js",
|
|
30
|
+
"types": "./dist/components/tabs.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./slider": {
|
|
33
|
+
"import": "./dist/components/slider.js",
|
|
34
|
+
"types": "./dist/components/slider.d.ts"
|
|
35
|
+
},
|
|
36
|
+
"./dialog": {
|
|
37
|
+
"import": "./dist/components/dialog.js",
|
|
38
|
+
"types": "./dist/components/dialog.d.ts"
|
|
39
|
+
},
|
|
40
|
+
"./popover": {
|
|
41
|
+
"import": "./dist/components/popover.js",
|
|
42
|
+
"types": "./dist/components/popover.d.ts"
|
|
43
|
+
},
|
|
44
|
+
"./tooltip": {
|
|
45
|
+
"import": "./dist/components/tooltip.js",
|
|
46
|
+
"types": "./dist/components/tooltip.d.ts"
|
|
47
|
+
},
|
|
48
|
+
"./menu": {
|
|
49
|
+
"import": "./dist/components/menu.js",
|
|
50
|
+
"types": "./dist/components/menu.d.ts"
|
|
51
|
+
},
|
|
52
|
+
"./switch": {
|
|
53
|
+
"import": "./dist/components/switch.js",
|
|
54
|
+
"types": "./dist/components/switch.d.ts"
|
|
55
|
+
},
|
|
56
|
+
"./radio-group": {
|
|
57
|
+
"import": "./dist/components/radio-group.js",
|
|
58
|
+
"types": "./dist/components/radio-group.d.ts"
|
|
59
|
+
},
|
|
60
|
+
"./collapsible": {
|
|
61
|
+
"import": "./dist/components/collapsible.js",
|
|
62
|
+
"types": "./dist/components/collapsible.d.ts"
|
|
63
|
+
},
|
|
64
|
+
"./toggle-group": {
|
|
65
|
+
"import": "./dist/components/toggle-group.js",
|
|
66
|
+
"types": "./dist/components/toggle-group.d.ts"
|
|
67
|
+
},
|
|
68
|
+
"./number-input": {
|
|
69
|
+
"import": "./dist/components/number-input.js",
|
|
70
|
+
"types": "./dist/components/number-input.d.ts"
|
|
71
|
+
},
|
|
72
|
+
"./pin-input": {
|
|
73
|
+
"import": "./dist/components/pin-input.js",
|
|
74
|
+
"types": "./dist/components/pin-input.d.ts"
|
|
75
|
+
},
|
|
76
|
+
"./progress": {
|
|
77
|
+
"import": "./dist/components/progress.js",
|
|
78
|
+
"types": "./dist/components/progress.d.ts"
|
|
79
|
+
},
|
|
80
|
+
"./rating-group": {
|
|
81
|
+
"import": "./dist/components/rating-group.js",
|
|
82
|
+
"types": "./dist/components/rating-group.d.ts"
|
|
83
|
+
},
|
|
84
|
+
"./pagination": {
|
|
85
|
+
"import": "./dist/components/pagination.js",
|
|
86
|
+
"types": "./dist/components/pagination.d.ts"
|
|
87
|
+
},
|
|
88
|
+
"./alert-dialog": {
|
|
89
|
+
"import": "./dist/components/alert-dialog.js",
|
|
90
|
+
"types": "./dist/components/alert-dialog.d.ts"
|
|
91
|
+
},
|
|
92
|
+
"./drawer": {
|
|
93
|
+
"import": "./dist/components/drawer.js",
|
|
94
|
+
"types": "./dist/components/drawer.d.ts"
|
|
95
|
+
},
|
|
96
|
+
"./toast": {
|
|
97
|
+
"import": "./dist/components/toast.js",
|
|
98
|
+
"types": "./dist/components/toast.d.ts"
|
|
99
|
+
},
|
|
100
|
+
"./listbox": {
|
|
101
|
+
"import": "./dist/components/listbox.js",
|
|
102
|
+
"types": "./dist/components/listbox.d.ts"
|
|
103
|
+
},
|
|
104
|
+
"./select": {
|
|
105
|
+
"import": "./dist/components/select.js",
|
|
106
|
+
"types": "./dist/components/select.d.ts"
|
|
107
|
+
},
|
|
108
|
+
"./combobox": {
|
|
109
|
+
"import": "./dist/components/combobox.js",
|
|
110
|
+
"types": "./dist/components/combobox.d.ts"
|
|
111
|
+
},
|
|
112
|
+
"./hover-card": {
|
|
113
|
+
"import": "./dist/components/hover-card.js",
|
|
114
|
+
"types": "./dist/components/hover-card.d.ts"
|
|
115
|
+
},
|
|
116
|
+
"./avatar": {
|
|
117
|
+
"import": "./dist/components/avatar.js",
|
|
118
|
+
"types": "./dist/components/avatar.d.ts"
|
|
119
|
+
},
|
|
120
|
+
"./clipboard": {
|
|
121
|
+
"import": "./dist/components/clipboard.js",
|
|
122
|
+
"types": "./dist/components/clipboard.d.ts"
|
|
123
|
+
},
|
|
124
|
+
"./editable": {
|
|
125
|
+
"import": "./dist/components/editable.js",
|
|
126
|
+
"types": "./dist/components/editable.d.ts"
|
|
127
|
+
},
|
|
128
|
+
"./tags-input": {
|
|
129
|
+
"import": "./dist/components/tags-input.js",
|
|
130
|
+
"types": "./dist/components/tags-input.d.ts"
|
|
131
|
+
},
|
|
132
|
+
"./splitter": {
|
|
133
|
+
"import": "./dist/components/splitter.js",
|
|
134
|
+
"types": "./dist/components/splitter.d.ts"
|
|
135
|
+
},
|
|
136
|
+
"./file-upload": {
|
|
137
|
+
"import": "./dist/components/file-upload.js",
|
|
138
|
+
"types": "./dist/components/file-upload.d.ts"
|
|
139
|
+
},
|
|
140
|
+
"./tree-view": {
|
|
141
|
+
"import": "./dist/components/tree-view.js",
|
|
142
|
+
"types": "./dist/components/tree-view.d.ts"
|
|
143
|
+
},
|
|
144
|
+
"./context-menu": {
|
|
145
|
+
"import": "./dist/components/context-menu.js",
|
|
146
|
+
"types": "./dist/components/context-menu.d.ts"
|
|
147
|
+
},
|
|
148
|
+
"./password-input": {
|
|
149
|
+
"import": "./dist/components/password-input.js",
|
|
150
|
+
"types": "./dist/components/password-input.d.ts"
|
|
151
|
+
},
|
|
152
|
+
"./steps": {
|
|
153
|
+
"import": "./dist/components/steps.js",
|
|
154
|
+
"types": "./dist/components/steps.d.ts"
|
|
155
|
+
},
|
|
156
|
+
"./time-picker": {
|
|
157
|
+
"import": "./dist/components/time-picker.js",
|
|
158
|
+
"types": "./dist/components/time-picker.d.ts"
|
|
159
|
+
},
|
|
160
|
+
"./date-picker": {
|
|
161
|
+
"import": "./dist/components/date-picker.js",
|
|
162
|
+
"types": "./dist/components/date-picker.d.ts"
|
|
163
|
+
},
|
|
164
|
+
"./color-picker": {
|
|
165
|
+
"import": "./dist/components/color-picker.js",
|
|
166
|
+
"types": "./dist/components/color-picker.d.ts"
|
|
167
|
+
},
|
|
168
|
+
"./timer": {
|
|
169
|
+
"import": "./dist/components/timer.js",
|
|
170
|
+
"types": "./dist/components/timer.d.ts"
|
|
171
|
+
},
|
|
172
|
+
"./angle-slider": {
|
|
173
|
+
"import": "./dist/components/angle-slider.js",
|
|
174
|
+
"types": "./dist/components/angle-slider.d.ts"
|
|
175
|
+
},
|
|
176
|
+
"./marquee": {
|
|
177
|
+
"import": "./dist/components/marquee.js",
|
|
178
|
+
"types": "./dist/components/marquee.d.ts"
|
|
179
|
+
},
|
|
180
|
+
"./presence": {
|
|
181
|
+
"import": "./dist/components/presence.js",
|
|
182
|
+
"types": "./dist/components/presence.d.ts"
|
|
183
|
+
},
|
|
184
|
+
"./signature-pad": {
|
|
185
|
+
"import": "./dist/components/signature-pad.js",
|
|
186
|
+
"types": "./dist/components/signature-pad.d.ts"
|
|
187
|
+
},
|
|
188
|
+
"./toc": {
|
|
189
|
+
"import": "./dist/components/toc.js",
|
|
190
|
+
"types": "./dist/components/toc.d.ts"
|
|
191
|
+
},
|
|
192
|
+
"./tour": {
|
|
193
|
+
"import": "./dist/components/tour.js",
|
|
194
|
+
"types": "./dist/components/tour.d.ts"
|
|
195
|
+
},
|
|
196
|
+
"./date-input": {
|
|
197
|
+
"import": "./dist/components/date-input.js",
|
|
198
|
+
"types": "./dist/components/date-input.d.ts"
|
|
199
|
+
},
|
|
200
|
+
"./async-list": {
|
|
201
|
+
"import": "./dist/components/async-list.js",
|
|
202
|
+
"types": "./dist/components/async-list.d.ts"
|
|
203
|
+
},
|
|
204
|
+
"./cascade-select": {
|
|
205
|
+
"import": "./dist/components/cascade-select.js",
|
|
206
|
+
"types": "./dist/components/cascade-select.d.ts"
|
|
207
|
+
},
|
|
208
|
+
"./scroll-area": {
|
|
209
|
+
"import": "./dist/components/scroll-area.js",
|
|
210
|
+
"types": "./dist/components/scroll-area.d.ts"
|
|
211
|
+
},
|
|
212
|
+
"./floating-panel": {
|
|
213
|
+
"import": "./dist/components/floating-panel.js",
|
|
214
|
+
"types": "./dist/components/floating-panel.d.ts"
|
|
215
|
+
},
|
|
216
|
+
"./image-cropper": {
|
|
217
|
+
"import": "./dist/components/image-cropper.js",
|
|
218
|
+
"types": "./dist/components/image-cropper.d.ts"
|
|
219
|
+
},
|
|
220
|
+
"./navigation-menu": {
|
|
221
|
+
"import": "./dist/components/navigation-menu.js",
|
|
222
|
+
"types": "./dist/components/navigation-menu.d.ts"
|
|
223
|
+
},
|
|
224
|
+
"./qr-code": {
|
|
225
|
+
"import": "./dist/components/qr-code.js",
|
|
226
|
+
"types": "./dist/components/qr-code.d.ts"
|
|
227
|
+
},
|
|
228
|
+
"./carousel": {
|
|
229
|
+
"import": "./dist/components/carousel.js",
|
|
230
|
+
"types": "./dist/components/carousel.d.ts"
|
|
231
|
+
},
|
|
232
|
+
"./patterns": {
|
|
233
|
+
"import": "./dist/patterns/index.js",
|
|
234
|
+
"types": "./dist/patterns/index.d.ts"
|
|
235
|
+
},
|
|
236
|
+
"./patterns/confirm-dialog": {
|
|
237
|
+
"import": "./dist/patterns/confirm-dialog.js",
|
|
238
|
+
"types": "./dist/patterns/confirm-dialog.d.ts"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
"scripts": {
|
|
242
|
+
"build": "tsc -p tsconfig.build.json",
|
|
243
|
+
"check": "tsc --noEmit -p tsconfig.check.json",
|
|
244
|
+
"lint": "eslint src",
|
|
245
|
+
"test": "vitest run"
|
|
246
|
+
},
|
|
247
|
+
"peerDependencies": {
|
|
248
|
+
"@llui/dom": "^0.0.1"
|
|
249
|
+
},
|
|
250
|
+
"devDependencies": {
|
|
251
|
+
"@llui/dom": "workspace:*",
|
|
252
|
+
"typescript": "^6.0.0",
|
|
253
|
+
"vitest": "^4.1.2"
|
|
254
|
+
},
|
|
255
|
+
"sideEffects": false,
|
|
256
|
+
"dependencies": {
|
|
257
|
+
"@floating-ui/dom": "^1.7.6"
|
|
258
|
+
},
|
|
259
|
+
"description": "54 headless UI components for LLui — accordion, dialog, tabs, select, tree-view, timer, tour, and more",
|
|
260
|
+
"keywords": [
|
|
261
|
+
"llui",
|
|
262
|
+
"components",
|
|
263
|
+
"headless",
|
|
264
|
+
"ui",
|
|
265
|
+
"accessible",
|
|
266
|
+
"state-machine"
|
|
267
|
+
],
|
|
268
|
+
"author": "Franco Ponticelli <franco.ponticelli@gmail.com>",
|
|
269
|
+
"license": "MIT",
|
|
270
|
+
"repository": {
|
|
271
|
+
"type": "git",
|
|
272
|
+
"url": "git+https://github.com/fponticelli/llui.git",
|
|
273
|
+
"directory": "packages/components"
|
|
274
|
+
},
|
|
275
|
+
"bugs": {
|
|
276
|
+
"url": "https://github.com/fponticelli/llui/issues"
|
|
277
|
+
},
|
|
278
|
+
"homepage": "https://github.com/fponticelli/llui/tree/main/packages/components#readme",
|
|
279
|
+
"files": [
|
|
280
|
+
"dist"
|
|
281
|
+
]
|
|
282
|
+
}
|