@particle-academy/react-fancy 2.5.0 → 2.6.0

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
@@ -1,4 +1,4 @@
1
- import { forwardRef, useId, useRef, useEffect, useState, useCallback, useMemo, createContext, Children, isValidElement, cloneElement, useLayoutEffect, useContext, Fragment as Fragment$1 } from 'react';
1
+ import { forwardRef, createContext, useId, useRef, useEffect, useState, useCallback, useMemo, Children, isValidElement, cloneElement, useLayoutEffect, useContext, Fragment as Fragment$1 } from 'react';
2
2
  import { clsx } from 'clsx';
3
3
  import { twMerge } from 'tailwind-merge';
4
4
  import * as LucideIcons from 'lucide-react';
@@ -2556,6 +2556,283 @@ var Action = forwardRef(
2556
2556
  }
2557
2557
  );
2558
2558
  Action.displayName = "Action";
2559
+ function useControllableState(controlledValue, defaultValue, onChange) {
2560
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
2561
+ const isControlled = controlledValue !== void 0;
2562
+ const value = isControlled ? controlledValue : uncontrolledValue;
2563
+ const onChangeRef = useRef(onChange);
2564
+ onChangeRef.current = onChange;
2565
+ const setValue = useCallback(
2566
+ (next) => {
2567
+ const nextValue = typeof next === "function" ? next(value) : next;
2568
+ if (!isControlled) {
2569
+ setUncontrolledValue(nextValue);
2570
+ }
2571
+ onChangeRef.current?.(nextValue);
2572
+ },
2573
+ [isControlled, value]
2574
+ );
2575
+ return [value, setValue];
2576
+ }
2577
+ var AccordionPanelContext = createContext(null);
2578
+ function useAccordionPanel() {
2579
+ const ctx = useContext(AccordionPanelContext);
2580
+ if (!ctx) {
2581
+ throw new Error(
2582
+ "AccordionPanel components must be used inside <AccordionPanel>"
2583
+ );
2584
+ }
2585
+ return ctx;
2586
+ }
2587
+ var AccordionSectionContext = createContext(null);
2588
+ function useAccordionSection() {
2589
+ const ctx = useContext(AccordionSectionContext);
2590
+ if (!ctx) {
2591
+ throw new Error(
2592
+ "<AccordionPanel.Trigger> must be rendered inside <AccordionPanel.Section>"
2593
+ );
2594
+ }
2595
+ return ctx;
2596
+ }
2597
+ function AccordionPanelSection({
2598
+ id,
2599
+ pinned = false,
2600
+ className,
2601
+ openClassName,
2602
+ closedClassName,
2603
+ children
2604
+ }) {
2605
+ const panel = useAccordionPanel();
2606
+ const { orientation, isOpen, toggle, registerSection } = panel;
2607
+ useEffect(() => registerSection(id), [id, registerSection]);
2608
+ const open = pinned || isOpen(id);
2609
+ const sectionCtx = useMemo(
2610
+ () => ({
2611
+ id,
2612
+ open,
2613
+ pinned,
2614
+ orientation,
2615
+ toggle: () => toggle(id)
2616
+ }),
2617
+ [id, open, pinned, orientation, toggle]
2618
+ );
2619
+ return /* @__PURE__ */ jsx(AccordionSectionContext.Provider, { value: sectionCtx, children: /* @__PURE__ */ jsx(
2620
+ "div",
2621
+ {
2622
+ "data-react-fancy-accordion-section": "",
2623
+ "data-state": open ? "open" : "closed",
2624
+ "data-pinned": pinned ? "" : void 0,
2625
+ "data-orientation": orientation,
2626
+ className: cn(
2627
+ "flex shrink-0 items-center gap-1",
2628
+ orientation === "horizontal" ? "flex-row" : "flex-col",
2629
+ className,
2630
+ open ? openClassName : closedClassName
2631
+ ),
2632
+ children
2633
+ }
2634
+ ) });
2635
+ }
2636
+ AccordionPanelSection.displayName = "AccordionPanelSection";
2637
+ function renderSlot(slot, state) {
2638
+ return typeof slot === "function" ? slot(state) : slot;
2639
+ }
2640
+ function AccordionPanelTrigger({
2641
+ children,
2642
+ className,
2643
+ "aria-label": ariaLabel
2644
+ }) {
2645
+ const { id, open, orientation, toggle } = useAccordionSection();
2646
+ const state = { id, open, orientation, toggle };
2647
+ if (children !== void 0) {
2648
+ return /* @__PURE__ */ jsx(
2649
+ "div",
2650
+ {
2651
+ "data-react-fancy-accordion-trigger": "",
2652
+ "data-state": open ? "open" : "closed",
2653
+ "data-orientation": orientation,
2654
+ className,
2655
+ children: renderSlot(children, state)
2656
+ }
2657
+ );
2658
+ }
2659
+ if (open) {
2660
+ return /* @__PURE__ */ jsx(
2661
+ "button",
2662
+ {
2663
+ type: "button",
2664
+ onClick: toggle,
2665
+ "aria-label": ariaLabel ?? "Collapse section",
2666
+ "data-react-fancy-accordion-trigger": "",
2667
+ "data-state": "open",
2668
+ "data-orientation": orientation,
2669
+ className: cn(
2670
+ "group relative flex shrink-0 items-center justify-center cursor-pointer",
2671
+ "text-zinc-500 dark:text-zinc-500",
2672
+ "hover:text-zinc-900 dark:hover:text-zinc-100",
2673
+ orientation === "horizontal" ? "w-px self-stretch hover:w-3 mx-1" : "h-px self-stretch hover:h-3 my-1",
2674
+ "before:absolute before:inset-0 before:bg-zinc-200 dark:before:bg-zinc-700",
2675
+ orientation === "horizontal" ? "before:w-px before:left-1/2 before:-translate-x-1/2" : "before:h-px before:top-1/2 before:-translate-y-1/2",
2676
+ "transition-all duration-150",
2677
+ className
2678
+ ),
2679
+ children: /* @__PURE__ */ jsx(
2680
+ ChevronIcon,
2681
+ {
2682
+ orientation,
2683
+ purpose: "collapse",
2684
+ className: "relative opacity-0 group-hover:opacity-100 transition-opacity"
2685
+ }
2686
+ )
2687
+ }
2688
+ );
2689
+ }
2690
+ return /* @__PURE__ */ jsx(
2691
+ "button",
2692
+ {
2693
+ type: "button",
2694
+ onClick: toggle,
2695
+ "aria-label": ariaLabel ?? "Expand section",
2696
+ "data-react-fancy-accordion-trigger": "",
2697
+ "data-state": "closed",
2698
+ "data-orientation": orientation,
2699
+ className: cn(
2700
+ "flex shrink-0 items-center justify-center rounded-md",
2701
+ "text-zinc-400 dark:text-zinc-500",
2702
+ "hover:text-zinc-900 dark:hover:text-zinc-100",
2703
+ "hover:bg-zinc-100 dark:hover:bg-zinc-800",
2704
+ "transition-colors cursor-pointer",
2705
+ orientation === "horizontal" ? "h-8 w-6 mx-0.5" : "w-8 h-6 my-0.5",
2706
+ className
2707
+ ),
2708
+ children: /* @__PURE__ */ jsx(ChevronIcon, { orientation, purpose: "expand" })
2709
+ }
2710
+ );
2711
+ }
2712
+ AccordionPanelTrigger.displayName = "AccordionPanelTrigger";
2713
+ function ChevronIcon({
2714
+ orientation,
2715
+ purpose,
2716
+ className
2717
+ }) {
2718
+ const transform = orientation === "horizontal" ? "rotate(180deg)" : purpose === "expand" ? "rotate(90deg)" : "rotate(270deg)";
2719
+ return /* @__PURE__ */ jsx(
2720
+ "svg",
2721
+ {
2722
+ viewBox: "0 0 16 16",
2723
+ width: "12",
2724
+ height: "12",
2725
+ fill: "none",
2726
+ stroke: "currentColor",
2727
+ strokeWidth: "2",
2728
+ strokeLinecap: "round",
2729
+ strokeLinejoin: "round",
2730
+ style: { transform },
2731
+ className,
2732
+ "aria-hidden": "true",
2733
+ children: /* @__PURE__ */ jsx("polyline", { points: "6 4 10 8 6 12" })
2734
+ }
2735
+ );
2736
+ }
2737
+ function AccordionPanelContent({
2738
+ children,
2739
+ className
2740
+ }) {
2741
+ const { open, orientation } = useAccordionSection();
2742
+ if (!open) return null;
2743
+ return /* @__PURE__ */ jsx(
2744
+ "div",
2745
+ {
2746
+ "data-react-fancy-accordion-content": "",
2747
+ "data-orientation": orientation,
2748
+ className: cn(
2749
+ "flex items-center gap-1",
2750
+ orientation === "horizontal" ? "flex-row" : "flex-col",
2751
+ className
2752
+ ),
2753
+ children
2754
+ }
2755
+ );
2756
+ }
2757
+ AccordionPanelContent.displayName = "AccordionPanelContent";
2758
+ function AccordionPanelRoot({
2759
+ orientation = "horizontal",
2760
+ value: controlledValue,
2761
+ defaultValue,
2762
+ onValueChange,
2763
+ className,
2764
+ children
2765
+ }) {
2766
+ const [openIds, setOpenIds] = useControllableState(
2767
+ controlledValue,
2768
+ defaultValue ?? [],
2769
+ onValueChange
2770
+ );
2771
+ const openSet = useMemo(() => new Set(openIds), [openIds]);
2772
+ const isOpen = useCallback((id) => openSet.has(id), [openSet]);
2773
+ const open = useCallback(
2774
+ (id) => {
2775
+ setOpenIds(openSet.has(id) ? openIds ?? [] : [...openIds ?? [], id]);
2776
+ },
2777
+ [openSet, openIds, setOpenIds]
2778
+ );
2779
+ const close = useCallback(
2780
+ (id) => {
2781
+ setOpenIds((openIds ?? []).filter((x) => x !== id));
2782
+ },
2783
+ [openIds, setOpenIds]
2784
+ );
2785
+ const toggle = useCallback(
2786
+ (id) => {
2787
+ setOpenIds(
2788
+ openSet.has(id) ? (openIds ?? []).filter((x) => x !== id) : [...openIds ?? [], id]
2789
+ );
2790
+ },
2791
+ [openSet, openIds, setOpenIds]
2792
+ );
2793
+ const [sectionIds, setSectionIds] = useState([]);
2794
+ const orderRef = useRef([]);
2795
+ const registerSection = useCallback((id) => {
2796
+ if (!orderRef.current.includes(id)) {
2797
+ orderRef.current = [...orderRef.current, id];
2798
+ setSectionIds(orderRef.current);
2799
+ }
2800
+ return () => {
2801
+ orderRef.current = orderRef.current.filter((x) => x !== id);
2802
+ setSectionIds(orderRef.current);
2803
+ };
2804
+ }, []);
2805
+ const ctx = useMemo(
2806
+ () => ({
2807
+ orientation,
2808
+ isOpen,
2809
+ toggle,
2810
+ open,
2811
+ close,
2812
+ sectionIds,
2813
+ registerSection
2814
+ }),
2815
+ [orientation, isOpen, toggle, open, close, sectionIds, registerSection]
2816
+ );
2817
+ return /* @__PURE__ */ jsx(AccordionPanelContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
2818
+ "div",
2819
+ {
2820
+ "data-react-fancy-accordion-panel": "",
2821
+ "data-orientation": orientation,
2822
+ className: cn(
2823
+ "inline-flex items-stretch",
2824
+ orientation === "horizontal" ? "flex-row" : "flex-col",
2825
+ className
2826
+ ),
2827
+ children
2828
+ }
2829
+ ) });
2830
+ }
2831
+ AccordionPanelRoot.displayName = "AccordionPanel";
2832
+ var AccordionPanel = AccordionPanelRoot;
2833
+ AccordionPanel.Section = AccordionPanelSection;
2834
+ AccordionPanel.Trigger = AccordionPanelTrigger;
2835
+ AccordionPanel.Content = AccordionPanelContent;
2559
2836
 
2560
2837
  // src/components/inputs/inputs.utils.ts
2561
2838
  var inputSizeClasses = {
@@ -3442,24 +3719,6 @@ var Select = forwardRef(
3442
3719
  }
3443
3720
  );
3444
3721
  Select.displayName = "Select";
3445
- function useControllableState(controlledValue, defaultValue, onChange) {
3446
- const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
3447
- const isControlled = controlledValue !== void 0;
3448
- const value = isControlled ? controlledValue : uncontrolledValue;
3449
- const onChangeRef = useRef(onChange);
3450
- onChangeRef.current = onChange;
3451
- const setValue = useCallback(
3452
- (next) => {
3453
- const nextValue = typeof next === "function" ? next(value) : next;
3454
- if (!isControlled) {
3455
- setUncontrolledValue(nextValue);
3456
- }
3457
- onChangeRef.current?.(nextValue);
3458
- },
3459
- [isControlled, value]
3460
- );
3461
- return [value, setValue];
3462
- }
3463
3722
  var Checkbox = forwardRef(
3464
3723
  ({
3465
3724
  size = "md",
@@ -11593,7 +11852,7 @@ function DiagramToolbar({ className }) {
11593
11852
  const canImport = importableRef.current;
11594
11853
  const handleDownload = useCallback(
11595
11854
  async (format) => {
11596
- const { serializeToERD, serializeToUML, serializeToDFD } = await import('./diagram.serializers-OK4HP7AB.js');
11855
+ const { serializeToERD, serializeToUML, serializeToDFD } = await import('./diagram.serializers-6RPUO46U.js');
11597
11856
  let content;
11598
11857
  switch (format) {
11599
11858
  case "erd":
@@ -11624,7 +11883,7 @@ function DiagramToolbar({ className }) {
11624
11883
  if (!file || !onImport) return;
11625
11884
  const text = await file.text();
11626
11885
  const ext = file.name.split(".").pop()?.toLowerCase();
11627
- const { deserializeSchema } = await import('./diagram.serializers-OK4HP7AB.js');
11886
+ const { deserializeSchema } = await import('./diagram.serializers-6RPUO46U.js');
11628
11887
  let format = "erd";
11629
11888
  if (ext === "puml" || ext === "uml") format = "uml";
11630
11889
  else if (ext === "dfd") format = "dfd";
@@ -11692,9 +11951,12 @@ var VERTICAL_GAP = 60;
11692
11951
  function getEntityHeight(fieldCount) {
11693
11952
  return HEADER_HEIGHT2 + Math.max(fieldCount, 1) * FIELD_HEIGHT2;
11694
11953
  }
11954
+ function resolveEntityId(entity) {
11955
+ return entity.id ?? entity.name;
11956
+ }
11695
11957
  function computeDiagramLayout(schema) {
11696
11958
  const positions = /* @__PURE__ */ new Map();
11697
- const entityIds = new Set(schema.entities.map((e) => e.id));
11959
+ const entityIds = new Set(schema.entities.map(resolveEntityId));
11698
11960
  const incoming = /* @__PURE__ */ new Map();
11699
11961
  for (const id of entityIds) {
11700
11962
  incoming.set(id, /* @__PURE__ */ new Set());
@@ -11715,7 +11977,7 @@ function computeDiagramLayout(schema) {
11715
11977
  }
11716
11978
  }
11717
11979
  if (queue.length === 0 && entityIds.size > 0) {
11718
- const firstId = schema.entities[0].id;
11980
+ const firstId = resolveEntityId(schema.entities[0]);
11719
11981
  rowAssignment.set(firstId, 0);
11720
11982
  assigned.add(firstId);
11721
11983
  queue.push(firstId);
@@ -11755,7 +12017,7 @@ function computeDiagramLayout(schema) {
11755
12017
  }
11756
12018
  const fieldCounts = /* @__PURE__ */ new Map();
11757
12019
  for (const entity of schema.entities) {
11758
- fieldCounts.set(entity.id, entity.fields?.length ?? 0);
12020
+ fieldCounts.set(resolveEntityId(entity), entity.fields?.length ?? 0);
11759
12021
  }
11760
12022
  const sortedRows = Array.from(rows.keys()).sort((a, b) => a - b);
11761
12023
  let currentY = 0;
@@ -11952,7 +12214,7 @@ function FolderIcon({ open }) {
11952
12214
  }
11953
12215
  return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: /* @__PURE__ */ jsx("path", { d: "M1.5 3a1 1 0 011-1h3l1.5 1.5H13a1 1 0 011 1v8a1 1 0 01-1 1H2.5a1 1 0 01-1-1V3z", fill: "#fbbf24" }) });
11954
12216
  }
11955
- function ChevronIcon({ open }) {
12217
+ function ChevronIcon2({ open }) {
11956
12218
  return /* @__PURE__ */ jsx(
11957
12219
  "svg",
11958
12220
  {
@@ -12134,7 +12396,7 @@ function TreeNode({ node, depth }) {
12134
12396
  ),
12135
12397
  style: { paddingLeft },
12136
12398
  children: [
12137
- isFolder && /* @__PURE__ */ jsx(ChevronIcon, { open: isExpanded }),
12399
+ isFolder && /* @__PURE__ */ jsx(ChevronIcon2, { open: isExpanded }),
12138
12400
  !isFolder && /* @__PURE__ */ jsx("span", { className: "w-3.5 shrink-0" }),
12139
12401
  showIcons && (node.icon ?? (isFolder ? /* @__PURE__ */ jsx(FolderIcon, { open: isExpanded }) : /* @__PURE__ */ jsx(FileIcon, { ext: node.ext ?? node.label.split(".").pop() }))),
12140
12402
  /* @__PURE__ */ jsx("span", { className: "truncate", children: node.label })
@@ -12263,6 +12525,6 @@ var TreeNav = Object.assign(TreeNavRoot, {
12263
12525
  Node: TreeNode
12264
12526
  });
12265
12527
 
12266
- export { Accordion, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Calendar, Callout, Canvas, Card, Carousel, Chart, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, Diagram, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, Field, FileUpload, Heading, Icon, Input, Kanban, Menu2 as Menu, MobileMenu, Modal, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, RadioGroup, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, Switch, Table, Tabs, Text, Textarea, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, find, hasSkinTones, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, useAccordion, useAnimation, useCanvas, useCarousel, useCommand, useContextMenu, useControllableState, useDiagram, useDropdown, useEditor, useEscapeKey, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
12528
+ export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Calendar, Callout, Canvas, Card, Carousel, Chart, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, Diagram, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, Field, FileUpload, Heading, Icon, Input, Kanban, Menu2 as Menu, MobileMenu, Modal, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, RadioGroup, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, Switch, Table, Tabs, Text, Textarea, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, find, hasSkinTones, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCanvas, useCarousel, useCommand, useContextMenu, useControllableState, useDiagram, useDropdown, useEditor, useEscapeKey, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
12267
12529
  //# sourceMappingURL=index.js.map
12268
12530
  //# sourceMappingURL=index.js.map