@mirror-physics/fractal-ui 0.2.0-next.4 → 0.2.0-next.40
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 +954 -209
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1178 -75
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +239 -13
- package/dist/index.d.ts +239 -13
- package/dist/index.js +907 -197
- package/dist/index.js.map +1 -1
- package/dist/lattice-FAYE5KWW.svg +3 -0
- package/dist/tokens.css +5 -3
- package/package.json +2 -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,65 @@ var Button = React.forwardRef(
|
|
|
165
165
|
);
|
|
166
166
|
Button.displayName = "Button";
|
|
167
167
|
|
|
168
|
+
// src/components/Breadcrumbs/Breadcrumbs.tsx
|
|
169
|
+
import { ChevronRight } from "@mirror-physics/fractal-icons";
|
|
170
|
+
import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
171
|
+
function Breadcrumbs({
|
|
172
|
+
items,
|
|
173
|
+
ariaLabel = "Breadcrumbs",
|
|
174
|
+
separator = /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true", size: 14 }),
|
|
175
|
+
className,
|
|
176
|
+
...props
|
|
177
|
+
}) {
|
|
178
|
+
if (items.length === 0) return null;
|
|
179
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, className: cn("fractal-breadcrumbs", className), ...props, children: /* @__PURE__ */ jsx("ol", { className: "fractal-breadcrumbs__list", children: items.map((item, index) => {
|
|
180
|
+
const isCurrent = index === items.length - 1;
|
|
181
|
+
const content = isCurrent ? /* @__PURE__ */ jsx("span", { "aria-current": "page", className: "fractal-breadcrumbs__current", children: item.label }) : /* @__PURE__ */ jsx("a", { className: "fractal-breadcrumbs__link", href: item.href ?? "#", onClick: item.onClick, children: item.label });
|
|
182
|
+
return /* @__PURE__ */ jsxs2("li", { className: "fractal-breadcrumbs__item", children: [
|
|
183
|
+
index > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "fractal-breadcrumbs__separator", children: separator }),
|
|
184
|
+
content
|
|
185
|
+
] }, index);
|
|
186
|
+
}) }) });
|
|
187
|
+
}
|
|
188
|
+
|
|
168
189
|
// src/components/Card/Card.tsx
|
|
169
190
|
import * as React2 from "react";
|
|
170
191
|
import { Folder as FolderIcon } from "@mirror-physics/fractal-icons";
|
|
171
|
-
import { jsx, jsxs as
|
|
192
|
+
import { jsx as jsx2, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
172
193
|
var Card = React2.forwardRef(
|
|
173
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
194
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("div", { ref, className: cn("fractal-card", className), ...props })
|
|
174
195
|
);
|
|
175
196
|
Card.displayName = "Card";
|
|
176
197
|
var CardHeader = React2.forwardRef(
|
|
177
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
198
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("div", { ref, className: cn("fractal-card-header", className), ...props })
|
|
178
199
|
);
|
|
179
200
|
CardHeader.displayName = "CardHeader";
|
|
180
201
|
var CardTitle = React2.forwardRef(
|
|
181
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
202
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("h3", { ref, className: cn("fractal-card-title", className), ...props })
|
|
182
203
|
);
|
|
183
204
|
CardTitle.displayName = "CardTitle";
|
|
184
205
|
var CardDescription = React2.forwardRef(
|
|
185
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
206
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("p", { ref, className: cn("fractal-card-description", className), ...props })
|
|
186
207
|
);
|
|
187
208
|
CardDescription.displayName = "CardDescription";
|
|
188
209
|
var CardContent = React2.forwardRef(
|
|
189
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
210
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("div", { ref, className: cn("fractal-card-content", className), ...props })
|
|
190
211
|
);
|
|
191
212
|
CardContent.displayName = "CardContent";
|
|
192
213
|
var CardFooter = React2.forwardRef(
|
|
193
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
214
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx2("div", { ref, className: cn("fractal-card-footer", className), ...props })
|
|
194
215
|
);
|
|
195
216
|
CardFooter.displayName = "CardFooter";
|
|
196
217
|
var FeatureCard = React2.forwardRef(
|
|
197
|
-
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */
|
|
198
|
-
icon && /* @__PURE__ */
|
|
199
|
-
/* @__PURE__ */
|
|
200
|
-
/* @__PURE__ */
|
|
218
|
+
({ icon, title, description, className, ...props }, ref) => /* @__PURE__ */ jsxs3("div", { ref, className: cn("fractal-feature-card", className), ...props, children: [
|
|
219
|
+
icon && /* @__PURE__ */ jsx2("div", { className: "fractal-feature-card__icon", children: icon }),
|
|
220
|
+
/* @__PURE__ */ jsx2("h3", { className: "fractal-feature-card__title", children: title }),
|
|
221
|
+
/* @__PURE__ */ jsx2("p", { className: "fractal-feature-card__description", children: description })
|
|
201
222
|
] })
|
|
202
223
|
);
|
|
203
224
|
FeatureCard.displayName = "FeatureCard";
|
|
204
225
|
var FolderCard = React2.forwardRef(
|
|
205
|
-
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */
|
|
226
|
+
({ name, sessionCount, selected, className, onClick, ...props }, ref) => /* @__PURE__ */ jsxs3(
|
|
206
227
|
"div",
|
|
207
228
|
{
|
|
208
229
|
ref,
|
|
@@ -218,11 +239,11 @@ var FolderCard = React2.forwardRef(
|
|
|
218
239
|
className: cn("fractal-folder-card", selected && "fractal-folder-card--selected", className),
|
|
219
240
|
...props,
|
|
220
241
|
children: [
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
/* @__PURE__ */
|
|
223
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ jsxs3("div", { className: "fractal-folder-card__header", children: [
|
|
243
|
+
/* @__PURE__ */ jsx2(FolderIcon, { size: 16, className: "fractal-folder-card__icon", "aria-hidden": true }),
|
|
244
|
+
/* @__PURE__ */ jsx2("span", { className: "fractal-folder-card__name", children: name })
|
|
224
245
|
] }),
|
|
225
|
-
sessionCount !== void 0 && /* @__PURE__ */
|
|
246
|
+
sessionCount !== void 0 && /* @__PURE__ */ jsx2("div", { className: "fractal-folder-card__footer", children: /* @__PURE__ */ jsxs3("span", { className: "fractal-folder-card__sessions", children: [
|
|
226
247
|
sessionCount,
|
|
227
248
|
" ",
|
|
228
249
|
sessionCount === 1 ? "session" : "sessions"
|
|
@@ -235,7 +256,7 @@ FolderCard.displayName = "FolderCard";
|
|
|
235
256
|
|
|
236
257
|
// src/components/PromptCard/PromptCard.tsx
|
|
237
258
|
import * as React3 from "react";
|
|
238
|
-
import { jsx as
|
|
259
|
+
import { jsx as jsx3, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
239
260
|
var titleToPrompt = (title) => typeof title === "string" || typeof title === "number" ? String(title) : "";
|
|
240
261
|
var PromptCard = React3.forwardRef(
|
|
241
262
|
({
|
|
@@ -256,7 +277,7 @@ var PromptCard = React3.forwardRef(
|
|
|
256
277
|
onPromptSelect?.(prompt ?? titleToPrompt(title));
|
|
257
278
|
}
|
|
258
279
|
};
|
|
259
|
-
return /* @__PURE__ */
|
|
280
|
+
return /* @__PURE__ */ jsxs4(
|
|
260
281
|
"button",
|
|
261
282
|
{
|
|
262
283
|
ref,
|
|
@@ -271,8 +292,8 @@ var PromptCard = React3.forwardRef(
|
|
|
271
292
|
onClick: handleClick,
|
|
272
293
|
...props,
|
|
273
294
|
children: [
|
|
274
|
-
icon && /* @__PURE__ */
|
|
275
|
-
/* @__PURE__ */
|
|
295
|
+
icon && /* @__PURE__ */ jsx3("span", { className: "fractal-prompt-card__icon", "aria-hidden": "true", children: icon }),
|
|
296
|
+
/* @__PURE__ */ jsx3("span", { className: "fractal-prompt-card__title", children: title })
|
|
276
297
|
]
|
|
277
298
|
}
|
|
278
299
|
);
|
|
@@ -280,7 +301,7 @@ var PromptCard = React3.forwardRef(
|
|
|
280
301
|
);
|
|
281
302
|
PromptCard.displayName = "PromptCard";
|
|
282
303
|
var PromptGrid = React3.forwardRef(
|
|
283
|
-
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */
|
|
304
|
+
({ compact, padded, className, ...props }, ref) => /* @__PURE__ */ jsx3(
|
|
284
305
|
"div",
|
|
285
306
|
{
|
|
286
307
|
ref,
|
|
@@ -298,9 +319,9 @@ PromptGrid.displayName = "PromptGrid";
|
|
|
298
319
|
|
|
299
320
|
// src/components/Input/Input.tsx
|
|
300
321
|
import * as React4 from "react";
|
|
301
|
-
import { jsx as
|
|
322
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
302
323
|
var Input = React4.forwardRef(
|
|
303
|
-
({ className, type, ...props }, ref) => /* @__PURE__ */
|
|
324
|
+
({ className, type, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
304
325
|
"input",
|
|
305
326
|
{
|
|
306
327
|
type,
|
|
@@ -314,9 +335,9 @@ Input.displayName = "Input";
|
|
|
314
335
|
|
|
315
336
|
// src/components/Label/Label.tsx
|
|
316
337
|
import * as React5 from "react";
|
|
317
|
-
import { jsx as
|
|
338
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
318
339
|
var Label = React5.forwardRef(
|
|
319
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
340
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
|
|
320
341
|
"label",
|
|
321
342
|
{
|
|
322
343
|
ref,
|
|
@@ -329,43 +350,47 @@ Label.displayName = "Label";
|
|
|
329
350
|
|
|
330
351
|
// src/components/Alert/Alert.tsx
|
|
331
352
|
import * as React6 from "react";
|
|
332
|
-
import {
|
|
353
|
+
import { CircleCheck, CircleClose, CircleInfo, Warning } from "@mirror-physics/fractal-icons";
|
|
354
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
333
355
|
var defaultIcons = {
|
|
334
|
-
default:
|
|
335
|
-
info:
|
|
336
|
-
success:
|
|
337
|
-
warning:
|
|
338
|
-
error:
|
|
356
|
+
default: CircleInfo,
|
|
357
|
+
info: CircleInfo,
|
|
358
|
+
success: CircleCheck,
|
|
359
|
+
warning: Warning,
|
|
360
|
+
error: CircleClose
|
|
339
361
|
};
|
|
340
362
|
var Alert = React6.forwardRef(
|
|
341
|
-
({ className, variant = "default", icon, children, ...props }, ref) =>
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
363
|
+
({ className, variant = "default", icon, children, ...props }, ref) => {
|
|
364
|
+
const DefaultIcon = defaultIcons[variant];
|
|
365
|
+
return /* @__PURE__ */ jsxs5(
|
|
366
|
+
"div",
|
|
367
|
+
{
|
|
368
|
+
ref,
|
|
369
|
+
role: "alert",
|
|
370
|
+
className: cn("fractal-alert", `fractal-alert--${variant}`, className),
|
|
371
|
+
...props,
|
|
372
|
+
children: [
|
|
373
|
+
/* @__PURE__ */ jsx6("span", { className: "fractal-alert-icon", "aria-hidden": true, children: icon ?? /* @__PURE__ */ jsx6(DefaultIcon, { size: 18 }) }),
|
|
374
|
+
/* @__PURE__ */ jsx6("div", { className: "fractal-alert-content", children })
|
|
375
|
+
]
|
|
376
|
+
}
|
|
377
|
+
);
|
|
378
|
+
}
|
|
354
379
|
);
|
|
355
380
|
Alert.displayName = "Alert";
|
|
356
381
|
var AlertTitle = React6.forwardRef(
|
|
357
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
382
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx6("h5", { ref, className: cn("fractal-alert-title", className), ...props })
|
|
358
383
|
);
|
|
359
384
|
AlertTitle.displayName = "AlertTitle";
|
|
360
385
|
var AlertDescription = React6.forwardRef(
|
|
361
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
386
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx6("div", { ref, className: cn("fractal-alert-description", className), ...props })
|
|
362
387
|
);
|
|
363
388
|
AlertDescription.displayName = "AlertDescription";
|
|
364
389
|
|
|
365
390
|
// src/components/Toggle/Toggle.tsx
|
|
366
|
-
import { jsx as
|
|
391
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
367
392
|
function Toggle({ checked, onChange, label, className }) {
|
|
368
|
-
return /* @__PURE__ */
|
|
393
|
+
return /* @__PURE__ */ jsxs6(
|
|
369
394
|
"button",
|
|
370
395
|
{
|
|
371
396
|
type: "button",
|
|
@@ -374,8 +399,8 @@ function Toggle({ checked, onChange, label, className }) {
|
|
|
374
399
|
className: cn("fractal-toggle", className),
|
|
375
400
|
onClick: () => onChange(!checked),
|
|
376
401
|
children: [
|
|
377
|
-
/* @__PURE__ */
|
|
378
|
-
label && /* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ jsx7("span", { className: cn("fractal-toggle-track", checked && "fractal-toggle-track--checked"), children: /* @__PURE__ */ jsx7("span", { className: cn("fractal-toggle-thumb", checked && "fractal-toggle-thumb--checked") }) }),
|
|
403
|
+
label && /* @__PURE__ */ jsx7("span", { className: "fractal-toggle-label", children: label })
|
|
379
404
|
]
|
|
380
405
|
}
|
|
381
406
|
);
|
|
@@ -434,27 +459,72 @@ function useEscapeDismiss(priority, handler, enabled = true) {
|
|
|
434
459
|
}, [priority, enabled]);
|
|
435
460
|
}
|
|
436
461
|
|
|
462
|
+
// src/components/UILoader/UILoader.tsx
|
|
463
|
+
import { useId } from "react";
|
|
464
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
465
|
+
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";
|
|
466
|
+
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";
|
|
467
|
+
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";
|
|
468
|
+
function UILoader({ size = 48, tone = "neutral", className, style, label = "Loading", ariaHidden = false }) {
|
|
469
|
+
const rawId = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
470
|
+
const clipId = `fractal-ui-loader-clip-${rawId}`;
|
|
471
|
+
const gradientId = `fractal-ui-loader-gradient-${rawId}`;
|
|
472
|
+
const height = typeof size === "number" ? `${size}px` : size;
|
|
473
|
+
return /* @__PURE__ */ jsx8(
|
|
474
|
+
"span",
|
|
475
|
+
{
|
|
476
|
+
"aria-hidden": ariaHidden || void 0,
|
|
477
|
+
"aria-label": ariaHidden ? void 0 : label,
|
|
478
|
+
className: cn("fractal-ui-loader", `fractal-ui-loader--${tone}`, className),
|
|
479
|
+
role: ariaHidden ? void 0 : "status",
|
|
480
|
+
style,
|
|
481
|
+
children: /* @__PURE__ */ jsxs7("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 144 92", style: { height, width: "auto" }, children: [
|
|
482
|
+
/* @__PURE__ */ jsxs7("defs", { children: [
|
|
483
|
+
/* @__PURE__ */ jsxs7("linearGradient", { id: gradientId, x1: "59", x2: "94.3", y1: "0", y2: "89.1", gradientUnits: "userSpaceOnUse", children: [
|
|
484
|
+
/* @__PURE__ */ jsx8("stop", { className: "fractal-ui-loader__stop-start", offset: "0" }),
|
|
485
|
+
/* @__PURE__ */ jsx8("stop", { className: "fractal-ui-loader__stop-end", offset: "1" })
|
|
486
|
+
] }),
|
|
487
|
+
/* @__PURE__ */ jsxs7("linearGradient", { id: `${gradientId}-shine`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
|
|
488
|
+
/* @__PURE__ */ jsx8("stop", { offset: "0.4", stopColor: "white", stopOpacity: "0" }),
|
|
489
|
+
/* @__PURE__ */ jsx8("stop", { offset: "0.5", stopColor: "white", stopOpacity: "0.62" }),
|
|
490
|
+
/* @__PURE__ */ jsx8("stop", { offset: "0.6", stopColor: "white", stopOpacity: "0" })
|
|
491
|
+
] }),
|
|
492
|
+
/* @__PURE__ */ jsxs7("clipPath", { id: clipId, children: [
|
|
493
|
+
/* @__PURE__ */ jsx8("path", { d: LEFT }),
|
|
494
|
+
/* @__PURE__ */ jsx8("path", { d: CENTER }),
|
|
495
|
+
/* @__PURE__ */ jsx8("path", { d: RIGHT })
|
|
496
|
+
] })
|
|
497
|
+
] }),
|
|
498
|
+
/* @__PURE__ */ jsx8("path", { d: CENTER, fill: `url(#${gradientId})` }),
|
|
499
|
+
/* @__PURE__ */ jsx8("path", { d: RIGHT, fill: `url(#${gradientId})` }),
|
|
500
|
+
/* @__PURE__ */ jsx8("path", { d: LEFT, fill: `url(#${gradientId})` }),
|
|
501
|
+
/* @__PURE__ */ jsx8("g", { clipPath: `url(#${clipId})`, children: /* @__PURE__ */ jsx8("g", { className: "fractal-ui-loader__shine-axis", transform: "translate(72 46) rotate(68.4)", children: /* @__PURE__ */ jsx8("rect", { className: "fractal-ui-loader__shine", x: "-160", y: "-100", width: "320", height: "200", fill: `url(#${gradientId}-shine)` }) }) })
|
|
502
|
+
] })
|
|
503
|
+
}
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
|
|
437
507
|
// 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);
|
|
508
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
509
|
+
var CloseIcon = () => /* @__PURE__ */ jsx9("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx9("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
510
|
+
function Modal({ open, onClose, title, children, danger, warn, footer, noClose, closeDisabled = false, size = "sm", loading = false, loadingLabel = "Loading", className }) {
|
|
511
|
+
useEscapeDismiss(80, onClose, open && !noClose && !closeDisabled);
|
|
442
512
|
if (!open) return null;
|
|
443
513
|
const sizeClass = `fractal-modal-panel--${size}`;
|
|
444
514
|
const accentClass = danger ? "fractal-modal-panel--danger" : warn ? "fractal-modal-panel--warn" : "";
|
|
445
515
|
return createPortal(
|
|
446
|
-
/* @__PURE__ */
|
|
516
|
+
/* @__PURE__ */ jsx9("div", { className: "fractal-modal-overlay", onClick: noClose || closeDisabled ? void 0 : onClose, children: /* @__PURE__ */ jsxs8(
|
|
447
517
|
"div",
|
|
448
518
|
{
|
|
449
519
|
className: cn("fractal-modal-panel", sizeClass, accentClass, className),
|
|
450
520
|
onClick: (e) => e.stopPropagation(),
|
|
451
521
|
children: [
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
!noClose && /* @__PURE__ */
|
|
522
|
+
/* @__PURE__ */ jsxs8("div", { className: "fractal-modal-title-row", children: [
|
|
523
|
+
/* @__PURE__ */ jsx9("h3", { className: cn("fractal-modal-title", danger && "fractal-modal-title--danger", warn && "fractal-modal-title--warn"), children: title }),
|
|
524
|
+
!noClose && /* @__PURE__ */ jsx9("button", { type: "button", onClick: onClose, title: "Close", disabled: closeDisabled, className: "fractal-modal-close", children: /* @__PURE__ */ jsx9(CloseIcon, {}) })
|
|
455
525
|
] }),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
footer && /* @__PURE__ */
|
|
526
|
+
/* @__PURE__ */ jsx9("div", { "aria-busy": loading || void 0, className: cn("fractal-modal-body", size === "lg" && "fractal-modal-body--lg", loading && "fractal-modal-body--loading"), children: loading ? /* @__PURE__ */ jsx9(UILoader, { label: loadingLabel }) : children }),
|
|
527
|
+
footer && /* @__PURE__ */ jsx9("div", { className: "fractal-modal-footer", children: footer })
|
|
458
528
|
]
|
|
459
529
|
}
|
|
460
530
|
) }),
|
|
@@ -463,17 +533,17 @@ function Modal({ open, onClose, title, children, danger, warn, footer, noClose,
|
|
|
463
533
|
}
|
|
464
534
|
|
|
465
535
|
// src/components/DataTable/DataTable.tsx
|
|
466
|
-
import { jsx as
|
|
536
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
467
537
|
function DataTable({ columns, data, emptyMessage, header, size = "md", className }) {
|
|
468
|
-
return /* @__PURE__ */
|
|
469
|
-
header && /* @__PURE__ */
|
|
470
|
-
data.length === 0 ? /* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */
|
|
472
|
-
/* @__PURE__ */
|
|
538
|
+
return /* @__PURE__ */ jsx10("div", { className: cn("fractal-datatable", `fractal-datatable--${size}`, className), children: /* @__PURE__ */ jsxs9("div", { className: "fractal-datatable-surface", children: [
|
|
539
|
+
header && /* @__PURE__ */ jsx10("div", { className: "fractal-datatable-header", children: header }),
|
|
540
|
+
data.length === 0 ? /* @__PURE__ */ jsx10("div", { className: "fractal-datatable-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs9("table", { className: "fractal-datatable-table", children: [
|
|
541
|
+
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsx10("tr", { className: "fractal-datatable-thead-row", children: columns.map((col) => /* @__PURE__ */ jsx10("th", { className: "fractal-datatable-th", style: { width: col.width }, children: col.header }, col.key)) }) }),
|
|
542
|
+
/* @__PURE__ */ jsx10("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx10(
|
|
473
543
|
"tr",
|
|
474
544
|
{
|
|
475
545
|
className: "fractal-datatable-row",
|
|
476
|
-
children: columns.map((col) => /* @__PURE__ */
|
|
546
|
+
children: columns.map((col) => /* @__PURE__ */ jsx10("td", { className: "fractal-datatable-td", style: { width: col.width }, children: col.render(row, rowIndex) }, col.key))
|
|
477
547
|
},
|
|
478
548
|
rowIndex
|
|
479
549
|
)) })
|
|
@@ -484,7 +554,7 @@ function DataTable({ columns, data, emptyMessage, header, size = "md", className
|
|
|
484
554
|
// src/components/Dropdown/Dropdown.tsx
|
|
485
555
|
import * as React7 from "react";
|
|
486
556
|
import { ChevronDown, ChevronUp } from "@mirror-physics/fractal-icons";
|
|
487
|
-
import { Fragment as Fragment2, jsx as
|
|
557
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
488
558
|
var MARGIN = 4;
|
|
489
559
|
function Dropdown({
|
|
490
560
|
items,
|
|
@@ -495,13 +565,15 @@ function Dropdown({
|
|
|
495
565
|
align = "left",
|
|
496
566
|
triggerContent,
|
|
497
567
|
label,
|
|
568
|
+
iconOnly = false,
|
|
498
569
|
noChevron = false,
|
|
499
570
|
size = "md",
|
|
500
571
|
triggerVariant = "outline",
|
|
501
572
|
className,
|
|
502
573
|
triggerClassName,
|
|
503
574
|
panelClassName,
|
|
504
|
-
closeOnSelect = true
|
|
575
|
+
closeOnSelect = true,
|
|
576
|
+
disabled = false
|
|
505
577
|
}) {
|
|
506
578
|
const [open, setOpen] = React7.useState(false);
|
|
507
579
|
const triggerRef = React7.useRef(null);
|
|
@@ -559,12 +631,13 @@ function Dropdown({
|
|
|
559
631
|
document.addEventListener("mousedown", handleClickOutside);
|
|
560
632
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
561
633
|
}, [open]);
|
|
562
|
-
return /* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
634
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("fractal-dropdown", className), children: [
|
|
635
|
+
/* @__PURE__ */ jsxs10(
|
|
564
636
|
"button",
|
|
565
637
|
{
|
|
566
638
|
ref: triggerRef,
|
|
567
639
|
type: "button",
|
|
640
|
+
disabled,
|
|
568
641
|
"aria-haspopup": "listbox",
|
|
569
642
|
"aria-expanded": open,
|
|
570
643
|
"aria-label": triggerLabel,
|
|
@@ -573,18 +646,19 @@ function Dropdown({
|
|
|
573
646
|
"fractal-dropdown-trigger",
|
|
574
647
|
`fractal-dropdown-trigger--${size}`,
|
|
575
648
|
`fractal-dropdown-trigger--${triggerVariant}`,
|
|
649
|
+
iconOnly && "fractal-dropdown-trigger--icon-only",
|
|
576
650
|
triggerClassName
|
|
577
651
|
),
|
|
578
652
|
children: [
|
|
579
|
-
triggerContent != null ? triggerContent : /* @__PURE__ */
|
|
580
|
-
selected.icon != null && /* @__PURE__ */
|
|
581
|
-
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */
|
|
653
|
+
triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
654
|
+
selected.icon != null && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-icon fractal-dropdown-icon--trigger", children: selected.icon }),
|
|
655
|
+
selected.description != null && (typeof selected.description !== "string" || selected.description !== "") && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-selected-text", children: selected.description })
|
|
582
656
|
] }),
|
|
583
|
-
!noChevron && /* @__PURE__ */
|
|
657
|
+
!noChevron && !iconOnly && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-chevron", "aria-hidden": true, children: /* @__PURE__ */ jsx11(ChevronIcon, { size: size === "sm" ? 14 : 16 }) })
|
|
584
658
|
]
|
|
585
659
|
}
|
|
586
660
|
),
|
|
587
|
-
open && /* @__PURE__ */
|
|
661
|
+
open && /* @__PURE__ */ jsxs10(
|
|
588
662
|
"div",
|
|
589
663
|
{
|
|
590
664
|
ref: panelRef,
|
|
@@ -593,21 +667,21 @@ function Dropdown({
|
|
|
593
667
|
className: cn("fractal-dropdown-panel", `fractal-dropdown-panel--${size}`, panelClassName),
|
|
594
668
|
style: panelStyle,
|
|
595
669
|
children: [
|
|
596
|
-
label != null && /* @__PURE__ */
|
|
670
|
+
label != null && /* @__PURE__ */ jsx11("div", { className: "fractal-dropdown-label", children: label }),
|
|
597
671
|
visibleItems.map((item, index) => {
|
|
598
|
-
const topDivider = item.border === "top" ? /* @__PURE__ */
|
|
599
|
-
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */
|
|
672
|
+
const topDivider = item.border === "top" ? /* @__PURE__ */ jsx11("div", { className: "fractal-dropdown-separator" }) : null;
|
|
673
|
+
const bottomDivider = item.border === "bottom" ? /* @__PURE__ */ jsx11("div", { className: "fractal-dropdown-separator" }) : null;
|
|
600
674
|
if (item.kind === "header") {
|
|
601
|
-
return /* @__PURE__ */
|
|
675
|
+
return /* @__PURE__ */ jsxs10(React7.Fragment, { children: [
|
|
602
676
|
topDivider,
|
|
603
|
-
/* @__PURE__ */
|
|
677
|
+
/* @__PURE__ */ jsx11("div", { role: "presentation", className: "fractal-dropdown-label", children: item.description }),
|
|
604
678
|
bottomDivider
|
|
605
679
|
] }, `header-${index}`);
|
|
606
680
|
}
|
|
607
681
|
const isSelected = item.value === selectedValue;
|
|
608
|
-
return /* @__PURE__ */
|
|
682
|
+
return /* @__PURE__ */ jsxs10(React7.Fragment, { children: [
|
|
609
683
|
topDivider,
|
|
610
|
-
/* @__PURE__ */
|
|
684
|
+
/* @__PURE__ */ jsxs10(
|
|
611
685
|
"button",
|
|
612
686
|
{
|
|
613
687
|
type: "button",
|
|
@@ -619,9 +693,9 @@ function Dropdown({
|
|
|
619
693
|
},
|
|
620
694
|
className: "fractal-dropdown-option",
|
|
621
695
|
children: [
|
|
622
|
-
item.icon != null && /* @__PURE__ */
|
|
623
|
-
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */
|
|
624
|
-
item.trailing != null && /* @__PURE__ */
|
|
696
|
+
item.icon != null && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-icon", children: item.icon }),
|
|
697
|
+
item.description != null && (typeof item.description !== "string" || item.description !== "") && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-option-text", children: item.description }),
|
|
698
|
+
item.trailing != null && /* @__PURE__ */ jsx11("span", { className: "fractal-dropdown-trailing", children: item.trailing })
|
|
625
699
|
]
|
|
626
700
|
}
|
|
627
701
|
),
|
|
@@ -636,9 +710,9 @@ function Dropdown({
|
|
|
636
710
|
|
|
637
711
|
// src/components/Link/Link.tsx
|
|
638
712
|
import * as React8 from "react";
|
|
639
|
-
import { jsx as
|
|
713
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
640
714
|
var Link = React8.forwardRef(
|
|
641
|
-
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */
|
|
715
|
+
({ className, theme = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
642
716
|
"a",
|
|
643
717
|
{
|
|
644
718
|
ref,
|
|
@@ -651,9 +725,9 @@ Link.displayName = "Link";
|
|
|
651
725
|
|
|
652
726
|
// src/components/Chip/Chip.tsx
|
|
653
727
|
import * as React9 from "react";
|
|
654
|
-
import { jsx as
|
|
728
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
655
729
|
var Chip = React9.forwardRef(
|
|
656
|
-
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */
|
|
730
|
+
({ className, tone = "neutral", ...props }, ref) => /* @__PURE__ */ jsx13(
|
|
657
731
|
"span",
|
|
658
732
|
{
|
|
659
733
|
ref,
|
|
@@ -664,35 +738,69 @@ var Chip = React9.forwardRef(
|
|
|
664
738
|
);
|
|
665
739
|
Chip.displayName = "Chip";
|
|
666
740
|
|
|
741
|
+
// src/components/Checkbox/Checkbox.tsx
|
|
742
|
+
import { Checkbox as CheckboxIcon, CheckboxChecked } from "@mirror-physics/fractal-icons";
|
|
743
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
744
|
+
function Checkbox({ checked, onCheckedChange, className, disabled, onClick, onKeyDown, ...props }) {
|
|
745
|
+
return /* @__PURE__ */ jsx14(
|
|
746
|
+
"button",
|
|
747
|
+
{
|
|
748
|
+
...props,
|
|
749
|
+
className: cn("fractal-checkbox", checked && "fractal-checkbox--checked", className),
|
|
750
|
+
type: "button",
|
|
751
|
+
role: "checkbox",
|
|
752
|
+
"aria-checked": checked,
|
|
753
|
+
disabled,
|
|
754
|
+
onClick: (event) => {
|
|
755
|
+
onClick?.(event);
|
|
756
|
+
if (!event.defaultPrevented) onCheckedChange(!checked);
|
|
757
|
+
},
|
|
758
|
+
onKeyDown: (event) => {
|
|
759
|
+
onKeyDown?.(event);
|
|
760
|
+
if (event.key === " " || event.key === "Enter") event.stopPropagation();
|
|
761
|
+
},
|
|
762
|
+
children: checked ? /* @__PURE__ */ jsx14(CheckboxChecked, { "aria-hidden": "true", size: 18 }) : /* @__PURE__ */ jsx14(CheckboxIcon, { "aria-hidden": "true", size: 18 })
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
667
767
|
// src/components/SortableTable/SortableTable.tsx
|
|
668
768
|
import { useMemo, useState as useState3 } from "react";
|
|
669
769
|
import { ArrowUp, ArrowDown, ArrowsUpDown } from "@mirror-physics/fractal-icons";
|
|
670
|
-
import { jsx as
|
|
770
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
671
771
|
function SortableTable({
|
|
672
772
|
columns,
|
|
673
773
|
data,
|
|
674
774
|
emptyMessage,
|
|
675
775
|
header,
|
|
676
776
|
size = "md",
|
|
777
|
+
embedded = false,
|
|
677
778
|
className,
|
|
779
|
+
defaultSort,
|
|
678
780
|
defaultSortKey = void 0,
|
|
679
781
|
defaultSortDirection = null,
|
|
680
782
|
sortKey: controlledKey,
|
|
681
783
|
sortDirection: controlledDirection,
|
|
682
784
|
onSortChange,
|
|
683
|
-
highlightRow
|
|
785
|
+
highlightRow,
|
|
786
|
+
onRowClick,
|
|
787
|
+
rowAction
|
|
684
788
|
}) {
|
|
685
789
|
const [internalKey, setInternalKey] = useState3(defaultSortKey ?? null);
|
|
686
790
|
const [internalDirection, setInternalDirection] = useState3(defaultSortDirection);
|
|
687
791
|
const isControlled = controlledKey !== void 0 && controlledDirection !== void 0;
|
|
688
792
|
const activeKey = isControlled ? controlledKey : internalKey;
|
|
689
793
|
const activeDirection = isControlled ? controlledDirection : internalDirection;
|
|
794
|
+
const baselineKey = defaultSort?.key ?? null;
|
|
795
|
+
const baselineDirection = defaultSort?.direction ?? null;
|
|
796
|
+
const effectiveKey = activeKey && activeDirection ? activeKey : baselineKey;
|
|
797
|
+
const effectiveDirection = activeKey && activeDirection ? activeDirection : baselineDirection;
|
|
690
798
|
const sorted = useMemo(() => {
|
|
691
|
-
if (!
|
|
692
|
-
const col = columns.find((c) => c.key ===
|
|
799
|
+
if (!effectiveKey || !effectiveDirection) return data;
|
|
800
|
+
const col = columns.find((c) => c.key === effectiveKey);
|
|
693
801
|
if (!col) return data;
|
|
694
802
|
const accessor = col.sortAccessor ?? ((row) => {
|
|
695
|
-
const value = row[
|
|
803
|
+
const value = row[effectiveKey];
|
|
696
804
|
return typeof value === "string" || typeof value === "number" ? value : null;
|
|
697
805
|
});
|
|
698
806
|
const copy = [...data];
|
|
@@ -703,26 +811,28 @@ function SortableTable({
|
|
|
703
811
|
if (av == null) return 1;
|
|
704
812
|
if (bv == null) return -1;
|
|
705
813
|
if (typeof av === "number" && typeof bv === "number") {
|
|
706
|
-
return
|
|
814
|
+
return effectiveDirection === "asc" ? av - bv : bv - av;
|
|
707
815
|
}
|
|
708
816
|
const as = String(av).toLowerCase();
|
|
709
817
|
const bs = String(bv).toLowerCase();
|
|
710
|
-
if (as < bs) return
|
|
711
|
-
if (as > bs) return
|
|
818
|
+
if (as < bs) return effectiveDirection === "asc" ? -1 : 1;
|
|
819
|
+
if (as > bs) return effectiveDirection === "asc" ? 1 : -1;
|
|
712
820
|
return 0;
|
|
713
821
|
});
|
|
714
822
|
return copy;
|
|
715
|
-
}, [data, columns,
|
|
823
|
+
}, [data, columns, effectiveKey, effectiveDirection]);
|
|
716
824
|
const handleSortClick = (key) => {
|
|
717
825
|
let nextDirection;
|
|
718
|
-
if (activeKey
|
|
826
|
+
if (!activeKey || !activeDirection) {
|
|
827
|
+
nextDirection = baselineKey === key && baselineDirection ? baselineDirection : "asc";
|
|
828
|
+
} else if (activeKey !== key) {
|
|
719
829
|
nextDirection = "asc";
|
|
830
|
+
} else if (baselineKey === key && baselineDirection) {
|
|
831
|
+
nextDirection = activeDirection === baselineDirection ? baselineDirection === "asc" ? "desc" : "asc" : null;
|
|
720
832
|
} else if (activeDirection === "asc") {
|
|
721
833
|
nextDirection = "desc";
|
|
722
|
-
} else if (activeDirection === "desc") {
|
|
723
|
-
nextDirection = null;
|
|
724
834
|
} else {
|
|
725
|
-
nextDirection =
|
|
835
|
+
nextDirection = null;
|
|
726
836
|
}
|
|
727
837
|
const nextKey = nextDirection === null ? null : key;
|
|
728
838
|
if (isControlled) {
|
|
@@ -733,13 +843,13 @@ function SortableTable({
|
|
|
733
843
|
onSortChange?.(nextKey, nextDirection);
|
|
734
844
|
}
|
|
735
845
|
};
|
|
736
|
-
return /* @__PURE__ */
|
|
737
|
-
header && /* @__PURE__ */
|
|
738
|
-
sorted.length === 0 ? /* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
846
|
+
return /* @__PURE__ */ jsx15("div", { className: cn("fractal-sortable-table", `fractal-sortable-table--${size}`, embedded && "fractal-sortable-table--embedded", className), children: /* @__PURE__ */ jsxs11("div", { className: "fractal-sortable-table-surface", children: [
|
|
847
|
+
header && /* @__PURE__ */ jsx15("div", { className: "fractal-sortable-table-header", children: header }),
|
|
848
|
+
sorted.length === 0 ? /* @__PURE__ */ jsx15("div", { className: "fractal-sortable-table-empty", children: emptyMessage || "No data" }) : /* @__PURE__ */ jsxs11("table", { className: "fractal-sortable-table-table", children: [
|
|
849
|
+
/* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsx15("tr", { className: "fractal-sortable-table-thead-row", children: columns.map((col) => {
|
|
740
850
|
const isActive = activeKey === col.key && activeDirection !== null;
|
|
741
851
|
if (!col.sortable) {
|
|
742
|
-
return /* @__PURE__ */
|
|
852
|
+
return /* @__PURE__ */ jsx15(
|
|
743
853
|
"th",
|
|
744
854
|
{
|
|
745
855
|
className: "fractal-sortable-table-th",
|
|
@@ -749,12 +859,12 @@ function SortableTable({
|
|
|
749
859
|
col.key
|
|
750
860
|
);
|
|
751
861
|
}
|
|
752
|
-
return /* @__PURE__ */
|
|
862
|
+
return /* @__PURE__ */ jsx15(
|
|
753
863
|
"th",
|
|
754
864
|
{
|
|
755
865
|
className: "fractal-sortable-table-th fractal-sortable-table-th--sortable",
|
|
756
866
|
style: { width: col.width },
|
|
757
|
-
children: /* @__PURE__ */
|
|
867
|
+
children: /* @__PURE__ */ jsxs11(
|
|
758
868
|
"button",
|
|
759
869
|
{
|
|
760
870
|
type: "button",
|
|
@@ -765,8 +875,8 @@ function SortableTable({
|
|
|
765
875
|
onClick: () => handleSortClick(col.key),
|
|
766
876
|
"aria-sort": isActive ? activeDirection === "asc" ? "ascending" : "descending" : "none",
|
|
767
877
|
children: [
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
878
|
+
/* @__PURE__ */ jsx15("span", { children: col.header }),
|
|
879
|
+
/* @__PURE__ */ jsx15("span", { className: "fractal-sortable-table-sort-icon", "aria-hidden": "true", children: isActive && activeDirection === "asc" ? /* @__PURE__ */ jsx15(ArrowUp, { size: 14 }) : isActive && activeDirection === "desc" ? /* @__PURE__ */ jsx15(ArrowDown, { size: 14 }) : /* @__PURE__ */ jsx15(ArrowsUpDown, { size: 14 }) })
|
|
770
880
|
]
|
|
771
881
|
}
|
|
772
882
|
)
|
|
@@ -774,21 +884,42 @@ function SortableTable({
|
|
|
774
884
|
col.key
|
|
775
885
|
);
|
|
776
886
|
}) }) }),
|
|
777
|
-
/* @__PURE__ */
|
|
887
|
+
/* @__PURE__ */ jsx15("tbody", { children: sorted.map((row, rowIndex) => {
|
|
778
888
|
const highlighted = highlightRow?.(row, rowIndex) ?? false;
|
|
779
|
-
|
|
889
|
+
const action = rowAction ? {
|
|
890
|
+
label: rowAction.label(row, rowIndex),
|
|
891
|
+
icon: rowAction.icon(row, rowIndex)
|
|
892
|
+
} : null;
|
|
893
|
+
return /* @__PURE__ */ jsx15(
|
|
780
894
|
"tr",
|
|
781
895
|
{
|
|
782
896
|
className: cn(
|
|
783
897
|
"fractal-sortable-table-row",
|
|
784
|
-
highlighted && "fractal-sortable-table-row--highlighted"
|
|
898
|
+
highlighted && "fractal-sortable-table-row--highlighted",
|
|
899
|
+
onRowClick && "fractal-sortable-table-row--interactive"
|
|
785
900
|
),
|
|
786
|
-
|
|
901
|
+
onClick: onRowClick ? () => onRowClick(row, rowIndex) : void 0,
|
|
902
|
+
onKeyDown: onRowClick ? (event) => {
|
|
903
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
onRowClick(row, rowIndex);
|
|
906
|
+
}
|
|
907
|
+
} : void 0,
|
|
908
|
+
"aria-label": action?.label,
|
|
909
|
+
role: onRowClick ? "button" : void 0,
|
|
910
|
+
tabIndex: onRowClick ? 0 : void 0,
|
|
911
|
+
children: columns.map((col, columnIndex) => /* @__PURE__ */ jsxs11(
|
|
787
912
|
"td",
|
|
788
913
|
{
|
|
789
|
-
className:
|
|
914
|
+
className: cn(
|
|
915
|
+
"fractal-sortable-table-td",
|
|
916
|
+
action && columnIndex === columns.length - 1 && "fractal-sortable-table-td--row-action"
|
|
917
|
+
),
|
|
790
918
|
style: { width: col.width, textAlign: col.align ?? "left" },
|
|
791
|
-
children:
|
|
919
|
+
children: [
|
|
920
|
+
col.render(row, rowIndex),
|
|
921
|
+
action && columnIndex === columns.length - 1 && /* @__PURE__ */ jsx15("span", { className: "fractal-sortable-table-row-action", "aria-hidden": "true", children: /* @__PURE__ */ jsx15("span", { className: "fractal-sortable-table-row-action__icon", children: action.icon }) })
|
|
922
|
+
]
|
|
792
923
|
},
|
|
793
924
|
col.key
|
|
794
925
|
))
|
|
@@ -801,23 +932,40 @@ function SortableTable({
|
|
|
801
932
|
}
|
|
802
933
|
|
|
803
934
|
// src/components/Tabs/Tabs.tsx
|
|
804
|
-
import { useId, useRef as useRef3, useState as useState4 } from "react";
|
|
805
|
-
import { jsx as
|
|
935
|
+
import { useId as useId2, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
936
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
806
937
|
function Tabs({
|
|
807
938
|
items,
|
|
808
939
|
defaultValue,
|
|
809
940
|
value: controlledValue,
|
|
810
941
|
onValueChange,
|
|
811
942
|
className,
|
|
812
|
-
ariaLabel
|
|
943
|
+
ariaLabel,
|
|
944
|
+
divider = false,
|
|
945
|
+
variant = "line"
|
|
813
946
|
}) {
|
|
814
|
-
const reactId =
|
|
947
|
+
const reactId = useId2();
|
|
815
948
|
const [internalValue, setInternalValue] = useState4(
|
|
816
949
|
defaultValue ?? items.find((i) => !i.disabled)?.id ?? items[0]?.id ?? ""
|
|
817
950
|
);
|
|
818
951
|
const isControlled = controlledValue !== void 0;
|
|
819
952
|
const activeId = isControlled ? controlledValue : internalValue;
|
|
953
|
+
const tabListRef = useRef3(null);
|
|
820
954
|
const tabRefs = useRef3({});
|
|
955
|
+
const [indicator, setIndicator] = useState4(null);
|
|
956
|
+
useLayoutEffect2(() => {
|
|
957
|
+
const updateIndicator = () => {
|
|
958
|
+
const activeTab = tabRefs.current[activeId];
|
|
959
|
+
if (!activeTab) return;
|
|
960
|
+
setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
|
|
961
|
+
};
|
|
962
|
+
updateIndicator();
|
|
963
|
+
const list = tabListRef.current;
|
|
964
|
+
if (!list || typeof ResizeObserver === "undefined") return;
|
|
965
|
+
const observer = new ResizeObserver(updateIndicator);
|
|
966
|
+
observer.observe(list);
|
|
967
|
+
return () => observer.disconnect();
|
|
968
|
+
}, [activeId, items.length]);
|
|
821
969
|
const selectTab = (id) => {
|
|
822
970
|
if (isControlled) {
|
|
823
971
|
onValueChange?.(id);
|
|
@@ -827,6 +975,10 @@ function Tabs({
|
|
|
827
975
|
}
|
|
828
976
|
};
|
|
829
977
|
const focusable = items.filter((i) => !i.disabled);
|
|
978
|
+
const indicatorStyle = indicator ? {
|
|
979
|
+
"--fractal-tabs-indicator-offset": `${indicator.offset}px`,
|
|
980
|
+
"--fractal-tabs-indicator-width": `${indicator.width}px`
|
|
981
|
+
} : void 0;
|
|
830
982
|
const onKeyDown = (event) => {
|
|
831
983
|
const currentIndex = focusable.findIndex((i) => i.id === activeId);
|
|
832
984
|
if (currentIndex === -1) return;
|
|
@@ -852,41 +1004,52 @@ function Tabs({
|
|
|
852
1004
|
selectTab(nextId2);
|
|
853
1005
|
requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
|
|
854
1006
|
};
|
|
855
|
-
return /* @__PURE__ */
|
|
856
|
-
/* @__PURE__ */
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
"
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
id
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1007
|
+
return /* @__PURE__ */ jsxs12("div", { className: cn("fractal-tabs", `fractal-tabs--${variant}`, divider && "fractal-tabs--divider", className), children: [
|
|
1008
|
+
/* @__PURE__ */ jsx16(
|
|
1009
|
+
"div",
|
|
1010
|
+
{
|
|
1011
|
+
ref: tabListRef,
|
|
1012
|
+
role: "tablist",
|
|
1013
|
+
"aria-label": ariaLabel,
|
|
1014
|
+
className: "fractal-tabs-list",
|
|
1015
|
+
"data-indicator-ready": indicator ? "true" : void 0,
|
|
1016
|
+
style: indicatorStyle,
|
|
1017
|
+
children: items.map((item) => {
|
|
1018
|
+
const isActive = item.id === activeId;
|
|
1019
|
+
const tabId = `${reactId}-tab-${item.id}`;
|
|
1020
|
+
const panelId = `${reactId}-panel-${item.id}`;
|
|
1021
|
+
return /* @__PURE__ */ jsx16(
|
|
1022
|
+
"button",
|
|
1023
|
+
{
|
|
1024
|
+
ref: (el) => {
|
|
1025
|
+
tabRefs.current[item.id] = el;
|
|
1026
|
+
},
|
|
1027
|
+
id: tabId,
|
|
1028
|
+
role: "tab",
|
|
1029
|
+
type: "button",
|
|
1030
|
+
"aria-selected": isActive,
|
|
1031
|
+
"aria-controls": panelId,
|
|
1032
|
+
tabIndex: isActive ? 0 : -1,
|
|
1033
|
+
disabled: item.disabled,
|
|
1034
|
+
className: cn(
|
|
1035
|
+
"fractal-tabs-trigger",
|
|
1036
|
+
isActive && "fractal-tabs-trigger--active",
|
|
1037
|
+
item.disabled && "fractal-tabs-trigger--disabled"
|
|
1038
|
+
),
|
|
1039
|
+
onClick: () => !item.disabled && selectTab(item.id),
|
|
1040
|
+
onKeyDown,
|
|
1041
|
+
children: item.label
|
|
1042
|
+
},
|
|
1043
|
+
item.id
|
|
1044
|
+
);
|
|
1045
|
+
})
|
|
1046
|
+
}
|
|
1047
|
+
),
|
|
885
1048
|
items.map((item) => {
|
|
886
1049
|
const tabId = `${reactId}-tab-${item.id}`;
|
|
887
1050
|
const panelId = `${reactId}-panel-${item.id}`;
|
|
888
1051
|
const isActive = item.id === activeId;
|
|
889
|
-
return /* @__PURE__ */
|
|
1052
|
+
return /* @__PURE__ */ jsx16(
|
|
890
1053
|
"div",
|
|
891
1054
|
{
|
|
892
1055
|
id: panelId,
|
|
@@ -902,10 +1065,112 @@ function Tabs({
|
|
|
902
1065
|
] });
|
|
903
1066
|
}
|
|
904
1067
|
|
|
1068
|
+
// src/components/ContentSwitcher/ContentSwitcher.tsx
|
|
1069
|
+
import * as React10 from "react";
|
|
1070
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1071
|
+
function ContentSwitcher({ items, value, onValueChange, ariaLabel, fullWidth = false, className }) {
|
|
1072
|
+
const switcherRef = React10.useRef(null);
|
|
1073
|
+
const buttonRefs = React10.useRef([]);
|
|
1074
|
+
const indicatorMotionReadyRef = React10.useRef(false);
|
|
1075
|
+
const activeIndex = items.findIndex((item) => item.value === value);
|
|
1076
|
+
React10.useLayoutEffect(() => {
|
|
1077
|
+
const switcher = switcherRef.current;
|
|
1078
|
+
const activeButton = buttonRefs.current[activeIndex];
|
|
1079
|
+
let motionFrame = 0;
|
|
1080
|
+
if (!switcher || !activeButton) {
|
|
1081
|
+
switcher?.removeAttribute("data-indicator-ready");
|
|
1082
|
+
switcher?.removeAttribute("data-indicator-animate");
|
|
1083
|
+
indicatorMotionReadyRef.current = false;
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
const updateIndicator = () => {
|
|
1087
|
+
const switcherRect = switcher.getBoundingClientRect();
|
|
1088
|
+
const activeButtonRect = activeButton.getBoundingClientRect();
|
|
1089
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-x", `${activeButtonRect.left - switcherRect.left - switcher.clientLeft}px`);
|
|
1090
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-y", `${activeButtonRect.top - switcherRect.top - switcher.clientTop}px`);
|
|
1091
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-width", `${activeButtonRect.width}px`);
|
|
1092
|
+
switcher.style.setProperty("--fractal-content-switcher-indicator-height", `${activeButtonRect.height}px`);
|
|
1093
|
+
switcher.setAttribute("data-indicator-ready", "true");
|
|
1094
|
+
if (!indicatorMotionReadyRef.current && motionFrame === 0) {
|
|
1095
|
+
motionFrame = window.requestAnimationFrame(() => {
|
|
1096
|
+
indicatorMotionReadyRef.current = true;
|
|
1097
|
+
switcher.setAttribute("data-indicator-animate", "true");
|
|
1098
|
+
motionFrame = 0;
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
updateIndicator();
|
|
1103
|
+
if (typeof ResizeObserver === "undefined") {
|
|
1104
|
+
return () => {
|
|
1105
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
const resizeObserver = new ResizeObserver(updateIndicator);
|
|
1109
|
+
resizeObserver.observe(switcher);
|
|
1110
|
+
buttonRefs.current.forEach((button) => {
|
|
1111
|
+
if (button) resizeObserver.observe(button);
|
|
1112
|
+
});
|
|
1113
|
+
return () => {
|
|
1114
|
+
resizeObserver.disconnect();
|
|
1115
|
+
if (motionFrame !== 0) window.cancelAnimationFrame(motionFrame);
|
|
1116
|
+
};
|
|
1117
|
+
}, [activeIndex, items.length]);
|
|
1118
|
+
const moveFocus = (index, direction) => {
|
|
1119
|
+
let nextIndex = index;
|
|
1120
|
+
do {
|
|
1121
|
+
nextIndex = (nextIndex + direction + items.length) % items.length;
|
|
1122
|
+
} while (items[nextIndex]?.disabled && nextIndex !== index);
|
|
1123
|
+
if (!items[nextIndex]?.disabled) {
|
|
1124
|
+
buttonRefs.current[nextIndex]?.focus();
|
|
1125
|
+
onValueChange(items[nextIndex].value);
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
return /* @__PURE__ */ jsxs13(
|
|
1129
|
+
"div",
|
|
1130
|
+
{
|
|
1131
|
+
className: cn("fractal-content-switcher", fullWidth && "fractal-content-switcher--full-width", className),
|
|
1132
|
+
role: "group",
|
|
1133
|
+
"aria-label": ariaLabel,
|
|
1134
|
+
ref: switcherRef,
|
|
1135
|
+
children: [
|
|
1136
|
+
/* @__PURE__ */ jsx17("span", { className: "fractal-content-switcher__indicator", "aria-hidden": true }),
|
|
1137
|
+
items.map((item, index) => {
|
|
1138
|
+
const active = item.value === value;
|
|
1139
|
+
return /* @__PURE__ */ jsx17(
|
|
1140
|
+
"button",
|
|
1141
|
+
{
|
|
1142
|
+
className: cn("fractal-content-switcher__item", active && "fractal-content-switcher__item--active"),
|
|
1143
|
+
type: "button",
|
|
1144
|
+
"aria-pressed": active,
|
|
1145
|
+
disabled: item.disabled,
|
|
1146
|
+
onClick: () => onValueChange(item.value),
|
|
1147
|
+
onKeyDown: (event) => {
|
|
1148
|
+
if (event.key === "ArrowRight") {
|
|
1149
|
+
event.preventDefault();
|
|
1150
|
+
moveFocus(index, 1);
|
|
1151
|
+
}
|
|
1152
|
+
if (event.key === "ArrowLeft") {
|
|
1153
|
+
event.preventDefault();
|
|
1154
|
+
moveFocus(index, -1);
|
|
1155
|
+
}
|
|
1156
|
+
},
|
|
1157
|
+
ref: (element) => {
|
|
1158
|
+
buttonRefs.current[index] = element;
|
|
1159
|
+
},
|
|
1160
|
+
children: item.label
|
|
1161
|
+
},
|
|
1162
|
+
item.value
|
|
1163
|
+
);
|
|
1164
|
+
})
|
|
1165
|
+
]
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
905
1170
|
// src/components/Disclosure/Disclosure.tsx
|
|
906
|
-
import { useId as
|
|
907
|
-
import { ChevronRight, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
908
|
-
import { jsx as
|
|
1171
|
+
import { useId as useId3, useState as useState5 } from "react";
|
|
1172
|
+
import { ChevronRight as ChevronRight2, ChevronDown as ChevronDown2 } from "@mirror-physics/fractal-icons";
|
|
1173
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
909
1174
|
function Disclosure({
|
|
910
1175
|
title,
|
|
911
1176
|
meta,
|
|
@@ -913,16 +1178,18 @@ function Disclosure({
|
|
|
913
1178
|
defaultOpen = false,
|
|
914
1179
|
open: controlledOpen,
|
|
915
1180
|
onOpenChange,
|
|
1181
|
+
disabled = false,
|
|
916
1182
|
className,
|
|
917
1183
|
variant = "card"
|
|
918
1184
|
}) {
|
|
919
|
-
const reactId =
|
|
1185
|
+
const reactId = useId3();
|
|
920
1186
|
const headerId = `${reactId}-header`;
|
|
921
1187
|
const panelId = `${reactId}-panel`;
|
|
922
1188
|
const [internalOpen, setInternalOpen] = useState5(defaultOpen);
|
|
923
1189
|
const isControlled = controlledOpen !== void 0;
|
|
924
1190
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
925
1191
|
const toggle = () => {
|
|
1192
|
+
if (disabled) return;
|
|
926
1193
|
const next = !isOpen;
|
|
927
1194
|
if (isControlled) {
|
|
928
1195
|
onOpenChange?.(next);
|
|
@@ -931,17 +1198,18 @@ function Disclosure({
|
|
|
931
1198
|
onOpenChange?.(next);
|
|
932
1199
|
}
|
|
933
1200
|
};
|
|
934
|
-
return /* @__PURE__ */
|
|
1201
|
+
return /* @__PURE__ */ jsxs14(
|
|
935
1202
|
"div",
|
|
936
1203
|
{
|
|
937
1204
|
className: cn(
|
|
938
1205
|
"fractal-disclosure",
|
|
939
1206
|
variant === "card" && "fractal-disclosure--card",
|
|
940
1207
|
isOpen && "fractal-disclosure--open",
|
|
1208
|
+
disabled && "fractal-disclosure--disabled",
|
|
941
1209
|
className
|
|
942
1210
|
),
|
|
943
1211
|
children: [
|
|
944
|
-
/* @__PURE__ */
|
|
1212
|
+
/* @__PURE__ */ jsxs14(
|
|
945
1213
|
"button",
|
|
946
1214
|
{
|
|
947
1215
|
type: "button",
|
|
@@ -949,15 +1217,16 @@ function Disclosure({
|
|
|
949
1217
|
className: "fractal-disclosure-trigger",
|
|
950
1218
|
"aria-expanded": isOpen,
|
|
951
1219
|
"aria-controls": panelId,
|
|
1220
|
+
disabled,
|
|
952
1221
|
onClick: toggle,
|
|
953
1222
|
children: [
|
|
954
|
-
/* @__PURE__ */
|
|
955
|
-
/* @__PURE__ */
|
|
956
|
-
meta && /* @__PURE__ */
|
|
1223
|
+
/* @__PURE__ */ jsx18("span", { className: "fractal-disclosure-icon", "aria-hidden": "true", children: isOpen ? /* @__PURE__ */ jsx18(ChevronDown2, { size: 16 }) : /* @__PURE__ */ jsx18(ChevronRight2, { size: 16 }) }),
|
|
1224
|
+
/* @__PURE__ */ jsx18("span", { className: "fractal-disclosure-title", children: title }),
|
|
1225
|
+
meta && /* @__PURE__ */ jsx18("span", { className: "fractal-disclosure-meta", children: meta })
|
|
957
1226
|
]
|
|
958
1227
|
}
|
|
959
1228
|
),
|
|
960
|
-
/* @__PURE__ */
|
|
1229
|
+
/* @__PURE__ */ jsx18(
|
|
961
1230
|
"div",
|
|
962
1231
|
{
|
|
963
1232
|
id: panelId,
|
|
@@ -965,7 +1234,7 @@ function Disclosure({
|
|
|
965
1234
|
"aria-labelledby": headerId,
|
|
966
1235
|
className: "fractal-disclosure-panel",
|
|
967
1236
|
hidden: !isOpen,
|
|
968
|
-
children: /* @__PURE__ */
|
|
1237
|
+
children: /* @__PURE__ */ jsx18("div", { className: "fractal-disclosure-panel-inner", children })
|
|
969
1238
|
}
|
|
970
1239
|
)
|
|
971
1240
|
]
|
|
@@ -973,39 +1242,232 @@ function Disclosure({
|
|
|
973
1242
|
);
|
|
974
1243
|
}
|
|
975
1244
|
|
|
1245
|
+
// src/components/LatticeLoader/LatticeLoader.tsx
|
|
1246
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1247
|
+
var LATTICE_COUNT = 160;
|
|
1248
|
+
var WAVE_PERIOD = 80;
|
|
1249
|
+
function LatticeLoader({ className, label = "Loading", ...props }) {
|
|
1250
|
+
return /* @__PURE__ */ jsx19(
|
|
1251
|
+
"span",
|
|
1252
|
+
{
|
|
1253
|
+
"aria-label": label,
|
|
1254
|
+
className: cn("fractal-lattice-loader", className),
|
|
1255
|
+
role: "progressbar",
|
|
1256
|
+
...props,
|
|
1257
|
+
children: Array.from({ length: LATTICE_COUNT }, (_, index) => /* @__PURE__ */ jsx19(
|
|
1258
|
+
"span",
|
|
1259
|
+
{
|
|
1260
|
+
"aria-hidden": "true",
|
|
1261
|
+
className: "fractal-lattice-loader__cell",
|
|
1262
|
+
style: { "--fractal-lattice-index": index % WAVE_PERIOD }
|
|
1263
|
+
},
|
|
1264
|
+
index
|
|
1265
|
+
))
|
|
1266
|
+
}
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
// src/components/Ghost/Ghost.tsx
|
|
1271
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1272
|
+
var toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
1273
|
+
function Ghost({ className, width, height, radius, style, ...props }) {
|
|
1274
|
+
return /* @__PURE__ */ jsx20(
|
|
1275
|
+
"div",
|
|
1276
|
+
{
|
|
1277
|
+
"aria-hidden": "true",
|
|
1278
|
+
className: cn("fractal-ghost", className),
|
|
1279
|
+
style: {
|
|
1280
|
+
width: toCssLength(width),
|
|
1281
|
+
height: toCssLength(height),
|
|
1282
|
+
borderRadius: toCssLength(radius),
|
|
1283
|
+
...style
|
|
1284
|
+
},
|
|
1285
|
+
...props
|
|
1286
|
+
}
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
function GhostLine({ className, size = "md", width = "100%", ...props }) {
|
|
1290
|
+
return /* @__PURE__ */ jsx20(Ghost, { className: cn("fractal-ghost-line", `fractal-ghost-line--${size}`, className), width, ...props });
|
|
1291
|
+
}
|
|
1292
|
+
function ButtonGhost({ className, size = "md", iconOnly = false, width, ...props }) {
|
|
1293
|
+
return /* @__PURE__ */ jsx20(Ghost, { className: cn("fractal-ghost-button", `fractal-ghost-button--${size}`, iconOnly && "fractal-ghost-button--icon-only", className), width, ...props });
|
|
1294
|
+
}
|
|
1295
|
+
function CardGhost({ className, lines = 3, showHeader = true, ...props }) {
|
|
1296
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-card", className), ...props, children: [
|
|
1297
|
+
showHeader && /* @__PURE__ */ jsx20(GhostLine, { width: "38%" }),
|
|
1298
|
+
/* @__PURE__ */ jsx20("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx20(GhostLine, { width: index === lines - 1 ? "62%" : "100%" }, index)) })
|
|
1299
|
+
] });
|
|
1300
|
+
}
|
|
1301
|
+
function DataTableGhost({
|
|
1302
|
+
className,
|
|
1303
|
+
showHeader = true,
|
|
1304
|
+
headers,
|
|
1305
|
+
columns = 4,
|
|
1306
|
+
rows = 5,
|
|
1307
|
+
columnWidths,
|
|
1308
|
+
size = "md",
|
|
1309
|
+
...props
|
|
1310
|
+
}) {
|
|
1311
|
+
const cells = Array.from({ length: columns }, (_, index) => index);
|
|
1312
|
+
return /* @__PURE__ */ jsx20("div", { "aria-busy": "true", "aria-label": "Loading table", className: cn("fractal-ghost-table", `fractal-ghost-table--${size}`, className), role: "status", ...props, children: /* @__PURE__ */ jsxs15("table", { className: "fractal-ghost-table__table", children: [
|
|
1313
|
+
(showHeader || headers) && /* @__PURE__ */ jsx20("thead", { children: /* @__PURE__ */ jsx20("tr", { className: "fractal-ghost-table__head-row", children: cells.map((index) => /* @__PURE__ */ jsx20("th", { style: { width: columnWidths?.[index] }, children: headers?.[index] ?? /* @__PURE__ */ jsx20(GhostLine, { size: "sm", width: index === columns - 1 ? "62%" : "76%" }) }, index)) }) }),
|
|
1314
|
+
/* @__PURE__ */ jsx20("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx20("tr", { className: "fractal-ghost-table__row", children: cells.map((columnIndex) => /* @__PURE__ */ jsx20("td", { style: { width: columnWidths?.[columnIndex] }, children: /* @__PURE__ */ jsx20(GhostLine, { width: `${[72, 54, 82, 63, 46][(rowIndex + columnIndex) % 5]}%` }) }, columnIndex)) }, rowIndex)) })
|
|
1315
|
+
] }) });
|
|
1316
|
+
}
|
|
1317
|
+
function InputGhost({ className, labelWidth = "26%", ...props }) {
|
|
1318
|
+
return /* @__PURE__ */ jsx20(FormFieldGhost, { className, labelWidth, ...props });
|
|
1319
|
+
}
|
|
1320
|
+
function TextareaGhost({ className, labelWidth = "26%", ...props }) {
|
|
1321
|
+
return /* @__PURE__ */ jsx20(FormFieldGhost, { className, labelWidth, multiline: true, ...props });
|
|
1322
|
+
}
|
|
1323
|
+
function LabelGhost({ className, width = "26%", ...props }) {
|
|
1324
|
+
return /* @__PURE__ */ jsx20(GhostLine, { className: cn("fractal-ghost-label", className), size: "sm", width, ...props });
|
|
1325
|
+
}
|
|
1326
|
+
function FormFieldGhost({ className, labelWidth = "26%", multiline = false, ...props }) {
|
|
1327
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-field", className), ...props, children: [
|
|
1328
|
+
/* @__PURE__ */ jsx20(LabelGhost, { width: labelWidth }),
|
|
1329
|
+
/* @__PURE__ */ jsx20(Ghost, { className: cn("fractal-ghost-field__control", multiline && "fractal-ghost-field__control--multiline") })
|
|
1330
|
+
] });
|
|
1331
|
+
}
|
|
1332
|
+
function AlertGhost({ className, ...props }) {
|
|
1333
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-alert", className), ...props, children: [
|
|
1334
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "30%" }),
|
|
1335
|
+
/* @__PURE__ */ jsx20(GhostLine, { size: "sm", width: "78%" })
|
|
1336
|
+
] });
|
|
1337
|
+
}
|
|
1338
|
+
function CheckboxGhost({ className, ...props }) {
|
|
1339
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-choice", className), ...props, children: [
|
|
1340
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-choice__control" }),
|
|
1341
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "42%" })
|
|
1342
|
+
] });
|
|
1343
|
+
}
|
|
1344
|
+
var ToggleGhost = CheckboxGhost;
|
|
1345
|
+
function ChipGhost({ className, width = 74, ...props }) {
|
|
1346
|
+
return /* @__PURE__ */ jsx20(Ghost, { className: cn("fractal-ghost-chip", className), height: 24, width, ...props });
|
|
1347
|
+
}
|
|
1348
|
+
function LinkGhost({ className, width = 96, ...props }) {
|
|
1349
|
+
return /* @__PURE__ */ jsx20(GhostLine, { className: cn("fractal-ghost-link", className), size: "sm", width, ...props });
|
|
1350
|
+
}
|
|
1351
|
+
var TextButtonGhost = LinkGhost;
|
|
1352
|
+
function DropdownGhost({ className, ...props }) {
|
|
1353
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropdown", className), ...props, children: [
|
|
1354
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "38%" }),
|
|
1355
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-dropdown__chevron" })
|
|
1356
|
+
] });
|
|
1357
|
+
}
|
|
1358
|
+
function ContentSwitcherGhost({ className, options = 3, ...props }) {
|
|
1359
|
+
return /* @__PURE__ */ jsx20("div", { "aria-hidden": "true", className: cn("fractal-ghost-switcher", className), ...props, children: Array.from({ length: options }, (_, index) => /* @__PURE__ */ jsx20(Ghost, {}, index)) });
|
|
1360
|
+
}
|
|
1361
|
+
var TabsGhost = ContentSwitcherGhost;
|
|
1362
|
+
function DisclosureGhost({ className, ...props }) {
|
|
1363
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-disclosure", className), ...props, children: [
|
|
1364
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-disclosure__icon" }),
|
|
1365
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "42%" })
|
|
1366
|
+
] });
|
|
1367
|
+
}
|
|
1368
|
+
function PaginationGhost({ className, pages = 5, ...props }) {
|
|
1369
|
+
return /* @__PURE__ */ jsx20("div", { "aria-hidden": "true", className: cn("fractal-ghost-pagination", className), ...props, children: Array.from({ length: pages }, (_, index) => /* @__PURE__ */ jsx20(Ghost, {}, index)) });
|
|
1370
|
+
}
|
|
1371
|
+
function FileDropzoneGhost({ className, ...props }) {
|
|
1372
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-dropzone", className), ...props, children: [
|
|
1373
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-dropzone__icon" }),
|
|
1374
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "26%" }),
|
|
1375
|
+
/* @__PURE__ */ jsx20(GhostLine, { size: "sm", width: "46%" })
|
|
1376
|
+
] });
|
|
1377
|
+
}
|
|
1378
|
+
function PromptCardGhost({ className, ...props }) {
|
|
1379
|
+
return /* @__PURE__ */ jsx20(CardGhost, { className: cn("fractal-ghost-prompt-card", className), lines: 4, ...props });
|
|
1380
|
+
}
|
|
1381
|
+
function SortableTableGhost(props) {
|
|
1382
|
+
return /* @__PURE__ */ jsx20(DataTableGhost, { ...props });
|
|
1383
|
+
}
|
|
1384
|
+
function SidebarGhost({ className, items = 6, ...props }) {
|
|
1385
|
+
return /* @__PURE__ */ jsxs15("aside", { "aria-hidden": "true", className: cn("fractal-ghost-sidebar", className), ...props, children: [
|
|
1386
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-sidebar__brand" }),
|
|
1387
|
+
/* @__PURE__ */ jsx20("div", { className: "fractal-ghost-sidebar__items", children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs15("div", { className: "fractal-ghost-sidebar__item", children: [
|
|
1388
|
+
/* @__PURE__ */ jsx20(Ghost, {}),
|
|
1389
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: `${[54, 68, 44, 61][index % 4]}%` })
|
|
1390
|
+
] }, index)) })
|
|
1391
|
+
] });
|
|
1392
|
+
}
|
|
1393
|
+
function ModalGhost({ className, title, lines = 3, ...props }) {
|
|
1394
|
+
return /* @__PURE__ */ jsx20(SurfaceGhost, { className: cn("fractal-ghost-modal", className), title, lines, ...props });
|
|
1395
|
+
}
|
|
1396
|
+
function SidePanelGhost({ className, title, lines = 5, ...props }) {
|
|
1397
|
+
return /* @__PURE__ */ jsx20(SurfaceGhost, { className: cn("fractal-ghost-side-panel", className), title, lines, ...props });
|
|
1398
|
+
}
|
|
1399
|
+
function SurfaceGhost({ className, title, lines = 3, ...props }) {
|
|
1400
|
+
return /* @__PURE__ */ jsxs15("div", { "aria-hidden": "true", className: cn("fractal-ghost-surface", className), ...props, children: [
|
|
1401
|
+
/* @__PURE__ */ jsxs15("div", { className: "fractal-ghost-surface__header", children: [
|
|
1402
|
+
/* @__PURE__ */ jsx20(GhostLine, { width: "42%" }),
|
|
1403
|
+
/* @__PURE__ */ jsx20(Ghost, { className: "fractal-ghost-surface__close" })
|
|
1404
|
+
] }),
|
|
1405
|
+
title && /* @__PURE__ */ jsx20("div", { className: "fractal-ghost-surface__title", children: title }),
|
|
1406
|
+
/* @__PURE__ */ jsx20("div", { className: "fractal-ghost-stack", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx20(GhostLine, { width: index === lines - 1 ? "64%" : "100%" }, index)) })
|
|
1407
|
+
] });
|
|
1408
|
+
}
|
|
1409
|
+
|
|
976
1410
|
// src/components/Sidebar/Sidebar.tsx
|
|
977
|
-
import * as
|
|
978
|
-
import { jsx as
|
|
979
|
-
var Sidebar =
|
|
980
|
-
({ className, width, style, ...props }, ref) => /* @__PURE__ */
|
|
1411
|
+
import * as React11 from "react";
|
|
1412
|
+
import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1413
|
+
var Sidebar = React11.forwardRef(
|
|
1414
|
+
({ className, width, compact = false, style, ...props }, ref) => /* @__PURE__ */ jsx21(
|
|
981
1415
|
"aside",
|
|
982
1416
|
{
|
|
983
1417
|
ref,
|
|
984
1418
|
className: cn("fractal-sidebar", className),
|
|
1419
|
+
"data-compact": compact || void 0,
|
|
985
1420
|
style: { ...style, ...width ? { "--fractal-sidebar-width": width } : {} },
|
|
986
1421
|
...props
|
|
987
1422
|
}
|
|
988
1423
|
)
|
|
989
1424
|
);
|
|
990
1425
|
Sidebar.displayName = "Sidebar";
|
|
991
|
-
var SidebarHeader =
|
|
992
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1426
|
+
var SidebarHeader = React11.forwardRef(
|
|
1427
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx21("div", { ref, className: cn("fractal-sidebar__header", className), ...props })
|
|
993
1428
|
);
|
|
994
1429
|
SidebarHeader.displayName = "SidebarHeader";
|
|
995
|
-
var SidebarBrand =
|
|
996
|
-
({ className, type = "button", ...props }, ref) => /* @__PURE__ */
|
|
1430
|
+
var SidebarBrand = React11.forwardRef(
|
|
1431
|
+
({ className, type = "button", ...props }, ref) => /* @__PURE__ */ jsx21("button", { ref, type, className: cn("fractal-sidebar__brand", className), ...props })
|
|
997
1432
|
);
|
|
998
1433
|
SidebarBrand.displayName = "SidebarBrand";
|
|
999
|
-
|
|
1000
|
-
|
|
1434
|
+
function SidebarAccountMenu({
|
|
1435
|
+
name,
|
|
1436
|
+
items,
|
|
1437
|
+
onSelect,
|
|
1438
|
+
triggerLabel = "Account menu",
|
|
1439
|
+
icon,
|
|
1440
|
+
className
|
|
1441
|
+
}) {
|
|
1442
|
+
return /* @__PURE__ */ jsx21(
|
|
1443
|
+
Dropdown,
|
|
1444
|
+
{
|
|
1445
|
+
align: "left",
|
|
1446
|
+
className: cn("fractal-sidebar__account", className),
|
|
1447
|
+
items,
|
|
1448
|
+
onSelect,
|
|
1449
|
+
panelClassName: "fractal-sidebar__account-panel",
|
|
1450
|
+
selectedValue: "",
|
|
1451
|
+
triggerClassName: "fractal-sidebar__account-trigger",
|
|
1452
|
+
triggerContent: /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
1453
|
+
icon && /* @__PURE__ */ jsx21("span", { className: "fractal-sidebar__account-icon", "aria-hidden": "true", children: icon }),
|
|
1454
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-sidebar__account-name", children: name })
|
|
1455
|
+
] }),
|
|
1456
|
+
triggerLabel,
|
|
1457
|
+
triggerVariant: "tertiary"
|
|
1458
|
+
}
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1461
|
+
var SidebarNav = React11.forwardRef(
|
|
1462
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx21("nav", { ref, className: cn("fractal-sidebar__nav", className), ...props })
|
|
1001
1463
|
);
|
|
1002
1464
|
SidebarNav.displayName = "SidebarNav";
|
|
1003
|
-
var SidebarSection =
|
|
1004
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1465
|
+
var SidebarSection = React11.forwardRef(
|
|
1466
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx21("div", { ref, className: cn("fractal-sidebar__section", className), ...props })
|
|
1005
1467
|
);
|
|
1006
1468
|
SidebarSection.displayName = "SidebarSection";
|
|
1007
|
-
var SidebarNavItem =
|
|
1008
|
-
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */
|
|
1469
|
+
var SidebarNavItem = React11.forwardRef(
|
|
1470
|
+
({ active = false, icon, endAdornment, className, type = "button", children, ...props }, ref) => /* @__PURE__ */ jsxs16(
|
|
1009
1471
|
"button",
|
|
1010
1472
|
{
|
|
1011
1473
|
ref,
|
|
@@ -1015,66 +1477,314 @@ var SidebarNavItem = React10.forwardRef(
|
|
|
1015
1477
|
"aria-current": active ? "page" : void 0,
|
|
1016
1478
|
...props,
|
|
1017
1479
|
children: [
|
|
1018
|
-
icon && /* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
endAdornment && /* @__PURE__ */
|
|
1480
|
+
icon && /* @__PURE__ */ jsx21("span", { className: "fractal-sidebar__nav-item-icon", "aria-hidden": "true", children: icon }),
|
|
1481
|
+
/* @__PURE__ */ jsx21("span", { className: "fractal-sidebar__nav-item-label", children }),
|
|
1482
|
+
endAdornment && /* @__PURE__ */ jsx21("span", { className: "fractal-sidebar__nav-item-end", children: endAdornment })
|
|
1021
1483
|
]
|
|
1022
1484
|
}
|
|
1023
1485
|
)
|
|
1024
1486
|
);
|
|
1025
1487
|
SidebarNavItem.displayName = "SidebarNavItem";
|
|
1026
|
-
var SidebarFooter =
|
|
1027
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
1488
|
+
var SidebarFooter = React11.forwardRef(
|
|
1489
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx21("div", { ref, className: cn("fractal-sidebar__footer", className), ...props })
|
|
1028
1490
|
);
|
|
1029
1491
|
SidebarFooter.displayName = "SidebarFooter";
|
|
1030
1492
|
|
|
1031
|
-
// src/components/
|
|
1032
|
-
import
|
|
1033
|
-
import {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1493
|
+
// src/components/SidePanel/SidePanel.tsx
|
|
1494
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
1495
|
+
import { Close } from "@mirror-physics/fractal-icons";
|
|
1496
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1497
|
+
function SidePanel({ open, onClose, title, description, children, footer, size = "md", loading = false, loadingLabel = "Loading", className }) {
|
|
1498
|
+
useEscapeDismiss(80, onClose, open);
|
|
1499
|
+
if (!open) return null;
|
|
1500
|
+
return createPortal2(
|
|
1501
|
+
/* @__PURE__ */ jsx22("div", { className: "fractal-side-panel-overlay", onMouseDown: onClose, children: /* @__PURE__ */ jsxs17(
|
|
1502
|
+
"aside",
|
|
1503
|
+
{
|
|
1504
|
+
className: cn("fractal-side-panel", `fractal-side-panel--${size}`, className),
|
|
1505
|
+
"aria-modal": "true",
|
|
1506
|
+
"aria-label": typeof title === "string" ? title : "Side panel",
|
|
1507
|
+
role: "dialog",
|
|
1508
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1509
|
+
children: [
|
|
1510
|
+
/* @__PURE__ */ jsxs17("header", { className: "fractal-side-panel__header", children: [
|
|
1511
|
+
/* @__PURE__ */ jsxs17("div", { className: "fractal-side-panel__heading", children: [
|
|
1512
|
+
typeof title === "string" ? /* @__PURE__ */ jsx22("h2", { className: "fractal-side-panel__title", children: title }) : /* @__PURE__ */ jsx22("div", { className: "fractal-side-panel__title", children: title }),
|
|
1513
|
+
description && /* @__PURE__ */ jsx22("p", { className: "fractal-side-panel__description", children: description })
|
|
1514
|
+
] }),
|
|
1515
|
+
/* @__PURE__ */ jsx22("button", { type: "button", className: "fractal-side-panel__close", "aria-label": "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx22(Close, { size: 18 }) })
|
|
1516
|
+
] }),
|
|
1517
|
+
/* @__PURE__ */ jsx22("div", { "aria-busy": loading || void 0, className: cn("fractal-side-panel__body", loading && "fractal-side-panel__body--loading"), children: loading ? /* @__PURE__ */ jsx22(UILoader, { label: loadingLabel }) : children }),
|
|
1518
|
+
footer && /* @__PURE__ */ jsx22("footer", { className: "fractal-side-panel__footer", children: footer })
|
|
1519
|
+
]
|
|
1520
|
+
}
|
|
1521
|
+
) }),
|
|
1522
|
+
document.body
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
// src/components/Textarea/Textarea.tsx
|
|
1527
|
+
import * as React12 from "react";
|
|
1528
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1529
|
+
var Textarea = React12.forwardRef(
|
|
1530
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx23("textarea", { ref, className: cn("fractal-textarea", className), ...props })
|
|
1531
|
+
);
|
|
1532
|
+
Textarea.displayName = "Textarea";
|
|
1533
|
+
|
|
1534
|
+
// src/components/TextButton/TextButton.tsx
|
|
1535
|
+
import * as React13 from "react";
|
|
1536
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1537
|
+
var TextButton = React13.forwardRef(
|
|
1538
|
+
({ className, icon, iconPosition = "start", size = "md", tone = "primary", children, ...props }, ref) => /* @__PURE__ */ jsxs18(
|
|
1539
|
+
"button",
|
|
1540
|
+
{
|
|
1541
|
+
ref,
|
|
1542
|
+
className: cn("fractal-text-button", `fractal-text-button--${size}`, `fractal-text-button--${tone}`, className),
|
|
1543
|
+
type: "button",
|
|
1544
|
+
...props,
|
|
1545
|
+
children: [
|
|
1546
|
+
icon && iconPosition === "start" && /* @__PURE__ */ jsx24("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon }),
|
|
1547
|
+
/* @__PURE__ */ jsx24("span", { children }),
|
|
1548
|
+
icon && iconPosition === "end" && /* @__PURE__ */ jsx24("span", { className: "fractal-text-button__icon", "aria-hidden": "true", children: icon })
|
|
1549
|
+
]
|
|
1550
|
+
}
|
|
1551
|
+
)
|
|
1042
1552
|
);
|
|
1043
|
-
|
|
1553
|
+
TextButton.displayName = "TextButton";
|
|
1554
|
+
|
|
1555
|
+
// src/components/FileDropzone/FileDropzone.tsx
|
|
1556
|
+
import * as React14 from "react";
|
|
1557
|
+
import { Close as Close2, FileArrowUp } from "@mirror-physics/fractal-icons";
|
|
1558
|
+
import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1559
|
+
function FileDropzone({
|
|
1560
|
+
files,
|
|
1561
|
+
onFilesChange,
|
|
1562
|
+
accept,
|
|
1563
|
+
multiple = true,
|
|
1564
|
+
disabled = false,
|
|
1565
|
+
title = "Drop files here or click to browse",
|
|
1566
|
+
description = "Files stay attached to this record.",
|
|
1567
|
+
className
|
|
1568
|
+
}) {
|
|
1569
|
+
const inputId = React14.useId();
|
|
1570
|
+
const inputRef = React14.useRef(null);
|
|
1571
|
+
const [isDragging, setIsDragging] = React14.useState(false);
|
|
1572
|
+
const addFiles = (nextFiles) => {
|
|
1573
|
+
if (disabled) return;
|
|
1574
|
+
const additions = Array.from(nextFiles);
|
|
1575
|
+
if (additions.length === 0) return;
|
|
1576
|
+
onFilesChange(multiple ? [...files, ...additions] : additions.slice(0, 1));
|
|
1577
|
+
};
|
|
1578
|
+
return /* @__PURE__ */ jsxs19("div", { className: cn("fractal-file-dropzone", className), children: [
|
|
1579
|
+
/* @__PURE__ */ jsx25(
|
|
1580
|
+
"input",
|
|
1581
|
+
{
|
|
1582
|
+
ref: inputRef,
|
|
1583
|
+
id: inputId,
|
|
1584
|
+
className: "fractal-file-dropzone__input",
|
|
1585
|
+
type: "file",
|
|
1586
|
+
accept,
|
|
1587
|
+
multiple,
|
|
1588
|
+
disabled,
|
|
1589
|
+
onChange: (event) => {
|
|
1590
|
+
if (event.target.files) addFiles(event.target.files);
|
|
1591
|
+
event.target.value = "";
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
/* @__PURE__ */ jsxs19(
|
|
1596
|
+
"button",
|
|
1597
|
+
{
|
|
1598
|
+
className: "fractal-file-dropzone__target",
|
|
1599
|
+
"data-dragging": isDragging || void 0,
|
|
1600
|
+
type: "button",
|
|
1601
|
+
disabled,
|
|
1602
|
+
onClick: () => inputRef.current?.click(),
|
|
1603
|
+
onDragEnter: (event) => {
|
|
1604
|
+
event.preventDefault();
|
|
1605
|
+
if (!disabled) setIsDragging(true);
|
|
1606
|
+
},
|
|
1607
|
+
onDragOver: (event) => event.preventDefault(),
|
|
1608
|
+
onDragLeave: (event) => {
|
|
1609
|
+
event.preventDefault();
|
|
1610
|
+
setIsDragging(false);
|
|
1611
|
+
},
|
|
1612
|
+
onDrop: (event) => {
|
|
1613
|
+
event.preventDefault();
|
|
1614
|
+
setIsDragging(false);
|
|
1615
|
+
addFiles(event.dataTransfer.files);
|
|
1616
|
+
},
|
|
1617
|
+
children: [
|
|
1618
|
+
/* @__PURE__ */ jsx25(FileArrowUp, { "aria-hidden": "true", size: 20 }),
|
|
1619
|
+
/* @__PURE__ */ jsxs19("span", { className: "fractal-file-dropzone__copy", children: [
|
|
1620
|
+
/* @__PURE__ */ jsx25("span", { className: "fractal-file-dropzone__title", children: title }),
|
|
1621
|
+
description && /* @__PURE__ */ jsx25("span", { className: "fractal-file-dropzone__description", children: description })
|
|
1622
|
+
] })
|
|
1623
|
+
]
|
|
1624
|
+
}
|
|
1625
|
+
),
|
|
1626
|
+
files.length > 0 && /* @__PURE__ */ jsx25("ul", { className: "fractal-file-dropzone__files", "aria-label": "Attached files", children: files.map((file, index) => /* @__PURE__ */ jsxs19("li", { className: "fractal-file-dropzone__file", children: [
|
|
1627
|
+
/* @__PURE__ */ jsx25("span", { className: "fractal-file-dropzone__file-name", children: file.name }),
|
|
1628
|
+
/* @__PURE__ */ jsx25("span", { className: "fractal-file-dropzone__file-meta", children: formatFileSize(file.size) }),
|
|
1629
|
+
/* @__PURE__ */ jsx25(
|
|
1630
|
+
"button",
|
|
1631
|
+
{
|
|
1632
|
+
className: "fractal-file-dropzone__remove",
|
|
1633
|
+
type: "button",
|
|
1634
|
+
"aria-label": `Remove ${file.name}`,
|
|
1635
|
+
disabled,
|
|
1636
|
+
onClick: () => onFilesChange(files.filter((_, fileIndex) => fileIndex !== index)),
|
|
1637
|
+
children: /* @__PURE__ */ jsx25(Close2, { "aria-hidden": "true", size: 14 })
|
|
1638
|
+
}
|
|
1639
|
+
)
|
|
1640
|
+
] }, `${file.name}-${file.size}-${index}`)) })
|
|
1641
|
+
] });
|
|
1642
|
+
}
|
|
1643
|
+
function formatFileSize(bytes) {
|
|
1644
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1645
|
+
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
1646
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
// src/components/Pagination/Pagination.tsx
|
|
1650
|
+
import { ArrowLeft, ArrowRight } from "@mirror-physics/fractal-icons";
|
|
1651
|
+
import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1652
|
+
function Pagination({
|
|
1653
|
+
page,
|
|
1654
|
+
pageSize,
|
|
1655
|
+
totalItems,
|
|
1656
|
+
onPageChange,
|
|
1657
|
+
pageSizeOptions,
|
|
1658
|
+
onPageSizeChange,
|
|
1659
|
+
ariaLabel = "Pagination",
|
|
1660
|
+
className
|
|
1661
|
+
}) {
|
|
1662
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
1663
|
+
const currentPage = Math.min(Math.max(page, 1), totalPages);
|
|
1664
|
+
const start = totalItems === 0 ? 0 : (currentPage - 1) * pageSize + 1;
|
|
1665
|
+
const end = Math.min(currentPage * pageSize, totalItems);
|
|
1666
|
+
const canChangePageSize = pageSizeOptions != null && pageSizeOptions.length > 0 && onPageSizeChange != null;
|
|
1667
|
+
return /* @__PURE__ */ jsxs20("nav", { className: cn("fractal-pagination", className), "aria-label": ariaLabel, children: [
|
|
1668
|
+
/* @__PURE__ */ jsx26("span", { className: "fractal-pagination__summary", children: totalItems === 0 ? "No results" : `${start}-${end} of ${totalItems}` }),
|
|
1669
|
+
/* @__PURE__ */ jsxs20("div", { className: "fractal-pagination__controls", children: [
|
|
1670
|
+
canChangePageSize && /* @__PURE__ */ jsx26(
|
|
1671
|
+
Dropdown,
|
|
1672
|
+
{
|
|
1673
|
+
align: "right",
|
|
1674
|
+
className: "fractal-pagination__page-size",
|
|
1675
|
+
direction: "up",
|
|
1676
|
+
items: pageSizeOptions.map((option) => ({
|
|
1677
|
+
value: String(option),
|
|
1678
|
+
description: `${option} per page`
|
|
1679
|
+
})),
|
|
1680
|
+
onSelect: (value) => onPageSizeChange(Number(value)),
|
|
1681
|
+
selectedValue: String(pageSize),
|
|
1682
|
+
size: "sm",
|
|
1683
|
+
triggerLabel: "Results per page",
|
|
1684
|
+
triggerVariant: "tertiary"
|
|
1685
|
+
}
|
|
1686
|
+
),
|
|
1687
|
+
/* @__PURE__ */ jsx26(
|
|
1688
|
+
"button",
|
|
1689
|
+
{
|
|
1690
|
+
className: "fractal-pagination__button",
|
|
1691
|
+
type: "button",
|
|
1692
|
+
"aria-label": "Previous page",
|
|
1693
|
+
title: "Previous page",
|
|
1694
|
+
disabled: currentPage === 1 || totalItems === 0,
|
|
1695
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1696
|
+
children: /* @__PURE__ */ jsx26(ArrowLeft, { "aria-hidden": "true", size: 16 })
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
/* @__PURE__ */ jsxs20("span", { className: "fractal-pagination__page", "aria-current": "page", children: [
|
|
1700
|
+
currentPage,
|
|
1701
|
+
" of ",
|
|
1702
|
+
totalPages
|
|
1703
|
+
] }),
|
|
1704
|
+
/* @__PURE__ */ jsx26(
|
|
1705
|
+
"button",
|
|
1706
|
+
{
|
|
1707
|
+
className: "fractal-pagination__button",
|
|
1708
|
+
type: "button",
|
|
1709
|
+
"aria-label": "Next page",
|
|
1710
|
+
title: "Next page",
|
|
1711
|
+
disabled: currentPage === totalPages || totalItems === 0,
|
|
1712
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1713
|
+
children: /* @__PURE__ */ jsx26(ArrowRight, { "aria-hidden": "true", size: 16 })
|
|
1714
|
+
}
|
|
1715
|
+
)
|
|
1716
|
+
] })
|
|
1717
|
+
] });
|
|
1718
|
+
}
|
|
1044
1719
|
export {
|
|
1045
1720
|
Alert,
|
|
1046
1721
|
AlertDescription,
|
|
1722
|
+
AlertGhost,
|
|
1047
1723
|
AlertTitle,
|
|
1724
|
+
Breadcrumbs,
|
|
1048
1725
|
Button,
|
|
1726
|
+
ButtonGhost,
|
|
1049
1727
|
Card,
|
|
1050
1728
|
CardContent,
|
|
1051
1729
|
CardDescription,
|
|
1052
1730
|
CardFooter,
|
|
1731
|
+
CardGhost,
|
|
1053
1732
|
CardHeader,
|
|
1054
1733
|
CardTitle,
|
|
1734
|
+
Checkbox,
|
|
1735
|
+
CheckboxGhost,
|
|
1055
1736
|
Chip,
|
|
1737
|
+
ChipGhost,
|
|
1738
|
+
ContentSwitcher,
|
|
1739
|
+
ContentSwitcherGhost,
|
|
1056
1740
|
DataTable,
|
|
1741
|
+
DataTableGhost,
|
|
1057
1742
|
Disclosure,
|
|
1743
|
+
DisclosureGhost,
|
|
1058
1744
|
Dropdown,
|
|
1745
|
+
DropdownGhost,
|
|
1059
1746
|
FeatureCard,
|
|
1747
|
+
FileDropzone,
|
|
1748
|
+
FileDropzoneGhost,
|
|
1060
1749
|
FolderCard,
|
|
1750
|
+
Ghost,
|
|
1751
|
+
GhostLine,
|
|
1061
1752
|
Input,
|
|
1753
|
+
InputGhost,
|
|
1062
1754
|
Label,
|
|
1755
|
+
LabelGhost,
|
|
1756
|
+
LatticeLoader,
|
|
1063
1757
|
Link,
|
|
1758
|
+
LinkGhost,
|
|
1064
1759
|
Modal,
|
|
1065
|
-
|
|
1760
|
+
ModalGhost,
|
|
1761
|
+
Pagination,
|
|
1762
|
+
PaginationGhost,
|
|
1066
1763
|
PromptCard,
|
|
1764
|
+
PromptCardGhost,
|
|
1067
1765
|
PromptGrid,
|
|
1766
|
+
SidePanel,
|
|
1767
|
+
SidePanelGhost,
|
|
1068
1768
|
Sidebar,
|
|
1769
|
+
SidebarAccountMenu,
|
|
1069
1770
|
SidebarBrand,
|
|
1070
1771
|
SidebarFooter,
|
|
1772
|
+
SidebarGhost,
|
|
1071
1773
|
SidebarHeader,
|
|
1072
1774
|
SidebarNav,
|
|
1073
1775
|
SidebarNavItem,
|
|
1074
1776
|
SidebarSection,
|
|
1075
1777
|
SortableTable,
|
|
1778
|
+
SortableTableGhost,
|
|
1076
1779
|
Tabs,
|
|
1780
|
+
TabsGhost,
|
|
1781
|
+
TextButton,
|
|
1782
|
+
TextButtonGhost,
|
|
1783
|
+
Textarea,
|
|
1784
|
+
TextareaGhost,
|
|
1077
1785
|
Toggle,
|
|
1786
|
+
ToggleGhost,
|
|
1787
|
+
UILoader,
|
|
1078
1788
|
cn,
|
|
1079
1789
|
useEscapeDismiss
|
|
1080
1790
|
};
|