@loykin/designkit 0.0.1-dev.1 → 0.0.1-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2151,6 +2151,71 @@ var DataPage = Object.assign(Root, {
2151
2151
  GroupBody,
2152
2152
  Footer
2153
2153
  });
2154
+ var DashboardPanel = React2.forwardRef(function DashboardPanel2({
2155
+ title,
2156
+ description,
2157
+ loading,
2158
+ error,
2159
+ transparent,
2160
+ editable,
2161
+ className,
2162
+ style,
2163
+ children,
2164
+ headerRight
2165
+ }, ref) {
2166
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2167
+ "div",
2168
+ {
2169
+ ref,
2170
+ className: cn(
2171
+ "group flex h-full flex-col overflow-hidden",
2172
+ transparent ? "" : "rounded-(--radius) border bg-card text-card-foreground",
2173
+ editable && "ring-1 ring-border/60 ring-inset",
2174
+ className
2175
+ ),
2176
+ style,
2177
+ children: [
2178
+ (title || headerRight || editable) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-2 pl-3 pr-1.5 py-2", children: [
2179
+ editable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 cursor-grab active:cursor-grabbing select-none text-muted-foreground/40 hover:text-muted-foreground/70 transition-colors -ml-1 px-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripHorizontal, { className: "h-3.5 w-3.5" }) }),
2180
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2181
+ title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs font-medium text-card-foreground", children: title }),
2182
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[11px] text-muted-foreground", children: description })
2183
+ ] }),
2184
+ headerRight && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity duration-150", children: headerRight })
2185
+ ] }),
2186
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-h-0 p-3", children: [
2187
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-card/70 z-10", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }) }),
2188
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: error }) }),
2189
+ !error && children
2190
+ ] })
2191
+ ]
2192
+ }
2193
+ );
2194
+ });
2195
+ function DashboardBodyTemplate({
2196
+ theme,
2197
+ className,
2198
+ title,
2199
+ description,
2200
+ topBar,
2201
+ toolbar,
2202
+ variableBar,
2203
+ children,
2204
+ contentClassName
2205
+ }) {
2206
+ return /* @__PURE__ */ jsxRuntime.jsxs(DataPage, { className: cn("layout-dashboard", className), style: theme, children: [
2207
+ topBar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: topBar }),
2208
+ (title || toolbar) && /* @__PURE__ */ jsxRuntime.jsx("header", { className: "shrink-0 border-b px-(--dk-page-padding-x) py-(--dk-page-padding-y)", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
2209
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2210
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-sm font-semibold truncate", children: title }),
2211
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description })
2212
+ ] }),
2213
+ toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 shrink-0", children: toolbar })
2214
+ ] }) }),
2215
+ variableBar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex flex-wrap items-center gap-2 px-(--dk-page-padding-x) py-1.5", children: variableBar }),
2216
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex-1 min-h-0 overflow-auto px-[calc(var(--dk-page-padding-x)-0.5rem)] pt-0 pb-(--dk-page-padding-y)", contentClassName), children })
2217
+ ] });
2218
+ }
2154
2219
  function DataBodyTab(_props) {
2155
2220
  return null;
2156
2221
  }
@@ -2429,6 +2494,284 @@ var DataBodyTemplate = Object.assign(Root2, {
2429
2494
  Row: DataBodyRow,
2430
2495
  Field: DataBodyField
2431
2496
  });
2497
+ function useIsNarrow() {
2498
+ const [narrow, setNarrow] = React2.useState(false);
2499
+ React2.useEffect(() => {
2500
+ const mql = window.matchMedia("(max-width: 1023px)");
2501
+ setNarrow(mql.matches);
2502
+ const handler = (e) => setNarrow(e.matches);
2503
+ mql.addEventListener("change", handler);
2504
+ return () => mql.removeEventListener("change", handler);
2505
+ }, []);
2506
+ return narrow;
2507
+ }
2508
+ function BrowseBodyTemplate({
2509
+ theme,
2510
+ className,
2511
+ topBar,
2512
+ title,
2513
+ description,
2514
+ actions,
2515
+ sidebar,
2516
+ sidebarTitle = "Filters",
2517
+ sidebarWidth = "18rem",
2518
+ toolbar,
2519
+ footer,
2520
+ contentClassName,
2521
+ children
2522
+ }) {
2523
+ const isNarrow = useIsNarrow();
2524
+ const hasHeader = title || description || actions;
2525
+ return /* @__PURE__ */ jsxRuntime.jsxs(DataPage, { className: cn("layout-browse", className), style: theme, children: [
2526
+ topBar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: topBar }),
2527
+ hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(DataPage.Header, { children: [
2528
+ /* @__PURE__ */ jsxRuntime.jsx(DataPage.TitleBlock, { title, description }),
2529
+ /* @__PURE__ */ jsxRuntime.jsx(DataPage.Actions, { children: actions })
2530
+ ] }),
2531
+ /* @__PURE__ */ jsxRuntime.jsxs(DataPage.Content, { padding: "none", className: "flex flex-col overflow-hidden", children: [
2532
+ (toolbar || isNarrow) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b px-(--dk-page-padding-x) py-2", children: [
2533
+ isNarrow && /* @__PURE__ */ jsxRuntime.jsxs(Sheet, { children: [
2534
+ /* @__PURE__ */ jsxRuntime.jsxs(
2535
+ SheetTrigger,
2536
+ {
2537
+ render: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", size: "sm", className: "shrink-0 gap-1.5" }),
2538
+ children: [
2539
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SlidersHorizontal, { className: "h-3.5 w-3.5" }),
2540
+ sidebarTitle
2541
+ ]
2542
+ }
2543
+ ),
2544
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { side: "left", className: "flex flex-col gap-0 p-0", children: [
2545
+ /* @__PURE__ */ jsxRuntime.jsx(SheetHeader, { className: "shrink-0 border-b px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { children: sidebarTitle }) }),
2546
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: sidebar }) })
2547
+ ] })
2548
+ ] }),
2549
+ toolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: toolbar })
2550
+ ] }),
2551
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 overflow-hidden", children: [
2552
+ !isNarrow && /* @__PURE__ */ jsxRuntime.jsx(
2553
+ "aside",
2554
+ {
2555
+ className: "shrink-0 overflow-hidden border-r",
2556
+ style: { width: sidebarWidth },
2557
+ children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-(--dk-page-padding-x) py-(--dk-page-padding-y)", children: sidebar }) })
2558
+ }
2559
+ ),
2560
+ /* @__PURE__ */ jsxRuntime.jsx(
2561
+ "div",
2562
+ {
2563
+ className: cn(
2564
+ "min-w-0 flex-1 overflow-hidden px-(--dk-page-padding-x) py-(--dk-page-padding-y)",
2565
+ "[&_.dg-shell]:h-full [&_.dg-table-stack]:flex-1 [&_.dg-table-stack]:min-h-0",
2566
+ "[&_.dg-card-container]:flex-1 [&_.dg-card-container]:min-h-0 [&_.dg-card-container]:overflow-auto",
2567
+ contentClassName
2568
+ ),
2569
+ children
2570
+ }
2571
+ )
2572
+ ] })
2573
+ ] }),
2574
+ footer && /* @__PURE__ */ jsxRuntime.jsx(DataPage.Footer, { children: footer })
2575
+ ] });
2576
+ }
2577
+ function DetailBodyHeader({
2578
+ eyebrow,
2579
+ title,
2580
+ description,
2581
+ status,
2582
+ actions,
2583
+ compact,
2584
+ className
2585
+ }) {
2586
+ return /* @__PURE__ */ jsxRuntime.jsxs(DataPage.Header, { className, children: [
2587
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2588
+ eyebrow && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: eyebrow }),
2589
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
2590
+ title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("min-w-0 truncate font-semibold", compact ? "text-base" : "text-lg"), children: title }),
2591
+ status && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: status })
2592
+ ] }),
2593
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
2594
+ ] }),
2595
+ /* @__PURE__ */ jsxRuntime.jsx(DataPage.Actions, { children: actions })
2596
+ ] });
2597
+ }
2598
+ function DetailBodyTab(_props) {
2599
+ return null;
2600
+ }
2601
+ function isDetailBodyTab(node) {
2602
+ return Boolean(node && typeof node === "object" && "type" in node && node.type === DetailBodyTab);
2603
+ }
2604
+ function DetailBodySection({
2605
+ title,
2606
+ description,
2607
+ actions,
2608
+ surface = "plain",
2609
+ className,
2610
+ children
2611
+ }) {
2612
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2613
+ "section",
2614
+ {
2615
+ className: cn(
2616
+ "min-h-0",
2617
+ surface === "card" && "rounded-(--radius) border bg-card p-(--dk-panel-gap) text-card-foreground shadow-sm",
2618
+ surface === "bordered" && "rounded-(--radius) border p-(--dk-panel-gap)",
2619
+ className
2620
+ ),
2621
+ children: [
2622
+ (title || description || actions) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
2623
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2624
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold", children: title }),
2625
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: description })
2626
+ ] }),
2627
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: actions })
2628
+ ] }),
2629
+ children
2630
+ ]
2631
+ }
2632
+ );
2633
+ }
2634
+ function renderChildren(nodes) {
2635
+ return React2.Children.toArray(nodes).map((child, i) => /* @__PURE__ */ jsxRuntime.jsx(React2.Fragment, { children: child }, i));
2636
+ }
2637
+ function DetailBodyTemplateRoot({
2638
+ variant = "record",
2639
+ theme,
2640
+ className,
2641
+ topBar,
2642
+ header,
2643
+ lead,
2644
+ eyebrow,
2645
+ title,
2646
+ description,
2647
+ status,
2648
+ actions,
2649
+ media,
2650
+ aside,
2651
+ summary,
2652
+ stickyAside = true,
2653
+ contentClassName,
2654
+ mediaClassName,
2655
+ asideClassName,
2656
+ children
2657
+ }) {
2658
+ const childArray = React2.useMemo(() => React2.Children.toArray(children), [children]);
2659
+ const tabs = childArray.filter(isDetailBodyTab);
2660
+ const hasTabs = tabs.length > 0;
2661
+ const [activeTab, setActiveTab] = React2.useState(() => tabs[0]?.props.id ?? "");
2662
+ const selectedTab = tabs.find((tab) => tab.props.id === activeTab) ?? tabs[0];
2663
+ const summarySlot = summary ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 rounded-(--radius) border bg-card p-(--dk-panel-gap) text-card-foreground", children: summary }) : null;
2664
+ const mediaSlot = media ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-h-0 overflow-hidden rounded-(--radius) border bg-card", mediaClassName), children: media }) : null;
2665
+ const leadGridClass = variant === "media" ? "xl:grid-cols-[minmax(0,1.35fr)_minmax(18rem,0.65fr)]" : "xl:grid-cols-2";
2666
+ const defaultHeader = eyebrow || title || description || status || actions ? /* @__PURE__ */ jsxRuntime.jsx(
2667
+ DetailBodyHeader,
2668
+ {
2669
+ eyebrow,
2670
+ title,
2671
+ description,
2672
+ status,
2673
+ actions
2674
+ }
2675
+ ) : null;
2676
+ const defaultLead = media || summary ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid gap-(--dk-panel-gap)", leadGridClass), children: [
2677
+ mediaSlot,
2678
+ summarySlot
2679
+ ] }) : null;
2680
+ const body = hasTabs ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0", children: [
2681
+ /* @__PURE__ */ jsxRuntime.jsx(DataPage.Tabs, { children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(
2682
+ DataPage.Tab,
2683
+ {
2684
+ active: (selectedTab?.props.id ?? "") === tab.props.id,
2685
+ count: tab.props.count,
2686
+ disabled: tab.props.disabled,
2687
+ onClick: () => setActiveTab(tab.props.id),
2688
+ children: tab.props.label
2689
+ },
2690
+ tab.props.id
2691
+ )) }),
2692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-(--dk-panel-gap)", children: selectedTab?.props.children })
2693
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-(--dk-panel-gap)", children: renderChildren(children) });
2694
+ const leadSlot = lead ?? defaultLead;
2695
+ const outsideAsideSlot = variant === "full" ? null : aside;
2696
+ const insideAsideSlot = variant === "full" ? aside : null;
2697
+ const hasRecordInspector = Boolean(leadSlot);
2698
+ const hasFullLeadArea = Boolean(leadSlot || insideAsideSlot);
2699
+ const layout = {
2700
+ media: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2701
+ leadSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-(--dk-panel-gap)", children: leadSlot }),
2702
+ body
2703
+ ] }),
2704
+ record: /* @__PURE__ */ jsxRuntime.jsxs(
2705
+ "div",
2706
+ {
2707
+ className: cn(
2708
+ "grid gap-(--dk-panel-gap)",
2709
+ hasRecordInspector && "xl:grid-cols-[minmax(28rem,1fr)_minmax(14rem,18rem)]"
2710
+ ),
2711
+ children: [
2712
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: body }),
2713
+ hasRecordInspector && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-(--dk-panel-gap)", children: leadSlot })
2714
+ ]
2715
+ }
2716
+ ),
2717
+ full: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2718
+ hasFullLeadArea && /* @__PURE__ */ jsxRuntime.jsxs(
2719
+ "div",
2720
+ {
2721
+ className: cn(
2722
+ "mb-(--dk-panel-gap) grid gap-(--dk-panel-gap)",
2723
+ insideAsideSlot && "xl:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]"
2724
+ ),
2725
+ children: [
2726
+ leadSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-(--dk-panel-gap)", children: leadSlot }),
2727
+ insideAsideSlot && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("min-h-0 rounded-(--radius) border bg-card p-(--dk-panel-gap)", asideClassName), children: insideAsideSlot })
2728
+ ]
2729
+ }
2730
+ ),
2731
+ body
2732
+ ] })
2733
+ };
2734
+ return /* @__PURE__ */ jsxRuntime.jsxs(DataPage, { className: cn("layout-detail", className), style: theme, "data-detail-variant": variant, children: [
2735
+ topBar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: topBar }),
2736
+ header ?? defaultHeader,
2737
+ /* @__PURE__ */ jsxRuntime.jsx(DataPage.Content, { padding: "none", className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
2738
+ "div",
2739
+ {
2740
+ className: cn(
2741
+ "grid h-full min-h-0 grid-cols-1 overflow-hidden",
2742
+ outsideAsideSlot && "lg:grid-cols-[minmax(0,1fr)_minmax(18rem,24rem)]"
2743
+ ),
2744
+ children: [
2745
+ /* @__PURE__ */ jsxRuntime.jsx(
2746
+ "main",
2747
+ {
2748
+ className: cn(
2749
+ "min-h-0 overflow-auto px-(--dk-page-padding-x) py-(--dk-page-padding-y)",
2750
+ contentClassName
2751
+ ),
2752
+ children: layout[variant]
2753
+ }
2754
+ ),
2755
+ outsideAsideSlot && /* @__PURE__ */ jsxRuntime.jsx("aside", { className: cn("min-h-0 border-t bg-background lg:border-l lg:border-t-0", asideClassName), children: /* @__PURE__ */ jsxRuntime.jsx(
2756
+ "div",
2757
+ {
2758
+ className: cn(
2759
+ "px-(--dk-page-padding-x) py-(--dk-page-padding-y)",
2760
+ stickyAside && "lg:sticky lg:top-0"
2761
+ ),
2762
+ children: outsideAsideSlot
2763
+ }
2764
+ ) })
2765
+ ]
2766
+ }
2767
+ ) })
2768
+ ] });
2769
+ }
2770
+ var DetailBodyTemplate = Object.assign(DetailBodyTemplateRoot, {
2771
+ Header: DetailBodyHeader,
2772
+ Tab: DetailBodyTab,
2773
+ Section: DetailBodySection
2774
+ });
2432
2775
  function FormWizardBodyTemplate({
2433
2776
  theme,
2434
2777
  title,
@@ -3236,6 +3579,7 @@ exports.AvatarGroup = AvatarGroup;
3236
3579
  exports.AvatarGroupCount = AvatarGroupCount;
3237
3580
  exports.AvatarImage = AvatarImage;
3238
3581
  exports.Badge = Badge;
3582
+ exports.BrowseBodyTemplate = BrowseBodyTemplate;
3239
3583
  exports.Button = Button;
3240
3584
  exports.Card = Card;
3241
3585
  exports.CardAction = CardAction;
@@ -3246,8 +3590,11 @@ exports.CardHeader = CardHeader;
3246
3590
  exports.CardTitle = CardTitle;
3247
3591
  exports.Checkbox = Checkbox;
3248
3592
  exports.ColorsBodyTemplate = ColorsBodyTemplate;
3593
+ exports.DashboardBodyTemplate = DashboardBodyTemplate;
3594
+ exports.DashboardPanel = DashboardPanel;
3249
3595
  exports.DataBodyTemplate = DataBodyTemplate;
3250
3596
  exports.DataPage = DataPage;
3597
+ exports.DetailBodyTemplate = DetailBodyTemplate;
3251
3598
  exports.DropdownMenu = DropdownMenu;
3252
3599
  exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem;
3253
3600
  exports.DropdownMenuContent = DropdownMenuContent;