@mirror-physics/fractal-ui 0.2.0-next.5 → 0.2.0-next.51
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/dist/index.cjs +1336 -246
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1345 -105
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +273 -20
- package/dist/index.d.ts +273 -20
- package/dist/index.js +1293 -240
- package/dist/index.js.map +1 -1
- package/dist/lattice-FAYE5KWW.svg +3 -0
- package/dist/tokens.css +5 -3
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ var colorPalette = {
|
|
|
50
50
|
var sizeConfig = {
|
|
51
51
|
xs: { height: "28px", padding: "4px 8px", iconOnly: "28px", fontSize: "0.75rem" },
|
|
52
52
|
sm: { height: "32px", padding: "6px 12px", iconOnly: "32px", fontSize: "0.75rem" },
|
|
53
|
-
md: { height: "
|
|
53
|
+
md: { height: "40px", padding: "8px 16px", iconOnly: "40px", fontSize: "0.875rem" },
|
|
54
54
|
lg: { height: "44px", padding: "10px 20px", iconOnly: "44px", fontSize: "1rem" },
|
|
55
55
|
xl: { height: "56px", padding: "14px 28px", iconOnly: "56px", fontSize: "1rem" }
|
|
56
56
|
};
|
|
@@ -165,44 +165,271 @@ var Button = React.forwardRef(
|
|
|
165
165
|
);
|
|
166
166
|
Button.displayName = "Button";
|
|
167
167
|
|
|
168
|
+
// src/components/CodeBlock/CodeBlock.tsx
|
|
169
|
+
import { useEffect, useMemo, useRef, useState as useState2 } from "react";
|
|
170
|
+
import CodeMirror from "@uiw/react-codemirror";
|
|
171
|
+
import { HighlightStyle, foldGutter, syntaxHighlighting } from "@codemirror/language";
|
|
172
|
+
import { json } from "@codemirror/lang-json";
|
|
173
|
+
import { EditorView, lineNumbers as lineNumberGutter } from "@codemirror/view";
|
|
174
|
+
import { tags } from "@lezer/highlight";
|
|
175
|
+
import { Check, Copy } from "@mirror-physics/fractal-icons";
|
|
176
|
+
import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
177
|
+
var codeTheme = EditorView.theme({
|
|
178
|
+
"&": {
|
|
179
|
+
backgroundColor: "transparent",
|
|
180
|
+
color: "var(--fg-primary)",
|
|
181
|
+
fontSize: "0.75rem"
|
|
182
|
+
},
|
|
183
|
+
"&.cm-focused": { outline: "none" },
|
|
184
|
+
".cm-scroller": {
|
|
185
|
+
fontFamily: "var(--font-mono)",
|
|
186
|
+
lineHeight: "1.55",
|
|
187
|
+
overscrollBehavior: "none"
|
|
188
|
+
},
|
|
189
|
+
".cm-content": { padding: "10px 0" },
|
|
190
|
+
".cm-line": { padding: "0 12px" },
|
|
191
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--fg-primary)" },
|
|
192
|
+
".cm-gutters": {
|
|
193
|
+
backgroundColor: "var(--bg-canvas)",
|
|
194
|
+
borderRight: "1px solid var(--border-subtle)",
|
|
195
|
+
color: "var(--fg-tertiary)"
|
|
196
|
+
},
|
|
197
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 10px 0 4px" },
|
|
198
|
+
".cm-foldGutter": { width: "14px" },
|
|
199
|
+
".cm-foldGutter .cm-gutterElement": {
|
|
200
|
+
display: "flex",
|
|
201
|
+
width: "14px",
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
justifyContent: "flex-end",
|
|
204
|
+
padding: "0 1px 0 0"
|
|
205
|
+
},
|
|
206
|
+
".cm-foldGutter .cm-gutterElement > span": {
|
|
207
|
+
display: "inline-flex",
|
|
208
|
+
width: "12px",
|
|
209
|
+
height: "100%",
|
|
210
|
+
alignItems: "center",
|
|
211
|
+
justifyContent: "center",
|
|
212
|
+
padding: "0",
|
|
213
|
+
color: "var(--fg-tertiary)",
|
|
214
|
+
lineHeight: "1",
|
|
215
|
+
transform: "translateY(-1px)",
|
|
216
|
+
transition: "color 120ms ease"
|
|
217
|
+
},
|
|
218
|
+
".cm-foldGutter .cm-gutterElement > span:hover": { color: "var(--fg-secondary)" },
|
|
219
|
+
".cm-activeLine, .cm-activeLineGutter": { backgroundColor: "var(--bg-surface-1)" },
|
|
220
|
+
".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection": {
|
|
221
|
+
backgroundColor: "var(--accent-surface-stroke) !important"
|
|
222
|
+
},
|
|
223
|
+
".cm-searchMatch": {
|
|
224
|
+
backgroundColor: "var(--warning-surface)",
|
|
225
|
+
outline: "1px solid var(--warning-surface-stroke)"
|
|
226
|
+
},
|
|
227
|
+
".cm-searchMatch.cm-searchMatch-selected": { backgroundColor: "var(--warning-subtle)" },
|
|
228
|
+
".cm-panels": { backgroundColor: "var(--bg-surface-1)", color: "var(--fg-primary)" },
|
|
229
|
+
".cm-tooltip": {
|
|
230
|
+
borderColor: "var(--border-subtle)",
|
|
231
|
+
backgroundColor: "var(--bg-canvas)",
|
|
232
|
+
color: "var(--fg-primary)"
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
var fractalHighlightStyle = HighlightStyle.define([
|
|
236
|
+
{ tag: tags.comment, color: "var(--fg-tertiary)", fontStyle: "italic" },
|
|
237
|
+
{ tag: [tags.keyword, tags.controlKeyword, tags.operatorKeyword], color: "var(--purple-default)" },
|
|
238
|
+
{ tag: [tags.string, tags.special(tags.string)], color: "var(--purple-default)" },
|
|
239
|
+
{ tag: [tags.number, tags.bool, tags.null], color: "var(--orange-default)" },
|
|
240
|
+
{ tag: [tags.function(tags.variableName), tags.labelName], color: "var(--accent-default)" },
|
|
241
|
+
{ tag: [tags.typeName, tags.className, tags.namespace], color: "var(--pink-default)" },
|
|
242
|
+
{ tag: [tags.propertyName, tags.attributeName], color: "var(--success-default)" },
|
|
243
|
+
{ tag: [tags.operator, tags.punctuation], color: "var(--fg-secondary)" },
|
|
244
|
+
{ tag: tags.bracket, color: "var(--accent-default)" },
|
|
245
|
+
{ tag: [tags.heading, tags.strong], color: "var(--fg-primary)", fontWeight: "600" },
|
|
246
|
+
{ tag: tags.emphasis, fontStyle: "italic" },
|
|
247
|
+
{ tag: tags.link, color: "var(--accent-default)", textDecoration: "underline" },
|
|
248
|
+
{ tag: tags.invalid, color: "var(--error-default)", textDecoration: "underline wavy" }
|
|
249
|
+
]);
|
|
250
|
+
var jsonSupport = json();
|
|
251
|
+
var JSON_LANGUAGE_NAMES = /* @__PURE__ */ new Set(["json", "jsonl", "ndjson", "geojson"]);
|
|
252
|
+
function resolveLanguage(language, fileName) {
|
|
253
|
+
const normalized = language?.trim().toLowerCase();
|
|
254
|
+
const extension = fileName?.split(/[?#]/, 1)[0].split(".").pop()?.toLowerCase();
|
|
255
|
+
if (normalized && JSON_LANGUAGE_NAMES.has(normalized) || extension && JSON_LANGUAGE_NAMES.has(extension)) {
|
|
256
|
+
return { label: normalized === "jsonl" || extension === "jsonl" ? "JSONL" : "JSON", support: jsonSupport };
|
|
257
|
+
}
|
|
258
|
+
if (normalized && !["text", "txt", "plaintext", "plain"].includes(normalized)) {
|
|
259
|
+
return { label: language?.trim(), support: null };
|
|
260
|
+
}
|
|
261
|
+
return { support: null };
|
|
262
|
+
}
|
|
263
|
+
function CodeBlock({
|
|
264
|
+
value,
|
|
265
|
+
language,
|
|
266
|
+
fileName,
|
|
267
|
+
label,
|
|
268
|
+
editable = false,
|
|
269
|
+
onChange,
|
|
270
|
+
lineNumbers = true,
|
|
271
|
+
wrap = true,
|
|
272
|
+
copyable = true,
|
|
273
|
+
ariaLabel,
|
|
274
|
+
height,
|
|
275
|
+
minHeight,
|
|
276
|
+
maxHeight = "28rem",
|
|
277
|
+
placeholder,
|
|
278
|
+
autoFocus,
|
|
279
|
+
className,
|
|
280
|
+
...props
|
|
281
|
+
}) {
|
|
282
|
+
const resolvedLanguage = useMemo(() => resolveLanguage(language, fileName), [fileName, language]);
|
|
283
|
+
const [copyStatus, setCopyStatus] = useState2("idle");
|
|
284
|
+
const copyResetTimer = useRef(null);
|
|
285
|
+
useEffect(() => () => {
|
|
286
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
287
|
+
}, []);
|
|
288
|
+
const extensions = useMemo(() => [
|
|
289
|
+
codeTheme,
|
|
290
|
+
syntaxHighlighting(fractalHighlightStyle),
|
|
291
|
+
...resolvedLanguage.support ? [resolvedLanguage.support] : [],
|
|
292
|
+
...lineNumbers ? [foldGutter(), lineNumberGutter()] : [],
|
|
293
|
+
...wrap ? [EditorView.lineWrapping] : []
|
|
294
|
+
], [lineNumbers, resolvedLanguage.support, wrap]);
|
|
295
|
+
const languageLabel = resolvedLanguage.label;
|
|
296
|
+
const toolbarLabel = label ?? fileName ?? languageLabel;
|
|
297
|
+
const surfaceLabel = ariaLabel ?? (fileName ? `${fileName} ${editable ? "editor" : "viewer"}` : `Code ${editable ? "editor" : "viewer"}`);
|
|
298
|
+
const copyCode = async () => {
|
|
299
|
+
try {
|
|
300
|
+
await navigator.clipboard.writeText(value);
|
|
301
|
+
setCopyStatus("copied");
|
|
302
|
+
} catch {
|
|
303
|
+
setCopyStatus("error");
|
|
304
|
+
}
|
|
305
|
+
if (copyResetTimer.current) clearTimeout(copyResetTimer.current);
|
|
306
|
+
copyResetTimer.current = setTimeout(() => setCopyStatus("idle"), 1800);
|
|
307
|
+
};
|
|
308
|
+
const showToolbar = toolbarLabel !== void 0 || copyable || editable;
|
|
309
|
+
return /* @__PURE__ */ jsxs2(
|
|
310
|
+
"div",
|
|
311
|
+
{
|
|
312
|
+
className: cn(
|
|
313
|
+
"fractal-code-block",
|
|
314
|
+
editable && "fractal-code-block--editable",
|
|
315
|
+
!lineNumbers && "fractal-code-block--no-line-numbers",
|
|
316
|
+
className
|
|
317
|
+
),
|
|
318
|
+
...props,
|
|
319
|
+
children: [
|
|
320
|
+
showToolbar && /* @__PURE__ */ jsxs2("div", { className: "fractal-code-block__toolbar", children: [
|
|
321
|
+
/* @__PURE__ */ jsxs2("div", { className: "fractal-code-block__identity", children: [
|
|
322
|
+
toolbarLabel !== void 0 && /* @__PURE__ */ jsx("span", { className: "fractal-code-block__label", title: typeof toolbarLabel === "string" ? toolbarLabel : void 0, children: toolbarLabel }),
|
|
323
|
+
fileName && languageLabel && /* @__PURE__ */ jsx("span", { className: "fractal-code-block__language", children: languageLabel }),
|
|
324
|
+
editable && /* @__PURE__ */ jsx("span", { className: "fractal-code-block__mode", children: "Editing" })
|
|
325
|
+
] }),
|
|
326
|
+
copyable && /* @__PURE__ */ jsxs2(
|
|
327
|
+
"button",
|
|
328
|
+
{
|
|
329
|
+
type: "button",
|
|
330
|
+
className: "fractal-code-block__copy",
|
|
331
|
+
"aria-label": copyStatus === "copied" ? "Code copied" : "Copy code",
|
|
332
|
+
onClick: () => void copyCode(),
|
|
333
|
+
children: [
|
|
334
|
+
copyStatus === "copied" ? /* @__PURE__ */ jsx(Check, { size: 14 }) : /* @__PURE__ */ jsx(Copy, { size: 14 }),
|
|
335
|
+
/* @__PURE__ */ jsx("span", { children: copyStatus === "copied" ? "Copied" : copyStatus === "error" ? "Copy failed" : "Copy" })
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
] }),
|
|
340
|
+
/* @__PURE__ */ jsx("div", { className: "fractal-code-block__surface", children: /* @__PURE__ */ jsx(
|
|
341
|
+
CodeMirror,
|
|
342
|
+
{
|
|
343
|
+
"aria-label": surfaceLabel,
|
|
344
|
+
value,
|
|
345
|
+
editable,
|
|
346
|
+
readOnly: !editable,
|
|
347
|
+
onChange,
|
|
348
|
+
extensions,
|
|
349
|
+
theme: "none",
|
|
350
|
+
basicSetup: {
|
|
351
|
+
lineNumbers: false,
|
|
352
|
+
foldGutter: false,
|
|
353
|
+
drawSelection: editable,
|
|
354
|
+
highlightActiveLine: editable,
|
|
355
|
+
highlightActiveLineGutter: editable,
|
|
356
|
+
highlightSelectionMatches: editable,
|
|
357
|
+
autocompletion: editable,
|
|
358
|
+
history: editable
|
|
359
|
+
},
|
|
360
|
+
indentWithTab: editable,
|
|
361
|
+
height,
|
|
362
|
+
minHeight,
|
|
363
|
+
maxHeight,
|
|
364
|
+
placeholder,
|
|
365
|
+
autoFocus
|
|
366
|
+
}
|
|
367
|
+
) }),
|
|
368
|
+
/* @__PURE__ */ jsx("span", { className: "fractal-code-block__status", "aria-live": "polite", children: copyStatus === "copied" ? "Code copied to clipboard." : copyStatus === "error" ? "Code could not be copied." : "" })
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
375
|
+
import { ChevronRight } from "@mirror-physics/fractal-icons";
|
|
376
|
+
import { jsx as jsx2, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
377
|
+
function Breadcrumbs({
|
|
378
|
+
items,
|
|
379
|
+
ariaLabel = "Breadcrumbs",
|
|
380
|
+
separator = /* @__PURE__ */ jsx2(ChevronRight, { "aria-hidden": "true", size: 14 }),
|
|
381
|
+
className,
|
|
382
|
+
...props
|
|
383
|
+
}) {
|
|
384
|
+
if (items.length === 0) return null;
|
|
385
|
+
return /* @__PURE__ */ jsx2("nav", { "aria-label": ariaLabel, className: cn("fractal-breadcrumbs", className), ...props, children: /* @__PURE__ */ jsx2("ol", { className: "fractal-breadcrumbs__list", children: items.map((item, index) => {
|
|
386
|
+
const isCurrent = index === items.length - 1;
|
|
387
|
+
const content = isCurrent ? /* @__PURE__ */ jsx2("span", { "aria-current": "page", className: "fractal-breadcrumbs__current", children: item.label }) : /* @__PURE__ */ jsx2("a", { className: "fractal-breadcrumbs__link", href: item.href ?? "#", onClick: item.onClick, children: item.label });
|
|
388
|
+
return /* @__PURE__ */ jsxs3("li", { className: "fractal-breadcrumbs__item", children: [
|
|
389
|
+
index > 0 && /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", className: "fractal-breadcrumbs__separator", children: separator }),
|
|
390
|
+
content
|
|
391
|
+
] }, index);
|
|
392
|
+
}) }) });
|
|
393
|
+
}
|
|
394
|
+
|
|
168
395
|
// src/components/Card/Card.tsx
|
|
169
396
|
import * as React2 from "react";
|
|
170
397
|
import { Folder as FolderIcon } from "@mirror-physics/fractal-icons";
|
|
171
|
-
import { jsx, jsxs as
|
|
398
|
+
import { jsx as jsx3, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
172
399
|
var Card = React2.forwardRef(
|
|
173
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
400
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", { ref, className: cn("fractal-card", className), ...props })
|
|
174
401
|
);
|
|
175
402
|
Card.displayName = "Card";
|
|
176
403
|
var CardHeader = React2.forwardRef(
|
|
177
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
404
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", { ref, className: cn("fractal-card-header", className), ...props })
|
|
178
405
|
);
|
|
179
406
|
CardHeader.displayName = "CardHeader";
|
|
180
407
|
var CardTitle = React2.forwardRef(
|
|
181
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
408
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("h3", { ref, className: cn("fractal-card-title", className), ...props })
|
|
182
409
|
);
|
|
183
410
|
CardTitle.displayName = "CardTitle";
|
|
184
411
|
var CardDescription = React2.forwardRef(
|
|
185
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
412
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("p", { ref, className: cn("fractal-card-description", className), ...props })
|
|
186
413
|
);
|
|
187
414
|
CardDescription.displayName = "CardDescription";
|
|
188
415
|
var CardContent = React2.forwardRef(
|
|
189
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
416
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", { ref, className: cn("fractal-card-content", className), ...props })
|
|
190
417
|
);
|
|
191
418
|
CardContent.displayName = "CardContent";
|
|
192
419
|
var CardFooter = React2.forwardRef(
|
|
193
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
420
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3("div", { ref, className: cn("fractal-card-footer", className), ...props })
|
|
194
421
|
);
|
|
195
422
|
CardFooter.displayName = "CardFooter";
|
|
196
423
|
var FeatureCard = React2.forwardRef(
|
|
197
|
-
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */
|
|
198
|
-
icon && /* @__PURE__ */
|
|
199
|
-
/* @__PURE__ */
|
|
200
|
-
/* @__PURE__ */
|
|
424
|
+
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ jsxs4("div", { ref, className: cn("fractal-feature-card", className), ...props, children: [
|
|
425
|
+
icon && /* @__PURE__ */ jsx3("div", { className: "fractal-feature-card__icon", children: icon }),
|
|
426
|
+
/* @__PURE__ */ jsx3("h3", { className: "fractal-feature-card__title", children: title }),
|
|
427
|
+
/* @__PURE__ */ jsx3("p", { className: "fractal-feature-card__description", children: description })
|
|
201
428
|
] })
|
|
202
429
|
);
|
|
203
430
|
FeatureCard.displayName = "FeatureCard";
|
|
204
431
|
var FolderCard = React2.forwardRef(
|
|
205
|
-
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */
|
|
432
|
+
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
206
433
|
"div",
|
|
207
434
|
{
|
|
208
435
|
ref,
|
|
@@ -218,11 +445,11 @@ var FolderCard = React2.forwardRef(
|
|
|
218
445
|
className: cn("fractal-folder-card", selected && "fractal-folder-card--selected", className),
|
|
219
446
|
...props,
|
|
220
447
|
children: [
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
/* @__PURE__ */
|
|
223
|
-
/* @__PURE__ */
|
|
448
|
+
/* @__PURE__ */ jsxs4("div", { className: "fractal-folder-card__header", children: [
|
|
449
|
+
/* @__PURE__ */ jsx3(FolderIcon, { size: 16, className: "fractal-folder-card__icon", "aria-hidden": true }),
|
|
450
|
+
/* @__PURE__ */ jsx3("span", { className: "fractal-folder-card__name", children: name })
|
|
224
451
|
] }),
|
|
225
|
-
sessionCount !== void 0 && /* @__PURE__ */
|
|
452
|
+
sessionCount !== void 0 && /* @__PURE__ */ jsx3("div", { className: "fractal-folder-card__footer", children: /* @__PURE__ */ jsxs4("span", { className: "fractal-folder-card__sessions", children: [
|
|
226
453
|
sessionCount,
|
|
227
454
|
" ",
|
|
228
455
|
sessionCount === 1 ? "session" : "sessions"
|
|
@@ -235,7 +462,7 @@ FolderCard.displayName = "FolderCard";
|
|
|
235
462
|
|
|
236
463
|
// src/components/PromptCard/PromptCard.tsx
|
|
237
464
|
import * as React3 from "react";
|
|
238
|
-
import { jsx as
|
|
465
|
+
import { jsx as jsx4, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
239
466
|
var titleToPrompt = (title) => typeof title === "string" || typeof title === "number" ? String(title) : "";
|
|
240
467
|
var PromptCard = React3.forwardRef(
|
|
241
468
|
({
|
|
@@ -256,7 +483,7 @@ var PromptCard = React3.forwardRef(
|
|
|
256
483
|
onPromptSelect?.(prompt ?? titleToPrompt(title));
|
|
257
484
|
}
|
|
258
485
|
};
|
|
259
|
-
return /* @__PURE__ */
|
|
486
|
+
return /* @__PURE__ */ jsxs5(
|
|
260
487
|
"button",
|
|
261
488
|
{
|
|
262
489
|
ref,
|
|
@@ -271,8 +498,8 @@ var PromptCard = React3.forwardRef(
|
|
|
271
498
|
onClick: handleClick,
|
|
272
499
|
...props,
|
|
273
500
|
children: [
|
|
274
|
-
icon && /* @__PURE__ */
|
|
275
|
-
/* @__PURE__ */
|
|
501
|
+
icon && /* @__PURE__ */ jsx4("span", { className: "fractal-prompt-card__icon", "aria-hidden": "true", children: icon }),
|
|
502
|
+
/* @__PURE__ */ jsx4("span", { className: "fractal-prompt-card__title", children: title })
|
|
276
503
|
]
|
|
277
504
|
}
|
|
278
505
|
);
|
|
@@ -280,7 +507,7 @@ var PromptCard = React3.forwardRef(
|
|
|
280
507
|
);
|
|
281
508
|
PromptCard.displayName = "PromptCard";
|
|
282
509
|
var PromptGrid = React3.forwardRef(
|
|
283
|
-
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */
|
|
510
|
+
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
284
511
|
"div",
|
|
285
512
|
{
|
|
286
513
|
ref,
|
|
@@ -298,9 +525,9 @@ PromptGrid.displayName = "PromptGrid";
|
|
|
298
525
|
|
|
299
526
|
// src/components/Input/Input.tsx
|
|
300
527
|
import * as React4 from "react";
|
|
301
|
-
import { jsx as
|
|
528
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
302
529
|
var Input = React4.forwardRef(
|
|
303
|
-
({ className, type, ...props }, ref) => /* @__PURE__ */
|
|
530
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ jsx5(
|
|
304
531
|
"input",
|
|
305
532
|
{
|
|
306
533
|
type,
|
|
@@ -312,11 +539,141 @@ var Input = React4.forwardRef(
|
|
|
312
539
|
);
|
|
313
540
|
Input.displayName = "Input";
|
|
314
541
|
|
|
315
|
-
// src/components/
|
|
542
|
+
// src/components/NumberInput/NumberInput.tsx
|
|
316
543
|
import * as React5 from "react";
|
|
317
|
-
import {
|
|
318
|
-
|
|
319
|
-
|
|
544
|
+
import { Minus, Plus } from "@mirror-physics/fractal-icons";
|
|
545
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
546
|
+
function NumberInput({
|
|
547
|
+
unit,
|
|
548
|
+
className,
|
|
549
|
+
value,
|
|
550
|
+
defaultValue,
|
|
551
|
+
disabled,
|
|
552
|
+
readOnly,
|
|
553
|
+
min,
|
|
554
|
+
max,
|
|
555
|
+
...props
|
|
556
|
+
}) {
|
|
557
|
+
const inputRef = React5.useRef(null);
|
|
558
|
+
const numericValue = Number(value ?? defaultValue);
|
|
559
|
+
const characterCount = Math.max(String(value ?? defaultValue ?? "").length, 1);
|
|
560
|
+
const controlLabel = typeof props["aria-label"] === "string" ? props["aria-label"] : "value";
|
|
561
|
+
const decrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && min !== void 0 && numericValue <= Number(min);
|
|
562
|
+
const incrementDisabled = disabled || readOnly || Number.isFinite(numericValue) && max !== void 0 && numericValue >= Number(max);
|
|
563
|
+
const changeByStep = (direction) => {
|
|
564
|
+
const input = inputRef.current;
|
|
565
|
+
if (!input) return;
|
|
566
|
+
if (direction === -1) input.stepDown();
|
|
567
|
+
else input.stepUp();
|
|
568
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
569
|
+
input.focus();
|
|
570
|
+
};
|
|
571
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("fractal-number-input", unit && "fractal-number-input--with-unit", className), children: [
|
|
572
|
+
/* @__PURE__ */ jsx6(
|
|
573
|
+
Input,
|
|
574
|
+
{
|
|
575
|
+
ref: inputRef,
|
|
576
|
+
type: "number",
|
|
577
|
+
value,
|
|
578
|
+
defaultValue,
|
|
579
|
+
disabled,
|
|
580
|
+
readOnly,
|
|
581
|
+
min,
|
|
582
|
+
max,
|
|
583
|
+
...props
|
|
584
|
+
}
|
|
585
|
+
),
|
|
586
|
+
unit && /* @__PURE__ */ jsx6(
|
|
587
|
+
"span",
|
|
588
|
+
{
|
|
589
|
+
className: "fractal-number-input-unit",
|
|
590
|
+
style: { left: `calc(var(--space-3, 12px) + ${characterCount}ch)` },
|
|
591
|
+
"aria-hidden": "true",
|
|
592
|
+
children: unit
|
|
593
|
+
}
|
|
594
|
+
),
|
|
595
|
+
/* @__PURE__ */ jsxs6("div", { className: "fractal-number-input-controls", children: [
|
|
596
|
+
/* @__PURE__ */ jsx6(
|
|
597
|
+
"button",
|
|
598
|
+
{
|
|
599
|
+
type: "button",
|
|
600
|
+
className: "fractal-number-input-step",
|
|
601
|
+
"aria-label": `Decrease ${controlLabel}`,
|
|
602
|
+
disabled: decrementDisabled,
|
|
603
|
+
onClick: () => changeByStep(-1),
|
|
604
|
+
children: /* @__PURE__ */ jsx6(Minus, { "aria-hidden": "true", size: 16 })
|
|
605
|
+
}
|
|
606
|
+
),
|
|
607
|
+
/* @__PURE__ */ jsx6(
|
|
608
|
+
"button",
|
|
609
|
+
{
|
|
610
|
+
type: "button",
|
|
611
|
+
className: "fractal-number-input-step",
|
|
612
|
+
"aria-label": `Increase ${controlLabel}`,
|
|
613
|
+
disabled: incrementDisabled,
|
|
614
|
+
onClick: () => changeByStep(1),
|
|
615
|
+
children: /* @__PURE__ */ jsx6(Plus, { "aria-hidden": "true", size: 16 })
|
|
616
|
+
}
|
|
617
|
+
)
|
|
618
|
+
] })
|
|
619
|
+
] });
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// src/components/PasswordInput/PasswordInput.tsx
|
|
623
|
+
import * as React6 from "react";
|
|
624
|
+
import { Eye, EyeSlash } from "@mirror-physics/fractal-icons";
|
|
625
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
626
|
+
var PasswordInput = React6.forwardRef(
|
|
627
|
+
({
|
|
628
|
+
className,
|
|
629
|
+
disabled,
|
|
630
|
+
showPasswordLabel = "Show password",
|
|
631
|
+
hidePasswordLabel = "Hide password",
|
|
632
|
+
...props
|
|
633
|
+
}, ref) => {
|
|
634
|
+
const [passwordVisible, setPasswordVisible] = React6.useState(false);
|
|
635
|
+
const toggleLabel = passwordVisible ? hidePasswordLabel : showPasswordLabel;
|
|
636
|
+
return /* @__PURE__ */ jsxs7(
|
|
637
|
+
"div",
|
|
638
|
+
{
|
|
639
|
+
className: cn("fractal-password-input", className),
|
|
640
|
+
"data-password-visible": passwordVisible ? "" : void 0,
|
|
641
|
+
children: [
|
|
642
|
+
/* @__PURE__ */ jsx7(
|
|
643
|
+
Input,
|
|
644
|
+
{
|
|
645
|
+
...props,
|
|
646
|
+
ref,
|
|
647
|
+
className: "fractal-password-input-field",
|
|
648
|
+
disabled,
|
|
649
|
+
type: passwordVisible ? "text" : "password"
|
|
650
|
+
}
|
|
651
|
+
),
|
|
652
|
+
/* @__PURE__ */ jsx7(
|
|
653
|
+
"button",
|
|
654
|
+
{
|
|
655
|
+
type: "button",
|
|
656
|
+
className: "fractal-password-input-toggle",
|
|
657
|
+
"aria-label": toggleLabel,
|
|
658
|
+
"aria-pressed": passwordVisible,
|
|
659
|
+
disabled,
|
|
660
|
+
title: toggleLabel,
|
|
661
|
+
onClick: () => setPasswordVisible((visible) => !visible),
|
|
662
|
+
children: passwordVisible ? /* @__PURE__ */ jsx7(EyeSlash, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ jsx7(Eye, { "aria-hidden": "true", size: 18 })
|
|
663
|
+
}
|
|
664
|
+
)
|
|
665
|
+
]
|
|
666
|
+
}
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
);
|
|
670
|
+
PasswordInput.displayName = "PasswordInput";
|
|
671
|
+
|
|
672
|
+
// src/components/Label/Label.tsx
|
|
673
|
+
import * as React7 from "react";
|
|
674
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
675
|
+
var Label = React7.forwardRef(
|
|
676
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx8(
|
|
320
677
|
"label",
|
|
321
678
|
{
|
|
322
679
|
ref,
|
|
@@ -328,44 +685,48 @@ var Label = React5.forwardRef(
|
|
|
328
685
|
Label.displayName = "Label";
|
|
329
686
|
|
|
330
687
|
// src/components/Alert/Alert.tsx
|
|
331
|
-
import * as
|
|
332
|
-
import {
|
|
688
|
+
import * as React8 from "react";
|
|
689
|
+
import { CircleCheck, CircleClose, CircleInfo, Warning } from "@mirror-physics/fractal-icons";
|
|
690
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
333
691
|
var defaultIcons = {
|
|
334
|
-
default:
|
|
335
|
-
info:
|
|
336
|
-
success:
|
|
337
|
-
warning:
|
|
338
|
-
error:
|
|
692
|
+
default: CircleInfo,
|
|
693
|
+
info: CircleInfo,
|
|
694
|
+
success: CircleCheck,
|
|
695
|
+
warning: Warning,
|
|
696
|
+
error: CircleClose
|
|
339
697
|
};
|
|
340
|
-
var Alert =
|
|
341
|
-
({ className, variant = "default", icon, children, ...props }, ref) =>
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
698
|
+
var Alert = React8.forwardRef(
|
|
699
|
+
({ className, variant = "default", icon, children, ...props }, ref) => {
|
|
700
|
+
const DefaultIcon = defaultIcons[variant];
|
|
701
|
+
return /* @__PURE__ */ jsxs8(
|
|
702
|
+
"div",
|
|
703
|
+
{
|
|
704
|
+
ref,
|
|
705
|
+
role: "alert",
|
|
706
|
+
className: cn("fractal-alert", `fractal-alert--${variant}`, className),
|
|
707
|
+
...props,
|
|
708
|
+
children: [
|
|
709
|
+
/* @__PURE__ */ jsx9("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ jsx9(DefaultIcon, { size: 18 }) }),
|
|
710
|
+
/* @__PURE__ */ jsx9("div", { className: "fractal-alert-content", children })
|
|
711
|
+
]
|
|
712
|
+
}
|
|
713
|
+
);
|
|
714
|
+
}
|
|
354
715
|
);
|
|
355
716
|
Alert.displayName = "Alert";
|
|
356
|
-
var AlertTitle =
|
|
357
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
717
|
+
var AlertTitle = React8.forwardRef(
|
|
718
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx9("h5", { ref, className: cn("fractal-alert-title", className), ...props })
|
|
358
719
|
);
|
|
359
720
|
AlertTitle.displayName = "AlertTitle";
|
|
360
|
-
var AlertDescription =
|
|
361
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
721
|
+
var AlertDescription = React8.forwardRef(
|
|
722
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx9("div", { ref, className: cn("fractal-alert-description", className), ...props })
|
|
362
723
|
);
|
|
363
724
|
AlertDescription.displayName = "AlertDescription";
|
|
364
725
|
|
|
365
726
|
// src/components/Toggle/Toggle.tsx
|
|
366
|
-
import { jsx as
|
|
727
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
367
728
|
function Toggle({ checked, onChange, label, className }) {
|
|
368
|
-
return /* @__PURE__ */
|
|
729
|
+
return /* @__PURE__ */ jsxs9(
|
|
369
730
|
"button",
|
|
370
731
|
{
|
|
371
732
|
type: "button",
|
|
@@ -374,8 +735,8 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
374
735
|
className: cn("fractal-toggle", className),
|
|
375
736
|
onClick: () => onChange(!checked),
|
|
376
737
|
children: [
|
|
377
|
-
/* @__PURE__ */
|
|
378
|
-
label && /* @__PURE__ */
|
|
738
|
+
/* @__PURE__ */ jsx10("span", { className: cn("fractal-toggle-track", checked && "fractal-toggle-track--checked"), children: /* @__PURE__ */ jsx10("span", { className: cn("fractal-toggle-thumb", checked && "fractal-toggle-thumb--checked") }) }),
|
|
739
|
+
label && /* @__PURE__ */ jsx10("span", { className: "fractal-toggle-label", children: label })
|
|
379
740
|
]
|
|
380
741
|
}
|
|
381
742
|
);
|
|
@@ -385,7 +746,7 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
385
746
|
import { createPortal } from "react-dom";
|
|
386
747
|
|
|
387
748
|
// src/hooks/useEscapeDismiss.ts
|
|
388
|
-
import { useEffect, useRef } from "react";
|
|
749
|
+
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
389
750
|
var nextId = 0;
|
|
390
751
|
var stack = [];
|
|
391
752
|
function insertSorted(entry) {
|
|
@@ -418,9 +779,9 @@ function ensureGlobalListener() {
|
|
|
418
779
|
);
|
|
419
780
|
}
|
|
420
781
|
function useEscapeDismiss(priority, handler, enabled = true) {
|
|
421
|
-
const handlerRef =
|
|
782
|
+
const handlerRef = useRef3(handler);
|
|
422
783
|
handlerRef.current = handler;
|
|
423
|
-
|
|
784
|
+
useEffect2(() => {
|
|
424
785
|
if (!enabled) return;
|
|
425
786
|
ensureGlobalListener();
|
|
426
787
|
const id = nextId++;
|
|
@@ -434,27 +795,84 @@ function useEscapeDismiss(priority, handler, enabled = true) {
|
|
|
434
795
|
}, [priority, enabled]);
|
|
435
796
|
}
|
|
436
797
|
|
|
798
|
+
// src/components/UILoader/UILoader.tsx
|
|
799
|
+
import { useId } from "react";
|
|
800
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
801
|
+
var LEFT = "M0 53C0 51 1.6 49.5 3.6 49.5h16.5c1 0 1.9.4 2.5 1L42.1 69.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H23.1c-1 0-1.9-.4-2.5-1L1.1 71.7C.4 71 0 70.1 0 69.2V53Z";
|
|
802
|
+
var CENTER = "M0 3.5C0 1.6 1.6 0 3.6 0h16.5c1 0 1.9.4 2.5 1L92.5 69.6c.7.7 1 1.6 1 2.5v16.2c0 2-1.6 3.5-3.6 3.5H73.4c-1 0-1.9-.4-2.5-1L1.1 22.2C.4 21.6 0 20.7 0 19.7V3.5Z";
|
|
803
|
+
var RIGHT = "M50.4 3.5C50.4 1.6 52 0 54 0h16.5c1 0 1.9.4 2.5 1l69.8 68.6c.7.7 1.1 1.6 1.1 2.5v16.2c0 2-1.6 3.5-3.6 3.5h-16.5c-1 0-1.9-.4-2.5-1L51.4 22.2c-.7-.6-1-1.5-1-2.5V3.5Z";
|
|
804
|
+
function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
|
|
805
|
+
const rawId = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
806
|
+
const clipId = `fractal-ui-loader-clip-${rawId}`;
|
|
807
|
+
const gradientId = `fractal-ui-loader-gradient-${rawId}`;
|
|
808
|
+
const height = typeof size === "number" ? `${size}px` : size;
|
|
809
|
+
return /* @__PURE__ */ jsx11(
|
|
810
|
+
"span",
|
|
811
|
+
{
|
|
812
|
+
"aria-hidden": ariaHidden || void 0,
|
|
813
|
+
"aria-label": ariaHidden ? void 0 : label,
|
|
814
|
+
className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
|
|
815
|
+
role: ariaHidden ? void 0 : "status",
|
|
816
|
+
style,
|
|
817
|
+
children: /* @__PURE__ */ jsxs10("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
|
|
818
|
+
/* @__PURE__ */ jsxs10("defs", { children: [
|
|
819
|
+
/* @__PURE__ */ jsxs10("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
|
|
820
|
+
/* @__PURE__ */ jsx11("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
|
|
821
|
+
/* @__PURE__ */ jsx11("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
|
|
822
|
+
] }),
|
|
823
|
+
/* @__PURE__ */ jsxs10("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
|
|
824
|
+
/* @__PURE__ */ jsx11("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
|
|
825
|
+
/* @__PURE__ */ jsx11("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
|
|
826
|
+
/* @__PURE__ */ jsx11("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
|
|
827
|
+
] }),
|
|
828
|
+
/* @__PURE__ */ jsxs10("clipPath", { id: clipId, children: [
|
|
829
|
+
/* @__PURE__ */ jsx11("path", { d: LEFT }),
|
|
830
|
+
/* @__PURE__ */ jsx11("path", { d: CENTER }),
|
|
831
|
+
/* @__PURE__ */ jsx11("path", { d: RIGHT })
|
|
832
|
+
] })
|
|
833
|
+
] }),
|
|
834
|
+
/* @__PURE__ */ jsx11("path", { d: CENTER, fill: `url(#${gradientId})` }),
|
|
835
|
+
/* @__PURE__ */ jsx11("path", { d: RIGHT, fill: `url(#${gradientId})` }),
|
|
836
|
+
/* @__PURE__ */ jsx11("path", { d: LEFT, fill: `url(#${gradientId})` }),
|
|
837
|
+
/* @__PURE__ */ jsx11("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ jsx11("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ jsx11("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
|
|
838
|
+
] })
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
|
|
437
843
|
// src/components/Modal/Modal.tsx
|
|
438
|
-
import { jsx as
|
|
439
|
-
var CloseIcon = () => /* @__PURE__ */
|
|
440
|
-
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, size = "sm", className }) {
|
|
441
|
-
useEscapeDismiss(80, onClose, open && !noClose);
|
|
844
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
845
|
+
var CloseIcon = () => /* @__PURE__ */ jsx12("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx12("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
846
|
+
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", scrollable = false, className }) {
|
|
847
|
+
useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
|
|
442
848
|
if (!open) return null;
|
|
443
849
|
const sizeClass = `fractal-modal-panel--${size}`;
|
|
444
850
|
const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
|
|
445
851
|
return createPortal(
|
|
446
|
-
/* @__PURE__ */
|
|
852
|
+
/* @__PURE__ */ jsx12("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ jsxs11(
|
|
447
853
|
"div",
|
|
448
854
|
{
|
|
449
|
-
className: cn("fractal-modal-panel", sizeClass, accentClass, className),
|
|
855
|
+
className: cn("fractal-modal-panel", sizeClass, accentClass, scrollable && "fractal-modal-panel--scrollable", className),
|
|
450
856
|
onClick: (e) => e.stopPropagation(),
|
|
451
857
|
children: [
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
!noClose && /* @__PURE__ */
|
|
858
|
+
/* @__PURE__ */ jsxs11("div", { className: "fractal-modal-title-row", children: [
|
|
859
|
+
/* @__PURE__ */ jsx12("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
|
|
860
|
+
!noClose && /* @__PURE__ */ jsx12("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ jsx12(CloseIcon, {}) })
|
|
455
861
|
] }),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
|
|
862
|
+
/* @__PURE__ */ jsx12(
|
|
863
|
+
"div",
|
|
864
|
+
{
|
|
865
|
+
"aria-busy": loading || void 0,
|
|
866
|
+
className: cn(
|
|
867
|
+
"fractal-modal-body",
|
|
868
|
+
size === "lg" && "fractal-modal-body--lg",
|
|
869
|
+
loading && "fractal-modal-body--loading",
|
|
870
|
+
scrollable && "fractal-modal-body--scrollable"
|
|
871
|
+
),
|
|
872
|
+
children: loading ? /* @__PURE__ */ jsx12(UILoader, { label: loadingLabel }) : children
|
|
873
|
+
}
|
|
874
|
+
),
|
|
875
|
+
footer && /* @__PURE__ */ jsx12("div", { className: cn("fractal-modal-footer", scrollable && "fractal-modal-footer--divided"), children: footer })
|
|
458
876
|
]
|
|
459
877
|
}
|
|
460
878
|
) }),
|
|
@@ -463,17 +881,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
|
|
|
463
881
|
}
|
|
464
882
|
|
|
465
883
|
// src/components/DataTable/DataTable.tsx
|
|
466
|
-
import { jsx as
|
|
884
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
467
885
|
function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
|
|
468
|
-
return /* @__PURE__ */
|
|
469
|
-
header && /* @__PURE__ */
|
|
470
|
-
data.length === 0 ? /* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */
|
|
472
|
-
/* @__PURE__ */
|
|
886
|
+
return /* @__PURE__ */ jsx13("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ jsxs12("div", { className: "fractal-datatable-surface", children: [
|
|
887
|
+
header && /* @__PURE__ */ jsx13("div", { className: "fractal-datatable-header", children: header }),
|
|
888
|
+
data.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs12("table", { className: "fractal-datatable-table", children: [
|
|
889
|
+
/* @__PURE__ */ jsx13("thead", { children: /* @__PURE__ */ jsx13("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ jsx13("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
|
|
890
|
+
/* @__PURE__ */ jsx13("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx13(
|
|
473
891
|
"tr",
|
|
474
892
|
{
|
|
475
893
|
className: "fractal-datatable-row",
|
|
476
|
-
children: columns.map((col) => /* @__PURE__ */
|
|
894
|
+
children: columns.map((col) => /* @__PURE__ */ jsx13("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
|
|
477
895
|
},
|
|
478
896
|
rowIndex
|
|
479
897
|
)) })
|
|
@@ -482,9 +900,9 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
|
|
|
482
900
|
}
|
|
483
901
|
|
|
484
902
|
// src/components/Dropdown/Dropdown.tsx
|
|
485
|
-
import * as
|
|
903
|
+
import * as React9 from "react";
|
|
486
904
|
import { ChevronDown, ChevronUp } from "@mirror-physics/fractal-icons";
|
|
487
|
-
import { Fragment as Fragment2, jsx as
|
|
905
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
488
906
|
var MARGIN = 4;
|
|
489
907
|
function Dropdown({
|
|
490
908
|
items,
|
|
@@ -495,18 +913,20 @@ function Dropdown({
|
|
|
495
913
|
align = "left",
|
|
496
914
|
triggerContent,
|
|
497
915
|
label,
|
|
916
|
+
iconOnly = false,
|
|
498
917
|
noChevron = false,
|
|
499
918
|
size = "md",
|
|
500
919
|
triggerVariant = "outline",
|
|
501
920
|
className,
|
|
502
921
|
triggerClassName,
|
|
503
922
|
panelClassName,
|
|
504
|
-
closeOnSelect = true
|
|
923
|
+
closeOnSelect = true,
|
|
924
|
+
disabled = false
|
|
505
925
|
}) {
|
|
506
|
-
const [open, setOpen] =
|
|
507
|
-
const triggerRef =
|
|
508
|
-
const panelRef =
|
|
509
|
-
const [panelStyle, setPanelStyle] =
|
|
926
|
+
const [open, setOpen] = React9.useState(false);
|
|
927
|
+
const triggerRef = React9.useRef(null);
|
|
928
|
+
const panelRef = React9.useRef(null);
|
|
929
|
+
const [panelStyle, setPanelStyle] = React9.useState({});
|
|
510
930
|
const visibleItems = items.filter(
|
|
511
931
|
(item) => item.icon != null || item.description != null && (typeof item.description === "string" ? item.description !== "" : true)
|
|
512
932
|
);
|
|
@@ -515,7 +935,7 @@ function Dropdown({
|
|
|
515
935
|
const selected = items.find((i) => i.value === selectedValue && i.kind !== "header") ?? selectableItems[0] ?? visibleItems[0];
|
|
516
936
|
const isUp = direction === "up";
|
|
517
937
|
const ChevronIcon = isUp ? ChevronUp : ChevronDown;
|
|
518
|
-
|
|
938
|
+
React9.useLayoutEffect(() => {
|
|
519
939
|
if (!open || !triggerRef.current || !panelRef.current) return;
|
|
520
940
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
521
941
|
const panelRect = panelRef.current.getBoundingClientRect();
|
|
@@ -549,7 +969,7 @@ function Dropdown({
|
|
|
549
969
|
}
|
|
550
970
|
setPanelStyle({ top, left, right });
|
|
551
971
|
}, [open, isUp, align]);
|
|
552
|
-
|
|
972
|
+
React9.useEffect(() => {
|
|
553
973
|
if (!open) return;
|
|
554
974
|
const handleClickOutside = (e) => {
|
|
555
975
|
const target = e.target;
|
|
@@ -559,12 +979,13 @@ function Dropdown({
|
|
|
559
979
|
document.addEventListener("mousedown", handleClickOutside);
|
|
560
980
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
561
981
|
}, [open]);
|
|
562
|
-
return /* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
982
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("fractal-dropdown", className), children: [
|
|
983
|
+
/* @__PURE__ */ jsxs13(
|
|
564
984
|
"button",
|
|
565
985
|
{
|
|
566
986
|
ref: triggerRef,
|
|
567
987
|
type: "button",
|
|
988
|
+
disabled,
|
|
568
989
|
"aria-haspopup": "listbox",
|
|
569
990
|
"aria-expanded": open,
|
|
570
991
|
"aria-label": triggerLabel,
|
|
@@ -573,18 +994,19 @@ function Dropdown({
|
|
|
573
994
|
"fractal-dropdown-trigger",
|
|
574
995
|
`fractal-dropdown-trigger--${size}`,
|
|
575
996
|
`fractal-dropdown-trigger--${triggerVariant}`,
|
|
997
|
+
iconOnly && "fractal-dropdown-trigger--icon-only",
|
|
576
998
|
triggerClassName
|
|
577
999
|
),
|
|
578
1000
|
children: [
|
|
579
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */
|
|
580
|
-
selected.icon != null && /* @__PURE__ */
|
|
581
|
-
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */
|
|
1001
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
1002
|
+
selected.icon != null && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
|
|
1003
|
+
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-selected-text", children: selected.description })
|
|
582
1004
|
] }),
|
|
583
|
-
!noChevron && /* @__PURE__ */
|
|
1005
|
+
!noChevron && !iconOnly && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ jsx14(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
|
|
584
1006
|
]
|
|
585
1007
|
}
|
|
586
1008
|
),
|
|
587
|
-
open && /* @__PURE__ */
|
|
1009
|
+
open && /* @__PURE__ */ jsxs13(
|
|
588
1010
|
"div",
|
|
589
1011
|
{
|
|
590
1012
|
ref: panelRef,
|
|
@@ -593,21 +1015,21 @@ function Dropdown({
|
|
|
593
1015
|
className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
|
|
594
1016
|
style: panelStyle,
|
|
595
1017
|
children: [
|
|
596
|
-
label != null && /* @__PURE__ */
|
|
1018
|
+
label != null && /* @__PURE__ */ jsx14("div", { className: "fractal-dropdown-label", children: label }),
|
|
597
1019
|
visibleItems.map((item, index) => {
|
|
598
|
-
const topDivider = item.border === "top" ? /* @__PURE__ */
|
|
599
|
-
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */
|
|
1020
|
+
const topDivider = item.border === "top" ? /* @__PURE__ */ jsx14("div", { className: "fractal-dropdown-separator" }) : null;
|
|
1021
|
+
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ jsx14("div", { className: "fractal-dropdown-separator" }) : null;
|
|
600
1022
|
if (item.kind === "header") {
|
|
601
|
-
return /* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsxs13(React9.Fragment, { children: [
|
|
602
1024
|
topDivider,
|
|
603
|
-
/* @__PURE__ */
|
|
1025
|
+
/* @__PURE__ */ jsx14("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
|
|
604
1026
|
bottomDivider
|
|
605
1027
|
] }, `header-${index}`);
|
|
606
1028
|
}
|
|
607
1029
|
const isSelected = item.value === selectedValue;
|
|
608
|
-
return /* @__PURE__ */
|
|
1030
|
+
return /* @__PURE__ */ jsxs13(React9.Fragment, { children: [
|
|
609
1031
|
topDivider,
|
|
610
|
-
/* @__PURE__ */
|
|
1032
|
+
/* @__PURE__ */ jsxs13(
|
|
611
1033
|
"button",
|
|
612
1034
|
{
|
|
613
1035
|
type: "button",
|
|
@@ -619,9 +1041,9 @@ function Dropdown({
|
|
|
619
1041
|
},
|
|
620
1042
|
className: "fractal-dropdown-option",
|
|
621
1043
|
children: [
|
|
622
|
-
item.icon != null && /* @__PURE__ */
|
|
623
|
-
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */
|
|
624
|
-
item.trailing != null && /* @__PURE__ */
|
|
1044
|
+
item.icon != null && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-icon", children: item.icon }),
|
|
1045
|
+
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-option-text", children: item.description }),
|
|
1046
|
+
item.trailing != null && /* @__PURE__ */ jsx14("span", { className: "fractal-dropdown-trailing", children: item.trailing })
|
|
625
1047
|
]
|
|
626
1048
|
}
|
|
627
1049
|
),
|
|
@@ -635,10 +1057,10 @@ function Dropdown({
|
|
|
635
1057
|
}
|
|
636
1058
|
|
|
637
1059
|
// src/components/Link/Link.tsx
|
|
638
|
-
import * as
|
|
639
|
-
import { jsx as
|
|
640
|
-
var Link =
|
|
641
|
-
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */
|
|
1060
|
+
import * as React10 from "react";
|
|
1061
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1062
|
+
var Link = React10.forwardRef(
|
|
1063
|
+
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
642
1064
|
"a",
|
|
643
1065
|
{
|
|
644
1066
|
ref,
|
|
@@ -650,10 +1072,10 @@ var Link = React8.forwardRef(
|
|
|
650
1072
|
Link.displayName = "Link";
|
|
651
1073
|
|
|
652
1074
|
// src/components/Chip/Chip.tsx
|
|
653
|
-
import * as
|
|
654
|
-
import { jsx as
|
|
655
|
-
var Chip =
|
|
656
|
-
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */
|
|
1075
|
+
import * as React11 from "react";
|
|
1076
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1077
|
+
var Chip = React11.forwardRef(
|
|
1078
|
+
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
657
1079
|
"span",
|
|
658
1080
|
{
|
|
659
1081
|
ref,
|
|
@@ -664,36 +1086,86 @@ var Chip = React9.forwardRef(
|
|
|
664
1086
|
);
|
|
665
1087
|
Chip.displayName = "Chip";
|
|
666
1088
|
|
|
1089
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
1090
|
+
import { Checkbox as CheckboxIcon, CheckboxChecked, Minus as Minus2 } from "@mirror-physics/fractal-icons";
|
|
1091
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1092
|
+
function Checkbox({
|
|
1093
|
+
checked,
|
|
1094
|
+
indeterminate = false,
|
|
1095
|
+
onCheckedChange,
|
|
1096
|
+
className,
|
|
1097
|
+
disabled,
|
|
1098
|
+
onClick,
|
|
1099
|
+
onKeyDown,
|
|
1100
|
+
...props
|
|
1101
|
+
}) {
|
|
1102
|
+
return /* @__PURE__ */ jsx17(
|
|
1103
|
+
"button",
|
|
1104
|
+
{
|
|
1105
|
+
...props,
|
|
1106
|
+
className: cn(
|
|
1107
|
+
"fractal-checkbox",
|
|
1108
|
+
(checked || indeterminate) && "fractal-checkbox--checked",
|
|
1109
|
+
indeterminate && "fractal-checkbox--indeterminate",
|
|
1110
|
+
className
|
|
1111
|
+
),
|
|
1112
|
+
type: "button",
|
|
1113
|
+
role: "checkbox",
|
|
1114
|
+
"aria-checked": indeterminate ? "mixed" : checked,
|
|
1115
|
+
disabled,
|
|
1116
|
+
onClick: (event) => {
|
|
1117
|
+
onClick?.(event);
|
|
1118
|
+
if (!event.defaultPrevented) onCheckedChange(indeterminate || !checked);
|
|
1119
|
+
},
|
|
1120
|
+
onKeyDown: (event) => {
|
|
1121
|
+
onKeyDown?.(event);
|
|
1122
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
1123
|
+
},
|
|
1124
|
+
children: indeterminate ? /* @__PURE__ */ jsxs14("span", { className: "fractal-checkbox__indeterminate-icon", "aria-hidden": "true", children: [
|
|
1125
|
+
/* @__PURE__ */ jsx17(CheckboxIcon, { size: 18 }),
|
|
1126
|
+
/* @__PURE__ */ jsx17(Minus2, { className: "fractal-checkbox__indeterminate-mark", size: 12 })
|
|
1127
|
+
] }) : checked ? /* @__PURE__ */ jsx17(CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ jsx17(CheckboxIcon, { "aria-hidden": "true", size: 18 })
|
|
1128
|
+
}
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
667
1132
|
// src/components/SortableTable/SortableTable.tsx
|
|
668
|
-
import { useMemo, useState as
|
|
1133
|
+
import { useMemo as useMemo2, useState as useState5 } from "react";
|
|
669
1134
|
import { ArrowUp, ArrowDown, ArrowsUpDown } from "@mirror-physics/fractal-icons";
|
|
670
|
-
import { jsx as
|
|
1135
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
671
1136
|
function SortableTable({
|
|
672
1137
|
columns,
|
|
673
1138
|
data,
|
|
674
1139
|
emptyMessage,
|
|
675
1140
|
header,
|
|
676
1141
|
size = "md",
|
|
1142
|
+
embedded = false,
|
|
677
1143
|
className,
|
|
1144
|
+
defaultSort,
|
|
678
1145
|
defaultSortKey = void 0,
|
|
679
1146
|
defaultSortDirection = null,
|
|
680
1147
|
sortKey: controlledKey,
|
|
681
1148
|
sortDirection: controlledDirection,
|
|
682
1149
|
onSortChange,
|
|
683
1150
|
highlightRow,
|
|
684
|
-
onRowClick
|
|
1151
|
+
onRowClick,
|
|
1152
|
+
rowAction
|
|
685
1153
|
}) {
|
|
686
|
-
const [internalKey, setInternalKey] =
|
|
687
|
-
const [internalDirection, setInternalDirection] =
|
|
1154
|
+
const [internalKey, setInternalKey] = useState5(defaultSortKey ?? null);
|
|
1155
|
+
const [internalDirection, setInternalDirection] = useState5(defaultSortDirection);
|
|
688
1156
|
const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
|
|
689
1157
|
const activeKey = isControlled ? controlledKey : internalKey;
|
|
690
1158
|
const activeDirection = isControlled ? controlledDirection : internalDirection;
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
1159
|
+
const baselineKey = defaultSort?.key ?? null;
|
|
1160
|
+
const baselineDirection = defaultSort?.direction ?? null;
|
|
1161
|
+
const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
|
|
1162
|
+
const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
|
|
1163
|
+
const sorted = useMemo2(() => {
|
|
1164
|
+
if (!effectiveKey || !effectiveDirection) return data;
|
|
1165
|
+
const col = columns.find((c) => c.key === effectiveKey);
|
|
694
1166
|
if (!col) return data;
|
|
695
1167
|
const accessor = col.sortAccessor ?? ((row) => {
|
|
696
|
-
const value = row[
|
|
1168
|
+
const value = row[effectiveKey];
|
|
697
1169
|
return typeof value === "string" || typeof value === "number" ? value : null;
|
|
698
1170
|
});
|
|
699
1171
|
const copy = [...data];
|
|
@@ -704,26 +1176,28 @@ function SortableTable({
|
|
|
704
1176
|
if (av == null) return 1;
|
|
705
1177
|
if (bv == null) return -1;
|
|
706
1178
|
if (typeof av === "number" && typeof bv === "number") {
|
|
707
|
-
return
|
|
1179
|
+
return effectiveDirection === "asc" ? av - bv : bv - av;
|
|
708
1180
|
}
|
|
709
1181
|
const as = String(av).toLowerCase();
|
|
710
1182
|
const bs = String(bv).toLowerCase();
|
|
711
|
-
if (as < bs) return
|
|
712
|
-
if (as > bs) return
|
|
1183
|
+
if (as < bs) return effectiveDirection === "asc" ? -1 : 1;
|
|
1184
|
+
if (as > bs) return effectiveDirection === "asc" ? 1 : -1;
|
|
713
1185
|
return 0;
|
|
714
1186
|
});
|
|
715
1187
|
return copy;
|
|
716
|
-
}, [data, columns,
|
|
1188
|
+
}, [data, columns, effectiveKey, effectiveDirection]);
|
|
717
1189
|
const handleSortClick = (key) => {
|
|
718
1190
|
let nextDirection;
|
|
719
|
-
if (activeKey
|
|
1191
|
+
if (!activeKey || !activeDirection) {
|
|
1192
|
+
nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
|
|
1193
|
+
} else if (activeKey !== key) {
|
|
720
1194
|
nextDirection = "asc";
|
|
1195
|
+
} else if (baselineKey === key && baselineDirection) {
|
|
1196
|
+
nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
|
|
721
1197
|
} else if (activeDirection === "asc") {
|
|
722
1198
|
nextDirection = "desc";
|
|
723
|
-
} else if (activeDirection === "desc") {
|
|
724
|
-
nextDirection = null;
|
|
725
1199
|
} else {
|
|
726
|
-
nextDirection =
|
|
1200
|
+
nextDirection = null;
|
|
727
1201
|
}
|
|
728
1202
|
const nextKey = nextDirection === null ? null : key;
|
|
729
1203
|
if (isControlled) {
|
|
@@ -734,13 +1208,13 @@ function SortableTable({
|
|
|
734
1208
|
onSortChange?.(nextKey, nextDirection);
|
|
735
1209
|
}
|
|
736
1210
|
};
|
|
737
|
-
return /* @__PURE__ */
|
|
738
|
-
header && /* @__PURE__ */
|
|
739
|
-
sorted.length === 0 ? /* @__PURE__ */
|
|
740
|
-
/* @__PURE__ */
|
|
1211
|
+
return /* @__PURE__ */ jsx18("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ jsxs15("div", { className: "fractal-sortable-table-surface", children: [
|
|
1212
|
+
header && /* @__PURE__ */ jsx18("div", { className: "fractal-sortable-table-header", children: header }),
|
|
1213
|
+
sorted.length === 0 ? /* @__PURE__ */ jsx18("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs15("table", { className: "fractal-sortable-table-table", children: [
|
|
1214
|
+
/* @__PURE__ */ jsx18("thead", { children: /* @__PURE__ */ jsx18("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
|
|
741
1215
|
const isActive = activeKey === col.key && activeDirection !== null;
|
|
742
1216
|
if (!col.sortable) {
|
|
743
|
-
return /* @__PURE__ */
|
|
1217
|
+
return /* @__PURE__ */ jsx18(
|
|
744
1218
|
"th",
|
|
745
1219
|
{
|
|
746
1220
|
className: "fractal-sortable-table-th",
|
|
@@ -750,12 +1224,12 @@ function SortableTable({
|
|
|
750
1224
|
col.key
|
|
751
1225
|
);
|
|
752
1226
|
}
|
|
753
|
-
return /* @__PURE__ */
|
|
1227
|
+
return /* @__PURE__ */ jsx18(
|
|
754
1228
|
"th",
|
|
755
1229
|
{
|
|
756
1230
|
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
757
1231
|
style: { width: col.width },
|
|
758
|
-
children: /* @__PURE__ */
|
|
1232
|
+
children: /* @__PURE__ */ jsxs15(
|
|
759
1233
|
"button",
|
|
760
1234
|
{
|
|
761
1235
|
type: "button",
|
|
@@ -766,8 +1240,8 @@ function SortableTable({
|
|
|
766
1240
|
onClick: () => handleSortClick(col.key),
|
|
767
1241
|
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
768
1242
|
children: [
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
1243
|
+
/* @__PURE__ */ jsx18("span", { children: col.header }),
|
|
1244
|
+
/* @__PURE__ */ jsx18("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ jsx18(ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ jsx18(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx18(ArrowsUpDown, { size: 14 }) })
|
|
771
1245
|
]
|
|
772
1246
|
}
|
|
773
1247
|
)
|
|
@@ -775,9 +1249,13 @@ function SortableTable({
|
|
|
775
1249
|
col.key
|
|
776
1250
|
);
|
|
777
1251
|
}) }) }),
|
|
778
|
-
/* @__PURE__ */
|
|
1252
|
+
/* @__PURE__ */ jsx18("tbody", { children: sorted.map((row, rowIndex) => {
|
|
779
1253
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
780
|
-
|
|
1254
|
+
const action = rowAction ? {
|
|
1255
|
+
label: rowAction.label(row, rowIndex),
|
|
1256
|
+
icon: rowAction.icon(row, rowIndex)
|
|
1257
|
+
} : null;
|
|
1258
|
+
return /* @__PURE__ */ jsx18(
|
|
781
1259
|
"tr",
|
|
782
1260
|
{
|
|
783
1261
|
className: cn(
|
|
@@ -792,14 +1270,21 @@ function SortableTable({
|
|
|
792
1270
|
onRowClick(row, rowIndex);
|
|
793
1271
|
}
|
|
794
1272
|
} : void 0,
|
|
1273
|
+
"aria-label": action?.label,
|
|
795
1274
|
role: onRowClick ? "button" : void 0,
|
|
796
1275
|
tabIndex: onRowClick ? 0 : void 0,
|
|
797
|
-
children: columns.map((col) => /* @__PURE__ */
|
|
1276
|
+
children: columns.map((col, columnIndex) => /* @__PURE__ */ jsxs15(
|
|
798
1277
|
"td",
|
|
799
1278
|
{
|
|
800
|
-
className:
|
|
1279
|
+
className: cn(
|
|
1280
|
+
"fractal-sortable-table-td",
|
|
1281
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
1282
|
+
),
|
|
801
1283
|
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
802
|
-
children:
|
|
1284
|
+
children: [
|
|
1285
|
+
col.render(row, rowIndex),
|
|
1286
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ jsx18("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ jsx18("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
1287
|
+
]
|
|
803
1288
|
},
|
|
804
1289
|
col.key
|
|
805
1290
|
))
|
|
@@ -812,23 +1297,40 @@ function SortableTable({
|
|
|
812
1297
|
}
|
|
813
1298
|
|
|
814
1299
|
// src/components/Tabs/Tabs.tsx
|
|
815
|
-
import { useId, useRef as
|
|
816
|
-
import { jsx as
|
|
1300
|
+
import { useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "react";
|
|
1301
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
817
1302
|
function Tabs({
|
|
818
1303
|
items,
|
|
819
1304
|
defaultValue,
|
|
820
1305
|
value: controlledValue,
|
|
821
1306
|
onValueChange,
|
|
822
1307
|
className,
|
|
823
|
-
ariaLabel
|
|
1308
|
+
ariaLabel,
|
|
1309
|
+
divider = false,
|
|
1310
|
+
variant = "line"
|
|
824
1311
|
}) {
|
|
825
|
-
const reactId =
|
|
826
|
-
const [internalValue, setInternalValue] =
|
|
1312
|
+
const reactId = useId2();
|
|
1313
|
+
const [internalValue, setInternalValue] = useState6(
|
|
827
1314
|
defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
|
|
828
1315
|
);
|
|
829
1316
|
const isControlled = controlledValue !== void 0;
|
|
830
1317
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
831
|
-
const
|
|
1318
|
+
const tabListRef = useRef5(null);
|
|
1319
|
+
const tabRefs = useRef5({});
|
|
1320
|
+
const [indicator, setIndicator] = useState6(null);
|
|
1321
|
+
useLayoutEffect2(() => {
|
|
1322
|
+
const updateIndicator = () => {
|
|
1323
|
+
const activeTab = tabRefs.current[activeId];
|
|
1324
|
+
if (!activeTab) return;
|
|
1325
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
1326
|
+
};
|
|
1327
|
+
updateIndicator();
|
|
1328
|
+
const list = tabListRef.current;
|
|
1329
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
1330
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
1331
|
+
observer.observe(list);
|
|
1332
|
+
return () => observer.disconnect();
|
|
1333
|
+
}, [activeId, items.length]);
|
|
832
1334
|
const selectTab = (id) => {
|
|
833
1335
|
if (isControlled) {
|
|
834
1336
|
onValueChange?.(id);
|
|
@@ -838,6 +1340,10 @@ function Tabs({
|
|
|
838
1340
|
}
|
|
839
1341
|
};
|
|
840
1342
|
const focusable = items.filter((i) => !i.disabled);
|
|
1343
|
+
const indicatorStyle = indicator ? {
|
|
1344
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
1345
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
1346
|
+
} : void 0;
|
|
841
1347
|
const onKeyDown = (event) => {
|
|
842
1348
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
843
1349
|
if (currentIndex === -1) return;
|
|
@@ -863,41 +1369,52 @@ function Tabs({
|
|
|
863
1369
|
selectTab(nextId2);
|
|
864
1370
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
865
1371
|
};
|
|
866
|
-
return /* @__PURE__ */
|
|
867
|
-
/* @__PURE__ */
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
"
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
id
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1372
|
+
return /* @__PURE__ */ jsxs16("div", { className: cn("fractal-tabs", `fractal-tabs--${variant}`, divider && "fractal-tabs--divider", className), children: [
|
|
1373
|
+
/* @__PURE__ */ jsx19(
|
|
1374
|
+
"div",
|
|
1375
|
+
{
|
|
1376
|
+
ref: tabListRef,
|
|
1377
|
+
role: "tablist",
|
|
1378
|
+
"aria-label": ariaLabel,
|
|
1379
|
+
className: "fractal-tabs-list",
|
|
1380
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
1381
|
+
style: indicatorStyle,
|
|
1382
|
+
children: items.map((item) => {
|
|
1383
|
+
const isActive = item.id === activeId;
|
|
1384
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
1385
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
1386
|
+
return /* @__PURE__ */ jsx19(
|
|
1387
|
+
"button",
|
|
1388
|
+
{
|
|
1389
|
+
ref: (el) => {
|
|
1390
|
+
tabRefs.current[item.id] = el;
|
|
1391
|
+
},
|
|
1392
|
+
id: tabId,
|
|
1393
|
+
role: "tab",
|
|
1394
|
+
type: "button",
|
|
1395
|
+
"aria-selected": isActive,
|
|
1396
|
+
"aria-controls": panelId,
|
|
1397
|
+
tabIndex: isActive ? 0 : -1,
|
|
1398
|
+
disabled: item.disabled,
|
|
1399
|
+
className: cn(
|
|
1400
|
+
"fractal-tabs-trigger",
|
|
1401
|
+
isActive && "fractal-tabs-trigger--active",
|
|
1402
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
1403
|
+
),
|
|
1404
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
1405
|
+
onKeyDown,
|
|
1406
|
+
children: item.label
|
|
1407
|
+
},
|
|
1408
|
+
item.id
|
|
1409
|
+
);
|
|
1410
|
+
})
|
|
1411
|
+
}
|
|
1412
|
+
),
|
|
896
1413
|
items.map((item) => {
|
|
897
1414
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
898
1415
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
899
1416
|
const isActive = item.id === activeId;
|
|
900
|
-
return /* @__PURE__ */
|
|
1417
|
+
return /* @__PURE__ */ jsx19(
|
|
901
1418
|
"div",
|
|
902
1419
|
{
|
|
903
1420
|
id: panelId,
|
|
@@ -913,10 +1430,112 @@ function Tabs({
|
|
|
913
1430
|
] });
|
|
914
1431
|
}
|
|
915
1432
|
|
|
1433
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
1434
|
+
import * as React12 from "react";
|
|
1435
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1436
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
1437
|
+
const switcherRef = React12.useRef(null);
|
|
1438
|
+
const buttonRefs = React12.useRef([]);
|
|
1439
|
+
const indicatorMotionReadyRef = React12.useRef(false);
|
|
1440
|
+
const activeIndex = items.findIndex((item) => item.value === value);
|
|
1441
|
+
React12.useLayoutEffect(() => {
|
|
1442
|
+
const switcher = switcherRef.current;
|
|
1443
|
+
const activeButton = buttonRefs.current[activeIndex];
|
|
1444
|
+
let motionFrame = 0;
|
|
1445
|
+
if (!switcher || !activeButton) {
|
|
1446
|
+
switcher?.removeAttribute("data-indicator-ready");
|
|
1447
|
+
switcher?.removeAttribute("data-indicator-animate");
|
|
1448
|
+
indicatorMotionReadyRef.current = false;
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
const updateIndicator = () => {
|
|
1452
|
+
const switcherRect = switcher.getBoundingClientRect();
|
|
1453
|
+
const activeButtonRect = activeButton.getBoundingClientRect();
|
|
1454
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
|
|
1455
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
|
|
1456
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
|
|
1457
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
|
|
1458
|
+
switcher.setAttribute("data-indicator-ready", "true");
|
|
1459
|
+
if (!indicatorMotionReadyRef.current && motionFrame === 0) {
|
|
1460
|
+
motionFrame = window.requestAnimationFrame(() => {
|
|
1461
|
+
indicatorMotionReadyRef.current = true;
|
|
1462
|
+
switcher.setAttribute("data-indicator-animate", "true");
|
|
1463
|
+
motionFrame = 0;
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
updateIndicator();
|
|
1468
|
+
if (typeof ResizeObserver === "undefined") {
|
|
1469
|
+
return () => {
|
|
1470
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
const resizeObserver = new ResizeObserver(updateIndicator);
|
|
1474
|
+
resizeObserver.observe(switcher);
|
|
1475
|
+
buttonRefs.current.forEach((button) => {
|
|
1476
|
+
if (button) resizeObserver.observe(button);
|
|
1477
|
+
});
|
|
1478
|
+
return () => {
|
|
1479
|
+
resizeObserver.disconnect();
|
|
1480
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1481
|
+
};
|
|
1482
|
+
}, [activeIndex, items.length]);
|
|
1483
|
+
const moveFocus = (index, direction) => {
|
|
1484
|
+
let nextIndex = index;
|
|
1485
|
+
do {
|
|
1486
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
1487
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
1488
|
+
if (!items[nextIndex]?.disabled) {
|
|
1489
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
1490
|
+
onValueChange(items[nextIndex].value);
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
return /* @__PURE__ */ jsxs17(
|
|
1494
|
+
"div",
|
|
1495
|
+
{
|
|
1496
|
+
className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
|
|
1497
|
+
role: "group",
|
|
1498
|
+
"aria-label": ariaLabel,
|
|
1499
|
+
ref: switcherRef,
|
|
1500
|
+
children: [
|
|
1501
|
+
/* @__PURE__ */ jsx20("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
|
|
1502
|
+
items.map((item, index) => {
|
|
1503
|
+
const active = item.value === value;
|
|
1504
|
+
return /* @__PURE__ */ jsx20(
|
|
1505
|
+
"button",
|
|
1506
|
+
{
|
|
1507
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1508
|
+
type: "button",
|
|
1509
|
+
"aria-pressed": active,
|
|
1510
|
+
disabled: item.disabled,
|
|
1511
|
+
onClick: () => onValueChange(item.value),
|
|
1512
|
+
onKeyDown: (event) => {
|
|
1513
|
+
if (event.key === "ArrowRight") {
|
|
1514
|
+
event.preventDefault();
|
|
1515
|
+
moveFocus(index, 1);
|
|
1516
|
+
}
|
|
1517
|
+
if (event.key === "ArrowLeft") {
|
|
1518
|
+
event.preventDefault();
|
|
1519
|
+
moveFocus(index, -1);
|
|
1520
|
+
}
|
|
1521
|
+
},
|
|
1522
|
+
ref: (element) => {
|
|
1523
|
+
buttonRefs.current[index] = element;
|
|
1524
|
+
},
|
|
1525
|
+
children: item.label
|
|
1526
|
+
},
|
|
1527
|
+
item.value
|
|
1528
|
+
);
|
|
1529
|
+
})
|
|
1530
|
+
]
|
|
1531
|
+
}
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
916
1535
|
// src/components/Disclosure/Disclosure.tsx
|
|
917
|
-
import { useId as
|
|
918
|
-
import { ChevronRight, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
919
|
-
import { jsx as
|
|
1536
|
+
import { useId as useId3, useState as useState7 } from "react";
|
|
1537
|
+
import { ChevronRight as ChevronRight2, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
1538
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
920
1539
|
function Disclosure({
|
|
921
1540
|
title,
|
|
922
1541
|
meta,
|
|
@@ -924,16 +1543,18 @@ function Disclosure({
|
|
|
924
1543
|
defaultOpen = false,
|
|
925
1544
|
open: controlledOpen,
|
|
926
1545
|
onOpenChange,
|
|
1546
|
+
disabled = false,
|
|
927
1547
|
className,
|
|
928
1548
|
variant = "card"
|
|
929
1549
|
}) {
|
|
930
|
-
const reactId =
|
|
1550
|
+
const reactId = useId3();
|
|
931
1551
|
const headerId = `${reactId}-header`;
|
|
932
1552
|
const panelId = `${reactId}-panel`;
|
|
933
|
-
const [internalOpen, setInternalOpen] =
|
|
1553
|
+
const [internalOpen, setInternalOpen] = useState7(defaultOpen);
|
|
934
1554
|
const isControlled = controlledOpen !== void 0;
|
|
935
1555
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
936
1556
|
const toggle = () => {
|
|
1557
|
+
if (disabled) return;
|
|
937
1558
|
const next = !isOpen;
|
|
938
1559
|
if (isControlled) {
|
|
939
1560
|
onOpenChange?.(next);
|
|
@@ -942,17 +1563,18 @@ function Disclosure({
|
|
|
942
1563
|
onOpenChange?.(next);
|
|
943
1564
|
}
|
|
944
1565
|
};
|
|
945
|
-
return /* @__PURE__ */
|
|
1566
|
+
return /* @__PURE__ */ jsxs18(
|
|
946
1567
|
"div",
|
|
947
1568
|
{
|
|
948
1569
|
className: cn(
|
|
949
1570
|
"fractal-disclosure",
|
|
950
1571
|
variant === "card" && "fractal-disclosure--card",
|
|
951
1572
|
isOpen && "fractal-disclosure--open",
|
|
1573
|
+
disabled && "fractal-disclosure--disabled",
|
|
952
1574
|
className
|
|
953
1575
|
),
|
|
954
1576
|
children: [
|
|
955
|
-
/* @__PURE__ */
|
|
1577
|
+
/* @__PURE__ */ jsxs18(
|
|
956
1578
|
"button",
|
|
957
1579
|
{
|
|
958
1580
|
type: "button",
|
|
@@ -960,15 +1582,16 @@ function Disclosure({
|
|
|
960
1582
|
className: "fractal-disclosure-trigger",
|
|
961
1583
|
"aria-expanded": isOpen,
|
|
962
1584
|
"aria-controls": panelId,
|
|
1585
|
+
disabled,
|
|
963
1586
|
onClick: toggle,
|
|
964
1587
|
children: [
|
|
965
|
-
/* @__PURE__ */
|
|
966
|
-
/* @__PURE__ */
|
|
967
|
-
meta && /* @__PURE__ */
|
|
1588
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ jsx21(ChevronDown2, { size: 16 }) : /* @__PURE__ */ jsx21(ChevronRight2, { size: 16 }) }),
|
|
1589
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-disclosure-title", children: title }),
|
|
1590
|
+
meta && /* @__PURE__ */ jsx21("span", { className: "fractal-disclosure-meta", children: meta })
|
|
968
1591
|
]
|
|
969
1592
|
}
|
|
970
1593
|
),
|
|
971
|
-
/* @__PURE__ */
|
|
1594
|
+
/* @__PURE__ */ jsx21(
|
|
972
1595
|
"div",
|
|
973
1596
|
{
|
|
974
1597
|
id: panelId,
|
|
@@ -976,7 +1599,7 @@ function Disclosure({
|
|
|
976
1599
|
"aria-labelledby": headerId,
|
|
977
1600
|
className: "fractal-disclosure-panel",
|
|
978
1601
|
hidden: !isOpen,
|
|
979
|
-
children: /* @__PURE__ */
|
|
1602
|
+
children: /* @__PURE__ */ jsx21("div", { className: "fractal-disclosure-panel-inner", children })
|
|
980
1603
|
}
|
|
981
1604
|
)
|
|
982
1605
|
]
|
|
@@ -984,39 +1607,260 @@ function Disclosure({
|
|
|
984
1607
|
);
|
|
985
1608
|
}
|
|
986
1609
|
|
|
1610
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
1611
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1612
|
+
var LATTICE_COUNT = 160;
|
|
1613
|
+
var WAVE_PERIOD = 80;
|
|
1614
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
1615
|
+
return /* @__PURE__ */ jsx22(
|
|
1616
|
+
"span",
|
|
1617
|
+
{
|
|
1618
|
+
"aria-label": label,
|
|
1619
|
+
className: cn("fractal-lattice-loader", className),
|
|
1620
|
+
role: "progressbar",
|
|
1621
|
+
...props,
|
|
1622
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ jsx22(
|
|
1623
|
+
"span",
|
|
1624
|
+
{
|
|
1625
|
+
"aria-hidden": "true",
|
|
1626
|
+
className: "fractal-lattice-loader__cell",
|
|
1627
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
1628
|
+
},
|
|
1629
|
+
index
|
|
1630
|
+
))
|
|
1631
|
+
}
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// src/components/Ghost/Ghost.tsx
|
|
1636
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1637
|
+
var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
1638
|
+
function Ghost({ className, width, height, radius, style, ...props }) {
|
|
1639
|
+
return /* @__PURE__ */ jsx23(
|
|
1640
|
+
"div",
|
|
1641
|
+
{
|
|
1642
|
+
"aria-hidden": "true",
|
|
1643
|
+
className: cn("fractal-ghost", className),
|
|
1644
|
+
style: {
|
|
1645
|
+
width: toCssLength(width),
|
|
1646
|
+
height: toCssLength(height),
|
|
1647
|
+
borderRadius: toCssLength(radius),
|
|
1648
|
+
...style
|
|
1649
|
+
},
|
|
1650
|
+
...props
|
|
1651
|
+
}
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
function GhostLine({ className, size = "md", width = "100%", ...props }) {
|
|
1655
|
+
return /* @__PURE__ */ jsx23(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
|
|
1656
|
+
}
|
|
1657
|
+
function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
|
|
1658
|
+
return /* @__PURE__ */ jsx23(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
|
|
1659
|
+
}
|
|
1660
|
+
function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
|
|
1661
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
|
|
1662
|
+
showHeader && /* @__PURE__ */ jsx23(GhostLine, { width: "38%" }),
|
|
1663
|
+
/* @__PURE__ */ jsx23("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx23(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
|
|
1664
|
+
] });
|
|
1665
|
+
}
|
|
1666
|
+
function DataTableGhost({
|
|
1667
|
+
className,
|
|
1668
|
+
showHeader = true,
|
|
1669
|
+
headers,
|
|
1670
|
+
columns = 4,
|
|
1671
|
+
rows = 5,
|
|
1672
|
+
columnWidths,
|
|
1673
|
+
size = "md",
|
|
1674
|
+
...props
|
|
1675
|
+
}) {
|
|
1676
|
+
const cells = Array.from({ length: columns }, (_, index) => index);
|
|
1677
|
+
return /* @__PURE__ */ jsx23("div", { "aria-busy": "true", "aria-label": "Loading table", className: cn("fractal-ghost-table", `fractal-ghost-table--${size}`, className), role: "status", ...props, children: /* @__PURE__ */ jsxs19("table", { className: "fractal-ghost-table__table", children: [
|
|
1678
|
+
(showHeader || headers) && /* @__PURE__ */ jsx23("thead", { children: /* @__PURE__ */ jsx23("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ jsx23("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ jsx23(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
|
|
1679
|
+
/* @__PURE__ */ jsx23("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx23("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ jsx23("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ jsx23(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
|
|
1680
|
+
] }) });
|
|
1681
|
+
}
|
|
1682
|
+
function InputGhost({ className, labelWidth = "26%", ...props }) {
|
|
1683
|
+
return /* @__PURE__ */ jsx23(FormFieldGhost, { className, labelWidth, ...props });
|
|
1684
|
+
}
|
|
1685
|
+
function TextareaGhost({ className, labelWidth = "26%", ...props }) {
|
|
1686
|
+
return /* @__PURE__ */ jsx23(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
|
|
1687
|
+
}
|
|
1688
|
+
function LabelGhost({ className, width = "26%", ...props }) {
|
|
1689
|
+
return /* @__PURE__ */ jsx23(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
|
|
1690
|
+
}
|
|
1691
|
+
function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
|
|
1692
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
|
|
1693
|
+
/* @__PURE__ */ jsx23(LabelGhost, { width: labelWidth }),
|
|
1694
|
+
/* @__PURE__ */ jsx23(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
|
|
1695
|
+
] });
|
|
1696
|
+
}
|
|
1697
|
+
function AlertGhost({ className, ...props }) {
|
|
1698
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
|
|
1699
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "30%" }),
|
|
1700
|
+
/* @__PURE__ */ jsx23(GhostLine, { size: "sm", width: "78%" })
|
|
1701
|
+
] });
|
|
1702
|
+
}
|
|
1703
|
+
function CheckboxGhost({ className, ...props }) {
|
|
1704
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
|
|
1705
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-choice__control" }),
|
|
1706
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "42%" })
|
|
1707
|
+
] });
|
|
1708
|
+
}
|
|
1709
|
+
var ToggleGhost = CheckboxGhost;
|
|
1710
|
+
function ChipGhost({ className, width = 74, ...props }) {
|
|
1711
|
+
return /* @__PURE__ */ jsx23(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
|
|
1712
|
+
}
|
|
1713
|
+
function LinkGhost({ className, width = 96, ...props }) {
|
|
1714
|
+
return /* @__PURE__ */ jsx23(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
|
|
1715
|
+
}
|
|
1716
|
+
var TextButtonGhost = LinkGhost;
|
|
1717
|
+
function DropdownGhost({ className, ...props }) {
|
|
1718
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
|
|
1719
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "38%" }),
|
|
1720
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-dropdown__chevron" })
|
|
1721
|
+
] });
|
|
1722
|
+
}
|
|
1723
|
+
function ContentSwitcherGhost({ className, options = 3, ...props }) {
|
|
1724
|
+
return /* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ jsx23(Ghost, {}, index)) });
|
|
1725
|
+
}
|
|
1726
|
+
var TabsGhost = ContentSwitcherGhost;
|
|
1727
|
+
function DisclosureGhost({ className, ...props }) {
|
|
1728
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
|
|
1729
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-disclosure__icon" }),
|
|
1730
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "42%" })
|
|
1731
|
+
] });
|
|
1732
|
+
}
|
|
1733
|
+
function PaginationGhost({ className, pages = 5, ...props }) {
|
|
1734
|
+
return /* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ jsx23(Ghost, {}, index)) });
|
|
1735
|
+
}
|
|
1736
|
+
function FileDropzoneGhost({ className, ...props }) {
|
|
1737
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
|
|
1738
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-dropzone__icon" }),
|
|
1739
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "26%" }),
|
|
1740
|
+
/* @__PURE__ */ jsx23(GhostLine, { size: "sm", width: "46%" })
|
|
1741
|
+
] });
|
|
1742
|
+
}
|
|
1743
|
+
function PromptCardGhost({ className, ...props }) {
|
|
1744
|
+
return /* @__PURE__ */ jsx23(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
|
|
1745
|
+
}
|
|
1746
|
+
function ConversationGhost({
|
|
1747
|
+
className,
|
|
1748
|
+
"aria-label": ariaLabel = "Loading conversation",
|
|
1749
|
+
...props
|
|
1750
|
+
}) {
|
|
1751
|
+
return /* @__PURE__ */ jsxs19(
|
|
1752
|
+
"div",
|
|
1753
|
+
{
|
|
1754
|
+
"aria-busy": "true",
|
|
1755
|
+
"aria-label": ariaLabel,
|
|
1756
|
+
className: cn("fractal-ghost-conversation", className),
|
|
1757
|
+
role: "status",
|
|
1758
|
+
...props,
|
|
1759
|
+
children: [
|
|
1760
|
+
/* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--user", children: /* @__PURE__ */ jsxs19("div", { className: "fractal-ghost-conversation__bubble", children: [
|
|
1761
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "100%" }),
|
|
1762
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "86%" }),
|
|
1763
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "64%" })
|
|
1764
|
+
] }) }),
|
|
1765
|
+
/* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: "fractal-ghost-conversation__message fractal-ghost-conversation__message--assistant", children: [
|
|
1766
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "92%" }),
|
|
1767
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "78%" }),
|
|
1768
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "58%" })
|
|
1769
|
+
] })
|
|
1770
|
+
]
|
|
1771
|
+
}
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
function SortableTableGhost(props) {
|
|
1775
|
+
return /* @__PURE__ */ jsx23(DataTableGhost, { ...props });
|
|
1776
|
+
}
|
|
1777
|
+
function SidebarGhost({ className, items = 6, ...props }) {
|
|
1778
|
+
return /* @__PURE__ */ jsxs19("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
|
|
1779
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-sidebar__brand" }),
|
|
1780
|
+
/* @__PURE__ */ jsx23("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs19("div", { className: "fractal-ghost-sidebar__item", children: [
|
|
1781
|
+
/* @__PURE__ */ jsx23(Ghost, {}),
|
|
1782
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
|
|
1783
|
+
] }, index)) })
|
|
1784
|
+
] });
|
|
1785
|
+
}
|
|
1786
|
+
function ModalGhost({ className, title, lines = 3, ...props }) {
|
|
1787
|
+
return /* @__PURE__ */ jsx23(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
|
|
1788
|
+
}
|
|
1789
|
+
function SidePanelGhost({ className, title, lines = 5, ...props }) {
|
|
1790
|
+
return /* @__PURE__ */ jsx23(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
|
|
1791
|
+
}
|
|
1792
|
+
function SurfaceGhost({ className, title, lines = 3, ...props }) {
|
|
1793
|
+
return /* @__PURE__ */ jsxs19("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
|
|
1794
|
+
/* @__PURE__ */ jsxs19("div", { className: "fractal-ghost-surface__header", children: [
|
|
1795
|
+
/* @__PURE__ */ jsx23(GhostLine, { width: "42%" }),
|
|
1796
|
+
/* @__PURE__ */ jsx23(Ghost, { className: "fractal-ghost-surface__close" })
|
|
1797
|
+
] }),
|
|
1798
|
+
title && /* @__PURE__ */ jsx23("div", { className: "fractal-ghost-surface__title", children: title }),
|
|
1799
|
+
/* @__PURE__ */ jsx23("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx23(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
|
|
1800
|
+
] });
|
|
1801
|
+
}
|
|
1802
|
+
|
|
987
1803
|
// src/components/Sidebar/Sidebar.tsx
|
|
988
|
-
import * as
|
|
989
|
-
import { jsx as
|
|
990
|
-
var Sidebar =
|
|
991
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */
|
|
1804
|
+
import * as React13 from "react";
|
|
1805
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1806
|
+
var Sidebar = React13.forwardRef(
|
|
1807
|
+
({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
992
1808
|
"aside",
|
|
993
1809
|
{
|
|
994
1810
|
ref,
|
|
995
1811
|
className: cn("fractal-sidebar", className),
|
|
1812
|
+
"data-compact": compact || void 0,
|
|
996
1813
|
style: { ...style, ...width ? { "--fractal-sidebar-width": width } : {} },
|
|
997
1814
|
...props
|
|
998
1815
|
}
|
|
999
1816
|
)
|
|
1000
1817
|
);
|
|
1001
1818
|
Sidebar.displayName = "Sidebar";
|
|
1002
|
-
var SidebarHeader =
|
|
1003
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1819
|
+
var SidebarHeader = React13.forwardRef(
|
|
1820
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx24("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
1004
1821
|
);
|
|
1005
1822
|
SidebarHeader.displayName = "SidebarHeader";
|
|
1006
|
-
var SidebarBrand =
|
|
1007
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */
|
|
1823
|
+
var SidebarBrand = React13.forwardRef(
|
|
1824
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx24("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
1008
1825
|
);
|
|
1009
1826
|
SidebarBrand.displayName = "SidebarBrand";
|
|
1010
|
-
|
|
1011
|
-
|
|
1827
|
+
function SidebarAccountMenu({
|
|
1828
|
+
name,
|
|
1829
|
+
items,
|
|
1830
|
+
onSelect,
|
|
1831
|
+
triggerLabel = "Account menu",
|
|
1832
|
+
icon,
|
|
1833
|
+
className
|
|
1834
|
+
}) {
|
|
1835
|
+
return /* @__PURE__ */ jsx24(
|
|
1836
|
+
Dropdown,
|
|
1837
|
+
{
|
|
1838
|
+
align: "left",
|
|
1839
|
+
className: cn("fractal-sidebar__account", className),
|
|
1840
|
+
items,
|
|
1841
|
+
onSelect,
|
|
1842
|
+
panelClassName: "fractal-sidebar__account-panel",
|
|
1843
|
+
selectedValue: "",
|
|
1844
|
+
triggerClassName: "fractal-sidebar__account-trigger",
|
|
1845
|
+
triggerContent: /* @__PURE__ */ jsxs20(Fragment3, { children: [
|
|
1846
|
+
icon && /* @__PURE__ */ jsx24("span", { className: "fractal-sidebar__account-icon", "aria-hidden": "true", children: icon }),
|
|
1847
|
+
/* @__PURE__ */ jsx24("span", { className: "fractal-sidebar__account-name", children: name })
|
|
1848
|
+
] }),
|
|
1849
|
+
triggerLabel,
|
|
1850
|
+
triggerVariant: "tertiary"
|
|
1851
|
+
}
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
var SidebarNav = React13.forwardRef(
|
|
1855
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx24("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1012
1856
|
);
|
|
1013
1857
|
SidebarNav.displayName = "SidebarNav";
|
|
1014
|
-
var SidebarSection =
|
|
1015
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1858
|
+
var SidebarSection = React13.forwardRef(
|
|
1859
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx24("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1016
1860
|
);
|
|
1017
1861
|
SidebarSection.displayName = "SidebarSection";
|
|
1018
|
-
var SidebarNavItem =
|
|
1019
|
-
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */
|
|
1862
|
+
var SidebarNavItem = React13.forwardRef(
|
|
1863
|
+
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs20(
|
|
1020
1864
|
"button",
|
|
1021
1865
|
{
|
|
1022
1866
|
ref,
|
|
@@ -1026,42 +1870,28 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1026
1870
|
"aria-current": active ? "page" : void 0,
|
|
1027
1871
|
...props,
|
|
1028
1872
|
children: [
|
|
1029
|
-
icon && /* @__PURE__ */
|
|
1030
|
-
/* @__PURE__ */
|
|
1031
|
-
endAdornment && /* @__PURE__ */
|
|
1873
|
+
icon && /* @__PURE__ */ jsx24("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1874
|
+
/* @__PURE__ */ jsx24("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1875
|
+
endAdornment && /* @__PURE__ */ jsx24("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1032
1876
|
]
|
|
1033
1877
|
}
|
|
1034
1878
|
)
|
|
1035
1879
|
);
|
|
1036
1880
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1037
|
-
var SidebarFooter =
|
|
1038
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1881
|
+
var SidebarFooter = React13.forwardRef(
|
|
1882
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx24("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1039
1883
|
);
|
|
1040
1884
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1041
1885
|
|
|
1042
|
-
// src/components/PageHeader/PageHeader.tsx
|
|
1043
|
-
import * as React11 from "react";
|
|
1044
|
-
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1045
|
-
var PageHeader = React11.forwardRef(
|
|
1046
|
-
({ title, description, actions, className, ...props }, ref) => /* @__PURE__ */ jsxs13("div", { ref, className: cn("fractal-page-header", className), ...props, children: [
|
|
1047
|
-
/* @__PURE__ */ jsxs13("div", { className: "fractal-page-header__content", children: [
|
|
1048
|
-
/* @__PURE__ */ jsx16("h1", { className: "fractal-page-header__title", children: title }),
|
|
1049
|
-
description && /* @__PURE__ */ jsx16("p", { className: "fractal-page-header__description", children: description })
|
|
1050
|
-
] }),
|
|
1051
|
-
actions && /* @__PURE__ */ jsx16("div", { className: "fractal-page-header__actions", children: actions })
|
|
1052
|
-
] })
|
|
1053
|
-
);
|
|
1054
|
-
PageHeader.displayName = "PageHeader";
|
|
1055
|
-
|
|
1056
1886
|
// src/components/SidePanel/SidePanel.tsx
|
|
1057
1887
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1058
1888
|
import { Close } from "@mirror-physics/fractal-icons";
|
|
1059
|
-
import { jsx as
|
|
1060
|
-
function SidePanel({ open, onClose, title, description, children, footer, size = "md", className }) {
|
|
1889
|
+
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1890
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
|
|
1061
1891
|
useEscapeDismiss(80, onClose, open);
|
|
1062
1892
|
if (!open) return null;
|
|
1063
1893
|
return createPortal2(
|
|
1064
|
-
/* @__PURE__ */
|
|
1894
|
+
/* @__PURE__ */ jsx25("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ jsxs21(
|
|
1065
1895
|
"aside",
|
|
1066
1896
|
{
|
|
1067
1897
|
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
@@ -1070,15 +1900,15 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1070
1900
|
role: "dialog",
|
|
1071
1901
|
onMouseDown: (event) => event.stopPropagation(),
|
|
1072
1902
|
children: [
|
|
1073
|
-
/* @__PURE__ */
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1076
|
-
description && /* @__PURE__ */
|
|
1903
|
+
/* @__PURE__ */ jsxs21("header", { className: "fractal-side-panel__header", children: [
|
|
1904
|
+
/* @__PURE__ */ jsxs21("div", { className: "fractal-side-panel__heading", children: [
|
|
1905
|
+
typeof title === "string" ? /* @__PURE__ */ jsx25("h2", { className: "fractal-side-panel__title", children: title }) : /* @__PURE__ */ jsx25("div", { className: "fractal-side-panel__title", children: title }),
|
|
1906
|
+
description && /* @__PURE__ */ jsx25("p", { className: "fractal-side-panel__description", children: description })
|
|
1077
1907
|
] }),
|
|
1078
|
-
/* @__PURE__ */
|
|
1908
|
+
/* @__PURE__ */ jsx25("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx25(Close, { size: 18 }) })
|
|
1079
1909
|
] }),
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
footer && /* @__PURE__ */
|
|
1910
|
+
/* @__PURE__ */ jsx25("div", { "aria-busy": loading || void 0, className: cn("fractal-side-panel__body", loading && "fractal-side-panel__body--loading"), children: loading ? /* @__PURE__ */ jsx25(UILoader, { label: loadingLabel }) : children }),
|
|
1911
|
+
footer && /* @__PURE__ */ jsx25("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1082
1912
|
]
|
|
1083
1913
|
}
|
|
1084
1914
|
) }),
|
|
@@ -1087,48 +1917,271 @@ function SidePanel({ open, onClose, title, description, children, footer, size =
|
|
|
1087
1917
|
}
|
|
1088
1918
|
|
|
1089
1919
|
// src/components/Textarea/Textarea.tsx
|
|
1090
|
-
import * as
|
|
1091
|
-
import { jsx as
|
|
1092
|
-
var Textarea =
|
|
1093
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1920
|
+
import * as React14 from "react";
|
|
1921
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1922
|
+
var Textarea = React14.forwardRef(
|
|
1923
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx26("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1094
1924
|
);
|
|
1095
1925
|
Textarea.displayName = "Textarea";
|
|
1926
|
+
|
|
1927
|
+
// src/components/TextButton/TextButton.tsx
|
|
1928
|
+
import * as React15 from "react";
|
|
1929
|
+
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1930
|
+
var TextButton = React15.forwardRef(
|
|
1931
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs22(
|
|
1932
|
+
"button",
|
|
1933
|
+
{
|
|
1934
|
+
ref,
|
|
1935
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
1936
|
+
type: "button",
|
|
1937
|
+
...props,
|
|
1938
|
+
children: [
|
|
1939
|
+
icon && iconPosition === "start" && /* @__PURE__ */ jsx27("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
1940
|
+
/* @__PURE__ */ jsx27("span", { children }),
|
|
1941
|
+
icon && iconPosition === "end" && /* @__PURE__ */ jsx27("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
1942
|
+
]
|
|
1943
|
+
}
|
|
1944
|
+
)
|
|
1945
|
+
);
|
|
1946
|
+
TextButton.displayName = "TextButton";
|
|
1947
|
+
|
|
1948
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
1949
|
+
import * as React16 from "react";
|
|
1950
|
+
import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
|
|
1951
|
+
import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1952
|
+
function FileDropzone({
|
|
1953
|
+
files,
|
|
1954
|
+
onFilesChange,
|
|
1955
|
+
accept,
|
|
1956
|
+
multiple = true,
|
|
1957
|
+
disabled = false,
|
|
1958
|
+
title = "Drop files here or click to browse",
|
|
1959
|
+
description = "Files stay attached to this record.",
|
|
1960
|
+
className
|
|
1961
|
+
}) {
|
|
1962
|
+
const inputId = React16.useId();
|
|
1963
|
+
const inputRef = React16.useRef(null);
|
|
1964
|
+
const [isDragging, setIsDragging] = React16.useState(false);
|
|
1965
|
+
const addFiles = (nextFiles) => {
|
|
1966
|
+
if (disabled) return;
|
|
1967
|
+
const additions = Array.from(nextFiles);
|
|
1968
|
+
if (additions.length === 0) return;
|
|
1969
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
1970
|
+
};
|
|
1971
|
+
return /* @__PURE__ */ jsxs23("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
1972
|
+
/* @__PURE__ */ jsx28(
|
|
1973
|
+
"input",
|
|
1974
|
+
{
|
|
1975
|
+
ref: inputRef,
|
|
1976
|
+
id: inputId,
|
|
1977
|
+
className: "fractal-file-dropzone__input",
|
|
1978
|
+
type: "file",
|
|
1979
|
+
accept,
|
|
1980
|
+
multiple,
|
|
1981
|
+
disabled,
|
|
1982
|
+
onChange: (event) => {
|
|
1983
|
+
if (event.target.files) addFiles(event.target.files);
|
|
1984
|
+
event.target.value = "";
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
),
|
|
1988
|
+
/* @__PURE__ */ jsxs23(
|
|
1989
|
+
"button",
|
|
1990
|
+
{
|
|
1991
|
+
className: "fractal-file-dropzone__target",
|
|
1992
|
+
"data-dragging": isDragging || void 0,
|
|
1993
|
+
type: "button",
|
|
1994
|
+
disabled,
|
|
1995
|
+
onClick: () => inputRef.current?.click(),
|
|
1996
|
+
onDragEnter: (event) => {
|
|
1997
|
+
event.preventDefault();
|
|
1998
|
+
if (!disabled) setIsDragging(true);
|
|
1999
|
+
},
|
|
2000
|
+
onDragOver: (event) => event.preventDefault(),
|
|
2001
|
+
onDragLeave: (event) => {
|
|
2002
|
+
event.preventDefault();
|
|
2003
|
+
setIsDragging(false);
|
|
2004
|
+
},
|
|
2005
|
+
onDrop: (event) => {
|
|
2006
|
+
event.preventDefault();
|
|
2007
|
+
setIsDragging(false);
|
|
2008
|
+
addFiles(event.dataTransfer.files);
|
|
2009
|
+
},
|
|
2010
|
+
children: [
|
|
2011
|
+
/* @__PURE__ */ jsx28(FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
2012
|
+
/* @__PURE__ */ jsxs23("span", { className: "fractal-file-dropzone__copy", children: [
|
|
2013
|
+
/* @__PURE__ */ jsx28("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
2014
|
+
description && /* @__PURE__ */ jsx28("span", { className: "fractal-file-dropzone__description", children: description })
|
|
2015
|
+
] })
|
|
2016
|
+
]
|
|
2017
|
+
}
|
|
2018
|
+
),
|
|
2019
|
+
files.length > 0 && /* @__PURE__ */ jsx28("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ jsxs23("li", { className: "fractal-file-dropzone__file", children: [
|
|
2020
|
+
/* @__PURE__ */ jsx28("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
2021
|
+
/* @__PURE__ */ jsx28("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
2022
|
+
/* @__PURE__ */ jsx28(
|
|
2023
|
+
"button",
|
|
2024
|
+
{
|
|
2025
|
+
className: "fractal-file-dropzone__remove",
|
|
2026
|
+
type: "button",
|
|
2027
|
+
"aria-label": `Remove ${file.name}`,
|
|
2028
|
+
disabled,
|
|
2029
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
2030
|
+
children: /* @__PURE__ */ jsx28(Close2, { "aria-hidden": "true", size: 14 })
|
|
2031
|
+
}
|
|
2032
|
+
)
|
|
2033
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
2034
|
+
] });
|
|
2035
|
+
}
|
|
2036
|
+
function formatFileSize(bytes) {
|
|
2037
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
2038
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
2039
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
// src/components/Pagination/Pagination.tsx
|
|
2043
|
+
import { ArrowLeft, ArrowRight } from "@mirror-physics/fractal-icons";
|
|
2044
|
+
import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2045
|
+
function Pagination({
|
|
2046
|
+
page,
|
|
2047
|
+
pageSize,
|
|
2048
|
+
totalItems,
|
|
2049
|
+
onPageChange,
|
|
2050
|
+
pageSizeOptions,
|
|
2051
|
+
onPageSizeChange,
|
|
2052
|
+
ariaLabel = "Pagination",
|
|
2053
|
+
className
|
|
2054
|
+
}) {
|
|
2055
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
2056
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
2057
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
2058
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
2059
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
2060
|
+
return /* @__PURE__ */ jsxs24("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
2061
|
+
/* @__PURE__ */ jsx29("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
2062
|
+
/* @__PURE__ */ jsxs24("div", { className: "fractal-pagination__controls", children: [
|
|
2063
|
+
canChangePageSize && /* @__PURE__ */ jsx29(
|
|
2064
|
+
Dropdown,
|
|
2065
|
+
{
|
|
2066
|
+
align: "right",
|
|
2067
|
+
className: "fractal-pagination__page-size",
|
|
2068
|
+
direction: "up",
|
|
2069
|
+
items: pageSizeOptions.map((option) => ({
|
|
2070
|
+
value: String(option),
|
|
2071
|
+
description: `${option} per page`
|
|
2072
|
+
})),
|
|
2073
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
2074
|
+
selectedValue: String(pageSize),
|
|
2075
|
+
size: "sm",
|
|
2076
|
+
triggerLabel: "Results per page",
|
|
2077
|
+
triggerVariant: "tertiary"
|
|
2078
|
+
}
|
|
2079
|
+
),
|
|
2080
|
+
/* @__PURE__ */ jsx29(
|
|
2081
|
+
"button",
|
|
2082
|
+
{
|
|
2083
|
+
className: "fractal-pagination__button",
|
|
2084
|
+
type: "button",
|
|
2085
|
+
"aria-label": "Previous page",
|
|
2086
|
+
title: "Previous page",
|
|
2087
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
2088
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
2089
|
+
children: /* @__PURE__ */ jsx29(ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
2090
|
+
}
|
|
2091
|
+
),
|
|
2092
|
+
/* @__PURE__ */ jsxs24("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
2093
|
+
currentPage,
|
|
2094
|
+
" of ",
|
|
2095
|
+
totalPages
|
|
2096
|
+
] }),
|
|
2097
|
+
/* @__PURE__ */ jsx29(
|
|
2098
|
+
"button",
|
|
2099
|
+
{
|
|
2100
|
+
className: "fractal-pagination__button",
|
|
2101
|
+
type: "button",
|
|
2102
|
+
"aria-label": "Next page",
|
|
2103
|
+
title: "Next page",
|
|
2104
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
2105
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
2106
|
+
children: /* @__PURE__ */ jsx29(ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
2107
|
+
}
|
|
2108
|
+
)
|
|
2109
|
+
] })
|
|
2110
|
+
] });
|
|
2111
|
+
}
|
|
1096
2112
|
export {
|
|
1097
2113
|
Alert,
|
|
1098
2114
|
AlertDescription,
|
|
2115
|
+
AlertGhost,
|
|
1099
2116
|
AlertTitle,
|
|
2117
|
+
Breadcrumbs,
|
|
1100
2118
|
Button,
|
|
2119
|
+
ButtonGhost,
|
|
1101
2120
|
Card,
|
|
1102
2121
|
CardContent,
|
|
1103
2122
|
CardDescription,
|
|
1104
2123
|
CardFooter,
|
|
2124
|
+
CardGhost,
|
|
1105
2125
|
CardHeader,
|
|
1106
2126
|
CardTitle,
|
|
2127
|
+
Checkbox,
|
|
2128
|
+
CheckboxGhost,
|
|
1107
2129
|
Chip,
|
|
2130
|
+
ChipGhost,
|
|
2131
|
+
CodeBlock,
|
|
2132
|
+
ContentSwitcher,
|
|
2133
|
+
ContentSwitcherGhost,
|
|
2134
|
+
ConversationGhost,
|
|
1108
2135
|
DataTable,
|
|
2136
|
+
DataTableGhost,
|
|
1109
2137
|
Disclosure,
|
|
2138
|
+
DisclosureGhost,
|
|
1110
2139
|
Dropdown,
|
|
2140
|
+
DropdownGhost,
|
|
1111
2141
|
FeatureCard,
|
|
2142
|
+
FileDropzone,
|
|
2143
|
+
FileDropzoneGhost,
|
|
1112
2144
|
FolderCard,
|
|
2145
|
+
Ghost,
|
|
2146
|
+
GhostLine,
|
|
1113
2147
|
Input,
|
|
2148
|
+
InputGhost,
|
|
1114
2149
|
Label,
|
|
2150
|
+
LabelGhost,
|
|
2151
|
+
LatticeLoader,
|
|
1115
2152
|
Link,
|
|
2153
|
+
LinkGhost,
|
|
1116
2154
|
Modal,
|
|
1117
|
-
|
|
2155
|
+
ModalGhost,
|
|
2156
|
+
NumberInput,
|
|
2157
|
+
Pagination,
|
|
2158
|
+
PaginationGhost,
|
|
2159
|
+
PasswordInput,
|
|
1118
2160
|
PromptCard,
|
|
2161
|
+
PromptCardGhost,
|
|
1119
2162
|
PromptGrid,
|
|
1120
2163
|
SidePanel,
|
|
2164
|
+
SidePanelGhost,
|
|
1121
2165
|
Sidebar,
|
|
2166
|
+
SidebarAccountMenu,
|
|
1122
2167
|
SidebarBrand,
|
|
1123
2168
|
SidebarFooter,
|
|
2169
|
+
SidebarGhost,
|
|
1124
2170
|
SidebarHeader,
|
|
1125
2171
|
SidebarNav,
|
|
1126
2172
|
SidebarNavItem,
|
|
1127
2173
|
SidebarSection,
|
|
1128
2174
|
SortableTable,
|
|
2175
|
+
SortableTableGhost,
|
|
1129
2176
|
Tabs,
|
|
2177
|
+
TabsGhost,
|
|
2178
|
+
TextButton,
|
|
2179
|
+
TextButtonGhost,
|
|
1130
2180
|
Textarea,
|
|
2181
|
+
TextareaGhost,
|
|
1131
2182
|
Toggle,
|
|
2183
|
+
ToggleGhost,
|
|
2184
|
+
UILoader,
|
|
1132
2185
|
cn,
|
|
1133
2186
|
useEscapeDismiss
|
|
1134
2187
|
};
|