dustyui 1.0.1 → 2.0.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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -1
  3. package/dist/Avatar/Avatar.d.ts +9 -0
  4. package/dist/Avatar/Avatar.js +17 -0
  5. package/dist/Avatar/Avatar.module.css +33 -0
  6. package/dist/Avatar/getInitials.d.ts +1 -0
  7. package/dist/Avatar/getInitials.js +13 -0
  8. package/dist/Badge/Badge.d.ts +7 -6
  9. package/dist/Badge/Badge.js +6 -7
  10. package/dist/Badge/Badge.module.css +25 -2
  11. package/dist/Button/Button.d.ts +9 -6
  12. package/dist/Button/Button.js +22 -7
  13. package/dist/Button/Button.module.css +106 -6
  14. package/dist/IconButton/IconButton.d.ts +7 -0
  15. package/dist/IconButton/IconButton.js +8 -0
  16. package/dist/IconButton/IconButton.module.css +17 -0
  17. package/dist/ObjectInspector/InspectorDetails.d.ts +6 -0
  18. package/dist/ObjectInspector/InspectorDetails.js +32 -0
  19. package/dist/ObjectInspector/InspectorDetails.module.css +47 -0
  20. package/dist/ObjectInspector/InspectorSearch.d.ts +9 -0
  21. package/dist/ObjectInspector/InspectorSearch.js +12 -0
  22. package/dist/ObjectInspector/InspectorSearch.module.css +39 -0
  23. package/dist/ObjectInspector/ObjectInspector.d.ts +8 -0
  24. package/dist/ObjectInspector/ObjectInspector.js +83 -0
  25. package/dist/ObjectInspector/ObjectInspector.module.css +46 -0
  26. package/dist/ObjectInspector/describe/describe.d.ts +31 -0
  27. package/dist/ObjectInspector/describe/describe.js +123 -0
  28. package/dist/ObjectInspector/describe/getChildren.d.ts +21 -0
  29. package/dist/ObjectInspector/describe/getChildren.js +77 -0
  30. package/dist/ObjectInspector/describe/getNode.d.ts +2 -0
  31. package/dist/ObjectInspector/describe/getNode.js +9 -0
  32. package/dist/ObjectInspector/describe/getPath.d.ts +26 -0
  33. package/dist/ObjectInspector/describe/getPath.js +58 -0
  34. package/dist/ObjectInspector/describe/getPreview.d.ts +10 -0
  35. package/dist/ObjectInspector/describe/getPreview.js +189 -0
  36. package/dist/ObjectInspector/describe/getValueKind.d.ts +2 -0
  37. package/dist/ObjectInspector/describe/getValueKind.js +64 -0
  38. package/dist/ObjectInspector/describe/safeRead.d.ts +12 -0
  39. package/dist/ObjectInspector/describe/safeRead.js +88 -0
  40. package/dist/ObjectInspector/getCopyText.d.ts +2 -0
  41. package/dist/ObjectInspector/getCopyText.js +103 -0
  42. package/dist/ObjectInspector/getLabelText.d.ts +2 -0
  43. package/dist/ObjectInspector/getLabelText.js +15 -0
  44. package/dist/ObjectInspector/getValueText.d.ts +2 -0
  45. package/dist/ObjectInspector/getValueText.js +5 -0
  46. package/dist/ObjectInspector/search/getHighlightParts.d.ts +5 -0
  47. package/dist/ObjectInspector/search/getHighlightParts.js +20 -0
  48. package/dist/ObjectInspector/search/getMatches.d.ts +6 -0
  49. package/dist/ObjectInspector/search/getMatches.js +46 -0
  50. package/dist/ObjectInspector/search/getSearchStatus.d.ts +2 -0
  51. package/dist/ObjectInspector/search/getSearchStatus.js +14 -0
  52. package/dist/Tree/Tree.d.ts +14 -0
  53. package/dist/Tree/Tree.js +166 -0
  54. package/dist/Tree/Tree.module.css +65 -0
  55. package/dist/Tree/getWindow.d.ts +22 -0
  56. package/dist/Tree/getWindow.js +43 -0
  57. package/dist/Tree/treeModel.d.ts +55 -0
  58. package/dist/Tree/treeModel.js +203 -0
  59. package/dist/Tree/useRowWindow.d.ts +3 -0
  60. package/dist/Tree/useRowWindow.js +78 -0
  61. package/dist/Tree/useTypeahead.d.ts +2 -0
  62. package/dist/Tree/useTypeahead.js +15 -0
  63. package/dist/announcer/announcer.d.ts +2 -0
  64. package/dist/announcer/announcer.js +41 -0
  65. package/dist/index.d.ts +11 -2
  66. package/dist/index.js +10 -6
  67. package/dist/styles/themes/dusty.css +22 -0
  68. package/dist/styles/themes/mono.css +21 -0
  69. package/dist/styles/tokens.css +21 -0
  70. package/dist/styles/visuallyHidden.module.css +8 -0
  71. package/package.json +55 -36
  72. package/dist/Badge/Badge.cjs +0 -42
  73. package/dist/Button/Button.cjs +0 -42
  74. package/dist/index.cjs +0 -31
@@ -0,0 +1,22 @@
1
+ export interface RowWindow {
2
+ readonly start: number;
3
+ readonly end: number;
4
+ }
5
+ export interface WindowInput {
6
+ readonly rowCount: number;
7
+ readonly rowHeight: number;
8
+ readonly from: number;
9
+ readonly to: number;
10
+ readonly overscan: number;
11
+ readonly limit: number;
12
+ }
13
+ export type WindowItem = {
14
+ readonly type: "gap";
15
+ readonly id: "start" | "middle" | "end";
16
+ readonly rowCount: number;
17
+ } | {
18
+ readonly type: "row";
19
+ readonly index: number;
20
+ };
21
+ export declare function getWindow({ rowCount, rowHeight, from, to, overscan, limit, }: WindowInput): RowWindow;
22
+ export declare function getWindowItems(rowWindow: RowWindow, rowCount: number, pinned: number): WindowItem[];
@@ -0,0 +1,43 @@
1
+ function clamp(value, minimum, maximum) {
2
+ if (Number.isNaN(value)) {
3
+ return minimum;
4
+ }
5
+ return Math.min(Math.max(value, minimum), maximum);
6
+ }
7
+ export function getWindow({ rowCount, rowHeight, from, to, overscan, limit, }) {
8
+ if (!(rowCount > 0) || !(rowHeight > 0)) {
9
+ return { start: 0, end: 0 };
10
+ }
11
+ const start = clamp(Math.floor(from / rowHeight) - overscan, 0, rowCount);
12
+ const end = clamp(Math.ceil(to / rowHeight) + overscan, start, Math.min(rowCount, start + Math.max(limit, 0)));
13
+ return { start, end };
14
+ }
15
+ export function getWindowItems(rowWindow, rowCount, pinned) {
16
+ const start = clamp(rowWindow.start, 0, rowCount);
17
+ const end = clamp(rowWindow.end, start, rowCount);
18
+ const isPinnedBefore = pinned >= 0 && pinned < start;
19
+ const isPinnedAfter = pinned >= end && pinned < rowCount;
20
+ const items = [];
21
+ function addGap(id, gapRowCount) {
22
+ if (gapRowCount > 0 || id === "start") {
23
+ items.push({ type: "gap", id, rowCount: gapRowCount });
24
+ }
25
+ }
26
+ addGap("start", isPinnedBefore ? pinned : start);
27
+ if (isPinnedBefore) {
28
+ items.push({ type: "row", index: pinned });
29
+ addGap("middle", start - pinned - 1);
30
+ }
31
+ for (let index = start; index < end; index++) {
32
+ items.push({ type: "row", index });
33
+ }
34
+ if (isPinnedAfter) {
35
+ addGap("middle", pinned - end);
36
+ items.push({ type: "row", index: pinned });
37
+ addGap("end", rowCount - pinned - 1);
38
+ }
39
+ else {
40
+ addGap("end", rowCount - end);
41
+ }
42
+ return items;
43
+ }
@@ -0,0 +1,55 @@
1
+ export interface TreeNode {
2
+ readonly id: string;
3
+ readonly childCount: number;
4
+ children(): readonly this[];
5
+ }
6
+ export interface TreeRow<Node extends TreeNode = TreeNode> {
7
+ readonly node: Node;
8
+ readonly id: string;
9
+ readonly parentId: string | undefined;
10
+ readonly level: number;
11
+ readonly positionInSet: number;
12
+ readonly setSize: number;
13
+ readonly expandable: boolean;
14
+ readonly expanded: boolean;
15
+ }
16
+ export interface TreeState {
17
+ readonly expanded: ReadonlySet<string>;
18
+ readonly focused: string | undefined;
19
+ }
20
+ export type TreeAction = {
21
+ readonly type: "moveNext";
22
+ } | {
23
+ readonly type: "movePrevious";
24
+ } | {
25
+ readonly type: "moveFirst";
26
+ } | {
27
+ readonly type: "moveLast";
28
+ } | {
29
+ readonly type: "moveIn";
30
+ } | {
31
+ readonly type: "moveOut";
32
+ } | {
33
+ readonly type: "toggle";
34
+ readonly id?: string;
35
+ } | {
36
+ readonly type: "expand";
37
+ readonly id: string;
38
+ } | {
39
+ readonly type: "collapse";
40
+ readonly id: string;
41
+ } | {
42
+ readonly type: "expandSiblings";
43
+ } | {
44
+ readonly type: "focus";
45
+ readonly id: string;
46
+ } | {
47
+ readonly type: "typeahead";
48
+ readonly text: string;
49
+ };
50
+ export declare const INITIAL_TREE_STATE: TreeState;
51
+ export declare function visibleRows<Node extends TreeNode>(root: Node, expanded: ReadonlySet<string>): TreeRow<Node>[];
52
+ export declare function reduceTree<Node extends TreeNode>(rows: readonly TreeRow<Node>[], state: TreeState, action: TreeAction, labelOf?: (row: TreeRow<Node>) => string): TreeState;
53
+ export declare function findVisibleAncestor(previousRows: readonly TreeRow[], id: string, rows: readonly TreeRow[]): string | undefined;
54
+ export declare function getTypeaheadText(typed: string, key: string, isContinuing: boolean): string;
55
+ export declare function keyToAction(key: string): TreeAction | undefined;
@@ -0,0 +1,203 @@
1
+ export const INITIAL_TREE_STATE = {
2
+ expanded: new Set(),
3
+ focused: undefined,
4
+ };
5
+ export function visibleRows(root, expanded) {
6
+ const rows = [];
7
+ const pending = [toRow(root, undefined, 1, 1, 1, expanded)];
8
+ for (let row = pending.pop(); row; row = pending.pop()) {
9
+ rows.push(row);
10
+ if (!row.expanded) {
11
+ continue;
12
+ }
13
+ const children = row.node.children();
14
+ for (let index = children.length - 1; index >= 0; index--) {
15
+ const child = children[index];
16
+ if (child) {
17
+ pending.push(toRow(child, row.id, row.level + 1, index + 1, children.length, expanded));
18
+ }
19
+ }
20
+ }
21
+ return rows;
22
+ }
23
+ function toRow(node, parentId, level, positionInSet, setSize, expanded) {
24
+ return {
25
+ node,
26
+ id: node.id,
27
+ parentId,
28
+ level,
29
+ positionInSet,
30
+ setSize,
31
+ get expandable() {
32
+ return node.childCount > 0;
33
+ },
34
+ expanded: expanded.has(node.id) && node.childCount > 0,
35
+ };
36
+ }
37
+ function withExpanded(state, change) {
38
+ const next = new Set(state.expanded);
39
+ change(next);
40
+ return next;
41
+ }
42
+ function isInside(rows, index, ancestorId) {
43
+ const byId = new Map(rows.map((row) => [row.id, row]));
44
+ for (let current = rows[index]; current?.parentId !== undefined; current = byId.get(current.parentId)) {
45
+ if (current.parentId === ancestorId) {
46
+ return true;
47
+ }
48
+ }
49
+ return false;
50
+ }
51
+ function focusedIndex(rows, state) {
52
+ return state.focused === undefined
53
+ ? -1
54
+ : rows.findIndex((row) => row.id === state.focused);
55
+ }
56
+ function focusRow(state, rows, index) {
57
+ const row = rows[Math.min(Math.max(index, 0), rows.length - 1)];
58
+ return row && row.id !== state.focused
59
+ ? { ...state, focused: row.id }
60
+ : state;
61
+ }
62
+ function expand(state, row) {
63
+ return row?.expandable && !row.expanded
64
+ ? {
65
+ ...state,
66
+ expanded: withExpanded(state, (expanded) => expanded.add(row.id)),
67
+ }
68
+ : state;
69
+ }
70
+ function collapse(state, rows, row) {
71
+ if (!row?.expanded) {
72
+ return state;
73
+ }
74
+ const index = focusedIndex(rows, state);
75
+ return {
76
+ expanded: withExpanded(state, (expanded) => expanded.delete(row.id)),
77
+ focused: index >= 0 && isInside(rows, index, row.id) ? row.id : state.focused,
78
+ };
79
+ }
80
+ function expandSiblings(state, rows, current) {
81
+ const closed = rows.filter((row) => row.parentId === current.parentId && row.expandable && !row.expanded);
82
+ if (closed.length === 0) {
83
+ return state;
84
+ }
85
+ return {
86
+ ...state,
87
+ expanded: withExpanded(state, (expanded) => {
88
+ for (const row of closed) {
89
+ expanded.add(row.id);
90
+ }
91
+ }),
92
+ };
93
+ }
94
+ function typeahead(state, rows, index, text, labelOf) {
95
+ const query = text.toLocaleLowerCase();
96
+ if (query === "") {
97
+ return state;
98
+ }
99
+ const start = query.length === 1 ? index + 1 : Math.max(index, 0);
100
+ for (let offset = 0; offset < rows.length; offset++) {
101
+ const candidate = (start + offset) % rows.length;
102
+ const row = rows[candidate];
103
+ if (row && labelOf(row).toLocaleLowerCase().startsWith(query)) {
104
+ return focusRow(state, rows, candidate);
105
+ }
106
+ }
107
+ return state;
108
+ }
109
+ export function reduceTree(rows, state, action, labelOf = () => "") {
110
+ if (rows.length === 0) {
111
+ return state;
112
+ }
113
+ const index = focusedIndex(rows, state);
114
+ const current = rows[index];
115
+ const byId = (id) => rows.find((row) => row.id === id);
116
+ switch (action.type) {
117
+ case "moveNext":
118
+ return focusRow(state, rows, index + 1);
119
+ case "movePrevious":
120
+ return focusRow(state, rows, index < 0 ? 0 : index - 1);
121
+ case "moveFirst":
122
+ return focusRow(state, rows, 0);
123
+ case "moveLast":
124
+ return focusRow(state, rows, rows.length - 1);
125
+ case "moveIn":
126
+ if (!current) {
127
+ return focusRow(state, rows, 0);
128
+ }
129
+ return current.expanded
130
+ ? focusRow(state, rows, index + 1)
131
+ : expand(state, current);
132
+ case "moveOut": {
133
+ if (!current) {
134
+ return focusRow(state, rows, 0);
135
+ }
136
+ if (current.expanded) {
137
+ return collapse(state, rows, current);
138
+ }
139
+ const parent = rows.findIndex((row) => row.id === current.parentId);
140
+ return parent >= 0 ? focusRow(state, rows, parent) : state;
141
+ }
142
+ case "toggle": {
143
+ const row = action.id === undefined ? current : byId(action.id);
144
+ return row?.expanded ? collapse(state, rows, row) : expand(state, row);
145
+ }
146
+ case "expand":
147
+ return expand(state, byId(action.id));
148
+ case "collapse":
149
+ return collapse(state, rows, byId(action.id));
150
+ case "expandSiblings":
151
+ return current ? expandSiblings(state, rows, current) : state;
152
+ case "focus":
153
+ return byId(action.id) ? { ...state, focused: action.id } : state;
154
+ case "typeahead":
155
+ return typeahead(state, rows, index, action.text, labelOf);
156
+ }
157
+ }
158
+ export function findVisibleAncestor(previousRows, id, rows) {
159
+ const visible = new Set(rows.map((row) => row.id));
160
+ const previous = new Map(previousRows.map((row) => [row.id, row]));
161
+ for (let current = previous.get(id); current; current =
162
+ current.parentId === undefined
163
+ ? undefined
164
+ : previous.get(current.parentId)) {
165
+ if (visible.has(current.id)) {
166
+ return current.id;
167
+ }
168
+ }
169
+ return undefined;
170
+ }
171
+ export function getTypeaheadText(typed, key, isContinuing) {
172
+ if (!isContinuing) {
173
+ return key;
174
+ }
175
+ const letter = key.toLocaleLowerCase();
176
+ const isRepeat = Array.from(typed.toLocaleLowerCase()).every((character) => character === letter);
177
+ return isRepeat ? key : typed + key;
178
+ }
179
+ export function keyToAction(key) {
180
+ switch (key) {
181
+ case "ArrowDown":
182
+ return { type: "moveNext" };
183
+ case "ArrowUp":
184
+ return { type: "movePrevious" };
185
+ case "ArrowRight":
186
+ return { type: "moveIn" };
187
+ case "ArrowLeft":
188
+ return { type: "moveOut" };
189
+ case "Home":
190
+ return { type: "moveFirst" };
191
+ case "End":
192
+ return { type: "moveLast" };
193
+ case "Enter":
194
+ case " ":
195
+ return { type: "toggle" };
196
+ case "*":
197
+ return { type: "expandSiblings" };
198
+ default:
199
+ return Array.from(key).length === 1
200
+ ? { type: "typeahead", text: key }
201
+ : undefined;
202
+ }
203
+ }
@@ -0,0 +1,3 @@
1
+ import { type RefObject } from "react";
2
+ import { type RowWindow } from "./getWindow.js";
3
+ export declare function useRowWindow(element: RefObject<HTMLElement | null>, rowCount: number): RowWindow | undefined;
@@ -0,0 +1,78 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ import { getWindow } from "./getWindow.js";
3
+ const WINDOW_THRESHOLD = 200;
4
+ const WINDOW_OVERSCAN = 10;
5
+ const WINDOW_LIMIT = 500;
6
+ const INITIAL_WINDOW = { start: 0, end: 50 };
7
+ const ESTIMATED_ROW_HEIGHT = 21;
8
+ const TREE_ITEM = ':scope > [role="treeitem"]';
9
+ const GAP = ":scope > [data-gap-rows]";
10
+ function getRowHeight(tree) {
11
+ let gapHeight = 0;
12
+ let gapRows = 0;
13
+ for (const gap of tree.querySelectorAll(GAP)) {
14
+ gapHeight += gap.getBoundingClientRect().height;
15
+ gapRows += Number(gap.dataset.gapRows);
16
+ }
17
+ if (gapRows > 0 && gapHeight > 0) {
18
+ return gapHeight / gapRows;
19
+ }
20
+ return (tree.querySelector(TREE_ITEM)?.getBoundingClientRect().height ||
21
+ ESTIMATED_ROW_HEIGHT);
22
+ }
23
+ function getVisibleSpan(tree) {
24
+ const bounds = tree.getBoundingClientRect();
25
+ let top = Math.max(bounds.top, 0);
26
+ let bottom = Math.min(bounds.bottom, window.innerHeight);
27
+ for (let ancestor = tree.parentElement; ancestor; ancestor = ancestor.parentElement) {
28
+ if (getComputedStyle(ancestor).overflowY !== "visible") {
29
+ const clip = ancestor.getBoundingClientRect();
30
+ top = Math.max(top, clip.top);
31
+ bottom = Math.min(bottom, clip.bottom);
32
+ }
33
+ }
34
+ return { top, bottom };
35
+ }
36
+ export function useRowWindow(element, rowCount) {
37
+ const [rowWindow, setRowWindow] = useState(INITIAL_WINDOW);
38
+ const isWindowed = rowCount > WINDOW_THRESHOLD;
39
+ useLayoutEffect(() => {
40
+ const tree = element.current;
41
+ if (!isWindowed || !tree) {
42
+ return;
43
+ }
44
+ const container = tree;
45
+ function update() {
46
+ const origin = container.firstElementChild;
47
+ if (!origin) {
48
+ return;
49
+ }
50
+ const start = origin.getBoundingClientRect().top;
51
+ const { top, bottom } = getVisibleSpan(container);
52
+ const next = getWindow({
53
+ rowCount,
54
+ rowHeight: getRowHeight(container),
55
+ from: top - start,
56
+ to: bottom - start,
57
+ overscan: WINDOW_OVERSCAN,
58
+ limit: WINDOW_LIMIT,
59
+ });
60
+ setRowWindow((current) => current.start === next.start && current.end === next.end
61
+ ? current
62
+ : next);
63
+ }
64
+ const observer = new ResizeObserver(update);
65
+ observer.observe(container);
66
+ document.addEventListener("scroll", update, {
67
+ capture: true,
68
+ passive: true,
69
+ });
70
+ window.addEventListener("resize", update);
71
+ return () => {
72
+ observer.disconnect();
73
+ document.removeEventListener("scroll", update, { capture: true });
74
+ window.removeEventListener("resize", update);
75
+ };
76
+ }, [element, isWindowed, rowCount]);
77
+ return isWindowed ? rowWindow : undefined;
78
+ }
@@ -0,0 +1,2 @@
1
+ import { type TreeAction } from "./treeModel.js";
2
+ export declare function useTypeahead(): (action: TreeAction, timeStamp: number) => TreeAction;
@@ -0,0 +1,15 @@
1
+ import { useRef } from "react";
2
+ import { getTypeaheadText } from "./treeModel.js";
3
+ const TYPEAHEAD_PAUSE = 500;
4
+ export function useTypeahead() {
5
+ const typed = useRef({ text: "", at: 0 });
6
+ return (action, timeStamp) => {
7
+ if (action.type !== "typeahead") {
8
+ return action;
9
+ }
10
+ const isContinuing = timeStamp - typed.current.at < TYPEAHEAD_PAUSE;
11
+ const text = getTypeaheadText(typed.current.text, action.text, isContinuing);
12
+ typed.current = { text, at: timeStamp };
13
+ return { type: "typeahead", text };
14
+ };
15
+ }
@@ -0,0 +1,2 @@
1
+ export type Politeness = "polite" | "assertive";
2
+ export declare function announce(message: string, politeness?: Politeness): void;
@@ -0,0 +1,41 @@
1
+ import visuallyHidden from "../styles/visuallyHidden.module.css";
2
+ const REGION_READY_DELAY = 100;
3
+ const MESSAGE_LIFETIME = 7000;
4
+ let regions;
5
+ let regionsReadyAt = 0;
6
+ function createRegion(politeness) {
7
+ const region = document.createElement("div");
8
+ region.setAttribute("role", "log");
9
+ region.setAttribute("aria-live", politeness);
10
+ region.setAttribute("aria-relevant", "additions");
11
+ return region;
12
+ }
13
+ function ensureRegions() {
14
+ if (regions?.polite.isConnected && regions.assertive.isConnected) {
15
+ return regions;
16
+ }
17
+ const container = document.createElement("div");
18
+ container.dataset.dustyAnnouncer = "";
19
+ container.className = visuallyHidden.visuallyHidden ?? "";
20
+ regions = {
21
+ polite: createRegion("polite"),
22
+ assertive: createRegion("assertive"),
23
+ };
24
+ container.append(regions.polite, regions.assertive);
25
+ document.body.append(container);
26
+ regionsReadyAt = performance.now() + REGION_READY_DELAY;
27
+ return regions;
28
+ }
29
+ export function announce(message, politeness = "polite") {
30
+ if (typeof document === "undefined" || message.trim() === "") {
31
+ return;
32
+ }
33
+ const region = ensureRegions()[politeness];
34
+ const delay = Math.max(0, regionsReadyAt - performance.now());
35
+ setTimeout(() => {
36
+ const entry = document.createElement("div");
37
+ entry.textContent = message;
38
+ region.append(entry);
39
+ setTimeout(() => entry.remove(), MESSAGE_LIFETIME);
40
+ }, delay);
41
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,11 @@
1
- export { Badge } from "./Badge/Badge";
2
- export { Button } from "./Button/Button";
1
+ import "./styles/tokens.css";
2
+ import "./styles/themes/dusty.css";
3
+ export { announce, type Politeness } from "./announcer/announcer.js";
4
+ export { Avatar, type AvatarProps } from "./Avatar/Avatar.js";
5
+ export { Badge, type BadgeProps } from "./Badge/Badge.js";
6
+ export { Button, type ButtonProps, type ButtonVariant, } from "./Button/Button.js";
7
+ export { IconButton, type IconButtonProps } from "./IconButton/IconButton.js";
8
+ export { ObjectInspector, type ObjectInspectorProps, } from "./ObjectInspector/ObjectInspector.js";
9
+ export { describe, type InspectorNode, type NodeLabel, type ValueKind, } from "./ObjectInspector/describe/describe.js";
10
+ export { Tree, type TreeProps } from "./Tree/Tree.js";
11
+ export type { TreeNode, TreeRow } from "./Tree/treeModel.js";
package/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
- import { Badge } from "./Badge/Badge";
2
- import { Button } from "./Button/Button";
3
- export {
4
- Badge,
5
- Button
6
- };
1
+ import "./styles/tokens.css";
2
+ import "./styles/themes/dusty.css";
3
+ export { announce } from "./announcer/announcer.js";
4
+ export { Avatar } from "./Avatar/Avatar.js";
5
+ export { Badge } from "./Badge/Badge.js";
6
+ export { Button, } from "./Button/Button.js";
7
+ export { IconButton } from "./IconButton/IconButton.js";
8
+ export { ObjectInspector, } from "./ObjectInspector/ObjectInspector.js";
9
+ export { describe, } from "./ObjectInspector/describe/describe.js";
10
+ export { Tree } from "./Tree/Tree.js";
@@ -0,0 +1,22 @@
1
+ :where(:root),
2
+ [data-theme="dusty"] {
3
+ --dusty-surface: light-dark(#faf7f2, #14191b);
4
+ --dusty-surface-raised: light-dark(#fff, #1c2326);
5
+ --dusty-surface-sunken: light-dark(#f1ece3, #0f1314);
6
+ --dusty-surface-hover: light-dark(#f1ece3, #232c30);
7
+ --dusty-surface-selected: light-dark(#dcebed, #1f3a40);
8
+ --dusty-text: light-dark(#1f2a2e, #e8e4dc);
9
+ --dusty-text-muted: light-dark(#55636a, #a3acaf);
10
+ --dusty-text-disabled: light-dark(#9aa3a3, #5f6a6e);
11
+ --dusty-border: light-dark(#d9d2c5, #3a4448);
12
+ --dusty-border-strong: light-dark(#7d837f, #7f8a8e);
13
+ --dusty-focus-ring: light-dark(#1d6f7a, #6cc5d0);
14
+ --dusty-action: light-dark(#1f2a2e, #e8e4dc);
15
+ --dusty-action-hover: light-dark(#33424a, #cfc9be);
16
+ --dusty-action-active: light-dark(#465862, #b9b3a8);
17
+ --dusty-on-action: light-dark(#faf7f2, #14191b);
18
+ --dusty-syntax-string: light-dark(#a04a1c, #e8a87c);
19
+ --dusty-syntax-number: light-dark(#1d5f8a, #7fb8e0);
20
+ --dusty-syntax-boolean: light-dark(#7a4a9a, #c79be0);
21
+ --dusty-syntax-function: light-dark(#2f6b3f, #8fcf9a);
22
+ }
@@ -0,0 +1,21 @@
1
+ [data-theme="mono"] {
2
+ --dusty-surface: light-dark(#fafafa, #1a1a1a);
3
+ --dusty-surface-raised: light-dark(#fff, #242424);
4
+ --dusty-surface-sunken: light-dark(#eee, #121212);
5
+ --dusty-surface-hover: light-dark(#eee, #2e2e2e);
6
+ --dusty-surface-selected: light-dark(#e0e0e0, #3a3a3a);
7
+ --dusty-text: light-dark(#222, #f0f0f0);
8
+ --dusty-text-muted: light-dark(#555, #adadad);
9
+ --dusty-text-disabled: light-dark(#999, #6b6b6b);
10
+ --dusty-border: light-dark(#ddd, #3d3d3d);
11
+ --dusty-border-strong: light-dark(#767676, #8a8a8a);
12
+ --dusty-focus-ring: light-dark(#222, #fafafa);
13
+ --dusty-action: light-dark(#222, #f0f0f0);
14
+ --dusty-action-hover: light-dark(#3a3a3a, #d6d6d6);
15
+ --dusty-action-active: light-dark(#505050, #bdbdbd);
16
+ --dusty-on-action: light-dark(#fafafa, #1a1a1a);
17
+ --dusty-syntax-string: light-dark(#8a3d12, #e8a87c);
18
+ --dusty-syntax-number: light-dark(#1d5f8a, #7fb8e0);
19
+ --dusty-syntax-boolean: light-dark(#7a4a9a, #c79be0);
20
+ --dusty-syntax-function: light-dark(#2f6b3f, #8fcf9a);
21
+ }
@@ -0,0 +1,21 @@
1
+ :root {
2
+ --dusty-radius-sm: 0.25rem;
3
+ --dusty-radius-md: 0.5rem;
4
+ --dusty-radius-full: 999px;
5
+ --dusty-weight-semibold: 600;
6
+ --dusty-font-mono: ui-monospace, "SFMono-Regular", menlo, consolas, monospace;
7
+ --dusty-focus-ring-width: 2px;
8
+ --dusty-focus-ring-offset: 2px;
9
+ }
10
+
11
+ :where(:root) {
12
+ color-scheme: light dark;
13
+ }
14
+
15
+ [data-color-scheme="light"] {
16
+ color-scheme: light;
17
+ }
18
+
19
+ [data-color-scheme="dark"] {
20
+ color-scheme: dark;
21
+ }
@@ -0,0 +1,8 @@
1
+ .visuallyHidden {
2
+ position: absolute;
3
+ inline-size: 1px;
4
+ block-size: 1px;
5
+ overflow: hidden;
6
+ clip-path: inset(50%);
7
+ white-space: nowrap;
8
+ }