@classic-homes/theme-react 0.1.49 → 0.1.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.css +141 -0
- package/dist/index.d.mts +118 -4
- package/dist/index.d.ts +118 -4
- package/dist/index.js +911 -21
- package/dist/index.mjs +927 -20
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -41,6 +41,11 @@ __export(index_exports, {
|
|
|
41
41
|
CardFooter: () => CardFooter,
|
|
42
42
|
CardHeader: () => CardHeader,
|
|
43
43
|
CardTitle: () => CardTitle,
|
|
44
|
+
DataPanel: () => DataPanel,
|
|
45
|
+
DataPanelContent: () => DataPanelContent,
|
|
46
|
+
DataPanelFooter: () => DataPanelFooter,
|
|
47
|
+
DataPanelHeader: () => DataPanelHeader,
|
|
48
|
+
DataPanelTab: () => DataPanelTab,
|
|
44
49
|
Dialog: () => Dialog,
|
|
45
50
|
DialogClose: () => DialogClose,
|
|
46
51
|
DialogContent: () => DialogContent,
|
|
@@ -62,7 +67,8 @@ __export(index_exports, {
|
|
|
62
67
|
pageHeaderActionsVariants: () => pageHeaderActionsVariants,
|
|
63
68
|
pageHeaderContainerVariants: () => pageHeaderContainerVariants,
|
|
64
69
|
pageHeaderSubtitleVariants: () => pageHeaderSubtitleVariants,
|
|
65
|
-
pageHeaderTitleVariants: () => pageHeaderTitleVariants
|
|
70
|
+
pageHeaderTitleVariants: () => pageHeaderTitleVariants,
|
|
71
|
+
useDataPanel: () => useDataPanel
|
|
66
72
|
});
|
|
67
73
|
module.exports = __toCommonJS(index_exports);
|
|
68
74
|
|
|
@@ -190,6 +196,7 @@ var Label = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
190
196
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
191
197
|
|
|
192
198
|
// src/components/Badge.tsx
|
|
199
|
+
var React5 = __toESM(require("react"));
|
|
193
200
|
var import_class_variance_authority3 = require("class-variance-authority");
|
|
194
201
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
195
202
|
var badgeVariants = (0, import_class_variance_authority3.cva)(
|
|
@@ -208,15 +215,26 @@ var badgeVariants = (0, import_class_variance_authority3.cva)(
|
|
|
208
215
|
}
|
|
209
216
|
}
|
|
210
217
|
);
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
218
|
+
var Badge = React5.forwardRef(
|
|
219
|
+
({ className, variant, ...props }, ref) => {
|
|
220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
221
|
+
"div",
|
|
222
|
+
{
|
|
223
|
+
ref,
|
|
224
|
+
role: "status",
|
|
225
|
+
className: cn(badgeVariants({ variant }), className),
|
|
226
|
+
...props
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
Badge.displayName = "Badge";
|
|
214
232
|
|
|
215
233
|
// src/components/Separator.tsx
|
|
216
|
-
var
|
|
234
|
+
var React6 = __toESM(require("react"));
|
|
217
235
|
var SeparatorPrimitive = __toESM(require("@radix-ui/react-separator"));
|
|
218
236
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
219
|
-
var Separator =
|
|
237
|
+
var Separator = React6.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
220
238
|
SeparatorPrimitive.Root,
|
|
221
239
|
{
|
|
222
240
|
ref,
|
|
@@ -233,10 +251,10 @@ var Separator = React5.forwardRef(({ className, orientation = "horizontal", deco
|
|
|
233
251
|
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
234
252
|
|
|
235
253
|
// src/components/Switch.tsx
|
|
236
|
-
var
|
|
254
|
+
var React7 = __toESM(require("react"));
|
|
237
255
|
var SwitchPrimitives = __toESM(require("@radix-ui/react-switch"));
|
|
238
256
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
239
|
-
var Switch =
|
|
257
|
+
var Switch = React7.forwardRef(
|
|
240
258
|
({ className, size = "default", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
241
259
|
SwitchPrimitives.Root,
|
|
242
260
|
{
|
|
@@ -264,10 +282,10 @@ var Switch = React6.forwardRef(
|
|
|
264
282
|
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
265
283
|
|
|
266
284
|
// src/components/Avatar.tsx
|
|
267
|
-
var
|
|
285
|
+
var React8 = __toESM(require("react"));
|
|
268
286
|
var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"));
|
|
269
287
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
270
|
-
var Avatar =
|
|
288
|
+
var Avatar = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
271
289
|
AvatarPrimitive.Root,
|
|
272
290
|
{
|
|
273
291
|
ref,
|
|
@@ -276,16 +294,16 @@ var Avatar = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
276
294
|
}
|
|
277
295
|
));
|
|
278
296
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
279
|
-
var AvatarImage =
|
|
297
|
+
var AvatarImage = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
280
298
|
AvatarPrimitive.Image,
|
|
281
299
|
{
|
|
282
300
|
ref,
|
|
283
|
-
className: cn("aspect-square h-full w-full", className),
|
|
301
|
+
className: cn("aspect-square h-full w-full object-cover", className),
|
|
284
302
|
...props
|
|
285
303
|
}
|
|
286
304
|
));
|
|
287
305
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
288
|
-
var AvatarFallback =
|
|
306
|
+
var AvatarFallback = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
289
307
|
AvatarPrimitive.Fallback,
|
|
290
308
|
{
|
|
291
309
|
ref,
|
|
@@ -299,14 +317,14 @@ var AvatarFallback = React7.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
299
317
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
300
318
|
|
|
301
319
|
// src/components/Dialog.tsx
|
|
302
|
-
var
|
|
320
|
+
var React9 = __toESM(require("react"));
|
|
303
321
|
var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
|
|
304
322
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
305
323
|
var Dialog = DialogPrimitive.Root;
|
|
306
324
|
var DialogTrigger = DialogPrimitive.Trigger;
|
|
307
325
|
var DialogPortal = DialogPrimitive.Portal;
|
|
308
326
|
var DialogClose = DialogPrimitive.Close;
|
|
309
|
-
var DialogOverlay =
|
|
327
|
+
var DialogOverlay = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
310
328
|
DialogPrimitive.Overlay,
|
|
311
329
|
{
|
|
312
330
|
ref,
|
|
@@ -318,7 +336,7 @@ var DialogOverlay = React8.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
318
336
|
}
|
|
319
337
|
));
|
|
320
338
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
321
|
-
var DialogContent =
|
|
339
|
+
var DialogContent = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogPortal, { children: [
|
|
322
340
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogOverlay, {}),
|
|
323
341
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
324
342
|
DialogPrimitive.Content,
|
|
@@ -344,7 +362,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_r
|
|
|
344
362
|
}
|
|
345
363
|
);
|
|
346
364
|
DialogFooter.displayName = "DialogFooter";
|
|
347
|
-
var DialogTitle =
|
|
365
|
+
var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
348
366
|
DialogPrimitive.Title,
|
|
349
367
|
{
|
|
350
368
|
ref,
|
|
@@ -353,7 +371,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
353
371
|
}
|
|
354
372
|
));
|
|
355
373
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
356
|
-
var DialogDescription =
|
|
374
|
+
var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
357
375
|
DialogPrimitive.Description,
|
|
358
376
|
{
|
|
359
377
|
ref,
|
|
@@ -364,7 +382,7 @@ var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
364
382
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
365
383
|
|
|
366
384
|
// src/components/PageHeader.tsx
|
|
367
|
-
var
|
|
385
|
+
var React10 = __toESM(require("react"));
|
|
368
386
|
var import_class_variance_authority4 = require("class-variance-authority");
|
|
369
387
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
370
388
|
var pageHeaderContainerVariants = (0, import_class_variance_authority4.cva)("", {
|
|
@@ -415,7 +433,7 @@ var pageHeaderActionsVariants = (0, import_class_variance_authority4.cva)("flex
|
|
|
415
433
|
variant: "default"
|
|
416
434
|
}
|
|
417
435
|
});
|
|
418
|
-
var PageHeader =
|
|
436
|
+
var PageHeader = React10.forwardRef(
|
|
419
437
|
({ className, variant, title, subtitle, actions, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
420
438
|
"header",
|
|
421
439
|
{
|
|
@@ -431,6 +449,872 @@ var PageHeader = React9.forwardRef(
|
|
|
431
449
|
)
|
|
432
450
|
);
|
|
433
451
|
PageHeader.displayName = "PageHeader";
|
|
452
|
+
|
|
453
|
+
// src/components/DataPanel.tsx
|
|
454
|
+
var React11 = __toESM(require("react"));
|
|
455
|
+
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
|
|
456
|
+
var import_data_panel_core = require("@classic-homes/data-panel-core");
|
|
457
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
458
|
+
function useDataPanel(options = {}) {
|
|
459
|
+
const {
|
|
460
|
+
persistKey,
|
|
461
|
+
initialMode = import_data_panel_core.DEFAULT_PANEL_STATE.mode,
|
|
462
|
+
initialEdge = import_data_panel_core.DEFAULT_PANEL_STATE.edge,
|
|
463
|
+
initialExpanded = import_data_panel_core.DEFAULT_PANEL_STATE.isExpanded,
|
|
464
|
+
constraints = {}
|
|
465
|
+
} = options;
|
|
466
|
+
const resolvedConstraints = { ...import_data_panel_core.DEFAULT_CONSTRAINTS, ...constraints };
|
|
467
|
+
const [persistedState] = React11.useState(() => {
|
|
468
|
+
if (persistKey && typeof window !== "undefined") {
|
|
469
|
+
return (0, import_data_panel_core.loadPanelState)(persistKey);
|
|
470
|
+
}
|
|
471
|
+
return null;
|
|
472
|
+
});
|
|
473
|
+
const [mode, setMode] = React11.useState(persistedState?.mode ?? initialMode);
|
|
474
|
+
const [edge, setEdge] = React11.useState(persistedState?.edge ?? initialEdge);
|
|
475
|
+
const [isExpanded, setIsExpanded] = React11.useState(
|
|
476
|
+
persistedState?.isExpanded ?? initialExpanded
|
|
477
|
+
);
|
|
478
|
+
const [detachedPosition, setDetachedPosition] = React11.useState(
|
|
479
|
+
persistedState?.detachedPosition ?? import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition
|
|
480
|
+
);
|
|
481
|
+
const [detachedSize, setDetachedSize] = React11.useState(
|
|
482
|
+
persistedState?.detachedSize ?? import_data_panel_core.DEFAULT_PANEL_STATE.detachedSize
|
|
483
|
+
);
|
|
484
|
+
const [pinnedSize, setPinnedSize] = React11.useState(
|
|
485
|
+
persistedState?.pinnedSize ?? import_data_panel_core.DEFAULT_PANEL_STATE.pinnedSize
|
|
486
|
+
);
|
|
487
|
+
const saveTimeoutRef = React11.useRef(null);
|
|
488
|
+
const debouncedSave = React11.useCallback(() => {
|
|
489
|
+
if (!persistKey) return;
|
|
490
|
+
if (saveTimeoutRef.current) {
|
|
491
|
+
clearTimeout(saveTimeoutRef.current);
|
|
492
|
+
}
|
|
493
|
+
saveTimeoutRef.current = setTimeout(() => {
|
|
494
|
+
(0, import_data_panel_core.savePanelState)(persistKey, {
|
|
495
|
+
mode,
|
|
496
|
+
variant: "full",
|
|
497
|
+
edge,
|
|
498
|
+
isExpanded,
|
|
499
|
+
detachedPosition,
|
|
500
|
+
detachedSize,
|
|
501
|
+
pinnedSize,
|
|
502
|
+
cardSnapIndex: 0
|
|
503
|
+
});
|
|
504
|
+
}, 300);
|
|
505
|
+
}, [persistKey, mode, edge, isExpanded, detachedPosition, detachedSize, pinnedSize]);
|
|
506
|
+
const handleSetMode = React11.useCallback(
|
|
507
|
+
(newMode) => {
|
|
508
|
+
setMode(newMode);
|
|
509
|
+
if (newMode === "detached" && typeof window !== "undefined" && detachedPosition.x === import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition.x && detachedPosition.y === import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition.y) {
|
|
510
|
+
setDetachedPosition(
|
|
511
|
+
(0, import_data_panel_core.getInitialDetachedPosition)(detachedSize, window.innerWidth, window.innerHeight)
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
[detachedPosition, detachedSize]
|
|
516
|
+
);
|
|
517
|
+
const handleSetDetachedPosition = React11.useCallback(
|
|
518
|
+
(position) => {
|
|
519
|
+
if (typeof window === "undefined") {
|
|
520
|
+
setDetachedPosition(position);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
setDetachedPosition(
|
|
524
|
+
(0, import_data_panel_core.constrainPosition)(position, detachedSize, window.innerWidth, window.innerHeight)
|
|
525
|
+
);
|
|
526
|
+
},
|
|
527
|
+
[detachedSize]
|
|
528
|
+
);
|
|
529
|
+
const handleSetDetachedSize = React11.useCallback(
|
|
530
|
+
(size) => {
|
|
531
|
+
setDetachedSize((0, import_data_panel_core.constrainSize)(size, resolvedConstraints));
|
|
532
|
+
},
|
|
533
|
+
[resolvedConstraints]
|
|
534
|
+
);
|
|
535
|
+
const handleSetPinnedSize = React11.useCallback(
|
|
536
|
+
(size) => {
|
|
537
|
+
if (typeof window === "undefined") {
|
|
538
|
+
setPinnedSize(size);
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
if ((0, import_data_panel_core.isHorizontalEdge)(edge)) {
|
|
542
|
+
setPinnedSize((0, import_data_panel_core.constrainPinnedWidth)(size, resolvedConstraints, window.innerWidth));
|
|
543
|
+
} else {
|
|
544
|
+
setPinnedSize((0, import_data_panel_core.constrainPinnedHeight)(size, resolvedConstraints, window.innerHeight));
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
[edge, resolvedConstraints]
|
|
548
|
+
);
|
|
549
|
+
React11.useEffect(() => {
|
|
550
|
+
debouncedSave();
|
|
551
|
+
}, [debouncedSave]);
|
|
552
|
+
return {
|
|
553
|
+
mode,
|
|
554
|
+
setMode: handleSetMode,
|
|
555
|
+
edge,
|
|
556
|
+
setEdge,
|
|
557
|
+
isExpanded,
|
|
558
|
+
setIsExpanded,
|
|
559
|
+
detachedPosition,
|
|
560
|
+
setDetachedPosition: handleSetDetachedPosition,
|
|
561
|
+
detachedSize,
|
|
562
|
+
setDetachedSize: handleSetDetachedSize,
|
|
563
|
+
pinnedSize,
|
|
564
|
+
setPinnedSize: handleSetPinnedSize
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
var ChevronUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
568
|
+
"svg",
|
|
569
|
+
{
|
|
570
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
571
|
+
width: "16",
|
|
572
|
+
height: "16",
|
|
573
|
+
viewBox: "0 0 24 24",
|
|
574
|
+
fill: "none",
|
|
575
|
+
stroke: "currentColor",
|
|
576
|
+
strokeWidth: "2",
|
|
577
|
+
strokeLinecap: "round",
|
|
578
|
+
strokeLinejoin: "round",
|
|
579
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m18 15-6-6-6 6" })
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
var MoreVerticalIcon = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
583
|
+
"svg",
|
|
584
|
+
{
|
|
585
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
586
|
+
width: "16",
|
|
587
|
+
height: "16",
|
|
588
|
+
viewBox: "0 0 24 24",
|
|
589
|
+
fill: "none",
|
|
590
|
+
stroke: "currentColor",
|
|
591
|
+
strokeWidth: "2",
|
|
592
|
+
strokeLinecap: "round",
|
|
593
|
+
strokeLinejoin: "round",
|
|
594
|
+
children: [
|
|
595
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "12", cy: "12", r: "1" }),
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "12", cy: "5", r: "1" }),
|
|
597
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "12", cy: "19", r: "1" })
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
);
|
|
601
|
+
var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
602
|
+
"svg",
|
|
603
|
+
{
|
|
604
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
605
|
+
width: "16",
|
|
606
|
+
height: "16",
|
|
607
|
+
viewBox: "0 0 24 24",
|
|
608
|
+
fill: "none",
|
|
609
|
+
stroke: "currentColor",
|
|
610
|
+
strokeWidth: "2",
|
|
611
|
+
strokeLinecap: "round",
|
|
612
|
+
strokeLinejoin: "round",
|
|
613
|
+
children: [
|
|
614
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M18 6 6 18" }),
|
|
615
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m6 6 12 12" })
|
|
616
|
+
]
|
|
617
|
+
}
|
|
618
|
+
);
|
|
619
|
+
var edgeLabels = {
|
|
620
|
+
left: "Pin to left",
|
|
621
|
+
right: "Pin to right",
|
|
622
|
+
top: "Pin to top",
|
|
623
|
+
bottom: "Pin to bottom"
|
|
624
|
+
};
|
|
625
|
+
var DataPanelHeader = React11.forwardRef(
|
|
626
|
+
({
|
|
627
|
+
title,
|
|
628
|
+
subtitle,
|
|
629
|
+
mode,
|
|
630
|
+
edge,
|
|
631
|
+
isExpanded,
|
|
632
|
+
onModeChange,
|
|
633
|
+
onEdgeChange,
|
|
634
|
+
onExpandedChange,
|
|
635
|
+
onClose,
|
|
636
|
+
disableClose = false,
|
|
637
|
+
disableModeSwitch = false,
|
|
638
|
+
headerContent,
|
|
639
|
+
headerActions,
|
|
640
|
+
className,
|
|
641
|
+
draggable = false
|
|
642
|
+
}, ref) => {
|
|
643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
644
|
+
"div",
|
|
645
|
+
{
|
|
646
|
+
ref,
|
|
647
|
+
className: cn(
|
|
648
|
+
"flex items-center justify-between gap-2 border-b border-border bg-muted/30 px-4 py-3",
|
|
649
|
+
draggable && "cursor-grab active:cursor-grabbing",
|
|
650
|
+
className
|
|
651
|
+
),
|
|
652
|
+
"data-panel-header": true,
|
|
653
|
+
children: [
|
|
654
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-col min-w-0 flex-1", children: headerContent ? headerContent : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
655
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "text-sm font-semibold leading-none truncate", children: title }),
|
|
656
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: subtitle })
|
|
657
|
+
] }) }),
|
|
658
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
659
|
+
headerActions,
|
|
660
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
661
|
+
"button",
|
|
662
|
+
{
|
|
663
|
+
type: "button",
|
|
664
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md bg-transparent text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
665
|
+
onClick: () => onExpandedChange?.(!isExpanded),
|
|
666
|
+
"aria-label": isExpanded ? "Collapse panel" : "Expand panel",
|
|
667
|
+
"aria-expanded": isExpanded,
|
|
668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn("transition-transform", !isExpanded && "rotate-180"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronUpIcon, {}) })
|
|
669
|
+
}
|
|
670
|
+
),
|
|
671
|
+
!disableModeSwitch && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DropdownMenuPrimitive.Root, { children: [
|
|
672
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
673
|
+
"button",
|
|
674
|
+
{
|
|
675
|
+
type: "button",
|
|
676
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md bg-transparent text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
677
|
+
"aria-label": "Panel options",
|
|
678
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MoreVerticalIcon, {})
|
|
679
|
+
}
|
|
680
|
+
) }),
|
|
681
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
682
|
+
DropdownMenuPrimitive.Content,
|
|
683
|
+
{
|
|
684
|
+
className: "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
|
|
685
|
+
sideOffset: 4,
|
|
686
|
+
align: "end",
|
|
687
|
+
children: [
|
|
688
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.Label, { className: "px-2 py-1.5 text-sm font-semibold", children: "Panel Position" }),
|
|
689
|
+
["left", "right", "top", "bottom"].map((e) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
690
|
+
DropdownMenuPrimitive.Item,
|
|
691
|
+
{
|
|
692
|
+
className: "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
693
|
+
onSelect: () => {
|
|
694
|
+
onModeChange?.("pinned");
|
|
695
|
+
onEdgeChange?.(e);
|
|
696
|
+
},
|
|
697
|
+
children: [
|
|
698
|
+
edgeLabels[e],
|
|
699
|
+
mode === "pinned" && edge === e && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ml-auto text-xs", children: "\u2713" })
|
|
700
|
+
]
|
|
701
|
+
},
|
|
702
|
+
e
|
|
703
|
+
)),
|
|
704
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DropdownMenuPrimitive.Separator, { className: "-mx-1 my-1 h-px bg-muted" }),
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
706
|
+
DropdownMenuPrimitive.Item,
|
|
707
|
+
{
|
|
708
|
+
className: "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground",
|
|
709
|
+
onSelect: () => onModeChange?.("detached"),
|
|
710
|
+
children: [
|
|
711
|
+
"Detach",
|
|
712
|
+
mode === "detached" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ml-auto text-xs", children: "\u2713" })
|
|
713
|
+
]
|
|
714
|
+
}
|
|
715
|
+
)
|
|
716
|
+
]
|
|
717
|
+
}
|
|
718
|
+
) })
|
|
719
|
+
] }),
|
|
720
|
+
!disableClose && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
721
|
+
"button",
|
|
722
|
+
{
|
|
723
|
+
type: "button",
|
|
724
|
+
className: "flex h-8 w-8 items-center justify-center rounded-md bg-transparent text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
725
|
+
onClick: onClose,
|
|
726
|
+
"aria-label": "Close panel",
|
|
727
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CloseIcon, {})
|
|
728
|
+
}
|
|
729
|
+
)
|
|
730
|
+
] })
|
|
731
|
+
]
|
|
732
|
+
}
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
DataPanelHeader.displayName = "DataPanelHeader";
|
|
737
|
+
var DataPanelContent = React11.forwardRef(
|
|
738
|
+
({ children, className }, ref) => {
|
|
739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref, className: cn("flex-1 overflow-auto p-4", className), children });
|
|
740
|
+
}
|
|
741
|
+
);
|
|
742
|
+
DataPanelContent.displayName = "DataPanelContent";
|
|
743
|
+
var DataPanelFooter = React11.forwardRef(
|
|
744
|
+
({ actions = [], footerContent, footerActions, className }, ref) => {
|
|
745
|
+
if (!footerContent && actions.length === 0 && !footerActions) {
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
const mapVariant = (variant) => {
|
|
749
|
+
if (variant === "primary") return "default";
|
|
750
|
+
return variant ?? "default";
|
|
751
|
+
};
|
|
752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
753
|
+
"div",
|
|
754
|
+
{
|
|
755
|
+
ref,
|
|
756
|
+
className: cn(
|
|
757
|
+
"flex items-center justify-end gap-2 border-t border-border bg-muted/30 px-4 py-3",
|
|
758
|
+
className
|
|
759
|
+
),
|
|
760
|
+
children: footerContent ? footerContent : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
761
|
+
footerActions,
|
|
762
|
+
actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
763
|
+
Button,
|
|
764
|
+
{
|
|
765
|
+
variant: mapVariant(action.variant),
|
|
766
|
+
size: "sm",
|
|
767
|
+
disabled: action.disabled,
|
|
768
|
+
onClick: action.onClick,
|
|
769
|
+
children: action.label
|
|
770
|
+
},
|
|
771
|
+
index
|
|
772
|
+
))
|
|
773
|
+
] })
|
|
774
|
+
}
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
);
|
|
778
|
+
DataPanelFooter.displayName = "DataPanelFooter";
|
|
779
|
+
var DataPanelTab = React11.forwardRef(
|
|
780
|
+
({ title = "Panel", edge, onClick, className }, ref) => {
|
|
781
|
+
const positionClasses = {
|
|
782
|
+
left: "left-0 top-1/2 -translate-y-1/2 rounded-r-md border-l-0",
|
|
783
|
+
right: "right-0 top-1/2 -translate-y-1/2 rounded-l-md border-r-0",
|
|
784
|
+
top: "top-0 left-1/2 -translate-x-1/2 rounded-b-md border-t-0",
|
|
785
|
+
bottom: "bottom-0 left-1/2 -translate-x-1/2 rounded-t-md border-b-0"
|
|
786
|
+
}[edge];
|
|
787
|
+
const isVertical = edge === "left" || edge === "right";
|
|
788
|
+
const iconRotation = {
|
|
789
|
+
left: "rotate-90",
|
|
790
|
+
right: "-rotate-90",
|
|
791
|
+
top: "rotate-180",
|
|
792
|
+
bottom: ""
|
|
793
|
+
}[edge];
|
|
794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
795
|
+
"button",
|
|
796
|
+
{
|
|
797
|
+
ref,
|
|
798
|
+
type: "button",
|
|
799
|
+
className: cn(
|
|
800
|
+
"fixed z-40 flex items-center justify-center gap-2 border border-border bg-background px-3 py-2 text-sm font-medium shadow-md transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
801
|
+
positionClasses,
|
|
802
|
+
isVertical && "[writing-mode:vertical-rl]",
|
|
803
|
+
className
|
|
804
|
+
),
|
|
805
|
+
onClick,
|
|
806
|
+
"aria-label": `Expand ${title} panel`,
|
|
807
|
+
children: [
|
|
808
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn("shrink-0", iconRotation), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChevronUpIcon, {}) }),
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cn(isVertical && "rotate-180"), children: title })
|
|
810
|
+
]
|
|
811
|
+
}
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
DataPanelTab.displayName = "DataPanelTab";
|
|
816
|
+
var DataPanel = React11.forwardRef(
|
|
817
|
+
({
|
|
818
|
+
open: controlledOpen,
|
|
819
|
+
onOpenChange,
|
|
820
|
+
mode: controlledMode,
|
|
821
|
+
onModeChange,
|
|
822
|
+
edge: controlledEdge,
|
|
823
|
+
onEdgeChange,
|
|
824
|
+
expanded: controlledExpanded,
|
|
825
|
+
onExpandedChange,
|
|
826
|
+
title,
|
|
827
|
+
subtitle,
|
|
828
|
+
children,
|
|
829
|
+
actions = [],
|
|
830
|
+
constraints = {},
|
|
831
|
+
disableClose = false,
|
|
832
|
+
disableResize = false,
|
|
833
|
+
disableDrag = false,
|
|
834
|
+
disableModeSwitch = false,
|
|
835
|
+
persistKey,
|
|
836
|
+
snapThreshold = 20,
|
|
837
|
+
detachThreshold = 40,
|
|
838
|
+
headerContent,
|
|
839
|
+
headerActions,
|
|
840
|
+
footerContent,
|
|
841
|
+
footerActions,
|
|
842
|
+
className
|
|
843
|
+
}, ref) => {
|
|
844
|
+
const resolvedConstraints = { ...import_data_panel_core.DEFAULT_CONSTRAINTS, ...constraints };
|
|
845
|
+
const [internalOpen, setInternalOpen] = React11.useState(true);
|
|
846
|
+
const [internalMode, setInternalMode] = React11.useState(import_data_panel_core.DEFAULT_PANEL_STATE.mode);
|
|
847
|
+
const [internalEdge, setInternalEdge] = React11.useState(import_data_panel_core.DEFAULT_PANEL_STATE.edge);
|
|
848
|
+
const [internalExpanded, setInternalExpanded] = React11.useState(
|
|
849
|
+
import_data_panel_core.DEFAULT_PANEL_STATE.isExpanded
|
|
850
|
+
);
|
|
851
|
+
const [detachedPosition, setDetachedPosition] = React11.useState(
|
|
852
|
+
import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition
|
|
853
|
+
);
|
|
854
|
+
const [detachedSize, setDetachedSize] = React11.useState(import_data_panel_core.DEFAULT_PANEL_STATE.detachedSize);
|
|
855
|
+
const [pinnedSize, setPinnedSize] = React11.useState(import_data_panel_core.DEFAULT_PANEL_STATE.pinnedSize);
|
|
856
|
+
const [isDragging, setIsDragging] = React11.useState(false);
|
|
857
|
+
const [isResizing, setIsResizing] = React11.useState(false);
|
|
858
|
+
const [snapPreview, setSnapPreview] = React11.useState(null);
|
|
859
|
+
const [isPinnedDragging, setIsPinnedDragging] = React11.useState(false);
|
|
860
|
+
const [pullOffset, setPullOffset] = React11.useState(0);
|
|
861
|
+
const dragStateRef = React11.useRef({
|
|
862
|
+
startPosition: { x: 0, y: 0 },
|
|
863
|
+
startPanelPosition: { x: 0, y: 0 }
|
|
864
|
+
});
|
|
865
|
+
const pinnedDragStateRef = React11.useRef({
|
|
866
|
+
startPosition: { x: 0, y: 0 },
|
|
867
|
+
hasDetached: false
|
|
868
|
+
});
|
|
869
|
+
const resizeStateRef = React11.useRef({
|
|
870
|
+
handle: null,
|
|
871
|
+
startPosition: { x: 0, y: 0 },
|
|
872
|
+
startSize: { width: 0, height: 0 },
|
|
873
|
+
startPanelPosition: { x: 0, y: 0 }
|
|
874
|
+
});
|
|
875
|
+
const open = controlledOpen ?? internalOpen;
|
|
876
|
+
const mode = controlledMode ?? internalMode;
|
|
877
|
+
const edge = controlledEdge ?? internalEdge;
|
|
878
|
+
const isExpanded = controlledExpanded ?? internalExpanded;
|
|
879
|
+
const saveTimeoutRef = React11.useRef(null);
|
|
880
|
+
const debouncedSave = React11.useCallback(() => {
|
|
881
|
+
if (!persistKey) return;
|
|
882
|
+
if (saveTimeoutRef.current) {
|
|
883
|
+
clearTimeout(saveTimeoutRef.current);
|
|
884
|
+
}
|
|
885
|
+
saveTimeoutRef.current = setTimeout(() => {
|
|
886
|
+
(0, import_data_panel_core.savePanelState)(persistKey, {
|
|
887
|
+
mode: internalMode,
|
|
888
|
+
variant: "full",
|
|
889
|
+
edge: internalEdge,
|
|
890
|
+
isExpanded: internalExpanded,
|
|
891
|
+
detachedPosition,
|
|
892
|
+
detachedSize,
|
|
893
|
+
pinnedSize,
|
|
894
|
+
cardSnapIndex: 0
|
|
895
|
+
});
|
|
896
|
+
}, 300);
|
|
897
|
+
}, [
|
|
898
|
+
persistKey,
|
|
899
|
+
internalMode,
|
|
900
|
+
internalEdge,
|
|
901
|
+
internalExpanded,
|
|
902
|
+
detachedPosition,
|
|
903
|
+
detachedSize,
|
|
904
|
+
pinnedSize
|
|
905
|
+
]);
|
|
906
|
+
React11.useEffect(() => {
|
|
907
|
+
if (!persistKey) return;
|
|
908
|
+
const persisted = (0, import_data_panel_core.loadPanelState)(persistKey);
|
|
909
|
+
if (persisted) {
|
|
910
|
+
if (controlledMode === void 0 && persisted.mode) setInternalMode(persisted.mode);
|
|
911
|
+
if (controlledEdge === void 0 && persisted.edge) setInternalEdge(persisted.edge);
|
|
912
|
+
if (controlledExpanded === void 0 && persisted.isExpanded !== void 0)
|
|
913
|
+
setInternalExpanded(persisted.isExpanded);
|
|
914
|
+
if (persisted.detachedPosition) setDetachedPosition(persisted.detachedPosition);
|
|
915
|
+
if (persisted.detachedSize) setDetachedSize(persisted.detachedSize);
|
|
916
|
+
if (persisted.pinnedSize) setPinnedSize(persisted.pinnedSize);
|
|
917
|
+
}
|
|
918
|
+
}, [persistKey, controlledMode, controlledEdge, controlledExpanded]);
|
|
919
|
+
React11.useEffect(() => {
|
|
920
|
+
if (mode === "detached" && detachedPosition.x === import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition.x && detachedPosition.y === import_data_panel_core.DEFAULT_PANEL_STATE.detachedPosition.y) {
|
|
921
|
+
setDetachedPosition(
|
|
922
|
+
(0, import_data_panel_core.getInitialDetachedPosition)(detachedSize, window.innerWidth, window.innerHeight)
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
}, [mode, detachedPosition, detachedSize]);
|
|
926
|
+
const handleOpenChange = (newOpen) => {
|
|
927
|
+
if (controlledOpen === void 0) {
|
|
928
|
+
setInternalOpen(newOpen);
|
|
929
|
+
}
|
|
930
|
+
onOpenChange?.(newOpen);
|
|
931
|
+
};
|
|
932
|
+
const handleModeChange = (newMode) => {
|
|
933
|
+
if (controlledMode === void 0) {
|
|
934
|
+
setInternalMode(newMode);
|
|
935
|
+
}
|
|
936
|
+
onModeChange?.(newMode);
|
|
937
|
+
debouncedSave();
|
|
938
|
+
};
|
|
939
|
+
const handleEdgeChange = (newEdge) => {
|
|
940
|
+
if (controlledEdge === void 0) {
|
|
941
|
+
setInternalEdge(newEdge);
|
|
942
|
+
}
|
|
943
|
+
onEdgeChange?.(newEdge);
|
|
944
|
+
debouncedSave();
|
|
945
|
+
};
|
|
946
|
+
const handleExpandedChange = (newExpanded) => {
|
|
947
|
+
if (controlledExpanded === void 0) {
|
|
948
|
+
setInternalExpanded(newExpanded);
|
|
949
|
+
}
|
|
950
|
+
onExpandedChange?.(newExpanded);
|
|
951
|
+
debouncedSave();
|
|
952
|
+
};
|
|
953
|
+
const handleDragStart = (e) => {
|
|
954
|
+
if (disableDrag) return;
|
|
955
|
+
const target = e.target;
|
|
956
|
+
if (!target.closest("[data-panel-header]")) return;
|
|
957
|
+
const pos = (0, import_data_panel_core.getPointerPosition)(e.nativeEvent);
|
|
958
|
+
if (mode === "detached") {
|
|
959
|
+
setIsDragging(true);
|
|
960
|
+
dragStateRef.current = {
|
|
961
|
+
startPosition: pos,
|
|
962
|
+
startPanelPosition: { ...detachedPosition }
|
|
963
|
+
};
|
|
964
|
+
document.body.style.cursor = "grabbing";
|
|
965
|
+
document.body.style.userSelect = "none";
|
|
966
|
+
} else if (mode === "pinned" && detachThreshold > 0) {
|
|
967
|
+
setIsPinnedDragging(true);
|
|
968
|
+
pinnedDragStateRef.current = {
|
|
969
|
+
startPosition: pos,
|
|
970
|
+
hasDetached: false
|
|
971
|
+
};
|
|
972
|
+
setPullOffset(0);
|
|
973
|
+
document.body.style.cursor = "grab";
|
|
974
|
+
document.body.style.userSelect = "none";
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
const handleDragMove = React11.useCallback(
|
|
978
|
+
(e) => {
|
|
979
|
+
if (!isDragging) return;
|
|
980
|
+
const currentPos = (0, import_data_panel_core.getPointerPosition)(e);
|
|
981
|
+
const newPosition = (0, import_data_panel_core.calculateDragPosition)(
|
|
982
|
+
{
|
|
983
|
+
isDragging: true,
|
|
984
|
+
startPosition: dragStateRef.current.startPosition,
|
|
985
|
+
startPanelPosition: dragStateRef.current.startPanelPosition,
|
|
986
|
+
currentPosition: currentPos
|
|
987
|
+
},
|
|
988
|
+
currentPos
|
|
989
|
+
);
|
|
990
|
+
const snap = (0, import_data_panel_core.detectEdgeSnap)(
|
|
991
|
+
newPosition,
|
|
992
|
+
detachedSize,
|
|
993
|
+
window.innerWidth,
|
|
994
|
+
window.innerHeight,
|
|
995
|
+
snapThreshold
|
|
996
|
+
);
|
|
997
|
+
setSnapPreview(snap.shouldSnap ? snap.edge : null);
|
|
998
|
+
setDetachedPosition(
|
|
999
|
+
(0, import_data_panel_core.constrainPosition)(newPosition, detachedSize, window.innerWidth, window.innerHeight)
|
|
1000
|
+
);
|
|
1001
|
+
},
|
|
1002
|
+
[isDragging, detachedSize, snapThreshold]
|
|
1003
|
+
);
|
|
1004
|
+
const handleDragEnd = React11.useCallback(() => {
|
|
1005
|
+
if (!isDragging) return;
|
|
1006
|
+
setIsDragging(false);
|
|
1007
|
+
document.body.style.cursor = "";
|
|
1008
|
+
document.body.style.userSelect = "";
|
|
1009
|
+
if (snapPreview) {
|
|
1010
|
+
handleModeChange("pinned");
|
|
1011
|
+
handleEdgeChange(snapPreview);
|
|
1012
|
+
setSnapPreview(null);
|
|
1013
|
+
} else {
|
|
1014
|
+
debouncedSave();
|
|
1015
|
+
}
|
|
1016
|
+
}, [isDragging, snapPreview, handleModeChange, handleEdgeChange, debouncedSave]);
|
|
1017
|
+
const handlePinnedDragMove = React11.useCallback(
|
|
1018
|
+
(e) => {
|
|
1019
|
+
if (!isPinnedDragging) return;
|
|
1020
|
+
const currentPos = (0, import_data_panel_core.getPointerPosition)(e);
|
|
1021
|
+
const distance = (0, import_data_panel_core.calculateDetachDistance)(
|
|
1022
|
+
pinnedDragStateRef.current.startPosition,
|
|
1023
|
+
currentPos,
|
|
1024
|
+
edge
|
|
1025
|
+
);
|
|
1026
|
+
if (distance >= detachThreshold && !pinnedDragStateRef.current.hasDetached) {
|
|
1027
|
+
pinnedDragStateRef.current.hasDetached = true;
|
|
1028
|
+
setIsPinnedDragging(false);
|
|
1029
|
+
setPullOffset(0);
|
|
1030
|
+
const newPosition = (0, import_data_panel_core.calculateDetachedPositionFromPinned)(
|
|
1031
|
+
currentPos,
|
|
1032
|
+
pinnedSize,
|
|
1033
|
+
detachedSize,
|
|
1034
|
+
edge,
|
|
1035
|
+
window.innerWidth,
|
|
1036
|
+
window.innerHeight
|
|
1037
|
+
);
|
|
1038
|
+
setDetachedPosition(newPosition);
|
|
1039
|
+
handleModeChange("detached");
|
|
1040
|
+
setIsDragging(true);
|
|
1041
|
+
dragStateRef.current = {
|
|
1042
|
+
startPosition: currentPos,
|
|
1043
|
+
startPanelPosition: newPosition
|
|
1044
|
+
};
|
|
1045
|
+
document.body.style.cursor = "grabbing";
|
|
1046
|
+
} else if (!pinnedDragStateRef.current.hasDetached) {
|
|
1047
|
+
const pull = (0, import_data_panel_core.calculatePullOffset)(distance, detachThreshold);
|
|
1048
|
+
setPullOffset(pull);
|
|
1049
|
+
}
|
|
1050
|
+
},
|
|
1051
|
+
[isPinnedDragging, edge, detachThreshold, pinnedSize, detachedSize, handleModeChange]
|
|
1052
|
+
);
|
|
1053
|
+
const handlePinnedDragEnd = React11.useCallback(() => {
|
|
1054
|
+
if (!isPinnedDragging) return;
|
|
1055
|
+
setIsPinnedDragging(false);
|
|
1056
|
+
setPullOffset(0);
|
|
1057
|
+
document.body.style.cursor = "";
|
|
1058
|
+
document.body.style.userSelect = "";
|
|
1059
|
+
}, [isPinnedDragging]);
|
|
1060
|
+
const handleResizeStart = (e, handle) => {
|
|
1061
|
+
if (disableResize) return;
|
|
1062
|
+
e.preventDefault();
|
|
1063
|
+
e.stopPropagation();
|
|
1064
|
+
setIsResizing(true);
|
|
1065
|
+
const pos = (0, import_data_panel_core.getPointerPosition)(e.nativeEvent);
|
|
1066
|
+
resizeStateRef.current = {
|
|
1067
|
+
handle,
|
|
1068
|
+
startPosition: pos,
|
|
1069
|
+
startSize: mode === "detached" ? { ...detachedSize } : { width: pinnedSize, height: pinnedSize },
|
|
1070
|
+
startPanelPosition: { ...detachedPosition }
|
|
1071
|
+
};
|
|
1072
|
+
document.body.style.cursor = (0, import_data_panel_core.getResizeCursor)(handle);
|
|
1073
|
+
document.body.style.userSelect = "none";
|
|
1074
|
+
};
|
|
1075
|
+
const handleResizeMove = React11.useCallback(
|
|
1076
|
+
(e) => {
|
|
1077
|
+
if (!isResizing || !resizeStateRef.current.handle) return;
|
|
1078
|
+
const currentPos = (0, import_data_panel_core.getPointerPosition)(e);
|
|
1079
|
+
const { handle, startPosition, startSize, startPanelPosition } = resizeStateRef.current;
|
|
1080
|
+
if (mode === "detached") {
|
|
1081
|
+
const result = (0, import_data_panel_core.calculateResize)(
|
|
1082
|
+
{
|
|
1083
|
+
isResizing: true,
|
|
1084
|
+
handle,
|
|
1085
|
+
startPosition,
|
|
1086
|
+
startSize,
|
|
1087
|
+
startPanelPosition
|
|
1088
|
+
},
|
|
1089
|
+
currentPos
|
|
1090
|
+
);
|
|
1091
|
+
const constrainedSize = (0, import_data_panel_core.constrainSize)(result.size, resolvedConstraints);
|
|
1092
|
+
const constrainedPosition = (0, import_data_panel_core.constrainPosition)(
|
|
1093
|
+
result.position,
|
|
1094
|
+
constrainedSize,
|
|
1095
|
+
window.innerWidth,
|
|
1096
|
+
window.innerHeight
|
|
1097
|
+
);
|
|
1098
|
+
setDetachedSize(constrainedSize);
|
|
1099
|
+
setDetachedPosition(constrainedPosition);
|
|
1100
|
+
} else {
|
|
1101
|
+
const delta = (0, import_data_panel_core.isHorizontalEdge)(edge) ? currentPos.x - startPosition.x : currentPos.y - startPosition.y;
|
|
1102
|
+
const direction = edge === "left" || edge === "top" ? 1 : -1;
|
|
1103
|
+
const newSize = startSize.width + delta * direction;
|
|
1104
|
+
if ((0, import_data_panel_core.isHorizontalEdge)(edge)) {
|
|
1105
|
+
setPinnedSize((0, import_data_panel_core.constrainPinnedWidth)(newSize, resolvedConstraints, window.innerWidth));
|
|
1106
|
+
} else {
|
|
1107
|
+
setPinnedSize((0, import_data_panel_core.constrainPinnedHeight)(newSize, resolvedConstraints, window.innerHeight));
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
},
|
|
1111
|
+
[isResizing, mode, edge, resolvedConstraints]
|
|
1112
|
+
);
|
|
1113
|
+
const handleResizeEnd = React11.useCallback(() => {
|
|
1114
|
+
if (!isResizing) return;
|
|
1115
|
+
setIsResizing(false);
|
|
1116
|
+
resizeStateRef.current.handle = null;
|
|
1117
|
+
document.body.style.cursor = "";
|
|
1118
|
+
document.body.style.userSelect = "";
|
|
1119
|
+
debouncedSave();
|
|
1120
|
+
}, [isResizing, debouncedSave]);
|
|
1121
|
+
React11.useEffect(() => {
|
|
1122
|
+
if (isDragging) {
|
|
1123
|
+
window.addEventListener("pointermove", handleDragMove);
|
|
1124
|
+
window.addEventListener("pointerup", handleDragEnd);
|
|
1125
|
+
return () => {
|
|
1126
|
+
window.removeEventListener("pointermove", handleDragMove);
|
|
1127
|
+
window.removeEventListener("pointerup", handleDragEnd);
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
}, [isDragging, handleDragMove, handleDragEnd]);
|
|
1131
|
+
React11.useEffect(() => {
|
|
1132
|
+
if (isPinnedDragging) {
|
|
1133
|
+
window.addEventListener("pointermove", handlePinnedDragMove);
|
|
1134
|
+
window.addEventListener("pointerup", handlePinnedDragEnd);
|
|
1135
|
+
return () => {
|
|
1136
|
+
window.removeEventListener("pointermove", handlePinnedDragMove);
|
|
1137
|
+
window.removeEventListener("pointerup", handlePinnedDragEnd);
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
}, [isPinnedDragging, handlePinnedDragMove, handlePinnedDragEnd]);
|
|
1141
|
+
React11.useEffect(() => {
|
|
1142
|
+
if (isResizing) {
|
|
1143
|
+
window.addEventListener("pointermove", handleResizeMove);
|
|
1144
|
+
window.addEventListener("pointerup", handleResizeEnd);
|
|
1145
|
+
return () => {
|
|
1146
|
+
window.removeEventListener("pointermove", handleResizeMove);
|
|
1147
|
+
window.removeEventListener("pointerup", handleResizeEnd);
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
}, [isResizing, handleResizeMove, handleResizeEnd]);
|
|
1151
|
+
const panelStyles = React11.useMemo(() => {
|
|
1152
|
+
if (mode === "pinned") {
|
|
1153
|
+
const baseStyles = (0, import_data_panel_core.getPinnedPositionStyles)(edge, pinnedSize);
|
|
1154
|
+
if (pullOffset > 0) {
|
|
1155
|
+
const transform = (0, import_data_panel_core.getPinnedPullTransform)(pullOffset, edge);
|
|
1156
|
+
return { ...baseStyles, transform };
|
|
1157
|
+
}
|
|
1158
|
+
return baseStyles;
|
|
1159
|
+
}
|
|
1160
|
+
return (0, import_data_panel_core.getDetachedPositionStyles)(detachedPosition, detachedSize);
|
|
1161
|
+
}, [mode, edge, pinnedSize, detachedPosition, detachedSize, pullOffset]);
|
|
1162
|
+
const pinnedClasses = {
|
|
1163
|
+
left: "left-0 top-0 bottom-0 border-r",
|
|
1164
|
+
right: "right-0 top-0 bottom-0 border-l",
|
|
1165
|
+
top: "top-0 left-0 right-0 border-b",
|
|
1166
|
+
bottom: "bottom-0 left-0 right-0 border-t"
|
|
1167
|
+
}[edge];
|
|
1168
|
+
const animationClass = mode === "pinned" ? {
|
|
1169
|
+
left: "animate-slide-right",
|
|
1170
|
+
right: "animate-slide-left",
|
|
1171
|
+
top: "animate-slide-down",
|
|
1172
|
+
bottom: "animate-slide-up"
|
|
1173
|
+
}[edge] : "animate-scale-in";
|
|
1174
|
+
if (!open) return null;
|
|
1175
|
+
if (!isExpanded && mode === "pinned") {
|
|
1176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DataPanelTab, { title, edge, onClick: () => handleExpandedChange(true) });
|
|
1177
|
+
}
|
|
1178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1179
|
+
snapPreview && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1180
|
+
"div",
|
|
1181
|
+
{
|
|
1182
|
+
className: cn(
|
|
1183
|
+
"fixed z-40 bg-primary/20 border-2 border-primary border-dashed transition-all",
|
|
1184
|
+
snapPreview === "left" && "left-0 top-0 bottom-0 w-80",
|
|
1185
|
+
snapPreview === "right" && "right-0 top-0 bottom-0 w-80",
|
|
1186
|
+
snapPreview === "top" && "top-0 left-0 right-0 h-64",
|
|
1187
|
+
snapPreview === "bottom" && "bottom-0 left-0 right-0 h-64"
|
|
1188
|
+
)
|
|
1189
|
+
}
|
|
1190
|
+
),
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1192
|
+
"div",
|
|
1193
|
+
{
|
|
1194
|
+
ref,
|
|
1195
|
+
className: cn(
|
|
1196
|
+
"fixed z-50 flex flex-col bg-background border border-border shadow-lg overflow-hidden",
|
|
1197
|
+
mode === "pinned" && pinnedClasses,
|
|
1198
|
+
mode === "detached" && "rounded-lg",
|
|
1199
|
+
isPinnedDragging && pullOffset > 0 && "shadow-2xl",
|
|
1200
|
+
animationClass,
|
|
1201
|
+
className
|
|
1202
|
+
),
|
|
1203
|
+
style: panelStyles,
|
|
1204
|
+
role: mode === "detached" ? "dialog" : void 0,
|
|
1205
|
+
"aria-modal": mode === "detached" ? "true" : void 0,
|
|
1206
|
+
"aria-labelledby": title ? "data-panel-title" : void 0,
|
|
1207
|
+
onPointerDown: handleDragStart,
|
|
1208
|
+
children: [
|
|
1209
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1210
|
+
DataPanelHeader,
|
|
1211
|
+
{
|
|
1212
|
+
title,
|
|
1213
|
+
subtitle,
|
|
1214
|
+
mode,
|
|
1215
|
+
edge,
|
|
1216
|
+
isExpanded,
|
|
1217
|
+
onModeChange: handleModeChange,
|
|
1218
|
+
onEdgeChange: handleEdgeChange,
|
|
1219
|
+
onExpandedChange: handleExpandedChange,
|
|
1220
|
+
onClose: () => handleOpenChange(false),
|
|
1221
|
+
disableClose,
|
|
1222
|
+
disableModeSwitch,
|
|
1223
|
+
headerContent,
|
|
1224
|
+
headerActions,
|
|
1225
|
+
draggable: !disableDrag && (mode === "detached" || mode === "pinned" && detachThreshold > 0)
|
|
1226
|
+
}
|
|
1227
|
+
),
|
|
1228
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DataPanelContent, { children }),
|
|
1229
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1230
|
+
DataPanelFooter,
|
|
1231
|
+
{
|
|
1232
|
+
actions,
|
|
1233
|
+
footerContent,
|
|
1234
|
+
footerActions
|
|
1235
|
+
}
|
|
1236
|
+
),
|
|
1237
|
+
!disableResize && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: mode === "detached" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1239
|
+
"div",
|
|
1240
|
+
{
|
|
1241
|
+
className: "resize-handle resize-handle--horizontal resize-handle--top",
|
|
1242
|
+
onPointerDown: (e) => handleResizeStart(e, "top")
|
|
1243
|
+
}
|
|
1244
|
+
),
|
|
1245
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1246
|
+
"div",
|
|
1247
|
+
{
|
|
1248
|
+
className: "resize-handle resize-handle--horizontal resize-handle--bottom",
|
|
1249
|
+
onPointerDown: (e) => handleResizeStart(e, "bottom")
|
|
1250
|
+
}
|
|
1251
|
+
),
|
|
1252
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1253
|
+
"div",
|
|
1254
|
+
{
|
|
1255
|
+
className: "resize-handle resize-handle--vertical resize-handle--left",
|
|
1256
|
+
onPointerDown: (e) => handleResizeStart(e, "left")
|
|
1257
|
+
}
|
|
1258
|
+
),
|
|
1259
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1260
|
+
"div",
|
|
1261
|
+
{
|
|
1262
|
+
className: "resize-handle resize-handle--vertical resize-handle--right",
|
|
1263
|
+
onPointerDown: (e) => handleResizeStart(e, "right")
|
|
1264
|
+
}
|
|
1265
|
+
),
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1267
|
+
"div",
|
|
1268
|
+
{
|
|
1269
|
+
className: "resize-handle resize-handle--corner resize-handle--top-left",
|
|
1270
|
+
style: { "--handle-radius": "6px" },
|
|
1271
|
+
onPointerDown: (e) => handleResizeStart(e, "top-left")
|
|
1272
|
+
}
|
|
1273
|
+
),
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1275
|
+
"div",
|
|
1276
|
+
{
|
|
1277
|
+
className: "resize-handle resize-handle--corner resize-handle--top-right",
|
|
1278
|
+
style: { "--handle-radius": "6px" },
|
|
1279
|
+
onPointerDown: (e) => handleResizeStart(e, "top-right")
|
|
1280
|
+
}
|
|
1281
|
+
),
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1283
|
+
"div",
|
|
1284
|
+
{
|
|
1285
|
+
className: "resize-handle resize-handle--corner resize-handle--bottom-left",
|
|
1286
|
+
style: { "--handle-radius": "6px" },
|
|
1287
|
+
onPointerDown: (e) => handleResizeStart(e, "bottom-left")
|
|
1288
|
+
}
|
|
1289
|
+
),
|
|
1290
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1291
|
+
"div",
|
|
1292
|
+
{
|
|
1293
|
+
className: "resize-handle resize-handle--corner resize-handle--bottom-right",
|
|
1294
|
+
style: { "--handle-radius": "6px" },
|
|
1295
|
+
onPointerDown: (e) => handleResizeStart(e, "bottom-right")
|
|
1296
|
+
}
|
|
1297
|
+
)
|
|
1298
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1299
|
+
"div",
|
|
1300
|
+
{
|
|
1301
|
+
className: cn(
|
|
1302
|
+
"resize-handle",
|
|
1303
|
+
edge === "left" && "resize-handle--vertical resize-handle--right",
|
|
1304
|
+
edge === "right" && "resize-handle--vertical resize-handle--left",
|
|
1305
|
+
edge === "top" && "resize-handle--horizontal resize-handle--bottom",
|
|
1306
|
+
edge === "bottom" && "resize-handle--horizontal resize-handle--top"
|
|
1307
|
+
),
|
|
1308
|
+
onPointerDown: (e) => handleResizeStart(e, (0, import_data_panel_core.getPinnedResizeHandle)(edge))
|
|
1309
|
+
}
|
|
1310
|
+
) })
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
)
|
|
1314
|
+
] });
|
|
1315
|
+
}
|
|
1316
|
+
);
|
|
1317
|
+
DataPanel.displayName = "DataPanel";
|
|
434
1318
|
// Annotate the CommonJS export names for ESM import in node:
|
|
435
1319
|
0 && (module.exports = {
|
|
436
1320
|
Avatar,
|
|
@@ -444,6 +1328,11 @@ PageHeader.displayName = "PageHeader";
|
|
|
444
1328
|
CardFooter,
|
|
445
1329
|
CardHeader,
|
|
446
1330
|
CardTitle,
|
|
1331
|
+
DataPanel,
|
|
1332
|
+
DataPanelContent,
|
|
1333
|
+
DataPanelFooter,
|
|
1334
|
+
DataPanelHeader,
|
|
1335
|
+
DataPanelTab,
|
|
447
1336
|
Dialog,
|
|
448
1337
|
DialogClose,
|
|
449
1338
|
DialogContent,
|
|
@@ -465,5 +1354,6 @@ PageHeader.displayName = "PageHeader";
|
|
|
465
1354
|
pageHeaderActionsVariants,
|
|
466
1355
|
pageHeaderContainerVariants,
|
|
467
1356
|
pageHeaderSubtitleVariants,
|
|
468
|
-
pageHeaderTitleVariants
|
|
1357
|
+
pageHeaderTitleVariants,
|
|
1358
|
+
useDataPanel
|
|
469
1359
|
});
|