@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.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
- function Badge({ className, variant, ...props }) {
212
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
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 React5 = __toESM(require("react"));
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 = React5.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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 React6 = __toESM(require("react"));
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 = React6.forwardRef(
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 React7 = __toESM(require("react"));
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 = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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 = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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 = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
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 React8 = __toESM(require("react"));
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 = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
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 = React8.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogPortal, { children: [
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 = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
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 = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
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 React9 = __toESM(require("react"));
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 = React9.forwardRef(
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
  });