@bioturing/components 0.25.0 → 0.27.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.
Files changed (48) hide show
  1. package/dist/components/checkbox/component.js +12 -4
  2. package/dist/components/checkbox/component.js.map +1 -1
  3. package/dist/components/checkbox/style.css +1 -1
  4. package/dist/components/choice-list/component.js +24 -21
  5. package/dist/components/choice-list/component.js.map +1 -1
  6. package/dist/components/cmdk/index.js.map +1 -1
  7. package/dist/components/dropdown-menu/component.js +16 -15
  8. package/dist/components/dropdown-menu/component.js.map +1 -1
  9. package/dist/components/form/item.js +31 -28
  10. package/dist/components/form/item.js.map +1 -1
  11. package/dist/components/form/style.css +1 -1
  12. package/dist/components/popup-panel/component.js +142 -164
  13. package/dist/components/popup-panel/component.js.map +1 -1
  14. package/dist/components/popup-panel/style.css +1 -1
  15. package/dist/components/resizable/component.js +171 -0
  16. package/dist/components/resizable/component.js.map +1 -0
  17. package/dist/components/resizable/style.css +1 -0
  18. package/dist/components/segmented/component.js +3 -3
  19. package/dist/components/segmented/component.js.map +1 -1
  20. package/dist/components/spin/component.js +9 -8
  21. package/dist/components/spin/component.js.map +1 -1
  22. package/dist/components/splitter/component.js +7 -36
  23. package/dist/components/splitter/component.js.map +1 -1
  24. package/dist/components/splitter/context.js +6 -0
  25. package/dist/components/splitter/context.js.map +1 -0
  26. package/dist/components/splitter/splitter-panel.js +35 -0
  27. package/dist/components/splitter/splitter-panel.js.map +1 -0
  28. package/dist/components/splitter/splitter.js +158 -0
  29. package/dist/components/splitter/splitter.js.map +1 -0
  30. package/dist/components/splitter/style.css +1 -1
  31. package/dist/components/splitter/useSizes.js +86 -0
  32. package/dist/components/splitter/useSizes.js.map +1 -0
  33. package/dist/components/upload/dragger.js +19 -10
  34. package/dist/components/upload/dragger.js.map +1 -1
  35. package/dist/components/upload/item.js +21 -18
  36. package/dist/components/upload/item.js.map +1 -1
  37. package/dist/components/utils/antdUtils.js +18 -56
  38. package/dist/components/utils/antdUtils.js.map +1 -1
  39. package/dist/components/utils/placement.js +58 -0
  40. package/dist/components/utils/placement.js.map +1 -0
  41. package/dist/components/utils/reactElement.js +5 -0
  42. package/dist/components/utils/reactElement.js.map +1 -0
  43. package/dist/index.d.ts +196 -25
  44. package/dist/index.js +164 -158
  45. package/dist/index.js.map +1 -1
  46. package/dist/metadata.js +22 -2
  47. package/dist/metadata.js.map +1 -1
  48. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sources":["../../../src/components/dropdown-menu/component.tsx"],"sourcesContent":["\"use client\";\nimport { Menu } from \"@base-ui-components/react/menu\";\nimport { useControlled } from \"@base-ui-components/react/utils\";\nimport { Popover } from \"@base-ui-components/react/popover\";\nimport { type PopoverProps } from \"antd/es/popover\";\nimport { Ref, useCallback, useRef } from \"react\";\nimport {\n clsx,\n DROPDOWN_COLLISION_AVOIDANCE,\n parseAntdPlacement,\n useAntdCssVarClassname,\n useCls,\n} from \"../utils\";\nimport { Command } from \"../cmdk\";\nimport { ScrollArea } from \"../scroll-area\";\n\n// Import component-specific styles\nimport { Input } from \"../input\";\nimport { PopupPanelSize } from \"../popup-panel/constants\";\n\nimport \"./style.css\";\n\nexport type DropdownMenuItemType =\n | {\n type: \"item\";\n label?: React.ReactNode;\n disabled?: boolean;\n icon?: React.ReactNode;\n key: React.Key;\n onClick?: React.HTMLAttributes<HTMLElement>[\"onClick\"];\n onMouseEnter?: React.HTMLAttributes<HTMLElement>[\"onMouseEnter\"];\n onMouseLeave?: React.HTMLAttributes<HTMLElement>[\"onMouseLeave\"];\n onMouseOver?: React.HTMLAttributes<HTMLElement>[\"onMouseOver\"];\n onMouseOut?: React.HTMLAttributes<HTMLElement>[\"onMouseOut\"];\n danger?: boolean;\n ref?: React.Ref<HTMLElement>;\n }\n | {\n type: \"divider\";\n }\n | {\n type: \"header\";\n title?: React.ReactNode;\n };\n\nexport interface DropdownMenuProps {\n /** Array of menu items to be displayed in the dropdown */\n items: DropdownMenuItemType[];\n /** Custom render function for the trigger element */\n children?: React.ComponentProps<typeof Menu.Trigger>[\"render\"];\n /**\n * Placement of the dropdown relative to the trigger element\n * @default \"bottomLeft\"\n */\n placement?: PopoverProps[\"placement\"];\n /**\n * Whether to open the dropdown on hover instead of click\n * @default false\n */\n openOnHover?: boolean;\n /**\n * Controlled open state of the dropdown\n */\n open?: boolean;\n /**\n * Callback fired when the dropdown open state changes\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Additional CSS class for the dropdown component\n */\n className?: string;\n /**\n * Custom class names for different parts of the dropdown\n * @default {}\n */\n classNames?: {\n root?: string;\n trigger?: string;\n popup?: string;\n group?: string;\n groupLabel?: string;\n item?: string;\n itemIcon?: string;\n itemText?: string;\n separator?: string;\n positioner?: string;\n };\n /**\n * Custom render function for menu items\n */\n itemRender?: (\n item: DropdownMenuItemType,\n props: React.HTMLAttributes<HTMLElement>\n ) => React.ReactElement;\n /**\n * Whether to show search input\n * @default false\n */\n showSearch?: boolean;\n /**\n * Size of the dropdown menu\n * @default \"auto\"\n */\n size?: \"auto\" | keyof typeof PopupPanelSize;\n /**\n * Search placeholder\n */\n searchProps?: Omit<\n React.ComponentProps<typeof Command.Input>,\n \"size\" | \"ref\"\n >;\n /**\n *\n */\n}\n\ninterface DropdownMenuGroup {\n label: React.ReactNode | null;\n items: DropdownMenuItemType[];\n}\n\nexport const DropdownMenu = ({\n children,\n items,\n placement,\n openOnHover,\n open: outsideOpen,\n onOpenChange: outsideOnOpenChange,\n className,\n itemRender,\n classNames,\n size = \"auto\",\n showSearch,\n searchProps = {\n placeholder: \"Search...\",\n },\n}: DropdownMenuProps) => {\n const [open, setOpen] = useControlled({\n controlled: outsideOpen,\n default: false,\n name: \"open\",\n });\n const onOpenChange = useCallback(\n (newValue: boolean) => {\n setOpen(newValue);\n outsideOnOpenChange?.(newValue);\n },\n [setOpen, outsideOnOpenChange]\n );\n const cls = useCls();\n const antdCssVarClassname = useAntdCssVarClassname();\n const headlessUIPlacement = parseAntdPlacement(placement);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const itemGroups = items.reduce<DropdownMenuGroup[]>((acc, current) => {\n // If no groups exist yet and current item is not a header, create default group\n if (acc.length === 0 && current.type !== \"header\") {\n acc.push({\n label: null,\n items: [],\n });\n }\n\n // If it's a header, create a new group\n if (current.type === \"header\") {\n acc.push({\n label: current.title,\n items: [],\n });\n }\n // If it's an item and we have at least one group, add it to the last group's items\n else if (\n (current.type === \"item\" || current.type === \"divider\") &&\n acc.length > 0\n ) {\n acc[acc.length - 1].items.push(current);\n }\n // Skip dividers\n return acc;\n }, []);\n\n const MenuSeparator = showSearch ? Command.Separator : Menu.Separator;\n\n const renderMenuItem = useCallback(\n (item: DropdownMenuItemType, i: number, j: number) => {\n const MenuItem = showSearch ? Command.Item : Menu.Item;\n\n if (item.type === \"item\") {\n const props = {\n className: clsx(cls(\"dropdown-menu-item\"), classNames?.item),\n disabled: item.disabled,\n \"data-danger\": item.danger,\n ref: item.ref as Ref<HTMLDivElement>,\n onClick: item.onClick,\n onMouseEnter: item.onMouseEnter,\n onMouseLeave: item.onMouseLeave,\n onMouseOver: item.onMouseOver,\n onMouseOut: item.onMouseOut,\n onSelect: showSearch\n ? () => {\n const e = new MouseEvent(\"click\", {\n bubbles: true,\n cancelable: true,\n }) as unknown as React.MouseEvent<HTMLElement, MouseEvent>;\n item.onClick(e);\n onOpenChange?.(false);\n }\n : undefined,\n render: itemRender\n ? (itemProps: React.HTMLAttributes<HTMLElement>) =>\n itemRender(item, itemProps)\n : undefined,\n children: [\n item.icon && (\n <span\n key=\"icon\"\n className={clsx(\n cls(\"dropdown-menu-item-icon\"),\n classNames?.itemIcon\n )}\n >\n {item.icon}\n </span>\n ),\n <span key=\"label\">{item.label}</span>,\n ],\n };\n return showSearch ? (\n <Command.Item key={i + \"-\" + j} {...props}></Command.Item>\n ) : (\n <MenuItem key={i + \"-\" + j} {...props}></MenuItem>\n );\n } else if (item.type === \"divider\") {\n return (\n <MenuSeparator\n key={i + \"-\" + j}\n className={clsx(\n cls(\"dropdown-menu-divider\"),\n classNames?.separator\n )}\n />\n );\n }\n return null;\n },\n [cls, classNames, itemRender, onOpenChange, showSearch, MenuSeparator]\n );\n\n const renderGroup = useCallback(\n (group: DropdownMenuGroup, index: number) => (\n <Menu.Group\n key={\"group\" + index}\n className={clsx(cls(\"dropdown-menu-group\"), classNames?.group)}\n >\n {group.label && (\n <Menu.GroupLabel\n className={clsx(\n cls(\"dropdown-menu-header\"),\n classNames?.groupLabel\n )}\n >\n <span>{group.label}</span>\n </Menu.GroupLabel>\n )}\n {group.items.map((item, j) => renderMenuItem(item, index, j))}\n </Menu.Group>\n ),\n [cls, classNames, renderMenuItem]\n );\n\n const renderGroupShowSearch = useCallback(\n (group: DropdownMenuGroup, index: number) =>\n group.label ? (\n <Command.Group\n key={\"group\" + index}\n className={clsx(cls(\"dropdown-menu-group\"), classNames?.group)}\n heading={\n <Menu.GroupLabel\n className={clsx(\n cls(\"dropdown-menu-header\"),\n classNames?.groupLabel\n )}\n >\n <span>{group.label}</span>\n </Menu.GroupLabel>\n }\n >\n {group.items.map((item, j) => renderMenuItem(item, index, j))}\n </Command.Group>\n ) : (\n group.items.map((item, j) => renderMenuItem(item, index, j))\n ),\n [cls, classNames, renderMenuItem]\n );\n\n const renderMenuInner = useCallback(\n () =>\n showSearch ? (\n <Command className={cls(\"dropdown-menu-container\")}>\n <Command.Input\n {...searchProps}\n key=\"search\"\n render={\n <Input allowClear className={cls(\"dropdown-menu-search\")} />\n }\n />\n <ScrollArea>\n <Command.List className={cls(\"dropdown-menu-list\")}>\n <Command.Empty className={cls(\"dropdown-menu-empty\")}>\n No results found.\n </Command.Empty>\n {itemGroups.map(renderGroupShowSearch)}\n </Command.List>\n </ScrollArea>\n </Command>\n ) : (\n <div className={cls(\"dropdown-menu-container\")}>\n <ScrollArea>{itemGroups.map(renderGroup)}</ScrollArea>\n </div>\n ),\n [\n showSearch,\n itemGroups,\n renderGroupShowSearch,\n renderGroup,\n searchProps,\n cls,\n ]\n );\n\n const BaseComponent = showSearch ? Popover : Menu;\n\n return (\n <BaseComponent.Root\n openOnHover={openOnHover}\n open={open}\n onOpenChange={onOpenChange}\n >\n <BaseComponent.Trigger\n render={children}\n ref={buttonRef}\n className={clsx(\n cls(\"dropdown-menu-trigger\"),\n classNames?.trigger,\n antdCssVarClassname\n )}\n />\n <BaseComponent.Portal>\n <BaseComponent.Positioner\n side={headlessUIPlacement.placement}\n align={headlessUIPlacement.align}\n sideOffset={4}\n className={clsx(cls(\"dropdown-menu-root\"), classNames?.root)}\n collisionAvoidance={DROPDOWN_COLLISION_AVOIDANCE}\n >\n <BaseComponent.Popup\n className={clsx(\n cls(\"dropdown-menu\"),\n className,\n classNames?.popup,\n antdCssVarClassname\n )}\n style={\n {\n \"--size-width\":\n size in PopupPanelSize ? PopupPanelSize[size] : undefined,\n } as React.CSSProperties\n }\n >\n {renderMenuInner()}\n </BaseComponent.Popup>\n </BaseComponent.Positioner>\n </BaseComponent.Portal>\n </BaseComponent.Root>\n );\n};\n"],"names":["DropdownMenu","children","items","placement","openOnHover","outsideOpen","outsideOnOpenChange","className","itemRender","classNames","size","showSearch","searchProps","open","setOpen","useControlled","onOpenChange","useCallback","newValue","cls","useCls","antdCssVarClassname","useAntdCssVarClassname","headlessUIPlacement","parseAntdPlacement","buttonRef","useRef","itemGroups","acc","current","MenuSeparator","Command","Menu","renderMenuItem","item","i","j","MenuItem","props","clsx","e","itemProps","jsx","renderGroup","group","index","jsxs","renderGroupShowSearch","renderMenuInner","createElement","Input","ScrollArea","BaseComponent","Popover","DROPDOWN_COLLISION_AVOIDANCE","PopupPanelSize"],"mappings":";;;;;;;;;;;;;;AA0HO,MAAMA,KAAe,CAAC;AAAA,EAC3B,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAMC;AAAA,EACN,cAAcC;AAAA,EACd,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,YAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,YAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,IACZ,aAAa;AAAA,EAAA;AAEjB,MAAyB;AACvB,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAc;AAAA,IACpC,YAAYV;AAAA,IACZ,SAAS;AAAA,IACT,MAAM;AAAA,EAAA,CACP,GACKW,IAAeC;AAAA,IACnB,CAACC,MAAsB;AACrB,MAAAJ,EAAQI,CAAQ,GAChBZ,KAAA,QAAAA,EAAsBY;AAAA,IACxB;AAAA,IACA,CAACJ,GAASR,CAAmB;AAAA,EAC/B,GACMa,IAAMC,EAAO,GACbC,IAAsBC,EAAuB,GAC7CC,IAAsBC,EAAmBrB,CAAS,GAClDsB,IAAYC,EAA0B,IAAI,GAC1CC,IAAazB,EAAM,OAA4B,CAAC0B,GAAKC,OAErDD,EAAI,WAAW,KAAKC,EAAQ,SAAS,YACvCD,EAAI,KAAK;AAAA,IACP,OAAO;AAAA,IACP,OAAO,CAAA;AAAA,EAAC,CACT,GAICC,EAAQ,SAAS,WACnBD,EAAI,KAAK;AAAA,IACP,OAAOC,EAAQ;AAAA,IACf,OAAO,CAAA;AAAA,EAAC,CACT,KAIAA,EAAQ,SAAS,UAAUA,EAAQ,SAAS,cAC7CD,EAAI,SAAS,KAEbA,EAAIA,EAAI,SAAS,CAAC,EAAE,MAAM,KAAKC,CAAO,GAGjCD,IACN,EAAE,GAECE,IAAgBnB,IAAaoB,EAAQ,YAAYC,EAAK,WAEtDC,IAAiBhB;AAAA,IACrB,CAACiB,GAA4BC,GAAWC,MAAc;AACpD,YAAMC,IAAW1B,IAAaoB,EAAQ,OAAOC,EAAK;AAE9C,UAAAE,EAAK,SAAS,QAAQ;AACxB,cAAMI,IAAQ;AAAA,UACZ,WAAWC,EAAKpB,EAAI,oBAAoB,GAAGV,KAAA,gBAAAA,EAAY,IAAI;AAAA,UAC3D,UAAUyB,EAAK;AAAA,UACf,eAAeA,EAAK;AAAA,UACpB,KAAKA,EAAK;AAAA,UACV,SAASA,EAAK;AAAA,UACd,cAAcA,EAAK;AAAA,UACnB,cAAcA,EAAK;AAAA,UACnB,aAAaA,EAAK;AAAA,UAClB,YAAYA,EAAK;AAAA,UACjB,UAAUvB,IACN,MAAM;AACE,kBAAA6B,IAAI,IAAI,WAAW,SAAS;AAAA,cAChC,SAAS;AAAA,cACT,YAAY;AAAA,YAAA,CACb;AACD,YAAAN,EAAK,QAAQM,CAAC,GACdxB,KAAA,QAAAA,EAAe;AAAA,UAAK,IAEtB;AAAA,UACJ,QAAQR,IACJ,CAACiC,MACCjC,EAAW0B,GAAMO,CAAS,IAC5B;AAAA,UACJ,UAAU;AAAA,YACRP,EAAK,QACH,gBAAAQ;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAWH;AAAA,kBACTpB,EAAI,yBAAyB;AAAA,kBAC7BV,KAAA,gBAAAA,EAAY;AAAA,gBACd;AAAA,gBAEC,UAAKyB,EAAA;AAAA,cAAA;AAAA,cANF;AAAA,YAON;AAAA,YAED,gBAAAQ,EAAA,QAAA,EAAkB,UAAKR,EAAA,MAAA,GAAd,OAAoB;AAAA,UAAA;AAAA,QAElC;AACA,eAAOvB,IACJ,gBAAA+B,EAAAX,EAAQ,MAAR,EAAgC,GAAGO,EAAjB,GAAAH,IAAI,MAAMC,CAAc,IAE1C,gBAAAM,EAAAL,GAAA,EAA4B,GAAGC,EAAjB,GAAAH,IAAI,MAAMC,CAAc;AAAA,MAAA,WAEhCF,EAAK,SAAS;AAErB,eAAA,gBAAAQ;AAAA,UAACZ;AAAA,UAAA;AAAA,YAEC,WAAWS;AAAA,cACTpB,EAAI,uBAAuB;AAAA,cAC3BV,KAAA,gBAAAA,EAAY;AAAA,YAAA;AAAA,UACd;AAAA,UAJK0B,IAAI,MAAMC;AAAA,QAKjB;AAGG,aAAA;AAAA,IACT;AAAA,IACA,CAACjB,GAAKV,GAAYD,GAAYQ,GAAcL,GAAYmB,CAAa;AAAA,EACvE,GAEMa,IAAc1B;AAAA,IAClB,CAAC2B,GAA0BC,MACzB,gBAAAC;AAAA,MAACd,EAAK;AAAA,MAAL;AAAA,QAEC,WAAWO,EAAKpB,EAAI,qBAAqB,GAAGV,KAAA,gBAAAA,EAAY,KAAK;AAAA,QAE5D,UAAA;AAAA,UAAAmC,EAAM,SACL,gBAAAF;AAAA,YAACV,EAAK;AAAA,YAAL;AAAA,cACC,WAAWO;AAAA,gBACTpB,EAAI,sBAAsB;AAAA,gBAC1BV,KAAA,gBAAAA,EAAY;AAAA,cACd;AAAA,cAEA,UAAA,gBAAAiC,EAAC,QAAM,EAAA,UAAAE,EAAM,MAAM,CAAA;AAAA,YAAA;AAAA,UACrB;AAAA,UAEDA,EAAM,MAAM,IAAI,CAACV,GAAME,MAAMH,EAAeC,GAAMW,GAAOT,CAAC,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,MAbvD,UAAUS;AAAA,IAcjB;AAAA,IAEF,CAAC1B,GAAKV,GAAYwB,CAAc;AAAA,EAClC,GAEMc,IAAwB9B;AAAA,IAC5B,CAAC2B,GAA0BC,MACzBD,EAAM,QACJ,gBAAAF;AAAA,MAACX,EAAQ;AAAA,MAAR;AAAA,QAEC,WAAWQ,EAAKpB,EAAI,qBAAqB,GAAGV,KAAA,gBAAAA,EAAY,KAAK;AAAA,QAC7D,SACE,gBAAAiC;AAAA,UAACV,EAAK;AAAA,UAAL;AAAA,YACC,WAAWO;AAAA,cACTpB,EAAI,sBAAsB;AAAA,cAC1BV,KAAA,gBAAAA,EAAY;AAAA,YACd;AAAA,YAEA,UAAA,gBAAAiC,EAAC,QAAM,EAAA,UAAAE,EAAM,MAAM,CAAA;AAAA,UAAA;AAAA,QACrB;AAAA,QAGD,UAAAA,EAAM,MAAM,IAAI,CAACV,GAAME,MAAMH,EAAeC,GAAMW,GAAOT,CAAC,CAAC;AAAA,MAAA;AAAA,MAbvD,UAAUS;AAAA,IAcjB,IAEAD,EAAM,MAAM,IAAI,CAACV,GAAME,MAAMH,EAAeC,GAAMW,GAAOT,CAAC,CAAC;AAAA,IAE/D,CAACjB,GAAKV,GAAYwB,CAAc;AAAA,EAClC,GAEMe,IAAkB/B;AAAA,IACtB,MACEN,IACE,gBAAAmC,EAACf,KAAQ,WAAWZ,EAAI,yBAAyB,GAC/C,UAAA;AAAA,MAAA,gBAAA8B;AAAA,QAAClB,EAAQ;AAAA,QAAR;AAAA,UACE,GAAGnB;AAAA,UACJ,KAAI;AAAA,UACJ,0BACGsC,GAAM,EAAA,YAAU,IAAC,WAAW/B,EAAI,sBAAsB,EAAG,CAAA;AAAA,QAAA;AAAA,MAE9D;AAAA,MACA,gBAAAuB,EAACS,KACC,UAAC,gBAAAL,EAAAf,EAAQ,MAAR,EAAa,WAAWZ,EAAI,oBAAoB,GAC/C,UAAA;AAAA,QAAA,gBAAAuB,EAACX,EAAQ,OAAR,EAAc,WAAWZ,EAAI,qBAAqB,GAAG,UAEtD,qBAAA;AAAA,QACCQ,EAAW,IAAIoB,CAAqB;AAAA,MAAA,EAAA,CACvC,EACF,CAAA;AAAA,IAAA,EACF,CAAA,IAEA,gBAAAL,EAAC,OAAI,EAAA,WAAWvB,EAAI,yBAAyB,GAC3C,UAAA,gBAAAuB,EAACS,GAAY,EAAA,UAAAxB,EAAW,IAAIgB,CAAW,EAAE,CAAA,GAC3C;AAAA,IAEJ;AAAA,MACEhC;AAAA,MACAgB;AAAA,MACAoB;AAAA,MACAJ;AAAA,MACA/B;AAAA,MACAO;AAAA,IAAA;AAAA,EAEJ,GAEMiC,IAAgBzC,IAAa0C,IAAUrB;AAG3C,SAAA,gBAAAc;AAAA,IAACM,EAAc;AAAA,IAAd;AAAA,MACC,aAAAhD;AAAA,MACA,MAAAS;AAAA,MACA,cAAAG;AAAA,MAEA,UAAA;AAAA,QAAA,gBAAA0B;AAAA,UAACU,EAAc;AAAA,UAAd;AAAA,YACC,QAAQnD;AAAA,YACR,KAAKwB;AAAA,YACL,WAAWc;AAAA,cACTpB,EAAI,uBAAuB;AAAA,cAC3BV,KAAA,gBAAAA,EAAY;AAAA,cACZY;AAAA,YAAA;AAAA,UACF;AAAA,QACF;AAAA,QACA,gBAAAqB,EAACU,EAAc,QAAd,EACC,UAAA,gBAAAV;AAAA,UAACU,EAAc;AAAA,UAAd;AAAA,YACC,MAAM7B,EAAoB;AAAA,YAC1B,OAAOA,EAAoB;AAAA,YAC3B,YAAY;AAAA,YACZ,WAAWgB,EAAKpB,EAAI,oBAAoB,GAAGV,KAAA,gBAAAA,EAAY,IAAI;AAAA,YAC3D,oBAAoB6C;AAAA,YAEpB,UAAA,gBAAAZ;AAAA,cAACU,EAAc;AAAA,cAAd;AAAA,gBACC,WAAWb;AAAA,kBACTpB,EAAI,eAAe;AAAA,kBACnBZ;AAAA,kBACAE,KAAA,gBAAAA,EAAY;AAAA,kBACZY;AAAA,gBACF;AAAA,gBACA,OACE;AAAA,kBACE,gBACEX,KAAQ6C,IAAiBA,EAAe7C,CAAI,IAAI;AAAA,gBACpD;AAAA,gBAGD,UAAgBsC,EAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACnB;AAAA,QAAA,EAEJ,CAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF;AAEJ;"}
1
+ {"version":3,"file":"component.js","sources":["../../../src/components/dropdown-menu/component.tsx"],"sourcesContent":["\"use client\";\nimport { Menu } from \"@base-ui-components/react/menu\";\nimport { useControlled } from \"@base-ui-components/react/utils\";\nimport { Popover } from \"@base-ui-components/react/popover\";\nimport { type PopoverProps } from \"antd/es/popover\";\nimport { Ref, useCallback, useRef } from \"react\";\nimport {\n clsx,\n DROPDOWN_COLLISION_AVOIDANCE,\n parseAntdPlacement,\n useAntdCssVarClassname,\n useCls,\n BaseUIPlacement,\n} from \"../utils\";\nimport { Command } from \"../cmdk\";\nimport { ScrollArea } from \"../scroll-area\";\n\n// Import component-specific styles\nimport { Input } from \"../input\";\nimport { PopupPanelSize } from \"../popup-panel/constants\";\n\nimport \"./style.css\";\n\nexport type DropdownMenuItemType =\n | {\n type: \"item\";\n label?: React.ReactNode;\n disabled?: boolean;\n icon?: React.ReactNode;\n key: React.Key;\n onClick?: React.HTMLAttributes<HTMLElement>[\"onClick\"];\n onMouseEnter?: React.HTMLAttributes<HTMLElement>[\"onMouseEnter\"];\n onMouseLeave?: React.HTMLAttributes<HTMLElement>[\"onMouseLeave\"];\n onMouseOver?: React.HTMLAttributes<HTMLElement>[\"onMouseOver\"];\n onMouseOut?: React.HTMLAttributes<HTMLElement>[\"onMouseOut\"];\n danger?: boolean;\n ref?: React.Ref<HTMLElement>;\n }\n | {\n type: \"divider\";\n }\n | {\n type: \"header\";\n title?: React.ReactNode;\n };\n\nexport interface DropdownMenuProps {\n /** Array of menu items to be displayed in the dropdown */\n items: DropdownMenuItemType[];\n /** Custom render function for the trigger element */\n children?: React.ComponentProps<typeof Menu.Trigger>[\"render\"];\n /**\n * Placement of the dropdown relative to the trigger element\n * @default \"bottomLeft\"\n */\n placement?: PopoverProps[\"placement\"];\n /**\n * Whether to open the dropdown on hover instead of click\n * @default false\n */\n openOnHover?: boolean;\n /**\n * Controlled open state of the dropdown\n */\n open?: boolean;\n /**\n * Callback fired when the dropdown open state changes\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Additional CSS class for the dropdown component\n */\n className?: string;\n /**\n * Custom class names for different parts of the dropdown\n * @default {}\n */\n classNames?: {\n root?: string;\n trigger?: string;\n popup?: string;\n group?: string;\n groupLabel?: string;\n item?: string;\n itemIcon?: string;\n itemText?: string;\n separator?: string;\n positioner?: string;\n };\n /**\n * Custom render function for menu items\n */\n itemRender?: (\n item: DropdownMenuItemType,\n props: React.HTMLAttributes<HTMLElement>\n ) => React.ReactElement;\n /**\n * Whether to show search input\n * @default false\n */\n showSearch?: boolean;\n /**\n * Size of the dropdown menu\n * @default \"auto\"\n */\n size?: \"auto\" | keyof typeof PopupPanelSize;\n /**\n * Search placeholder\n */\n searchProps?: Omit<\n React.ComponentProps<typeof Command.Input>,\n \"size\" | \"ref\"\n >;\n /**\n *\n */\n}\n\ninterface DropdownMenuGroup {\n label: React.ReactNode | null;\n items: DropdownMenuItemType[];\n}\n\nexport const DropdownMenu = ({\n children,\n items,\n placement,\n openOnHover,\n open: outsideOpen,\n onOpenChange: outsideOnOpenChange,\n className,\n itemRender,\n classNames,\n size = \"auto\",\n showSearch,\n searchProps = {\n placeholder: \"Search...\",\n },\n}: DropdownMenuProps) => {\n const [open, setOpen] = useControlled({\n controlled: outsideOpen,\n default: false,\n name: \"open\",\n });\n const onOpenChange = useCallback(\n (newValue: boolean) => {\n setOpen(newValue);\n outsideOnOpenChange?.(newValue);\n },\n [setOpen, outsideOnOpenChange]\n );\n const cls = useCls();\n const antdCssVarClassname = useAntdCssVarClassname();\n const baseUIPlacement = parseAntdPlacement(placement);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const itemGroups = items.reduce<DropdownMenuGroup[]>((acc, current) => {\n // If no groups exist yet and current item is not a header, create default group\n if (acc.length === 0 && current.type !== \"header\") {\n acc.push({\n label: null,\n items: [],\n });\n }\n\n // If it's a header, create a new group\n if (current.type === \"header\") {\n acc.push({\n label: current.title,\n items: [],\n });\n }\n // If it's an item and we have at least one group, add it to the last group's items\n else if (\n (current.type === \"item\" || current.type === \"divider\") &&\n acc.length > 0\n ) {\n acc[acc.length - 1].items.push(current);\n }\n // Skip dividers\n return acc;\n }, []);\n\n const MenuSeparator = showSearch ? Command.Separator : Menu.Separator;\n\n const renderMenuItem = useCallback(\n (item: DropdownMenuItemType, i: number, j: number) => {\n const MenuItem = showSearch ? Command.Item : Menu.Item;\n\n if (item.type === \"item\") {\n const props = {\n className: clsx(cls(\"dropdown-menu-item\"), classNames?.item),\n disabled: item.disabled,\n \"data-danger\": item.danger,\n ref: item.ref as Ref<HTMLDivElement>,\n onClick: item.onClick,\n onMouseEnter: item.onMouseEnter,\n onMouseLeave: item.onMouseLeave,\n onMouseOver: item.onMouseOver,\n onMouseOut: item.onMouseOut,\n onSelect: showSearch\n ? () => {\n const e = new MouseEvent(\"click\", {\n bubbles: true,\n cancelable: true,\n }) as unknown as React.MouseEvent<HTMLElement, MouseEvent>;\n item.onClick(e);\n onOpenChange?.(false);\n }\n : undefined,\n render: itemRender\n ? (itemProps: React.HTMLAttributes<HTMLElement>) =>\n itemRender(item, itemProps)\n : undefined,\n children: [\n item.icon && (\n <span\n key=\"icon\"\n className={clsx(\n cls(\"dropdown-menu-item-icon\"),\n classNames?.itemIcon\n )}\n >\n {item.icon}\n </span>\n ),\n <span key=\"label\">{item.label}</span>,\n ],\n };\n return showSearch ? (\n <Command.Item key={i + \"-\" + j} {...props}></Command.Item>\n ) : (\n <MenuItem key={i + \"-\" + j} {...props}></MenuItem>\n );\n } else if (item.type === \"divider\") {\n return (\n <MenuSeparator\n key={i + \"-\" + j}\n className={clsx(\n cls(\"dropdown-menu-divider\"),\n classNames?.separator\n )}\n />\n );\n }\n return null;\n },\n [cls, classNames, itemRender, onOpenChange, showSearch, MenuSeparator]\n );\n\n const renderGroup = useCallback(\n (group: DropdownMenuGroup, index: number) => (\n <Menu.Group\n key={\"group\" + index}\n className={clsx(cls(\"dropdown-menu-group\"), classNames?.group)}\n >\n {group.label && (\n <Menu.GroupLabel\n className={clsx(\n cls(\"dropdown-menu-header\"),\n classNames?.groupLabel\n )}\n >\n <span>{group.label}</span>\n </Menu.GroupLabel>\n )}\n {group.items.map((item, j) => renderMenuItem(item, index, j))}\n </Menu.Group>\n ),\n [cls, classNames, renderMenuItem]\n );\n\n const renderGroupShowSearch = useCallback(\n (group: DropdownMenuGroup, index: number) =>\n group.label ? (\n <Command.Group\n key={\"group\" + index}\n className={clsx(cls(\"dropdown-menu-group\"), classNames?.group)}\n heading={\n <Menu.GroupLabel\n className={clsx(\n cls(\"dropdown-menu-header\"),\n classNames?.groupLabel\n )}\n >\n <span>{group.label}</span>\n </Menu.GroupLabel>\n }\n >\n {group.items.map((item, j) => renderMenuItem(item, index, j))}\n </Command.Group>\n ) : (\n group.items.map((item, j) => renderMenuItem(item, index, j))\n ),\n [cls, classNames, renderMenuItem]\n );\n\n const renderMenuInner = useCallback(\n () =>\n showSearch ? (\n <Command className={cls(\"dropdown-menu-container\")}>\n <Command.Input\n {...searchProps}\n key=\"search\"\n render={\n <Input allowClear className={cls(\"dropdown-menu-search\")} />\n }\n />\n <ScrollArea>\n <Command.List className={cls(\"dropdown-menu-list\")}>\n <Command.Empty className={cls(\"dropdown-menu-empty\")}>\n No results found.\n </Command.Empty>\n {itemGroups.map(renderGroupShowSearch)}\n </Command.List>\n </ScrollArea>\n </Command>\n ) : (\n <div className={cls(\"dropdown-menu-container\")}>\n <ScrollArea>{itemGroups.map(renderGroup)}</ScrollArea>\n </div>\n ),\n [\n showSearch,\n itemGroups,\n renderGroupShowSearch,\n renderGroup,\n searchProps,\n cls,\n ]\n );\n\n const BaseComponent = showSearch ? Popover : Menu;\n\n return (\n <BaseComponent.Root\n openOnHover={openOnHover}\n open={open}\n onOpenChange={onOpenChange}\n >\n <BaseComponent.Trigger\n render={children}\n ref={buttonRef}\n className={clsx(\n cls(\"dropdown-menu-trigger\"),\n classNames?.trigger,\n antdCssVarClassname\n )}\n />\n <BaseComponent.Portal>\n <BaseComponent.Positioner\n side={baseUIPlacement.side}\n align={baseUIPlacement.align}\n sideOffset={4}\n className={clsx(cls(\"dropdown-menu-root\"), classNames?.root)}\n collisionAvoidance={DROPDOWN_COLLISION_AVOIDANCE}\n >\n <BaseComponent.Popup\n className={clsx(\n cls(\"dropdown-menu\"),\n className,\n classNames?.popup,\n antdCssVarClassname\n )}\n style={\n {\n \"--size-width\":\n size in PopupPanelSize ? PopupPanelSize[size] : undefined,\n } as React.CSSProperties\n }\n >\n {renderMenuInner()}\n </BaseComponent.Popup>\n </BaseComponent.Positioner>\n </BaseComponent.Portal>\n </BaseComponent.Root>\n );\n};\n"],"names":["DropdownMenu","children","items","placement","openOnHover","outsideOpen","outsideOnOpenChange","className","itemRender","classNames","size","showSearch","searchProps","open","setOpen","useControlled","onOpenChange","useCallback","newValue","cls","useCls","antdCssVarClassname","useAntdCssVarClassname","baseUIPlacement","parseAntdPlacement","buttonRef","useRef","itemGroups","acc","current","MenuSeparator","Command","Menu","renderMenuItem","item","i","j","MenuItem","props","clsx","e","itemProps","jsx","renderGroup","group","index","jsxs","renderGroupShowSearch","renderMenuInner","createElement","Input","ScrollArea","BaseComponent","Popover","DROPDOWN_COLLISION_AVOIDANCE","PopupPanelSize"],"mappings":"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"}
@@ -1,40 +1,43 @@
1
1
  "use client";
2
- import { jsx as e } from "react/jsx-runtime";
3
- import f from "antd/es/form/FormItem";
4
- import { FormLabel as s } from "./label.js";
5
- import { isPlainObject as c } from "es-toolkit";
6
- const k = ({
7
- tooltip: n,
2
+ import { jsx as a } from "react/jsx-runtime";
3
+ import q from "antd/es/form/FormItem";
4
+ import { FormLabel as F } from "./label.js";
5
+ import { isPlainObject as b } from "es-toolkit";
6
+ const L = ({
7
+ tooltip: p,
8
8
  label: t,
9
- optionalMark: a = !1,
10
- requiredMark: p = !0,
11
- required: i,
9
+ optionalMark: d = !1,
10
+ requiredMark: s = !0,
11
+ labelRender: i,
12
+ required: m,
12
13
  rules: o,
13
- ...d
14
+ children: c,
15
+ ...f
14
16
  }) => {
15
- const m = i || (o == null ? void 0 : o.some(
16
- (r) => c(r) && "required" in r && r.required
17
- ));
18
- return /* @__PURE__ */ e(
19
- f,
17
+ const e = m || (o == null ? void 0 : o.some(
18
+ (r) => b(r) && "required" in r && r.required
19
+ )), n = t ? /* @__PURE__ */ a(
20
+ F,
20
21
  {
21
- required: i,
22
- label: t ? /* @__PURE__ */ e(
23
- s,
24
- {
25
- label: t,
26
- tooltip: n,
27
- optionalMark: !m && a,
28
- requiredMark: m && p,
29
- as: "span"
30
- }
31
- ) : void 0,
22
+ label: t,
23
+ tooltip: p,
24
+ optionalMark: !e && d,
25
+ requiredMark: e && s,
26
+ as: "span"
27
+ }
28
+ ) : void 0;
29
+ return /* @__PURE__ */ a(
30
+ q,
31
+ {
32
+ required: m,
33
+ label: i ? i(n) : n,
32
34
  rules: o,
33
- ...d
35
+ ...f,
36
+ children: c
34
37
  }
35
38
  );
36
39
  };
37
40
  export {
38
- k as FormItem
41
+ L as FormItem
39
42
  };
40
43
  //# sourceMappingURL=item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"item.js","sources":["../../../src/components/form/item.tsx"],"sourcesContent":["\"use client\";\nimport {\n default as AntdFormItem,\n type FormItemProps as AntdFormItemProps,\n} from \"antd/es/form/FormItem\";\nimport { FormLabel } from \"./label\";\nimport { isPlainObject } from \"es-toolkit\";\n\nexport interface FormItemProps<Values = unknown>\n extends AntdFormItemProps<Values> {\n // tooltip?: React.ReactNode | TooltipProps;\n /**\n * Whether show the optional mark. By default, optional item will not show the optional mark.\n * @default false\n */\n optionalMark?: boolean | React.ReactNode;\n /**\n * Whether show the asterisk when the field is required\n * @default true\n */\n requiredMark?: boolean | React.ReactNode;\n}\n\nexport const FormItem = <Values = unknown,>({\n tooltip,\n label,\n optionalMark = false,\n requiredMark = true,\n required,\n rules,\n ...rest\n}: FormItemProps<Values>) => {\n const isRequired =\n required ||\n rules?.some(\n (rule) => isPlainObject(rule) && \"required\" in rule && rule.required\n );\n return (\n <AntdFormItem\n required={required}\n label={\n label ? (\n <FormLabel\n label={label}\n tooltip={tooltip}\n optionalMark={!isRequired && optionalMark}\n requiredMark={isRequired && requiredMark}\n as=\"span\"\n />\n ) : undefined\n }\n rules={rules}\n {...rest}\n />\n );\n};\n"],"names":["FormItem","tooltip","label","optionalMark","requiredMark","required","rules","rest","isRequired","rule","isPlainObject","jsx","AntdFormItem","FormLabel"],"mappings":";;;;;AAuBO,MAAMA,IAAW,CAAoB;AAAA,EAC1C,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,cAAAC,IAAe;AAAA,EACf,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,GAAGC;AACL,MAA6B;AACrB,QAAAC,IACJH,MACAC,KAAA,gBAAAA,EAAO;AAAA,IACL,CAACG,MAASC,EAAcD,CAAI,KAAK,cAAcA,KAAQA,EAAK;AAAA;AAG9D,SAAA,gBAAAE;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,UAAAP;AAAA,MACA,OACEH,IACE,gBAAAS;AAAA,QAACE;AAAA,QAAA;AAAA,UACC,OAAAX;AAAA,UACA,SAAAD;AAAA,UACA,cAAc,CAACO,KAAcL;AAAA,UAC7B,cAAcK,KAAcJ;AAAA,UAC5B,IAAG;AAAA,QAAA;AAAA,MAAA,IAEH;AAAA,MAEN,OAAAE;AAAA,MACC,GAAGC;AAAA,IAAA;AAAA,EACN;AAEJ;"}
1
+ {"version":3,"file":"item.js","sources":["../../../src/components/form/item.tsx"],"sourcesContent":["\"use client\";\nimport {\n default as AntdFormItem,\n type FormItemProps as AntdFormItemProps,\n} from \"antd/es/form/FormItem\";\nimport { FormLabel } from \"./label\";\nimport { isPlainObject } from \"es-toolkit\";\nimport type React from \"react\";\n\nexport interface FormItemProps<Values = unknown>\n extends Omit<AntdFormItemProps<Values>, \"children\"> {\n // tooltip?: React.ReactNode | TooltipProps;\n /**\n * Whether show the optional mark. By default, optional item will not show the optional mark.\n * @default false\n */\n optionalMark?: boolean | React.ReactNode;\n /**\n * Whether show the asterisk when the field is required\n * @default true\n */\n requiredMark?: boolean | React.ReactNode;\n /**\n * Custom render function for the label\n */\n labelRender?: (label: React.ReactElement) => React.ReactElement;\n /**\n * Form item children - can be React nodes or render functions\n */\n children?: AntdFormItemProps<Values>[\"children\"];\n}\n\nexport const FormItem = <Values = unknown,>({\n tooltip,\n label,\n optionalMark = false,\n requiredMark = true,\n labelRender,\n required,\n rules,\n children,\n ...rest\n}: FormItemProps<Values>) => {\n const isRequired =\n required ||\n rules?.some(\n (rule) => isPlainObject(rule) && \"required\" in rule && rule.required\n );\n const renderedLabel = label ? (\n <FormLabel\n label={label}\n tooltip={tooltip}\n optionalMark={!isRequired && optionalMark}\n requiredMark={isRequired && requiredMark}\n as=\"span\"\n />\n ) : undefined;\n\n return (\n <AntdFormItem\n required={required}\n label={labelRender ? labelRender(renderedLabel) : renderedLabel}\n rules={rules}\n {...rest}\n >\n {children}\n </AntdFormItem>\n );\n};\n"],"names":["FormItem","tooltip","label","optionalMark","requiredMark","labelRender","required","rules","children","rest","isRequired","rule","isPlainObject","renderedLabel","jsx","FormLabel","AntdFormItem"],"mappings":";;;;;AAgCO,MAAMA,IAAW,CAAoB;AAAA,EAC1C,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,cAAAC,IAAe;AAAA,EACf,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,MAA6B;AACrB,QAAAC,IACJJ,MACAC,KAAA,gBAAAA,EAAO;AAAA,IACL,CAACI,MAASC,EAAcD,CAAI,KAAK,cAAcA,KAAQA,EAAK;AAAA,MAE1DE,IAAgBX,IACpB,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAAb;AAAA,MACA,SAAAD;AAAA,MACA,cAAc,CAACS,KAAcP;AAAA,MAC7B,cAAcO,KAAcN;AAAA,MAC5B,IAAG;AAAA,IAAA;AAAA,EAAA,IAEH;AAGF,SAAA,gBAAAU;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,UAAAV;AAAA,MACA,OAAOD,IAAcA,EAAYQ,CAAa,IAAIA;AAAA,MAClD,OAAAN;AAAA,MACC,GAAGE;AAAA,MAEH,UAAAD;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -1 +1 @@
1
- @layer components{.ds-form-item-label-inner{display:inline-flex;align-items:center;gap:.25rem}.ds-form-item-label-optional-mark{color:var(--ds-color-text-tertiary)}:is(.ds-form-item-label>label.ds-form-item-required):after{display:none}:is(.ds-form-item-label>label.ds-form-item-required):before{display:none}.ds-form-item-label-required-mark{display:inline-block;font-size:var(--ds-font-size);font-family:Inter,sans-serif;line-height:1;content:"*"}.ds-form-item-label-required-mark.ds-form-item-label-required-mark-asterisk{color:var(--ds-form-label-required-mark-color)}.ds-form-item .ds-form-item-label>label:after{display:none}.ds-form-horizontal .ds-form-item .ds-form-item-label .ds-form-item-label-inner:after{content:":";position:relative;margin-block:0;margin-inline-start:var(--ds-form-label-colon-margin-inline-start);margin-inline-end:var(--ds-form-label-colon-margin-inline-end)}.ds-form-item-explain{margin-top:.25rem}.ds-form-item-margin-offset{margin:0!important}}
1
+ @layer components{.ds-form-item-label-inner{display:inline-flex;align-items:center;gap:.25rem}.ds-form-item-label-optional-mark{color:var(--ds-color-text-tertiary)}:is(.ds-form-item-label>label.ds-form-item-required):after{display:none}:is(.ds-form-item-label>label.ds-form-item-required):before{display:none}.ds-form-item-label-required-mark{display:inline-block;font-size:var(--ds-font-size);font-family:Inter,sans-serif;line-height:1;content:"*"}.ds-form-item-label-required-mark.ds-form-item-label-required-mark-asterisk{color:var(--ds-form-label-required-mark-color)}.ds-form-item .ds-form-item-label>label:after{display:none}.ds-form-horizontal .ds-form-item .ds-form-item-label .ds-form-item-label-inner:after{content:":";position:relative;margin-block:0;margin-inline-start:var(--ds-form-label-colon-margin-inline-start);margin-inline-end:var(--ds-form-label-colon-margin-inline-end)}.ds-form-item-explain{margin-top:.25rem}.ds-form-item-margin-offset{margin:0!important}.ds-form-item-label{overflow:visible}.ds-form-item-row .ds-form-item-label label{width:100%}}
@@ -1,208 +1,186 @@
1
1
  "use client";
2
- import { jsx as o, jsxs as d, Fragment as a } from "react/jsx-runtime";
3
- import { Popover as i } from "@base-ui-components/react/popover";
4
- import { useState as f, useCallback as C, useEffect as O, useMemo as N } from "react";
5
- import s from "antd/es/flex";
6
- import { X as ee } from "@bioturing/assets";
7
- import { PopupPanelSize as te } from "./constants.js";
8
- import { useResizable as oe } from "react-use-resizable";
9
- import ne from "merge-refs";
2
+ import { jsx as t, jsxs as f } from "react/jsx-runtime";
3
+ import { Popover as o } from "@base-ui-components/react/popover";
4
+ import { useMemo as L, useRef as C, useState as Q, useEffect as W, useCallback as Y } from "react";
5
+ import { X as Z } from "@bioturing/assets";
6
+ import { PopupPanelSize as _ } from "./constants.js";
7
+ import { Stack as B } from "../stack/index.js";
10
8
  import './style.css';/* empty css */
11
- import { useControlledState as re } from "../hooks/useControlledState.js";
12
- import { useCls as pe, parseAntdPlacement as ie } from "../utils/antdUtils.js";
13
- import { clsx as r } from "../utils/cn.js";
14
- import { IconButton as de } from "../icon-button/component.js";
15
- const we = ({
16
- children: S,
9
+ import { parseAntdPlacement as m, buildAntdPlacement as a } from "../utils/placement.js";
10
+ import { Resizable as N } from "../resizable/component.js";
11
+ import { useControlledState as s } from "../hooks/useControlledState.js";
12
+ import { useCls as ee } from "../utils/antdUtils.js";
13
+ import { clsx as p } from "../utils/cn.js";
14
+ import { IconButton as te } from "../icon-button/component.js";
15
+ const ve = ({
16
+ children: H,
17
17
  placement: I,
18
- openOnHover: D = !1,
19
- open: W,
20
- onOpenChange: j,
21
- content: E,
18
+ openOnHover: K = !1,
19
+ open: j,
20
+ onOpenChange: E,
21
+ content: M,
22
22
  title: h,
23
23
  trigger: F = "click",
24
- className: V,
25
- anchor: $,
26
- beforeCloseButton: P,
27
- afterCloseButton: H,
28
- afterTitle: c,
29
- size: g = "medium",
24
+ className: T,
25
+ anchor: U,
26
+ beforeCloseButton: R,
27
+ afterCloseButton: S,
28
+ afterTitle: b,
29
+ size: v = "medium",
30
30
  footer: l,
31
- defaultOpen: A,
32
- resizable: y = !1,
31
+ defaultOpen: V,
32
+ resizable: X = !1,
33
33
  classNames: e,
34
- modal: M = !1,
35
- closeOnClickOutside: T = !0
34
+ modal: $ = !1,
35
+ closeOnClickOutside: q = !0,
36
+ onPlacementChange: P
36
37
  }) => {
37
- const [U, b] = re(
38
- W,
38
+ const [w, x] = s(
39
39
  j,
40
- A ?? !1
40
+ E,
41
+ V ?? !1
41
42
  // Always provide a default value to prevent undefined
42
- ), t = pe(), w = ie(I), [v, X] = f(null), [q, G] = f(), [J, K] = f(), L = C((n) => {
43
- X(n);
44
- }, []);
45
- O(() => {
46
- if (!v) return;
47
- const n = new ResizeObserver((u) => {
48
- for (const p of u)
49
- G(p.contentRect.width), K(p.contentRect.height);
43
+ ), r = ee(), c = m(I), z = L(() => /* @__PURE__ */ t(Z, { size: 16 }), []), k = C(null), y = C(c.side), O = C(c.align), [D, G] = Q(0);
44
+ W(() => {
45
+ const u = k.current;
46
+ if (!u || !w) return;
47
+ const g = new MutationObserver((d) => {
48
+ let A = !1;
49
+ if (d.forEach((i) => {
50
+ if (i.type === "attributes" && i.attributeName === "data-side") {
51
+ const n = u.getAttribute(i.attributeName);
52
+ n && n !== y.current && (y.current = n, A = !0);
53
+ }
54
+ if (i.type === "attributes" && i.attributeName === "data-align") {
55
+ const n = u.getAttribute(i.attributeName);
56
+ n && n !== O.current && (O.current = n, A = !0);
57
+ }
58
+ }), A) {
59
+ const i = a({
60
+ side: y.current,
61
+ align: O.current
62
+ });
63
+ G((n) => n + 1), P && P(i);
64
+ }
50
65
  });
51
- return n.observe(v), () => {
52
- n.disconnect();
66
+ return g.observe(u, {
67
+ attributes: !0,
68
+ attributeFilter: ["data-side", "data-align"],
69
+ attributeOldValue: !0
70
+ }), () => {
71
+ g.disconnect();
53
72
  };
54
- }, [v]);
55
- const x = N(() => /* @__PURE__ */ o(ee, { size: 16 }), []), Q = C(() => /* @__PURE__ */ d("div", { className: r(t("popup-panel-header"), e == null ? void 0 : e.header), children: [
56
- /* @__PURE__ */ d(
57
- s,
73
+ }, [P, w]);
74
+ const J = Y(() => /* @__PURE__ */ f("div", { className: p(r("popup-panel-header"), e == null ? void 0 : e.header), children: [
75
+ /* @__PURE__ */ f(
76
+ B,
58
77
  {
59
78
  align: "center",
60
79
  gap: 8,
61
- className: t("popup-panel-title-wrapper"),
80
+ className: r("popup-panel-title-wrapper"),
62
81
  children: [
63
- /* @__PURE__ */ o(
64
- i.Title,
82
+ /* @__PURE__ */ t(
83
+ o.Title,
65
84
  {
66
- render: /* @__PURE__ */ o("div", { className: r(t("grow", "truncate"), e == null ? void 0 : e.title), children: h })
85
+ render: /* @__PURE__ */ t("div", { className: p(r("grow", "truncate"), e == null ? void 0 : e.title), children: h })
67
86
  }
68
87
  ),
69
- /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
70
- P,
71
- /* @__PURE__ */ o(
72
- i.Close,
88
+ /* @__PURE__ */ f("div", { className: "flex items-center gap-2", children: [
89
+ R,
90
+ /* @__PURE__ */ t(
91
+ o.Close,
73
92
  {
74
- render: /* @__PURE__ */ o(de, { children: x })
93
+ render: /* @__PURE__ */ t(te, { children: z })
75
94
  }
76
95
  ),
77
- H
96
+ S
78
97
  ] })
79
98
  ]
80
99
  }
81
100
  ),
82
- c || null
101
+ b || null
83
102
  ] }), [
84
- H,
85
- c,
86
- P,
87
- t,
103
+ S,
104
+ b,
105
+ R,
106
+ r,
88
107
  e == null ? void 0 : e.header,
89
108
  e == null ? void 0 : e.title,
90
- x,
109
+ z,
91
110
  h
92
- ]), [R, k] = f(!1), { getRootProps: Y, getHandleProps: z, rootRef: Z } = oe({
93
- initialWidth: q,
94
- initialHeight: J,
95
- onDragStart: () => k(!0),
96
- onDragEnd: () => k(!1)
97
- });
98
- O(() => {
99
- R ? document.body.style.userSelect = "none" : document.body.style.userSelect = "";
100
- }, [R]);
101
- const { ref: _, ...B } = Y(), m = (n, u) => {
102
- if (!n.current) return;
103
- const { widthDiff: p } = u;
104
- n.current.style.left = `${parseInt(n.current.style.left || "0") - p}px`;
105
- };
106
- return /* @__PURE__ */ d(
107
- i.Root,
111
+ ]);
112
+ return /* @__PURE__ */ f(
113
+ o.Root,
108
114
  {
109
- openOnHover: F === "hover" ? !0 : D,
110
- open: U,
111
- onOpenChange: (n, u, p) => {
112
- (p === "outside-press" || p === "focus-out") && !T || b(n, u, p);
115
+ openOnHover: F === "hover" ? !0 : K,
116
+ open: w,
117
+ onOpenChange: (u, g, d) => {
118
+ (d === "outside-press" || d === "focus-out") && !q || x(u, g, d);
113
119
  },
114
- modal: M,
120
+ modal: $,
115
121
  children: [
116
- /* @__PURE__ */ o(
117
- i.Trigger,
122
+ /* @__PURE__ */ t(
123
+ o.Trigger,
118
124
  {
119
- render: S,
120
- className: r(t("popup-panel-trigger"), e == null ? void 0 : e.trigger)
125
+ render: H,
126
+ className: p(r("popup-panel-trigger"), e == null ? void 0 : e.trigger)
121
127
  }
122
128
  ),
123
- /* @__PURE__ */ o(i.Portal, { children: /* @__PURE__ */ o(
124
- i.Positioner,
129
+ /* @__PURE__ */ t(o.Portal, { children: /* @__PURE__ */ t(
130
+ o.Positioner,
125
131
  {
126
- className: r(t("popup-panel-root"), e == null ? void 0 : e.root),
127
- side: w.placement,
128
- align: w.align,
132
+ ref: k,
133
+ className: p(r("popup-panel-root"), e == null ? void 0 : e.root),
134
+ side: c.side,
135
+ align: c.align,
129
136
  sideOffset: 4,
130
- anchor: $,
137
+ anchor: U,
131
138
  style: {
132
- "--size-width": g ? te[g] : void 0
139
+ "--size-width": v ? _[v] : void 0
133
140
  },
134
- children: /* @__PURE__ */ d(
135
- i.Popup,
141
+ children: /* @__PURE__ */ t(
142
+ N,
136
143
  {
137
- className: r(
138
- t("popup-panel"),
139
- t(`popup-panel-size-${g}`),
140
- V,
141
- e == null ? void 0 : e.popup
142
- ),
143
- ref: ne(_, L),
144
- ...y ? B : {},
145
- ...R ? { "data-resizing": !0 } : {},
146
- children: [
147
- h && Q(),
148
- /* @__PURE__ */ o(
149
- "div",
150
- {
151
- className: r(t("popup-panel-content"), e == null ? void 0 : e.content),
152
- children: /* @__PURE__ */ o("div", { className: t("popup-panel-content-inner"), children: E })
153
- }
154
- ),
155
- l && /* @__PURE__ */ o(
156
- "div",
157
- {
158
- className: r(t("popup-panel-footer"), e == null ? void 0 : e.footer),
159
- children: typeof l == "function" ? l({ close: () => b(!1) }) : l
160
- }
161
- ),
162
- y && /* @__PURE__ */ d(a, { children: [
163
- /* @__PURE__ */ o(
164
- "div",
165
- {
166
- className: r(
167
- t("popup-panel-resize-handle"),
168
- e == null ? void 0 : e.resizeHandle
169
- ),
170
- "data-placement": "bottom-left",
171
- ...z({
172
- lockHorizontal: !0
173
- })
174
- }
175
- ),
176
- /* @__PURE__ */ o(
177
- "div",
178
- {
179
- className: r(
180
- t("popup-panel-resize-handle"),
181
- e == null ? void 0 : e.resizeHandle
182
- ),
183
- "data-placement": "top-left",
184
- ...z({
185
- reverse: !0,
186
- lockVertical: !0,
187
- onResize: (n) => m(Z, n)
188
- })
189
- }
144
+ resizable: X,
145
+ absolutePositioning: !0,
146
+ resetKey: D,
147
+ classNames: {
148
+ resizeHandle: e == null ? void 0 : e.resizeHandle
149
+ },
150
+ children: /* @__PURE__ */ f(
151
+ o.Popup,
152
+ {
153
+ className: p(
154
+ r("popup-panel"),
155
+ r(`popup-panel-size-${v}`),
156
+ T,
157
+ e == null ? void 0 : e.popup
190
158
  ),
191
- /* @__PURE__ */ o(
192
- "div",
193
- {
194
- className: r(
195
- t("popup-panel-resize-handle"),
196
- e == null ? void 0 : e.resizeHandle
197
- ),
198
- "data-placement": "top-right",
199
- ...z({
200
- lockVertical: !0
201
- })
202
- }
203
- )
204
- ] })
205
- ]
159
+ children: [
160
+ h && J(),
161
+ /* @__PURE__ */ t(
162
+ "div",
163
+ {
164
+ className: p(
165
+ r("popup-panel-content"),
166
+ e == null ? void 0 : e.content
167
+ ),
168
+ children: /* @__PURE__ */ t("div", { className: r("popup-panel-content-inner"), children: M })
169
+ }
170
+ ),
171
+ l && /* @__PURE__ */ t(
172
+ "div",
173
+ {
174
+ className: p(
175
+ r("popup-panel-footer"),
176
+ e == null ? void 0 : e.footer
177
+ ),
178
+ children: typeof l == "function" ? l({ close: () => x(!1) }) : l
179
+ }
180
+ )
181
+ ]
182
+ }
183
+ )
206
184
  }
207
185
  )
208
186
  }
@@ -212,6 +190,6 @@ const we = ({
212
190
  );
213
191
  };
214
192
  export {
215
- we as PopupPanel
193
+ ve as PopupPanel
216
194
  };
217
195
  //# sourceMappingURL=component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sources":["../../../src/components/popup-panel/component.tsx"],"sourcesContent":["\"use client\";\nimport { useCls, clsx, parseAntdPlacement } from \"../utils\";\nimport { Popover } from \"@base-ui-components/react/popover\";\n\nimport { type PopoverProps } from \"antd/es/popover\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport Flex from \"antd/es/flex\";\nimport { IconButton } from \"../icon-button\";\nimport { X } from \"@bioturing/assets\";\nimport { PopupPanelSize } from \"./constants\";\nimport { useControlledState } from \"../hooks\";\nimport { useResizable, type MoveValues } from \"react-use-resizable\";\nimport mergeRefs from \"merge-refs\";\n\n// Import component-specific styles\nimport \"./style.css\";\n\nexport interface PopupPanelProps\n extends Omit<\n React.ComponentPropsWithRef<\"div\">,\n \"title\" | \"content\" | \"children\"\n > {\n /** The trigger element that opens the popup panel */\n children?: React.ComponentProps<typeof Popover.Trigger>[\"render\"];\n /** Placement of the popup panel relative to its trigger */\n placement?: PopoverProps[\"placement\"];\n /** Whether to open the popup panel on hover */\n openOnHover?: boolean;\n /** Controls the open state of the popup panel */\n open?: boolean;\n /** Callback fired when the open state changes */\n onOpenChange?: Popover.Root.Props[\"onOpenChange\"];\n /** Content to display inside the popup panel */\n content?: React.ReactNode;\n /** Title text or element to display in the panel header */\n title?: React.ReactNode;\n /** The event that triggers the popup panel */\n /**\n * @default \"click\"\n */\n trigger?: \"click\" | \"hover\";\n /** Custom anchor element for positioning the panel */\n anchor?: Popover.Positioner.Props[\"anchor\"];\n /** Content to display before the close button */\n beforeCloseButton?: React.ReactNode;\n /** Content to display after the close button */\n afterCloseButton?: React.ReactNode;\n /** Content to display after the title */\n afterTitle?: React.ReactNode;\n /**\n * Predefined sizes for the popup panel\n * - xsmall: 320px\n * - small: 400px\n * - medium: 480px (default)\n * - large: 640px\n * - xlarge: 840px\n * @default \"medium\" for default type, \"xsmall\" for other types\n */\n size?: keyof typeof PopupPanelSize;\n /**\n * Footer content for the popup panel\n * Can be a React node or a function that returns a React node\n */\n footer?:\n | React.ReactNode\n | ((props: { close: () => void }) => React.ReactNode);\n /**\n * Whether the panel should be open by default when uncontrolled\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Whether the panel should be resizable\n * @default false\n */\n resizable?: boolean;\n /**\n * Custom class names for different parts of the popup panel\n * @default {}\n */\n classNames?: {\n root?: string;\n trigger?: string;\n popup?: string;\n header?: string;\n title?: string;\n content?: string;\n footer?: string;\n resizeHandle?: string;\n };\n /**\n * Whether to close the panel when clicking outside\n * @default true\n */\n closeOnClickOutside?: boolean;\n /**\n * Whether to use modal mode\n * @default false\n */\n modal?: Popover.Root.Props[\"modal\"];\n}\n\nexport const PopupPanel = ({\n children,\n placement,\n openOnHover = false,\n open: outsideOpen,\n onOpenChange: outsideOnOpenChange,\n content,\n title,\n trigger = \"click\",\n className,\n anchor,\n beforeCloseButton,\n afterCloseButton,\n afterTitle,\n size = \"medium\",\n footer,\n defaultOpen,\n resizable = false,\n classNames,\n modal = false,\n closeOnClickOutside = true,\n}: PopupPanelProps) => {\n // Use controlled state with proper initialization to prevent switching between controlled/uncontrolled\n const [open, setOpen] = useControlledState(\n outsideOpen,\n outsideOnOpenChange,\n defaultOpen ?? false // Always provide a default value to prevent undefined\n );\n\n const cls = useCls();\n const headlessUIPlacement = parseAntdPlacement(placement);\n // We don't need triggerRef since we're using callbackRef for the popup\n const [popupRef, setPopupRef] = useState<HTMLDivElement | null>(null);\n const [width, setWidth] = useState<number>();\n const [height, setHeight] = useState<number>();\n const callbackRef = useCallback((node: HTMLDivElement) => {\n setPopupRef(node);\n }, []);\n useEffect(() => {\n if (!popupRef) return;\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n setWidth(entry.contentRect.width);\n setHeight(entry.contentRect.height);\n }\n });\n observer.observe(popupRef);\n return () => {\n observer.disconnect();\n };\n }, [popupRef]);\n\n const defaultCloseIcon = useMemo(() => <X size={16} />, []);\n const renderTitle = useCallback(() => {\n return (\n <div className={clsx(cls(\"popup-panel-header\"), classNames?.header)}>\n <Flex\n align=\"center\"\n gap={8}\n className={cls(\"popup-panel-title-wrapper\")}\n >\n <Popover.Title\n render={\n <div className={clsx(cls(\"grow\", \"truncate\"), classNames?.title)}>\n {title}\n </div>\n }\n ></Popover.Title>\n <div className=\"flex items-center gap-2\">\n {beforeCloseButton}\n <Popover.Close\n render={<IconButton>{defaultCloseIcon}</IconButton>}\n />\n {afterCloseButton}\n </div>\n </Flex>\n {afterTitle ? afterTitle : null}\n </div>\n );\n }, [\n afterCloseButton,\n afterTitle,\n beforeCloseButton,\n cls,\n classNames?.header,\n classNames?.title,\n defaultCloseIcon,\n title,\n ]);\n const [resizing, setResizing] = useState(false);\n const { getRootProps, getHandleProps, rootRef } = useResizable({\n initialWidth: width,\n initialHeight: height,\n onDragStart: () => setResizing(true),\n onDragEnd: () => setResizing(false),\n });\n useEffect(() => {\n if (resizing) {\n document.body.style.userSelect = \"none\";\n } else {\n document.body.style.userSelect = \"\";\n }\n }, [resizing]);\n const { ref: rootRefProp, ...rootPropsWithoutRef } = getRootProps();\n // Handle reverse handle change for vertical resizing\n // Currently not used but kept for future implementation\n // const _onReverseHandleChangeVertical = (\n // parent: React.RefObject<HTMLDivElement>,\n // values: MoveValues\n // ) => {\n // if (!parent.current) return;\n // const { heightDiff } = values;\n // parent.current.style.top = `${\n // parseInt(parent.current.style.top || \"0\") - heightDiff\n // }px`;\n // };\n\n // Handle reverse handle change\n const onReverseHandleChangeHorizontal = (\n parent: React.RefObject<HTMLDivElement>,\n values: MoveValues\n ) => {\n if (!parent.current) return;\n const { widthDiff } = values;\n parent.current.style.left = `${\n parseInt(parent.current.style.left || \"0\") - widthDiff\n }px`;\n };\n\n return (\n <Popover.Root\n openOnHover={trigger === \"hover\" ? true : openOnHover}\n open={open}\n onOpenChange={(open, event, reason) => {\n if (\n (reason === \"outside-press\" || reason === \"focus-out\") &&\n !closeOnClickOutside\n )\n return;\n setOpen(open, event, reason);\n }}\n modal={modal}\n >\n <Popover.Trigger\n render={children}\n className={clsx(cls(\"popup-panel-trigger\"), classNames?.trigger)}\n ></Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner\n className={clsx(cls(\"popup-panel-root\"), classNames?.root)}\n side={headlessUIPlacement.placement}\n align={headlessUIPlacement.align}\n sideOffset={4}\n anchor={anchor}\n style={\n {\n \"--size-width\": size ? PopupPanelSize[size] : undefined,\n } as React.CSSProperties\n }\n >\n <Popover.Popup\n className={clsx(\n cls(\"popup-panel\"),\n cls(`popup-panel-size-${size}`),\n className,\n classNames?.popup\n )}\n ref={mergeRefs(rootRefProp, callbackRef)}\n // resizable props\n {...(resizable ? rootPropsWithoutRef : {})}\n {...(resizing ? { \"data-resizing\": true } : {})}\n >\n {/* <div ref={popupRef}> */}\n {title && renderTitle()}\n <div\n className={clsx(cls(\"popup-panel-content\"), classNames?.content)}\n >\n <div className={cls(\"popup-panel-content-inner\")}>{content}</div>\n </div>\n {footer && (\n <div\n className={clsx(cls(\"popup-panel-footer\"), classNames?.footer)}\n >\n {typeof footer === \"function\"\n ? footer({ close: () => setOpen(false) })\n : footer}\n </div>\n )}\n {resizable && (\n <>\n <div\n className={clsx(\n cls(\"popup-panel-resize-handle\"),\n classNames?.resizeHandle\n )}\n data-placement=\"bottom-left\"\n {...getHandleProps({\n lockHorizontal: true,\n })}\n />\n <div\n className={clsx(\n cls(\"popup-panel-resize-handle\"),\n classNames?.resizeHandle\n )}\n data-placement=\"top-left\"\n {...getHandleProps({\n reverse: true,\n lockVertical: true,\n onResize: (values) =>\n onReverseHandleChangeHorizontal(rootRef, values),\n })}\n />\n <div\n className={clsx(\n cls(\"popup-panel-resize-handle\"),\n classNames?.resizeHandle\n )}\n data-placement=\"top-right\"\n {...getHandleProps({\n lockVertical: true,\n })}\n />\n </>\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n"],"names":["PopupPanel","children","placement","openOnHover","outsideOpen","outsideOnOpenChange","content","title","trigger","className","anchor","beforeCloseButton","afterCloseButton","afterTitle","size","footer","defaultOpen","resizable","classNames","modal","closeOnClickOutside","open","setOpen","useControlledState","cls","useCls","headlessUIPlacement","parseAntdPlacement","popupRef","setPopupRef","useState","width","setWidth","height","setHeight","callbackRef","useCallback","node","useEffect","observer","entries","entry","defaultCloseIcon","useMemo","jsx","X","renderTitle","jsxs","clsx","Flex","Popover","IconButton","resizing","setResizing","getRootProps","getHandleProps","rootRef","useResizable","rootRefProp","rootPropsWithoutRef","onReverseHandleChangeHorizontal","parent","values","widthDiff","event","reason","PopupPanelSize","mergeRefs","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"component.js","sources":["../../../src/components/popup-panel/component.tsx"],"sourcesContent":["\"use client\";\nimport { useCls, clsx, parseAntdPlacement, buildAntdPlacement, BaseUIPlacement, BaseUISide, BaseUIAlign } from \"../utils\";\nimport { Popover } from \"@base-ui-components/react/popover\";\n\nimport { type PopoverProps } from \"antd/es/popover\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { IconButton } from \"../icon-button\";\nimport { X } from \"@bioturing/assets\";\nimport { PopupPanelSize } from \"./constants\";\nimport { useControlledState } from \"../hooks\";\nimport { Resizable } from \"../resizable\";\nimport { Stack } from \"../stack\";\n\n// Import component-specific styles\nimport \"./style.css\";\nimport { useRef } from \"react\";\n\nexport interface PopupPanelProps\n extends Omit<\n React.ComponentPropsWithRef<\"div\">,\n \"title\" | \"content\" | \"children\"\n > {\n /** The trigger element that opens the popup panel */\n children?: React.ComponentProps<typeof Popover.Trigger>[\"render\"];\n /** Placement of the popup panel relative to its trigger */\n placement?: PopoverProps[\"placement\"];\n /** Whether to open the popup panel on hover */\n openOnHover?: boolean;\n /** Controls the open state of the popup panel */\n open?: boolean;\n /** Callback fired when the open state changes */\n onOpenChange?: Popover.Root.Props[\"onOpenChange\"];\n /** Content to display inside the popup panel */\n content?: React.ReactNode;\n /** Title text or element to display in the panel header */\n title?: React.ReactNode;\n /** The event that triggers the popup panel */\n /**\n * @default \"click\"\n */\n trigger?: \"click\" | \"hover\";\n /** Custom anchor element for positioning the panel */\n anchor?: Popover.Positioner.Props[\"anchor\"];\n /** Content to display before the close button */\n beforeCloseButton?: React.ReactNode;\n /** Content to display after the close button */\n afterCloseButton?: React.ReactNode;\n /** Content to display after the title */\n afterTitle?: React.ReactNode;\n /**\n * Predefined sizes for the popup panel\n * - xsmall: 320px\n * - small: 400px\n * - medium: 480px (default)\n * - large: 640px\n * - xlarge: 840px\n * @default \"medium\" for default type, \"xsmall\" for other types\n */\n size?: keyof typeof PopupPanelSize;\n /**\n * Footer content for the popup panel\n * Can be a React node or a function that returns a React node\n */\n footer?:\n | React.ReactNode\n | ((props: { close: () => void }) => React.ReactNode);\n /**\n * Whether the panel should be open by default when uncontrolled\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Whether the panel should be resizable\n * @default false\n */\n resizable?: boolean;\n /**\n * Custom class names for different parts of the popup panel\n * @default {}\n */\n classNames?: {\n root?: string;\n trigger?: string;\n popup?: string;\n header?: string;\n title?: string;\n content?: string;\n footer?: string;\n resizeHandle?: string;\n };\n /**\n * Whether to close the panel when clicking outside\n * @default true\n */\n closeOnClickOutside?: boolean;\n /**\n * Whether to use modal mode\n * @default false\n */\n modal?: Popover.Root.Props[\"modal\"];\n /**\n * Callback function when the placement changes\n */\n onPlacementChange?: (placement: PopoverProps[\"placement\"]) => void;\n}\n\nexport const PopupPanel = ({\n children,\n placement,\n openOnHover = false,\n open: outsideOpen,\n onOpenChange: outsideOnOpenChange,\n content,\n title,\n trigger = \"click\",\n className,\n anchor,\n beforeCloseButton,\n afterCloseButton,\n afterTitle,\n size = \"medium\",\n footer,\n defaultOpen,\n resizable = false,\n classNames,\n modal = false,\n closeOnClickOutside = true,\n onPlacementChange,\n}: PopupPanelProps) => {\n // Use controlled state with proper initialization to prevent switching between controlled/uncontrolled\n const [open, setOpen] = useControlledState(\n outsideOpen,\n outsideOnOpenChange,\n defaultOpen ?? false // Always provide a default value to prevent undefined\n );\n\n const cls = useCls();\n const baseUIPlacement = parseAntdPlacement(placement);\n\n const defaultCloseIcon = useMemo(() => <X size={16} />, []);\n\n const positionerRef = useRef<HTMLDivElement>(null);\n const currentSideRef = useRef<BaseUISide>(baseUIPlacement.side);\n const currentAlignRef = useRef<BaseUIAlign>(baseUIPlacement.align);\n const [placementChangeKey, setPlacementChangeKey] = useState(0);\n\n useEffect(() => {\n const positioner = positionerRef.current;\n if (!positioner || !open) return; // Only observe when popup is open\n\n // Create MutationObserver to watch for data-side changes\n const observer = new MutationObserver((mutations) => {\n let hasPlacementChanged = false;\n \n mutations.forEach((mutation) => {\n if (\n mutation.type === \"attributes\" &&\n mutation.attributeName === \"data-side\"\n ) {\n const newSide = positioner.getAttribute(mutation.attributeName);\n if (newSide && newSide !== currentSideRef.current) {\n currentSideRef.current = newSide as BaseUISide;\n hasPlacementChanged = true;\n }\n }\n if (\n mutation.type === \"attributes\" &&\n mutation.attributeName === \"data-align\"\n ) {\n const newAlign = positioner.getAttribute(mutation.attributeName);\n if (newAlign && newAlign !== currentAlignRef.current) {\n currentAlignRef.current = newAlign as BaseUIAlign;\n hasPlacementChanged = true;\n }\n }\n });\n\n // Only trigger callbacks if placement actually changed\n if (hasPlacementChanged) {\n const newPlacement = buildAntdPlacement({\n side: currentSideRef.current,\n align: currentAlignRef.current\n });\n \n // Trigger resizable dimensions reset when placement changes\n setPlacementChangeKey(prev => prev + 1);\n \n if (onPlacementChange) {\n onPlacementChange(newPlacement);\n }\n }\n });\n\n // Start observing\n observer.observe(positioner, {\n attributes: true,\n attributeFilter: [\"data-side\", \"data-align\"],\n attributeOldValue: true,\n });\n\n return () => {\n observer.disconnect();\n };\n }, [onPlacementChange, open]);\n\n const renderTitle = useCallback(() => {\n return (\n <div className={clsx(cls(\"popup-panel-header\"), classNames?.header)}>\n <Stack\n align=\"center\"\n gap={8}\n className={cls(\"popup-panel-title-wrapper\")}\n >\n <Popover.Title\n render={\n <div className={clsx(cls(\"grow\", \"truncate\"), classNames?.title)}>\n {title}\n </div>\n }\n ></Popover.Title>\n <div className=\"flex items-center gap-2\">\n {beforeCloseButton}\n <Popover.Close\n render={<IconButton>{defaultCloseIcon}</IconButton>}\n />\n {afterCloseButton}\n </div>\n </Stack>\n {afterTitle ? afterTitle : null}\n </div>\n );\n }, [\n afterCloseButton,\n afterTitle,\n beforeCloseButton,\n cls,\n classNames?.header,\n classNames?.title,\n defaultCloseIcon,\n title,\n ]);\n\n return (\n <Popover.Root\n openOnHover={trigger === \"hover\" ? true : openOnHover}\n open={open}\n onOpenChange={(open, event, reason) => {\n if (\n (reason === \"outside-press\" || reason === \"focus-out\") &&\n !closeOnClickOutside\n )\n return;\n setOpen(open, event, reason);\n }}\n modal={modal}\n >\n <Popover.Trigger\n render={children}\n className={clsx(cls(\"popup-panel-trigger\"), classNames?.trigger)}\n ></Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner\n ref={positionerRef}\n className={clsx(cls(\"popup-panel-root\"), classNames?.root)}\n side={baseUIPlacement.side}\n align={baseUIPlacement.align}\n sideOffset={4}\n anchor={anchor}\n style={\n {\n \"--size-width\": size ? PopupPanelSize[size] : undefined,\n } as React.CSSProperties\n }\n >\n <Resizable\n resizable={resizable}\n absolutePositioning={true}\n resetKey={placementChangeKey}\n classNames={{\n resizeHandle: classNames?.resizeHandle,\n }}\n >\n <Popover.Popup\n className={clsx(\n cls(\"popup-panel\"),\n cls(`popup-panel-size-${size}`),\n className,\n classNames?.popup\n )}\n >\n {title && renderTitle()}\n <div\n className={clsx(\n cls(\"popup-panel-content\"),\n classNames?.content\n )}\n >\n <div className={cls(\"popup-panel-content-inner\")}>\n {content}\n </div>\n </div>\n {footer && (\n <div\n className={clsx(\n cls(\"popup-panel-footer\"),\n classNames?.footer\n )}\n >\n {typeof footer === \"function\"\n ? footer({ close: () => setOpen(false) })\n : footer}\n </div>\n )}\n </Popover.Popup>\n </Resizable>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n"],"names":["PopupPanel","children","placement","openOnHover","outsideOpen","outsideOnOpenChange","content","title","trigger","className","anchor","beforeCloseButton","afterCloseButton","afterTitle","size","footer","defaultOpen","resizable","classNames","modal","closeOnClickOutside","onPlacementChange","open","setOpen","useControlledState","cls","useCls","baseUIPlacement","parseAntdPlacement","defaultCloseIcon","useMemo","jsx","X","positionerRef","useRef","currentSideRef","currentAlignRef","placementChangeKey","setPlacementChangeKey","useState","useEffect","positioner","observer","mutations","hasPlacementChanged","mutation","newSide","newAlign","newPlacement","buildAntdPlacement","prev","renderTitle","useCallback","jsxs","clsx","Stack","Popover","IconButton","event","reason","PopupPanelSize","Resizable"],"mappings":"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"}