@dowel-ui/react 0.4.0 → 0.5.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/README.md +9 -5
- package/dist/components/ai-extraction-review/ai-extraction-review.d.ts +52 -0
- package/dist/components/ai-extraction-review/ai-extraction-review.d.ts.map +1 -0
- package/dist/components/ai-extraction-review/ai-extraction-review.js +249 -0
- package/dist/components/ai-extraction-review/ai-extraction-review.js.map +1 -0
- package/dist/components/ai-extraction-review/extraction-model.d.ts +94 -0
- package/dist/components/ai-extraction-review/extraction-model.d.ts.map +1 -0
- package/dist/components/ai-extraction-review/extraction-model.js +91 -0
- package/dist/components/ai-extraction-review/extraction-model.js.map +1 -0
- package/dist/components/ai-extraction-review/index.d.ts +3 -0
- package/dist/components/ai-extraction-review/index.js +3 -0
- package/dist/components/ai-extraction-review/meta.js +17 -0
- package/dist/components/ai-extraction-review/meta.js.map +1 -0
- package/dist/components/ai-suggested-value/ai-suggested-value.d.ts +72 -0
- package/dist/components/ai-suggested-value/ai-suggested-value.d.ts.map +1 -0
- package/dist/components/ai-suggested-value/ai-suggested-value.js +126 -0
- package/dist/components/ai-suggested-value/ai-suggested-value.js.map +1 -0
- package/dist/components/ai-suggested-value/index.d.ts +2 -0
- package/dist/components/ai-suggested-value/index.js +2 -0
- package/dist/components/ai-suggested-value/meta.js +17 -0
- package/dist/components/ai-suggested-value/meta.js.map +1 -0
- package/dist/components/alert/alert.d.ts +1 -1
- package/dist/components/avatar/avatar.d.ts +1 -1
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/button/button.d.ts +1 -1
- package/dist/components/confirm-typed/confirm-typed.d.ts +47 -0
- package/dist/components/confirm-typed/confirm-typed.d.ts.map +1 -0
- package/dist/components/confirm-typed/confirm-typed.js +106 -0
- package/dist/components/confirm-typed/confirm-typed.js.map +1 -0
- package/dist/components/confirm-typed/index.d.ts +2 -0
- package/dist/components/confirm-typed/index.js +2 -0
- package/dist/components/confirm-typed/meta.js +17 -0
- package/dist/components/confirm-typed/meta.js.map +1 -0
- package/dist/components/cron-editor/cron-editor.d.ts +36 -0
- package/dist/components/cron-editor/cron-editor.d.ts.map +1 -0
- package/dist/components/cron-editor/cron-editor.js +493 -0
- package/dist/components/cron-editor/cron-editor.js.map +1 -0
- package/dist/components/cron-editor/cron-expression.d.ts +82 -0
- package/dist/components/cron-editor/cron-expression.d.ts.map +1 -0
- package/dist/components/cron-editor/cron-expression.js +352 -0
- package/dist/components/cron-editor/cron-expression.js.map +1 -0
- package/dist/components/cron-editor/index.d.ts +3 -0
- package/dist/components/cron-editor/index.js +3 -0
- package/dist/components/cron-editor/meta.js +17 -0
- package/dist/components/cron-editor/meta.js.map +1 -0
- package/dist/components/dns-record/dns-record.d.ts +61 -0
- package/dist/components/dns-record/dns-record.d.ts.map +1 -0
- package/dist/components/dns-record/dns-record.js +227 -0
- package/dist/components/dns-record/dns-record.js.map +1 -0
- package/dist/components/dns-record/index.d.ts +2 -0
- package/dist/components/dns-record/index.js +2 -0
- package/dist/components/dns-record/meta.js +17 -0
- package/dist/components/dns-record/meta.js.map +1 -0
- package/dist/components/permission-matrix/index.d.ts +3 -0
- package/dist/components/permission-matrix/index.js +3 -0
- package/dist/components/permission-matrix/meta.js +17 -0
- package/dist/components/permission-matrix/meta.js.map +1 -0
- package/dist/components/permission-matrix/permission-matrix.d.ts +46 -0
- package/dist/components/permission-matrix/permission-matrix.d.ts.map +1 -0
- package/dist/components/permission-matrix/permission-matrix.js +199 -0
- package/dist/components/permission-matrix/permission-matrix.js.map +1 -0
- package/dist/components/permission-matrix/permission-model.d.ts +53 -0
- package/dist/components/permission-matrix/permission-model.d.ts.map +1 -0
- package/dist/components/permission-matrix/permission-model.js +64 -0
- package/dist/components/permission-matrix/permission-model.js.map +1 -0
- package/dist/components/progress/progress.d.ts +1 -1
- package/dist/components/secret-field/index.d.ts +2 -0
- package/dist/components/secret-field/index.js +2 -0
- package/dist/components/secret-field/meta.js +17 -0
- package/dist/components/secret-field/meta.js.map +1 -0
- package/dist/components/secret-field/secret-field.d.ts +58 -0
- package/dist/components/secret-field/secret-field.d.ts.map +1 -0
- package/dist/components/secret-field/secret-field.js +168 -0
- package/dist/components/secret-field/secret-field.js.map +1 -0
- package/dist/components/session-expiry/index.d.ts +2 -0
- package/dist/components/session-expiry/index.js +2 -0
- package/dist/components/session-expiry/meta.js +17 -0
- package/dist/components/session-expiry/meta.js.map +1 -0
- package/dist/components/session-expiry/session-expiry.d.ts +64 -0
- package/dist/components/session-expiry/session-expiry.d.ts.map +1 -0
- package/dist/components/session-expiry/session-expiry.js +185 -0
- package/dist/components/session-expiry/session-expiry.js.map +1 -0
- package/dist/components/shortcut-recorder/index.d.ts +3 -0
- package/dist/components/shortcut-recorder/index.js +3 -0
- package/dist/components/shortcut-recorder/meta.js +17 -0
- package/dist/components/shortcut-recorder/meta.js.map +1 -0
- package/dist/components/shortcut-recorder/shortcut-model.d.ts +67 -0
- package/dist/components/shortcut-recorder/shortcut-model.d.ts.map +1 -0
- package/dist/components/shortcut-recorder/shortcut-model.js +168 -0
- package/dist/components/shortcut-recorder/shortcut-model.js.map +1 -0
- package/dist/components/shortcut-recorder/shortcut-recorder.d.ts +47 -0
- package/dist/components/shortcut-recorder/shortcut-recorder.d.ts.map +1 -0
- package/dist/components/shortcut-recorder/shortcut-recorder.js +212 -0
- package/dist/components/shortcut-recorder/shortcut-recorder.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/sync-status/index.d.ts +2 -0
- package/dist/components/sync-status/index.js +2 -0
- package/dist/components/sync-status/meta.js +17 -0
- package/dist/components/sync-status/meta.js.map +1 -0
- package/dist/components/sync-status/sync-status.d.ts +65 -0
- package/dist/components/sync-status/sync-status.d.ts.map +1 -0
- package/dist/components/sync-status/sync-status.js +103 -0
- package/dist/components/sync-status/sync-status.js.map +1 -0
- package/dist/components/toast/toast.d.ts +1 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +16 -2
- package/dist/registry/components.d.ts.map +1 -1
- package/dist/registry/components.js +73 -53
- package/dist/registry/components.js.map +1 -1
- package/package.json +4 -4
- package/src/components/ai-extraction-review/ai-extraction-review.tsx +492 -0
- package/src/components/ai-extraction-review/extraction-model.ts +159 -0
- package/src/components/ai-extraction-review/index.ts +13 -0
- package/src/components/ai-extraction-review/meta.ts +24 -0
- package/src/components/ai-suggested-value/ai-suggested-value.tsx +295 -0
- package/src/components/ai-suggested-value/index.ts +6 -0
- package/src/components/ai-suggested-value/meta.ts +24 -0
- package/src/components/confirm-typed/confirm-typed.tsx +191 -0
- package/src/components/confirm-typed/index.ts +1 -0
- package/src/components/confirm-typed/meta.ts +22 -0
- package/src/components/cron-editor/cron-editor.tsx +676 -0
- package/src/components/cron-editor/cron-expression.ts +552 -0
- package/src/components/cron-editor/index.ts +23 -0
- package/src/components/cron-editor/meta.ts +23 -0
- package/src/components/dns-record/dns-record.tsx +315 -0
- package/src/components/dns-record/index.ts +7 -0
- package/src/components/dns-record/meta.ts +21 -0
- package/src/components/permission-matrix/index.ts +14 -0
- package/src/components/permission-matrix/meta.ts +23 -0
- package/src/components/permission-matrix/permission-matrix.tsx +368 -0
- package/src/components/permission-matrix/permission-model.ts +120 -0
- package/src/components/secret-field/index.ts +6 -0
- package/src/components/secret-field/meta.ts +21 -0
- package/src/components/secret-field/secret-field.tsx +284 -0
- package/src/components/session-expiry/index.ts +9 -0
- package/src/components/session-expiry/meta.ts +23 -0
- package/src/components/session-expiry/session-expiry.tsx +321 -0
- package/src/components/shortcut-recorder/index.ts +19 -0
- package/src/components/shortcut-recorder/meta.ts +22 -0
- package/src/components/shortcut-recorder/shortcut-model.ts +204 -0
- package/src/components/shortcut-recorder/shortcut-recorder.tsx +336 -0
- package/src/components/sync-status/index.ts +9 -0
- package/src/components/sync-status/meta.ts +21 -0
- package/src/components/sync-status/sync-status.tsx +217 -0
- package/src/index.ts +10 -0
- package/src/registry/components.ts +20 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { disabledStyles, focusRing } from "../../lib/styles.js";
|
|
3
|
+
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { describeShortcut, detectPlatform, needsModifier, parseShortcut, serializeShortcut, shortcutFromKey, shortcutParts, shortcutsEqual } from "./shortcut-model.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { useId, useState, useSyncExternalStore } from "react";
|
|
7
|
+
//#region src/components/shortcut-recorder/shortcut-recorder.tsx
|
|
8
|
+
const subscribeToNothing = () => () => void 0;
|
|
9
|
+
const readPlatform = () => detectPlatform();
|
|
10
|
+
const readNeutralPlatform = () => "other";
|
|
11
|
+
function ShortcutRecorder({ className, label, value: valueProp, defaultValue = null, onChange, taken = [], platform: platformProp, requireModifier = true, ...props }) {
|
|
12
|
+
const id = useId();
|
|
13
|
+
const detected = useSyncExternalStore(subscribeToNothing, readPlatform, readNeutralPlatform);
|
|
14
|
+
const platform = platformProp ?? detected;
|
|
15
|
+
const [uncontrolled, setUncontrolled] = useState(defaultValue);
|
|
16
|
+
const value = valueProp === void 0 ? uncontrolled : valueProp;
|
|
17
|
+
const current = value ? safeParse(value) : null;
|
|
18
|
+
const [recording, setRecording] = useState(false);
|
|
19
|
+
/** Modifiers held mid-chord, shown so the person sees the recorder listening. */
|
|
20
|
+
const [held, setHeld] = useState(null);
|
|
21
|
+
const [conflict, setConflict] = useState(null);
|
|
22
|
+
const [announcement, setAnnouncement] = useState("");
|
|
23
|
+
const commit = (next) => {
|
|
24
|
+
const serialized = next ? serializeShortcut(next) : null;
|
|
25
|
+
setUncontrolled(serialized);
|
|
26
|
+
onChange?.(serialized);
|
|
27
|
+
};
|
|
28
|
+
const stop = () => {
|
|
29
|
+
setRecording(false);
|
|
30
|
+
setHeld(null);
|
|
31
|
+
};
|
|
32
|
+
const onKeyDown = (event) => {
|
|
33
|
+
if (!recording) return;
|
|
34
|
+
if (event.key === "Tab") {
|
|
35
|
+
stop();
|
|
36
|
+
setAnnouncement("Cancelled.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
if (event.key === "Escape") {
|
|
41
|
+
stop();
|
|
42
|
+
setAnnouncement("Cancelled.");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if ((event.key === "Backspace" || event.key === "Delete") && !hasModifier(event)) {
|
|
46
|
+
stop();
|
|
47
|
+
commit(null);
|
|
48
|
+
setAnnouncement("Cleared.");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const chord = shortcutFromKey(event.nativeEvent, platform);
|
|
52
|
+
if (!chord) {
|
|
53
|
+
setHeld({
|
|
54
|
+
key: "",
|
|
55
|
+
mod: platform === "mac" ? event.metaKey : event.ctrlKey,
|
|
56
|
+
ctrl: platform === "mac" ? event.ctrlKey : false,
|
|
57
|
+
alt: event.altKey,
|
|
58
|
+
shift: event.shiftKey
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (requireModifier && needsModifier(chord)) {
|
|
63
|
+
setAnnouncement(`${describeShortcut(chord, platform)} needs a modifier — it would fire while typing. Try again.`);
|
|
64
|
+
setHeld(null);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const clash = taken.find((entry) => shortcutsEqual(safeParse(entry.shortcut) ?? chord, chord));
|
|
68
|
+
stop();
|
|
69
|
+
if (clash && !(current && shortcutsEqual(current, chord))) {
|
|
70
|
+
setConflict({
|
|
71
|
+
shortcut: chord,
|
|
72
|
+
with: clash
|
|
73
|
+
});
|
|
74
|
+
setAnnouncement(`${describeShortcut(chord, platform)} is already used by ${clash.label}.`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
commit(chord);
|
|
78
|
+
setAnnouncement(`Recorded ${describeShortcut(chord, platform)}.`);
|
|
79
|
+
};
|
|
80
|
+
const onKeyUp = (event) => {
|
|
81
|
+
if (!recording || !held) return;
|
|
82
|
+
setHeld({
|
|
83
|
+
key: "",
|
|
84
|
+
mod: platform === "mac" ? event.metaKey : event.ctrlKey,
|
|
85
|
+
ctrl: platform === "mac" ? event.ctrlKey : false,
|
|
86
|
+
alt: event.altKey,
|
|
87
|
+
shift: event.shiftKey
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
const shown = recording ? held : current;
|
|
91
|
+
const description = recording ? "Press the keys you want. Escape cancels, Backspace clears." : current ? `${describeShortcut(current, platform)}. Press to change.` : "Not set. Press to record.";
|
|
92
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
93
|
+
"data-slot": "shortcut-recorder",
|
|
94
|
+
"data-state": recording ? "recording" : conflict ? "conflict" : current ? "set" : "empty",
|
|
95
|
+
className: cn("flex flex-col gap-1.5", className),
|
|
96
|
+
...props,
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ jsx("span", {
|
|
99
|
+
id: `${id}-label`,
|
|
100
|
+
className: "text-xs font-medium",
|
|
101
|
+
children: label
|
|
102
|
+
}),
|
|
103
|
+
/* @__PURE__ */ jsxs("div", {
|
|
104
|
+
className: "flex flex-wrap items-center gap-2",
|
|
105
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
106
|
+
type: "button",
|
|
107
|
+
"aria-labelledby": `${id}-label`,
|
|
108
|
+
"aria-describedby": `${id}-description`,
|
|
109
|
+
"aria-pressed": recording,
|
|
110
|
+
className: cn("flex h-9 min-w-32 items-center justify-center gap-1 rounded-md border px-3 font-mono text-sm", recording ? "border-primary bg-primary/5 text-muted-foreground" : "border-input bg-background hover:bg-accent", focusRing, disabledStyles),
|
|
111
|
+
onClick: () => {
|
|
112
|
+
if (recording) return;
|
|
113
|
+
setConflict(null);
|
|
114
|
+
setRecording(true);
|
|
115
|
+
setAnnouncement("");
|
|
116
|
+
},
|
|
117
|
+
onKeyDown,
|
|
118
|
+
onKeyUp,
|
|
119
|
+
onBlur: () => {
|
|
120
|
+
if (recording) {
|
|
121
|
+
stop();
|
|
122
|
+
setAnnouncement("Cancelled.");
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
126
|
+
"aria-hidden": "true",
|
|
127
|
+
className: "flex items-center gap-1",
|
|
128
|
+
children: shown && (shown.key || shown.mod || shown.ctrl || shown.alt || shown.shift) ? shortcutParts(shown, platform).filter(Boolean).map((part, index) => /* @__PURE__ */ jsx("kbd", {
|
|
129
|
+
className: "rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-xs",
|
|
130
|
+
children: part
|
|
131
|
+
}, index)) : recording ? /* @__PURE__ */ jsx("span", {
|
|
132
|
+
className: "text-xs",
|
|
133
|
+
children: "Press keys…"
|
|
134
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
135
|
+
className: "text-xs text-muted-foreground",
|
|
136
|
+
children: "Not set"
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
}), current && !recording ? /* @__PURE__ */ jsx("button", {
|
|
140
|
+
type: "button",
|
|
141
|
+
"aria-label": `Clear — ${label}`,
|
|
142
|
+
className: cn("rounded-md border border-input bg-background px-2.5 py-1 text-xs font-medium hover:bg-accent", focusRing),
|
|
143
|
+
onClick: () => {
|
|
144
|
+
commit(null);
|
|
145
|
+
setConflict(null);
|
|
146
|
+
setAnnouncement("Cleared.");
|
|
147
|
+
},
|
|
148
|
+
children: "Clear"
|
|
149
|
+
}) : null]
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ jsx("p", {
|
|
152
|
+
id: `${id}-description`,
|
|
153
|
+
className: "text-xs text-muted-foreground",
|
|
154
|
+
children: description
|
|
155
|
+
}),
|
|
156
|
+
conflict ? /* @__PURE__ */ jsxs("div", {
|
|
157
|
+
"data-slot": "shortcut-conflict",
|
|
158
|
+
className: "flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/5 px-2.5 py-1.5 text-xs",
|
|
159
|
+
children: [
|
|
160
|
+
/* @__PURE__ */ jsxs("span", {
|
|
161
|
+
className: "flex-1 text-warning",
|
|
162
|
+
children: [
|
|
163
|
+
describeShortcut(conflict.shortcut, platform),
|
|
164
|
+
" is already used by",
|
|
165
|
+
" ",
|
|
166
|
+
/* @__PURE__ */ jsx("strong", { children: conflict.with.label }),
|
|
167
|
+
"."
|
|
168
|
+
]
|
|
169
|
+
}),
|
|
170
|
+
/* @__PURE__ */ jsx("button", {
|
|
171
|
+
type: "button",
|
|
172
|
+
className: cn("rounded-md border border-input bg-background px-2 py-0.5 font-medium hover:bg-accent", focusRing),
|
|
173
|
+
onClick: () => {
|
|
174
|
+
commit(conflict.shortcut);
|
|
175
|
+
setConflict(null);
|
|
176
|
+
setAnnouncement(`Recorded ${describeShortcut(conflict.shortcut, platform)}. ${conflict.with.label} no longer has a shortcut.`);
|
|
177
|
+
},
|
|
178
|
+
children: "Use anyway"
|
|
179
|
+
}),
|
|
180
|
+
/* @__PURE__ */ jsx("button", {
|
|
181
|
+
type: "button",
|
|
182
|
+
className: cn("rounded-md border border-input bg-background px-2 py-0.5 font-medium hover:bg-accent", focusRing),
|
|
183
|
+
onClick: () => {
|
|
184
|
+
setConflict(null);
|
|
185
|
+
},
|
|
186
|
+
children: "Keep the old one"
|
|
187
|
+
})
|
|
188
|
+
]
|
|
189
|
+
}) : null,
|
|
190
|
+
/* @__PURE__ */ jsx("span", {
|
|
191
|
+
role: "status",
|
|
192
|
+
"aria-live": "polite",
|
|
193
|
+
className: "sr-only",
|
|
194
|
+
children: announcement
|
|
195
|
+
})
|
|
196
|
+
]
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function hasModifier(event) {
|
|
200
|
+
return event.metaKey || event.ctrlKey || event.altKey || event.shiftKey;
|
|
201
|
+
}
|
|
202
|
+
function safeParse(text) {
|
|
203
|
+
try {
|
|
204
|
+
return parseShortcut(text);
|
|
205
|
+
} catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
export { ShortcutRecorder };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=shortcut-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcut-recorder.js","names":[],"sources":["../../../src/components/shortcut-recorder/shortcut-recorder.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useId,\n useState,\n useSyncExternalStore,\n type ComponentPropsWithRef,\n type KeyboardEvent,\n} from \"react\";\n\nimport { disabledStyles, focusRing } from \"@/lib/styles\";\nimport { cn } from \"@/lib/utils\";\n\nimport {\n describeShortcut,\n detectPlatform,\n needsModifier,\n parseShortcut,\n serializeShortcut,\n shortcutFromKey,\n shortcutParts,\n shortcutsEqual,\n type Platform,\n type Shortcut,\n} from \"./shortcut-model\";\n\n/**\n * Press the keys you want.\n *\n * Linear, Slack, VS Code, Figma and Superhuman each wrote one, and no\n * component library ships the recorder — only the `<kbd>` that displays the\n * result. The recorder is the hard part: a button that, when pressed, stops\n * being a button and starts being a keyboard listener, and has to come back.\n *\n * Three things it does that a listener bolted onto an input does not. It\n * reads letters from `code`, not `key`, so Option-K records as Option K and\n * not as the ˚ the Mac produced. It stores `Mod`, not Command or Control,\n * so a binding saved on one machine is right on the other. And it refuses a\n * bare printable key by saying so, because a shortcut that fires while\n * someone types a sentence is the bug every app that allowed it later fixed.\n *\n * Tab and Escape are never recorded: Tab leaves, Escape cancels, and a\n * recorder that captures both is a keyboard trap with a nice label. A\n * chord that another command already uses is said, with that command's\n * name, and applied only if the person says to use it anyway.\n */\n\nexport interface TakenShortcut {\n /** Stored form: `Mod+K`. */\n shortcut: string;\n /** What it does: \"Search\". */\n label: string;\n}\n\nexport interface ShortcutRecorderProps extends Omit<\n ComponentPropsWithRef<\"div\">,\n \"onChange\" | \"defaultValue\"\n> {\n /** What the shortcut triggers: \"Open search\". Names the control. */\n label: string;\n /** Stored form, `Mod+Shift+K`, or null for none. Controlled. */\n value?: string | null;\n defaultValue?: string | null;\n onChange?: (value: string | null) => void;\n /** Shortcuts other commands already use. A clash is said, and applied only on request. */\n taken?: TakenShortcut[];\n /** Mac shows ⌘⇧K; everything else shows Ctrl+Shift+K. Detected if omitted. */\n platform?: Platform;\n /** Printable keys need a modifier. On by default, for the reason in the source. */\n requireModifier?: boolean;\n}\n\n/* The platform, as an external store that never changes: a constant that the\n server cannot know, so the server snapshot is the neutral one and the real\n answer arrives after hydration without a mismatch. */\nconst subscribeToNothing = () => () => undefined;\nconst readPlatform = () => detectPlatform();\nconst readNeutralPlatform = (): Platform => \"other\";\n\nexport function ShortcutRecorder({\n className,\n label,\n value: valueProp,\n defaultValue = null,\n onChange,\n taken = [],\n platform: platformProp,\n requireModifier = true,\n ...props\n}: ShortcutRecorderProps) {\n const id = useId();\n const detected = useSyncExternalStore(subscribeToNothing, readPlatform, readNeutralPlatform);\n const platform = platformProp ?? detected;\n\n const [uncontrolled, setUncontrolled] = useState<string | null>(defaultValue);\n const value = valueProp === undefined ? uncontrolled : valueProp;\n const current = value ? safeParse(value) : null;\n\n const [recording, setRecording] = useState(false);\n /** Modifiers held mid-chord, shown so the person sees the recorder listening. */\n const [held, setHeld] = useState<Shortcut | null>(null);\n const [conflict, setConflict] = useState<{ shortcut: Shortcut; with: TakenShortcut } | null>(\n null,\n );\n const [announcement, setAnnouncement] = useState(\"\");\n\n const commit = (next: Shortcut | null) => {\n const serialized = next ? serializeShortcut(next) : null;\n setUncontrolled(serialized);\n onChange?.(serialized);\n };\n\n const stop = () => {\n setRecording(false);\n setHeld(null);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (!recording) return;\n // Tab leaves. A recorder that keeps it is a keyboard trap.\n if (event.key === \"Tab\") {\n stop();\n setAnnouncement(\"Cancelled.\");\n return;\n }\n event.preventDefault();\n if (event.key === \"Escape\") {\n stop();\n setAnnouncement(\"Cancelled.\");\n return;\n }\n if ((event.key === \"Backspace\" || event.key === \"Delete\") && !hasModifier(event)) {\n stop();\n commit(null);\n setAnnouncement(\"Cleared.\");\n return;\n }\n\n const chord = shortcutFromKey(event.nativeEvent, platform);\n if (!chord) {\n // Only modifiers so far. Show them, keep listening.\n setHeld({\n key: \"\",\n mod: platform === \"mac\" ? event.metaKey : event.ctrlKey,\n ctrl: platform === \"mac\" ? event.ctrlKey : false,\n alt: event.altKey,\n shift: event.shiftKey,\n });\n return;\n }\n\n if (requireModifier && needsModifier(chord)) {\n setAnnouncement(\n `${describeShortcut(chord, platform)} needs a modifier — it would fire while typing. Try again.`,\n );\n setHeld(null);\n return;\n }\n\n const clash = taken.find((entry) =>\n shortcutsEqual(safeParse(entry.shortcut) ?? chord, chord),\n );\n stop();\n if (clash && !(current && shortcutsEqual(current, chord))) {\n setConflict({ shortcut: chord, with: clash });\n setAnnouncement(\n `${describeShortcut(chord, platform)} is already used by ${clash.label}.`,\n );\n return;\n }\n commit(chord);\n setAnnouncement(`Recorded ${describeShortcut(chord, platform)}.`);\n };\n\n const onKeyUp = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (!recording || !held) return;\n setHeld({\n key: \"\",\n mod: platform === \"mac\" ? event.metaKey : event.ctrlKey,\n ctrl: platform === \"mac\" ? event.ctrlKey : false,\n alt: event.altKey,\n shift: event.shiftKey,\n });\n };\n\n const shown = recording ? held : current;\n const description = recording\n ? \"Press the keys you want. Escape cancels, Backspace clears.\"\n : current\n ? `${describeShortcut(current, platform)}. Press to change.`\n : \"Not set. Press to record.\";\n\n return (\n <div\n data-slot=\"shortcut-recorder\"\n data-state={recording ? \"recording\" : conflict ? \"conflict\" : current ? \"set\" : \"empty\"}\n className={cn(\"flex flex-col gap-1.5\", className)}\n {...props}\n >\n <span id={`${id}-label`} className=\"text-xs font-medium\">\n {label}\n </span>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n aria-labelledby={`${id}-label`}\n aria-describedby={`${id}-description`}\n aria-pressed={recording}\n className={cn(\n \"flex h-9 min-w-32 items-center justify-center gap-1 rounded-md border px-3 font-mono text-sm\",\n recording\n ? \"border-primary bg-primary/5 text-muted-foreground\"\n : \"border-input bg-background hover:bg-accent\",\n focusRing,\n disabledStyles,\n )}\n onClick={() => {\n if (recording) return;\n setConflict(null);\n setRecording(true);\n setAnnouncement(\"\");\n }}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n onBlur={() => {\n if (recording) {\n stop();\n setAnnouncement(\"Cancelled.\");\n }\n }}\n >\n {/* Symbols and key caps are for the eye; the description says the\n same thing in words. */}\n <span aria-hidden=\"true\" className=\"flex items-center gap-1\">\n {shown && (shown.key || shown.mod || shown.ctrl || shown.alt || shown.shift) ? (\n shortcutParts(shown, platform)\n .filter(Boolean)\n .map((part, index) => (\n <kbd\n key={index}\n className=\"rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-xs\"\n >\n {part}\n </kbd>\n ))\n ) : recording ? (\n <span className=\"text-xs\">Press keys…</span>\n ) : (\n <span className=\"text-xs text-muted-foreground\">Not set</span>\n )}\n </span>\n </button>\n\n {current && !recording ? (\n <button\n type=\"button\"\n aria-label={`Clear — ${label}`}\n className={cn(\n \"rounded-md border border-input bg-background px-2.5 py-1 text-xs font-medium hover:bg-accent\",\n focusRing,\n )}\n onClick={() => {\n commit(null);\n setConflict(null);\n setAnnouncement(\"Cleared.\");\n }}\n >\n Clear\n </button>\n ) : null}\n </div>\n\n <p id={`${id}-description`} className=\"text-xs text-muted-foreground\">\n {description}\n </p>\n\n {conflict ? (\n <div\n data-slot=\"shortcut-conflict\"\n className=\"flex flex-wrap items-center gap-2 rounded-md border border-warning/50 bg-warning/5 px-2.5 py-1.5 text-xs\"\n >\n <span className=\"flex-1 text-warning\">\n {describeShortcut(conflict.shortcut, platform)} is already used by{\" \"}\n <strong>{conflict.with.label}</strong>.\n </span>\n <button\n type=\"button\"\n className={cn(\n \"rounded-md border border-input bg-background px-2 py-0.5 font-medium hover:bg-accent\",\n focusRing,\n )}\n onClick={() => {\n commit(conflict.shortcut);\n setConflict(null);\n setAnnouncement(\n `Recorded ${describeShortcut(conflict.shortcut, platform)}. ${conflict.with.label} no longer has a shortcut.`,\n );\n }}\n >\n Use anyway\n </button>\n <button\n type=\"button\"\n className={cn(\n \"rounded-md border border-input bg-background px-2 py-0.5 font-medium hover:bg-accent\",\n focusRing,\n )}\n onClick={() => {\n setConflict(null);\n }}\n >\n Keep the old one\n </button>\n </div>\n ) : null}\n\n {/* Present from the start, so the first outcome is heard. */}\n <span role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </span>\n </div>\n );\n}\n\nfunction hasModifier(event: KeyboardEvent): boolean {\n return event.metaKey || event.ctrlKey || event.altKey || event.shiftKey;\n}\n\nfunction safeParse(text: string): Shortcut | null {\n try {\n return parseShortcut(text);\n } catch {\n return null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
2
2
|
import { ComponentPropsWithRef } from "react";
|
|
3
3
|
//#region src/components/spinner/spinner.d.ts
|
|
4
4
|
declare const spinnerVariants: (props?: ({
|
|
5
|
-
size?: "
|
|
5
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
interface SpinnerProps extends Omit<ComponentPropsWithRef<"svg">, "children">, VariantProps<typeof spinnerVariants> {
|
|
8
8
|
/**
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/components/sync-status/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "sync-status",
|
|
5
|
+
title: "Sync Status",
|
|
6
|
+
description: "Offline, saving, saved or failed — with the count of changes being held.",
|
|
7
|
+
category: "feedback",
|
|
8
|
+
status: "stable",
|
|
9
|
+
dependencies: [],
|
|
10
|
+
registryDependencies: ["button"],
|
|
11
|
+
files: ["sync-status.tsx"],
|
|
12
|
+
a11y: "The word is the status and the coloured dot is decoration, hidden from assistive technology. The visible text is not a live region: every save flips it and a region on it would narrate the whole session. A separate region, present from the first render, announces transitions only — went offline with what will happen to the changes, came back with what is being saved, could not save, saved after a failure — and never the churn of saving itself. Announcing is on by default because going offline is the one thing a reader who is typing has to be told, and it can be turned off. The server render assumes online, since a page with no interface to report has no business saying offline."
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { meta };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/components/sync-status/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"sync-status\",\n title: \"Sync Status\",\n description: \"Offline, saving, saved or failed — with the count of changes being held.\",\n category: \"feedback\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [\"button\"],\n files: [\"sync-status.tsx\"],\n a11y:\n \"The word is the status and the coloured dot is decoration, hidden from assistive \" +\n \"technology. The visible text is not a live region: every save flips it and a region on it \" +\n \"would narrate the whole session. A separate region, present from the first render, \" +\n \"announces transitions only — went offline with what will happen to the changes, came back \" +\n \"with what is being saved, could not save, saved after a failure — and never the churn of \" +\n \"saving itself. Announcing is on by default because going offline is the one thing a reader \" +\n \"who is typing has to be told, and it can be turned off. The server render assumes online, \" +\n \"since a page with no interface to report has no business saying offline.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,OAAO;CACP,aAAa;CACb,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB,CAAC,QAAQ;CAC/B,OAAO,CAAC,iBAAiB;CACzB,MACE;AAQJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ComponentPropsWithRef } from "react";
|
|
2
|
+
//#region src/components/sync-status/sync-status.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* "Offline — 3 changes will sync when you're back."
|
|
5
|
+
*
|
|
6
|
+
* Linear, Notion, Figma and Google Docs each built this, and nothing in a
|
|
7
|
+
* component library touches network state at all. It is small, and it is
|
|
8
|
+
* the difference between an app that loses work and one that says it is
|
|
9
|
+
* holding it: the moment a request fails, the reader needs to know whether
|
|
10
|
+
* to keep typing, and whether what they typed a minute ago is anywhere.
|
|
11
|
+
*
|
|
12
|
+
* Two things this gets right that the obvious version gets wrong.
|
|
13
|
+
*
|
|
14
|
+
* `navigator.onLine` is believed in one direction only. False is reliable —
|
|
15
|
+
* the interface is down. True means only that there is an interface, not
|
|
16
|
+
* that the server is reachable, so an application's own failed request is
|
|
17
|
+
* the real signal and takes precedence. The hook is exported for the rest
|
|
18
|
+
* of the app to share the same reading.
|
|
19
|
+
*
|
|
20
|
+
* Announcements are for transitions, not states. Every save flips
|
|
21
|
+
* "Saving…" to "Saved", and a live region on that text narrates the whole
|
|
22
|
+
* session. So the visible text is not live; a separate region says something
|
|
23
|
+
* only when the situation changes — went offline, came back, could not sync —
|
|
24
|
+
* which is when a reader who is typing needs to be told.
|
|
25
|
+
*/
|
|
26
|
+
type SyncState = "synced" | "pending" | "syncing" | "offline" | "error";
|
|
27
|
+
interface SyncInput {
|
|
28
|
+
/** From `useOnlineStatus`, or your own reading. */
|
|
29
|
+
online: boolean;
|
|
30
|
+
/** Changes waiting to be sent. */
|
|
31
|
+
pending?: number;
|
|
32
|
+
/** A send is in flight. */
|
|
33
|
+
syncing?: boolean;
|
|
34
|
+
/** The last send failed, in the reader's language. Takes precedence over `online`. */
|
|
35
|
+
error?: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Which state the inputs amount to. Error beats offline beats syncing beats
|
|
39
|
+
* pending beats synced: each one is the thing the reader most needs to know
|
|
40
|
+
* given the others.
|
|
41
|
+
*/
|
|
42
|
+
declare function syncState({ online, pending, syncing, error }: SyncInput): SyncState;
|
|
43
|
+
/** The state as a sentence. Used for the visible text and the announcement. */
|
|
44
|
+
declare function describeSyncState(state: SyncState, pending?: number, error?: string | null): string;
|
|
45
|
+
/** Whether the browser believes it has a network. False is reliable; true is not. */
|
|
46
|
+
declare function useOnlineStatus(): boolean;
|
|
47
|
+
interface SyncStatusProps extends Omit<ComponentPropsWithRef<"div">, "children">, Omit<SyncInput, "online"> {
|
|
48
|
+
/** Omit to read the browser's own status. */
|
|
49
|
+
online?: boolean;
|
|
50
|
+
/** When the last save succeeded. Shown as a time, not a relative phrase, so no clock is needed. */
|
|
51
|
+
lastSyncedAt?: Date;
|
|
52
|
+
locale?: string;
|
|
53
|
+
/** Offered when a save failed. */
|
|
54
|
+
onRetry?: () => void;
|
|
55
|
+
/**
|
|
56
|
+
* Announce transitions. On by default, because going offline is the one
|
|
57
|
+
* thing a reader who is typing has to be told; syncing itself never
|
|
58
|
+
* announces, whichever way this is set.
|
|
59
|
+
*/
|
|
60
|
+
announce?: boolean;
|
|
61
|
+
}
|
|
62
|
+
declare function SyncStatus({ className, online: onlineProp, pending, syncing, error, lastSyncedAt, locale, onRetry, announce, ...props }: SyncStatusProps): import("react").JSX.Element;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { SyncInput, SyncState, SyncStatus, SyncStatusProps, describeSyncState, syncState, useOnlineStatus };
|
|
65
|
+
//# sourceMappingURL=sync-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-status.d.ts","names":[],"sources":["../../../src/components/sync-status/sync-status.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;KA+BY;UAEK;;EAEf;;EAEA;;EAEA;;EAEA;;;;;;;iBAQc,YACd,QACA,SACA,SACA,SACC,YAAY;;iBAWC,kBACd,OAAO,WACP,kBACA;;iBAmCc;UAIC,wBACP,KAAK,2CAA2C,KAAK;;EAE7D;;EAEA,eAAe;EACf;;EAEA;;;;;;EAMA;;iBAGc,aACd,WACA,QAAQ,YACR,SACA,SACA,OACA,cACA,QACA,SACA,aACG,SACF,kCAAe,IAAA"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Button } from "../button/button.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useState, useSyncExternalStore } from "react";
|
|
6
|
+
//#region src/components/sync-status/sync-status.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Which state the inputs amount to. Error beats offline beats syncing beats
|
|
9
|
+
* pending beats synced: each one is the thing the reader most needs to know
|
|
10
|
+
* given the others.
|
|
11
|
+
*/
|
|
12
|
+
function syncState({ online, pending = 0, syncing = false, error }) {
|
|
13
|
+
if (error) return "error";
|
|
14
|
+
if (!online) return "offline";
|
|
15
|
+
if (syncing) return "syncing";
|
|
16
|
+
if (pending > 0) return "pending";
|
|
17
|
+
return "synced";
|
|
18
|
+
}
|
|
19
|
+
const changes = (n) => `${String(n)} ${n === 1 ? "change" : "changes"}`;
|
|
20
|
+
/** The state as a sentence. Used for the visible text and the announcement. */
|
|
21
|
+
function describeSyncState(state, pending = 0, error) {
|
|
22
|
+
switch (state) {
|
|
23
|
+
case "synced": return "All changes saved";
|
|
24
|
+
case "pending": return `${changes(pending)} waiting to save`;
|
|
25
|
+
case "syncing": return pending > 0 ? `Saving ${changes(pending)}…` : "Saving…";
|
|
26
|
+
case "offline": return pending > 0 ? `Offline. ${changes(pending)} will save when you're back online.` : "Offline. Changes will save when you're back online.";
|
|
27
|
+
case "error": return pending > 0 ? `Could not save ${changes(pending)}. ${error ?? ""}`.trim() : `Could not save. ${error ?? ""}`.trim();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function subscribeOnline(callback) {
|
|
31
|
+
window.addEventListener("online", callback);
|
|
32
|
+
window.addEventListener("offline", callback);
|
|
33
|
+
return () => {
|
|
34
|
+
window.removeEventListener("online", callback);
|
|
35
|
+
window.removeEventListener("offline", callback);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const readOnline = () => navigator.onLine;
|
|
39
|
+
const readOnlineOnServer = () => true;
|
|
40
|
+
/** Whether the browser believes it has a network. False is reliable; true is not. */
|
|
41
|
+
function useOnlineStatus() {
|
|
42
|
+
return useSyncExternalStore(subscribeOnline, readOnline, readOnlineOnServer);
|
|
43
|
+
}
|
|
44
|
+
function SyncStatus({ className, online: onlineProp, pending = 0, syncing = false, error, lastSyncedAt, locale, onRetry, announce = true, ...props }) {
|
|
45
|
+
const browserOnline = useOnlineStatus();
|
|
46
|
+
const state = syncState({
|
|
47
|
+
online: onlineProp ?? browserOnline,
|
|
48
|
+
pending,
|
|
49
|
+
syncing,
|
|
50
|
+
error
|
|
51
|
+
});
|
|
52
|
+
const text = describeSyncState(state, pending, error);
|
|
53
|
+
const [seen, setSeen] = useState(state);
|
|
54
|
+
const [announcement, setAnnouncement] = useState("");
|
|
55
|
+
const [recovering, setRecovering] = useState(false);
|
|
56
|
+
if (seen !== state) {
|
|
57
|
+
const from = seen;
|
|
58
|
+
setSeen(state);
|
|
59
|
+
if (state === "offline" || state === "error") {
|
|
60
|
+
setAnnouncement(text);
|
|
61
|
+
setRecovering(false);
|
|
62
|
+
} else if (from === "offline") setAnnouncement(pending > 0 ? `Back online. Saving ${changes(pending)}.` : "Back online.");
|
|
63
|
+
else if ((from === "error" || recovering) && state === "synced") {
|
|
64
|
+
setAnnouncement("Saved.");
|
|
65
|
+
setRecovering(false);
|
|
66
|
+
} else if (from === "error") setRecovering(true);
|
|
67
|
+
}
|
|
68
|
+
const savedAt = lastSyncedAt !== void 0 ? new Intl.DateTimeFormat(locale, { timeStyle: "short" }).format(lastSyncedAt) : null;
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
70
|
+
"data-slot": "sync-status",
|
|
71
|
+
"data-state": state,
|
|
72
|
+
className: cn("flex flex-wrap items-center gap-x-2 gap-y-1 text-xs", className),
|
|
73
|
+
...props,
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx("span", {
|
|
76
|
+
"aria-hidden": "true",
|
|
77
|
+
className: cn("size-2 shrink-0 rounded-full", state === "synced" && "bg-success", state === "pending" && "bg-muted-foreground", state === "syncing" && "animate-pulse-soft bg-info", state === "offline" && "bg-warning", state === "error" && "bg-destructive")
|
|
78
|
+
}),
|
|
79
|
+
/* @__PURE__ */ jsxs("span", {
|
|
80
|
+
"data-slot": "sync-status-text",
|
|
81
|
+
className: cn(state === "offline" && "text-warning", state === "error" && "text-destructive", (state === "synced" || state === "pending" || state === "syncing") && "text-muted-foreground"),
|
|
82
|
+
children: [text, savedAt && state === "synced" ? ` at ${savedAt}` : null]
|
|
83
|
+
}),
|
|
84
|
+
state === "error" && onRetry ? /* @__PURE__ */ jsx(Button, {
|
|
85
|
+
variant: "outline",
|
|
86
|
+
size: "sm",
|
|
87
|
+
className: "h-6 px-2 text-xs",
|
|
88
|
+
onClick: onRetry,
|
|
89
|
+
children: "Retry"
|
|
90
|
+
}) : null,
|
|
91
|
+
/* @__PURE__ */ jsx("span", {
|
|
92
|
+
role: "status",
|
|
93
|
+
"aria-live": announce ? "polite" : "off",
|
|
94
|
+
className: "sr-only",
|
|
95
|
+
children: announce ? announcement : ""
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { SyncStatus, describeSyncState, syncState, useOnlineStatus };
|
|
102
|
+
|
|
103
|
+
//# sourceMappingURL=sync-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-status.js","names":[],"sources":["../../../src/components/sync-status/sync-status.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, useSyncExternalStore, type ComponentPropsWithRef } from \"react\";\n\nimport { Button } from \"@/components/button\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * \"Offline — 3 changes will sync when you're back.\"\n *\n * Linear, Notion, Figma and Google Docs each built this, and nothing in a\n * component library touches network state at all. It is small, and it is\n * the difference between an app that loses work and one that says it is\n * holding it: the moment a request fails, the reader needs to know whether\n * to keep typing, and whether what they typed a minute ago is anywhere.\n *\n * Two things this gets right that the obvious version gets wrong.\n *\n * `navigator.onLine` is believed in one direction only. False is reliable —\n * the interface is down. True means only that there is an interface, not\n * that the server is reachable, so an application's own failed request is\n * the real signal and takes precedence. The hook is exported for the rest\n * of the app to share the same reading.\n *\n * Announcements are for transitions, not states. Every save flips\n * \"Saving…\" to \"Saved\", and a live region on that text narrates the whole\n * session. So the visible text is not live; a separate region says something\n * only when the situation changes — went offline, came back, could not sync —\n * which is when a reader who is typing needs to be told.\n */\n\nexport type SyncState = \"synced\" | \"pending\" | \"syncing\" | \"offline\" | \"error\";\n\nexport interface SyncInput {\n /** From `useOnlineStatus`, or your own reading. */\n online: boolean;\n /** Changes waiting to be sent. */\n pending?: number;\n /** A send is in flight. */\n syncing?: boolean;\n /** The last send failed, in the reader's language. Takes precedence over `online`. */\n error?: string | null;\n}\n\n/**\n * Which state the inputs amount to. Error beats offline beats syncing beats\n * pending beats synced: each one is the thing the reader most needs to know\n * given the others.\n */\nexport function syncState({\n online,\n pending = 0,\n syncing = false,\n error,\n}: SyncInput): SyncState {\n if (error) return \"error\";\n if (!online) return \"offline\";\n if (syncing) return \"syncing\";\n if (pending > 0) return \"pending\";\n return \"synced\";\n}\n\nconst changes = (n: number) => `${String(n)} ${n === 1 ? \"change\" : \"changes\"}`;\n\n/** The state as a sentence. Used for the visible text and the announcement. */\nexport function describeSyncState(\n state: SyncState,\n pending = 0,\n error?: string | null,\n): string {\n switch (state) {\n case \"synced\":\n return \"All changes saved\";\n case \"pending\":\n return `${changes(pending)} waiting to save`;\n case \"syncing\":\n return pending > 0 ? `Saving ${changes(pending)}…` : \"Saving…\";\n case \"offline\":\n return pending > 0\n ? `Offline. ${changes(pending)} will save when you're back online.`\n : \"Offline. Changes will save when you're back online.\";\n case \"error\":\n return pending > 0\n ? `Could not save ${changes(pending)}. ${error ?? \"\"}`.trim()\n : `Could not save. ${error ?? \"\"}`.trim();\n }\n}\n\n/* The browser's reading of the network, as an external store. The server\n snapshot is \"online\": a page rendered on the server has no interface to\n report, and rendering \"offline\" into HTML would be a lie until hydration. */\nfunction subscribeOnline(callback: () => void) {\n window.addEventListener(\"online\", callback);\n window.addEventListener(\"offline\", callback);\n return () => {\n window.removeEventListener(\"online\", callback);\n window.removeEventListener(\"offline\", callback);\n };\n}\nconst readOnline = () => navigator.onLine;\nconst readOnlineOnServer = () => true;\n\n/** Whether the browser believes it has a network. False is reliable; true is not. */\nexport function useOnlineStatus(): boolean {\n return useSyncExternalStore(subscribeOnline, readOnline, readOnlineOnServer);\n}\n\nexport interface SyncStatusProps\n extends Omit<ComponentPropsWithRef<\"div\">, \"children\">, Omit<SyncInput, \"online\"> {\n /** Omit to read the browser's own status. */\n online?: boolean;\n /** When the last save succeeded. Shown as a time, not a relative phrase, so no clock is needed. */\n lastSyncedAt?: Date;\n locale?: string;\n /** Offered when a save failed. */\n onRetry?: () => void;\n /**\n * Announce transitions. On by default, because going offline is the one\n * thing a reader who is typing has to be told; syncing itself never\n * announces, whichever way this is set.\n */\n announce?: boolean;\n}\n\nexport function SyncStatus({\n className,\n online: onlineProp,\n pending = 0,\n syncing = false,\n error,\n lastSyncedAt,\n locale,\n onRetry,\n announce = true,\n ...props\n}: SyncStatusProps) {\n const browserOnline = useOnlineStatus();\n const online = onlineProp ?? browserOnline;\n const state = syncState({ online, pending, syncing, error });\n const text = describeSyncState(state, pending, error);\n\n // Said once, when the situation changes. Adjusted during render so the\n // announcement lands in the same commit as the state it describes. Syncing\n // and pending are the ordinary churn of saving and are never announced.\n const [seen, setSeen] = useState(state);\n const [announcement, setAnnouncement] = useState(\"\");\n // A failure is over when a save lands, not when the retry starts, so the\n // recovery is remembered across the syncing in between.\n const [recovering, setRecovering] = useState(false);\n if (seen !== state) {\n const from = seen;\n setSeen(state);\n if (state === \"offline\" || state === \"error\") {\n setAnnouncement(text);\n setRecovering(false);\n } else if (from === \"offline\") {\n setAnnouncement(\n pending > 0 ? `Back online. Saving ${changes(pending)}.` : \"Back online.\",\n );\n } else if ((from === \"error\" || recovering) && state === \"synced\") {\n setAnnouncement(\"Saved.\");\n setRecovering(false);\n } else if (from === \"error\") {\n setRecovering(true);\n }\n }\n\n const savedAt =\n lastSyncedAt !== undefined\n ? new Intl.DateTimeFormat(locale, { timeStyle: \"short\" }).format(lastSyncedAt)\n : null;\n\n return (\n <div\n data-slot=\"sync-status\"\n data-state={state}\n className={cn(\"flex flex-wrap items-center gap-x-2 gap-y-1 text-xs\", className)}\n {...props}\n >\n {/* The dot is decoration. The word is the status. */}\n <span\n aria-hidden=\"true\"\n className={cn(\n \"size-2 shrink-0 rounded-full\",\n state === \"synced\" && \"bg-success\",\n state === \"pending\" && \"bg-muted-foreground\",\n state === \"syncing\" && \"animate-pulse-soft bg-info\",\n state === \"offline\" && \"bg-warning\",\n state === \"error\" && \"bg-destructive\",\n )}\n />\n <span\n data-slot=\"sync-status-text\"\n className={cn(\n state === \"offline\" && \"text-warning\",\n state === \"error\" && \"text-destructive\",\n (state === \"synced\" || state === \"pending\" || state === \"syncing\") &&\n \"text-muted-foreground\",\n )}\n >\n {text}\n {savedAt && state === \"synced\" ? ` at ${savedAt}` : null}\n </span>\n\n {state === \"error\" && onRetry ? (\n <Button variant=\"outline\" size=\"sm\" className=\"h-6 px-2 text-xs\" onClick={onRetry}>\n Retry\n </Button>\n ) : null}\n\n {/* Present from the start, so the first transition is heard. */}\n <span role=\"status\" aria-live={announce ? \"polite\" : \"off\"} className=\"sr-only\">\n {announce ? announcement : \"\"}\n </span>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ import { ComponentPropsWithRef } from "react";
|
|
|
12
12
|
* toast list from anywhere on the page.
|
|
13
13
|
*/
|
|
14
14
|
declare const toastVariants: (props?: ({
|
|
15
|
-
variant?: "
|
|
15
|
+
variant?: "success" | "warning" | "destructive" | "default" | "info" | null | undefined;
|
|
16
16
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
17
17
|
declare const ToastProvider: import("react").FC<Toast.ToastProviderProps>;
|
|
18
18
|
interface ToastProps extends ComponentPropsWithRef<typeof Toast.Root>, VariantProps<typeof toastVariants> {}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ import { Conversation, ConversationMessages, ConversationProps, ConversationScro
|
|
|
14
14
|
import "./components/ai-conversation/index.js";
|
|
15
15
|
import { AIDisclosure, AIDisclosureProps, AIDisclosureProvenance, AIDisclosureProvenanceProps, DisclosureKind, ProvenanceClaim, disclosureVariants } from "./components/ai-disclosure/ai-disclosure.js";
|
|
16
16
|
import "./components/ai-disclosure/index.js";
|
|
17
|
+
import { ExtractionField, FieldDecision, ReviewSummary, SourceRun, SourceSpan, clampSpan, evidenceOf, isSourced, segmentSource, summarizeReview } from "./components/ai-extraction-review/extraction-model.js";
|
|
18
|
+
import { ExtractionReview, ExtractionReviewProps } from "./components/ai-extraction-review/ai-extraction-review.js";
|
|
19
|
+
import "./components/ai-extraction-review/index.js";
|
|
17
20
|
import { InlineCompletion, InlineCompletionProps } from "./components/ai-inline-completion/ai-inline-completion.js";
|
|
18
21
|
import "./components/ai-inline-completion/index.js";
|
|
19
22
|
import { Message, MessageActions, MessageAvatar, MessageAvatarProps, MessageBody, MessageBodyProps, MessageFooter, MessageProps, MessageRole, messageBodyVariants, messageVariants } from "./components/ai-message/ai-message.js";
|
|
@@ -32,6 +35,8 @@ import { InlineCitation, InlineCitationProps, Source, SourceProps, Sources, Sour
|
|
|
32
35
|
import "./components/ai-sources/index.js";
|
|
33
36
|
import { FieldState, OutputField, StructuredConfidence, StructuredField, StructuredFieldError, StructuredFieldProps, StructuredOutput, StructuredOutputProps } from "./components/ai-structured-output/ai-structured-output.js";
|
|
34
37
|
import "./components/ai-structured-output/index.js";
|
|
38
|
+
import { SuggestedValue, SuggestedValueProps, Suggestion, SuggestionStatus } from "./components/ai-suggested-value/ai-suggested-value.js";
|
|
39
|
+
import "./components/ai-suggested-value/index.js";
|
|
35
40
|
import { TokenCount, TokenCountProps, TokenUsage, TokenUsageProps } from "./components/ai-token-usage/ai-token-usage.js";
|
|
36
41
|
import "./components/ai-token-usage/index.js";
|
|
37
42
|
import { Tool, ToolContent, ToolHeader, ToolHeaderProps, ToolPayload, ToolPayloadProps, ToolProps, ToolSection, ToolSectionProps, ToolStatus, toolVariants } from "./components/ai-tool/ai-tool.js";
|
|
@@ -58,6 +63,11 @@ import { Dialog, DialogClose, DialogContent, DialogContentProps, DialogDescripti
|
|
|
58
63
|
import "./components/dialog/index.js";
|
|
59
64
|
import { Command, CommandDialog, CommandDialogProps, CommandEmpty, CommandGroup, CommandGroupProps, CommandInput, CommandInputProps, CommandItem, CommandItemProps, CommandList, CommandProps, CommandSeparator, CommandShortcut, defaultCommandFilter } from "./components/command/command.js";
|
|
60
65
|
import "./components/command/index.js";
|
|
66
|
+
import { ConfirmTyped, ConfirmTypedProps } from "./components/confirm-typed/confirm-typed.js";
|
|
67
|
+
import "./components/confirm-typed/index.js";
|
|
68
|
+
import { Cron, CronBuilder, CronBuilderProps, CronExpression, CronExpressionProps, CronNextRuns, CronNextRunsProps, CronProps } from "./components/cron-editor/cron-editor.js";
|
|
69
|
+
import { CRON_SHORTCUTS, CronExpressionError, CronField, CronSchedule, DescribeOptions, NextRunsOptions, describeCron, isValidCron, nextRuns, parseCron, zonedTimeToInstant } from "./components/cron-editor/cron-expression.js";
|
|
70
|
+
import "./components/cron-editor/index.js";
|
|
61
71
|
import { DataTable, DataTableColumnHeader, DataTableColumnHeaderProps, DataTablePagination, DataTablePaginationProps, DataTableProps, DataTableViewOptions, DataTableViewOptionsProps, HideableTable, PaginatedTable, SortableColumn } from "./components/data-table/data-table.js";
|
|
62
72
|
import "./components/data-table/index.js";
|
|
63
73
|
import { DatePicker, DatePickerProps, DateRangePicker, DateRangePickerProps } from "./components/date-picker/date-picker.js";
|
|
@@ -65,6 +75,8 @@ import "./components/date-picker/index.js";
|
|
|
65
75
|
import { BuildDiffOptions, DiffHunk, DiffRow, RowKind, WordSegment, buildDiff, countChanges, groupIntoHunks, toSplitRows } from "./components/diff-viewer/diff-model.js";
|
|
66
76
|
import { DiffViewer, DiffViewerProps, DiffViewerToolbar, HunkDecision } from "./components/diff-viewer/diff-viewer.js";
|
|
67
77
|
import "./components/diff-viewer/index.js";
|
|
78
|
+
import { DnsHostForms, DnsRecord, DnsRecordProps, DnsRecordStatus, dnsHostForms } from "./components/dns-record/dns-record.js";
|
|
79
|
+
import "./components/dns-record/index.js";
|
|
68
80
|
import { Drawer, DrawerBody, DrawerCancel, DrawerClose, DrawerContent, DrawerContentProps, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerProps, DrawerTitle, DrawerTrigger } from "./components/drawer/drawer.js";
|
|
69
81
|
import "./components/drawer/index.js";
|
|
70
82
|
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, DropdownMenuItemProps, DropdownMenuLabel, DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuSubTriggerProps, DropdownMenuTrigger } from "./components/dropdown-menu/dropdown-menu.js";
|
|
@@ -89,6 +101,9 @@ import { MetricDelta, MetricDeltaProps, MetricPolarity, deltaVariants } from "./
|
|
|
89
101
|
import "./components/metric-delta/index.js";
|
|
90
102
|
import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationLinkProps, PaginationNext, PaginationPrevious } from "./components/pagination/pagination.js";
|
|
91
103
|
import "./components/pagination/index.js";
|
|
104
|
+
import { CellState, Grants, GroupState, Permission, PermissionGroup, Role, cellState, countGranted, groupPermissions, groupState, inheritedFrom } from "./components/permission-matrix/permission-model.js";
|
|
105
|
+
import { PermissionMatrix, PermissionMatrixProps } from "./components/permission-matrix/permission-matrix.js";
|
|
106
|
+
import "./components/permission-matrix/index.js";
|
|
92
107
|
import { Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverContentProps, PopoverTrigger } from "./components/popover/popover.js";
|
|
93
108
|
import "./components/popover/index.js";
|
|
94
109
|
import { Progress, ProgressProps, progressVariants } from "./components/progress/progress.js";
|
|
@@ -97,10 +112,17 @@ import { RadioGroup, RadioGroupItem, RadioGroupItemProps, RadioGroupProps } from
|
|
|
97
112
|
import "./components/radio-group/index.js";
|
|
98
113
|
import { FieldChange, RecordDiff, RecordDiffProps, RecordDiffSummary, RecordDiffTable, RecordDiffTableProps, RecordField, diffRecords } from "./components/record-diff/record-diff.js";
|
|
99
114
|
import "./components/record-diff/index.js";
|
|
115
|
+
import { SecretField, SecretFieldProps, SecretFieldState, maskSecret } from "./components/secret-field/secret-field.js";
|
|
116
|
+
import "./components/secret-field/index.js";
|
|
100
117
|
import { Separator, SeparatorProps } from "./components/separator/separator.js";
|
|
101
118
|
import "./components/separator/index.js";
|
|
119
|
+
import { SessionExpiry, SessionExpiryProps, SessionPhase, describeCountdown, formatCountdown, secondsLeft, sessionPhase } from "./components/session-expiry/session-expiry.js";
|
|
120
|
+
import "./components/session-expiry/index.js";
|
|
102
121
|
import { Sheet, SheetClose, SheetContent, SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, sheetVariants } from "./components/sheet/sheet.js";
|
|
103
122
|
import "./components/sheet/index.js";
|
|
123
|
+
import { Platform, RESERVED_KEYS, Shortcut, describeShortcut, detectPlatform, formatShortcut, needsModifier, parseShortcut, serializeShortcut, shortcutFromKey, shortcutParts, shortcutsEqual } from "./components/shortcut-recorder/shortcut-model.js";
|
|
124
|
+
import { ShortcutRecorder, ShortcutRecorderProps, TakenShortcut } from "./components/shortcut-recorder/shortcut-recorder.js";
|
|
125
|
+
import "./components/shortcut-recorder/index.js";
|
|
104
126
|
import { Skeleton } from "./components/skeleton/skeleton.js";
|
|
105
127
|
import "./components/skeleton/index.js";
|
|
106
128
|
import { Slider, SliderProps } from "./components/slider/slider.js";
|
|
@@ -109,6 +131,8 @@ import { Spinner, SpinnerProps, spinnerVariants } from "./components/spinner/spi
|
|
|
109
131
|
import "./components/spinner/index.js";
|
|
110
132
|
import { Switch, SwitchProps } from "./components/switch/switch.js";
|
|
111
133
|
import "./components/switch/index.js";
|
|
134
|
+
import { SyncInput, SyncState, SyncStatus, SyncStatusProps, describeSyncState, syncState, useOnlineStatus } from "./components/sync-status/sync-status.js";
|
|
135
|
+
import "./components/sync-status/index.js";
|
|
112
136
|
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableProps, TableRow } from "./components/table/table.js";
|
|
113
137
|
import "./components/table/index.js";
|
|
114
138
|
import { Tabs, TabsContent, TabsContentProps, TabsList, TabsListProps, TabsTrigger, TabsTriggerProps, tabsListVariants, tabsTriggerVariants } from "./components/tabs/tabs.js";
|
|
@@ -126,4 +150,4 @@ import "./components/tooltip/index.js";
|
|
|
126
150
|
import { cn } from "./lib/utils.js";
|
|
127
151
|
import { disabledStyles, focusRing, focusRingInset, iconSlot, invalidStyles } from "./lib/styles.js";
|
|
128
152
|
import { COMPONENT_CATEGORIES, COMPONENT_STATUSES, ComponentCategory, ComponentMeta, ComponentStatus, defineMeta } from "./registry/schema.js";
|
|
129
|
-
export { AIDisclosure, type AIDisclosureProps, AIDisclosureProvenance, type AIDisclosureProvenanceProps, Accordion, AccordionContent, type AccordionContentProps, AccordionItem, type AccordionItemProps, AccordionTrigger, type AccordionTriggerProps, ActionLedger, ActionLedgerEntry, type ActionLedgerEntryProps, ActionLedgerList, ActionLedgerPayload, type ActionLedgerProps, ActionLedgerSelectionSummary, ActionLedgerToolbar, type ActionStatus, ActivityContent, ActivityDescription, ActivityFeed, ActivityIndicator, type ActivityIndicatorProps, ActivityItem, type ActivityItemProps, ActivityTime, type ActivityTimeProps, ActivityTitle, AgentPlan, type AgentPlanProps, AgentPlanStep, type AgentPlanStepProps, AgentPlanSteps, AgentPlanSummary, type AgentState, AgentStatus, type AgentStatusProps, Alert, AlertDescription, type AlertLive, type AlertProps, AlertTitle, type ApprovalDecision, type ApprovalField, ApprovalRequest, type ApprovalRequestProps, type ApprovalScope, Avatar, AvatarFallback, type AvatarFallbackProps, AvatarImage, type AvatarImageProps, type AvatarProps, Badge, type BadgeProps, type BuildDiffOptions, Button, type ButtonProps, COMPONENT_CATEGORIES, COMPONENT_STATUSES, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, Checkbox, type CheckboxProps, CodeBlock, type CodeBlockProps, Combobox, ComboboxContent, type ComboboxContentProps, ComboboxEmpty, ComboboxInput, type ComboboxInputProps, ComboboxItem, type ComboboxItemProps, ComboboxList, type ComboboxProps, ComboboxTrigger, type ComboboxTriggerProps, Command, CommandDialog, type CommandDialogProps, CommandEmpty, CommandGroup, type CommandGroupProps, CommandInput, type CommandInputProps, CommandItem, type CommandItemProps, CommandList, type CommandProps, CommandSeparator, CommandShortcut, ComponentCategory, ComponentMeta, ComponentStatus, Conversation, ConversationMessages, type ConversationProps, ConversationScrollButton, type ConversationScrollButtonProps, ConversationStatus, type ConversationStatusProps, CopyButton, type CopyButtonProps, DEFAULT_PRESETS, DEFAULT_TOAST_DURATION, DataTable, DataTableColumnHeader, type DataTableColumnHeaderProps, DataTablePagination, type DataTablePaginationProps, type DataTableProps, DataTableViewOptions, type DataTableViewOptionsProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, DialogHeader, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type DiffHunk, type DiffRow, DiffViewer, type DiffViewerProps, DiffViewerToolbar, type DisclosureKind, Drawer, DrawerBody, DrawerCancel, DrawerClose, DrawerContent, type DrawerContentProps, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, type DrawerProps, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, type DropdownMenuSubTriggerProps, DropdownMenuTrigger, EmptyState, EmptyStateActions, EmptyStateDescription, EmptyStateIcon, type EmptyStateProps, EmptyStateTitle, type FieldChange, type FieldState, FileUpload, FileUploadItem, type FileUploadItemProps, FileUploadList, type FileUploadListProps, type FileUploadProps, FileUploadStatus, type FilterState, Form, FormControl, type FormControlProps, FormDescription, FormField, type FormFieldProps, FormLabel, type FormLabelProps, FormMessage, type FormMessageProps, type FormProps, type HideableTable, type HunkDecision, InlineCitation, type InlineCitationProps, InlineCompletion, type InlineCompletionProps, Input, type InputProps, LOG_LEVELS, Label, type LabelProps, type LedgerAction, type LogLevel, type LogLine, LogViewer, type LogViewerProps, LogViewerRow, type LogViewerRowProps, LogViewerToolbar, type LogViewerToolbarProps, type MatchRange, Message, MessageActions, MessageAvatar, type MessageAvatarProps, MessageBody, type MessageBodyProps, MessageFooter, type MessageProps, type MessageRole, Meter, MeterLegend, type MeterProps, type MeterSegment, type MeterTone, MeterValue, MetricDelta, type MetricDeltaProps, type MetricPolarity, type ModelOption, ModelSelector, type ModelSelectorProps, type OutputField, type PaginatedTable, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, type PlanStep, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, PromptInput, PromptInputCounter, type PromptInputCounterProps, type PromptInputProps, PromptInputSubmit, type PromptInputSubmitProps, PromptInputTextarea, type PromptInputTextareaProps, PromptInputToolbar, type ProvenanceClaim, type QueuedFile, RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, Reasoning, ReasoningContent, type ReasoningProps, ReasoningTrigger, type ReasoningTriggerProps, RecordDiff, type RecordDiffProps, RecordDiffSummary, RecordDiffTable, type RecordDiffTableProps, type RecordField, type ResolveOptions, type ResolvedRange, Response, ResponseCaret, type ResponseProps, type Reversibility, type RowKind, Select, SelectContent, type SelectContentProps, SelectGroup, SelectItem, type SelectItemProps, SelectLabel, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, type SeparatorProps, Sheet, SheetClose, SheetContent, type SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Skeleton, Slider, type SliderProps, type SortableColumn, Source, type SourceProps, Sources, SourcesContent, type SourcesProps, SourcesTrigger, type SourcesTriggerProps, Spinner, type SpinnerProps, type StepStatus, StructuredConfidence, StructuredField, StructuredFieldError, type StructuredFieldProps, StructuredOutput, type StructuredOutputProps, Switch, type SwitchProps, TOAST_LIMIT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, TabsTrigger, type TabsTriggerProps, type TagValidator, TagsInput, type TagsInputProps, ThinkingIndicator, type ThinkingIndicatorProps, TimeExpressionError, TimeRange, TimeRangeCalendar, TimeRangeContent, type TimeRangeContentProps, TimeRangeExpression, type TimeRangePreset, TimeRangePresets, type TimeRangeProps, TimeRangeTrigger, type TimeRangeTriggerProps, type TimeUnit, Toast, ToastAction, type ToastAction$1 as ToastActionOptions, ToastClose, ToastDescription, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, type ToastVariant, Toaster, type ToasterProps, TokenCount, type TokenCountProps, TokenUsage, type TokenUsageProps, Tool, ToolContent, ToolHeader, type ToolHeaderProps, ToolPayload, type ToolPayloadProps, type ToolProps, ToolSection, type ToolSectionProps, type ToolStatus, Tooltip, TooltipContent, type TooltipContentProps, type TooltipProps, TooltipProvider, TooltipTrigger, type UploadContext, type UploadFn, type UploadQueueOptions, type UploadStatus, type UseLogStreamOptions, type VisibleLine, type WordSegment, absoluteExpression, agentStatusVariants, alertVariants, avatarVariants, badgeVariants, buildDiff, buttonVariants, cn, compileQuery, countChanges, defaultComboboxFilter, defaultCommandFilter, defineMeta, deltaVariants, describeTimeRange, diffRecords, disabledStyles, disclosureVariants, emptyStateVariants, findMatches, focusRing, focusRingInset, formatBytes, formatResolvedRange, groupIntoHunks, iconSlot, inputVariants, invalidStyles, isValidTimeRange, ledgerEntryVariants, matchesAccept, messageBodyVariants, messageVariants, progressVariants, resolveExpression, resolveTimeRange, segment, selectTriggerVariants, sheetVariants, spinnerVariants, tabsListVariants, tabsTriggerVariants, toSplitRows, toast, toastVariants, toolVariants, useLogStream, useToasts, useUploadQueue, xhrUpload };
|
|
153
|
+
export { AIDisclosure, type AIDisclosureProps, AIDisclosureProvenance, type AIDisclosureProvenanceProps, Accordion, AccordionContent, type AccordionContentProps, AccordionItem, type AccordionItemProps, AccordionTrigger, type AccordionTriggerProps, ActionLedger, ActionLedgerEntry, type ActionLedgerEntryProps, ActionLedgerList, ActionLedgerPayload, type ActionLedgerProps, ActionLedgerSelectionSummary, ActionLedgerToolbar, type ActionStatus, ActivityContent, ActivityDescription, ActivityFeed, ActivityIndicator, type ActivityIndicatorProps, ActivityItem, type ActivityItemProps, ActivityTime, type ActivityTimeProps, ActivityTitle, AgentPlan, type AgentPlanProps, AgentPlanStep, type AgentPlanStepProps, AgentPlanSteps, AgentPlanSummary, type AgentState, AgentStatus, type AgentStatusProps, Alert, AlertDescription, type AlertLive, type AlertProps, AlertTitle, type ApprovalDecision, type ApprovalField, ApprovalRequest, type ApprovalRequestProps, type ApprovalScope, Avatar, AvatarFallback, type AvatarFallbackProps, AvatarImage, type AvatarImageProps, type AvatarProps, Badge, type BadgeProps, type BuildDiffOptions, Button, type ButtonProps, COMPONENT_CATEGORIES, COMPONENT_STATUSES, CRON_SHORTCUTS, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, type CardTitleProps, type CellState, Checkbox, type CheckboxProps, CodeBlock, type CodeBlockProps, Combobox, ComboboxContent, type ComboboxContentProps, ComboboxEmpty, ComboboxInput, type ComboboxInputProps, ComboboxItem, type ComboboxItemProps, ComboboxList, type ComboboxProps, ComboboxTrigger, type ComboboxTriggerProps, Command, CommandDialog, type CommandDialogProps, CommandEmpty, CommandGroup, type CommandGroupProps, CommandInput, type CommandInputProps, CommandItem, type CommandItemProps, CommandList, type CommandProps, CommandSeparator, CommandShortcut, ComponentCategory, ComponentMeta, ComponentStatus, ConfirmTyped, type ConfirmTypedProps, Conversation, ConversationMessages, type ConversationProps, ConversationScrollButton, type ConversationScrollButtonProps, ConversationStatus, type ConversationStatusProps, CopyButton, type CopyButtonProps, Cron, CronBuilder, type CronBuilderProps, CronExpression, CronExpressionError, type CronExpressionProps, type CronField, CronNextRuns, type CronNextRunsProps, type CronProps, type CronSchedule, DEFAULT_PRESETS, DEFAULT_TOAST_DURATION, DataTable, DataTableColumnHeader, type DataTableColumnHeaderProps, DataTablePagination, type DataTablePaginationProps, type DataTableProps, DataTableViewOptions, type DataTableViewOptionsProps, DatePicker, type DatePickerProps, DateRangePicker, type DateRangePickerProps, type DescribeOptions, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, DialogHeader, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type DiffHunk, type DiffRow, DiffViewer, type DiffViewerProps, DiffViewerToolbar, type DisclosureKind, type DnsHostForms, DnsRecord, type DnsRecordProps, type DnsRecordStatus, Drawer, DrawerBody, DrawerCancel, DrawerClose, DrawerContent, type DrawerContentProps, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, type DrawerProps, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, type DropdownMenuSubTriggerProps, DropdownMenuTrigger, EmptyState, EmptyStateActions, EmptyStateDescription, EmptyStateIcon, type EmptyStateProps, EmptyStateTitle, type ExtractionField, ExtractionReview, type ExtractionReviewProps, type FieldChange, type FieldDecision, type FieldState, FileUpload, FileUploadItem, type FileUploadItemProps, FileUploadList, type FileUploadListProps, type FileUploadProps, FileUploadStatus, type FilterState, Form, FormControl, type FormControlProps, FormDescription, FormField, type FormFieldProps, FormLabel, type FormLabelProps, FormMessage, type FormMessageProps, type FormProps, type Grants, type GroupState, type HideableTable, type HunkDecision, InlineCitation, type InlineCitationProps, InlineCompletion, type InlineCompletionProps, Input, type InputProps, LOG_LEVELS, Label, type LabelProps, type LedgerAction, type LogLevel, type LogLine, LogViewer, type LogViewerProps, LogViewerRow, type LogViewerRowProps, LogViewerToolbar, type LogViewerToolbarProps, type MatchRange, Message, MessageActions, MessageAvatar, type MessageAvatarProps, MessageBody, type MessageBodyProps, MessageFooter, type MessageProps, type MessageRole, Meter, MeterLegend, type MeterProps, type MeterSegment, type MeterTone, MeterValue, MetricDelta, type MetricDeltaProps, type MetricPolarity, type ModelOption, ModelSelector, type ModelSelectorProps, type NextRunsOptions, type OutputField, type PaginatedTable, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, type Permission, type PermissionGroup, PermissionMatrix, type PermissionMatrixProps, type PlanStep, type Platform, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, type PopoverContentProps, PopoverTrigger, Progress, type ProgressProps, PromptInput, PromptInputCounter, type PromptInputCounterProps, type PromptInputProps, PromptInputSubmit, type PromptInputSubmitProps, PromptInputTextarea, type PromptInputTextareaProps, PromptInputToolbar, type ProvenanceClaim, type QueuedFile, RESERVED_KEYS, RadioGroup, RadioGroupItem, type RadioGroupItemProps, type RadioGroupProps, Reasoning, ReasoningContent, type ReasoningProps, ReasoningTrigger, type ReasoningTriggerProps, RecordDiff, type RecordDiffProps, RecordDiffSummary, RecordDiffTable, type RecordDiffTableProps, type RecordField, type ResolveOptions, type ResolvedRange, Response, ResponseCaret, type ResponseProps, type Reversibility, type ReviewSummary, type Role, type RowKind, SecretField, type SecretFieldProps, type SecretFieldState, Select, SelectContent, type SelectContentProps, SelectGroup, SelectItem, type SelectItemProps, SelectLabel, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, type SeparatorProps, SessionExpiry, type SessionExpiryProps, type SessionPhase, Sheet, SheetClose, SheetContent, type SheetContentProps, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, type Shortcut, ShortcutRecorder, type ShortcutRecorderProps, Skeleton, Slider, type SliderProps, type SortableColumn, Source, type SourceProps, type SourceRun, type SourceSpan, Sources, SourcesContent, type SourcesProps, SourcesTrigger, type SourcesTriggerProps, Spinner, type SpinnerProps, type StepStatus, StructuredConfidence, StructuredField, StructuredFieldError, type StructuredFieldProps, StructuredOutput, type StructuredOutputProps, SuggestedValue, type SuggestedValueProps, type Suggestion, type SuggestionStatus, Switch, type SwitchProps, type SyncInput, type SyncState, SyncStatus, type SyncStatusProps, TOAST_LIMIT, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, type TableProps, TableRow, Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, TabsTrigger, type TabsTriggerProps, type TagValidator, TagsInput, type TagsInputProps, type TakenShortcut, ThinkingIndicator, type ThinkingIndicatorProps, TimeExpressionError, TimeRange, TimeRangeCalendar, TimeRangeContent, type TimeRangeContentProps, TimeRangeExpression, type TimeRangePreset, TimeRangePresets, type TimeRangeProps, TimeRangeTrigger, type TimeRangeTriggerProps, type TimeUnit, Toast, ToastAction, type ToastAction$1 as ToastActionOptions, ToastClose, ToastDescription, type ToastOptions, type ToastPosition, type ToastPromiseMessages, type ToastProps, ToastProvider, type ToastRecord, ToastTitle, type ToastVariant, Toaster, type ToasterProps, TokenCount, type TokenCountProps, TokenUsage, type TokenUsageProps, Tool, ToolContent, ToolHeader, type ToolHeaderProps, ToolPayload, type ToolPayloadProps, type ToolProps, ToolSection, type ToolSectionProps, type ToolStatus, Tooltip, TooltipContent, type TooltipContentProps, type TooltipProps, TooltipProvider, TooltipTrigger, type UploadContext, type UploadFn, type UploadQueueOptions, type UploadStatus, type UseLogStreamOptions, type VisibleLine, type WordSegment, absoluteExpression, agentStatusVariants, alertVariants, avatarVariants, badgeVariants, buildDiff, buttonVariants, cellState, clampSpan, cn, compileQuery, countChanges, countGranted, defaultComboboxFilter, defaultCommandFilter, defineMeta, deltaVariants, describeCountdown, describeCron, describeShortcut, describeSyncState, describeTimeRange, detectPlatform, diffRecords, disabledStyles, disclosureVariants, dnsHostForms, emptyStateVariants, evidenceOf, findMatches, focusRing, focusRingInset, formatBytes, formatCountdown, formatResolvedRange, formatShortcut, groupIntoHunks, groupPermissions, groupState, iconSlot, inheritedFrom, inputVariants, invalidStyles, isSourced, isValidCron, isValidTimeRange, ledgerEntryVariants, maskSecret, matchesAccept, messageBodyVariants, messageVariants, needsModifier, nextRuns, parseCron, parseShortcut, progressVariants, resolveExpression, resolveTimeRange, secondsLeft, segment, segmentSource, selectTriggerVariants, serializeShortcut, sessionPhase, sheetVariants, shortcutFromKey, shortcutParts, shortcutsEqual, spinnerVariants, summarizeReview, syncState, tabsListVariants, tabsTriggerVariants, toSplitRows, toast, toastVariants, toolVariants, useLogStream, useOnlineStatus, useToasts, useUploadQueue, xhrUpload, zonedTimeToInstant };
|