@clubmed/trident-ui 2.0.0-beta.27 → 2.0.0-beta.28
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/package.json +1 -1
- package/ui/Dropdown.js +2 -2
- package/ui/Dropdown.js.map +1 -1
package/package.json
CHANGED
package/ui/Dropdown.js
CHANGED
|
@@ -67,8 +67,8 @@ function d({ icon: n = "ArrowOutlinedDown", className: r, children: i, ...a }) {
|
|
|
67
67
|
})]
|
|
68
68
|
}), /* @__PURE__ */ c("div", {
|
|
69
69
|
className: t(e("dropdown-panel z-5 flex items-center gap-12 bg-white rounded-16 border-1 border-lightGrey absolute top-[calc(100%+8px)] right-0 text-black p-20 min-w-[120px] origin-center will-change[transform,opacity]", {
|
|
70
|
-
"animate-
|
|
71
|
-
"animate-
|
|
70
|
+
"animate-zoom-in": m,
|
|
71
|
+
"animate-zoom-out": !m && f,
|
|
72
72
|
"opacity-0 scale-90 pointer-events-none": !m && !f
|
|
73
73
|
})),
|
|
74
74
|
children: o
|
package/ui/Dropdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","names":[],"sources":["../../lib/ui/Dropdown.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\nimport clsx from 'clsx';\nimport { twMerge } from '@/ui/helpers/twMerge';\nimport { useSlots } from '@/ui/hooks/useSlots';\n\ninterface DropdownRenderContext {\n close: () => void;\n open: boolean;\n toggle: () => void;\n}\n\ntype DropdownChildren = ReactNode | ((context: DropdownRenderContext) => ReactNode);\n\nexport interface DropdownProps extends Omit<ComponentPropsWithoutRef<'button'>, 'children'> {\n children?: DropdownChildren;\n icon?: IconicNames;\n}\n\nexport function useDropdown(initialChildren?: DropdownChildren) {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const wasVisibleRef = useRef(open);\n const wasVisible = wasVisibleRef.current;\n const isLeaving = !open && wasVisible;\n\n // update ref for next render\n wasVisibleRef.current = open;\n\n const toggle = useCallback(() => {\n setOpen((prev) => !prev);\n }, []);\n\n const close = useCallback(() => {\n setOpen(false);\n }, []);\n\n const renderedChildren =\n typeof initialChildren === 'function'\n ? initialChildren({ close, open, toggle })\n : initialChildren;\n\n const { label, children } = useSlots(renderedChildren, ['label']);\n\n useEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const items = containerRef.current.querySelectorAll(\n '.dropdown-panel a[href], .dropdown-panel [data-dropdown-item]',\n );\n const listeners = Array.from(items, (item) => {\n const handleItemClick = () => {\n close();\n };\n item.addEventListener('click', handleItemClick);\n return { handleItemClick, item };\n });\n\n return () => {\n listeners.forEach(({ handleItemClick, item }) => {\n item.removeEventListener('click', handleItemClick);\n });\n };\n }, [close, renderedChildren]);\n\n // Close overlay when clicking outside using composedPath\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handleOutsideClick = (event: PointerEvent) => {\n if (!containerRef.current || event.composedPath().includes(containerRef.current)) {\n return;\n }\n\n close();\n };\n\n document.addEventListener('click', handleOutsideClick);\n return () => {\n document.removeEventListener('click', handleOutsideClick);\n };\n }, [close, open]);\n\n return {\n children,\n close,\n containerRef,\n isLeaving,\n label,\n open,\n toggle,\n };\n}\n\nexport function Dropdown({\n icon = 'ArrowOutlinedDown',\n className,\n children: initialChildren,\n ...attrs\n}: DropdownProps) {\n const { children, containerRef, isLeaving, label, open, toggle } = useDropdown(initialChildren);\n\n return (\n <div ref={containerRef} className={twMerge('flex items-center gap-8 relative', className)}>\n <button\n tabIndex={-1}\n {...attrs}\n className=\"flex gap-8 items-center relative\"\n onClick={toggle}\n >\n {label}\n\n <Icon name={icon} className=\"w-30\" />\n </button>\n\n <div\n className={twMerge(\n clsx(\n 'dropdown-panel z-5 flex items-center gap-12 bg-white rounded-16 border-1 border-lightGrey absolute top-[calc(100%+8px)] right-0 text-black p-20 min-w-[120px] origin-center will-change[transform,opacity]',\n {\n 'animate-
|
|
1
|
+
{"version":3,"file":"Dropdown.js","names":[],"sources":["../../lib/ui/Dropdown.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ReactNode,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Icon, type IconicNames } from '@clubmed/trident-icons';\nimport clsx from 'clsx';\nimport { twMerge } from '@/ui/helpers/twMerge';\nimport { useSlots } from '@/ui/hooks/useSlots';\n\ninterface DropdownRenderContext {\n close: () => void;\n open: boolean;\n toggle: () => void;\n}\n\ntype DropdownChildren = ReactNode | ((context: DropdownRenderContext) => ReactNode);\n\nexport interface DropdownProps extends Omit<ComponentPropsWithoutRef<'button'>, 'children'> {\n children?: DropdownChildren;\n icon?: IconicNames;\n}\n\nexport function useDropdown(initialChildren?: DropdownChildren) {\n const [open, setOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const wasVisibleRef = useRef(open);\n const wasVisible = wasVisibleRef.current;\n const isLeaving = !open && wasVisible;\n\n // update ref for next render\n wasVisibleRef.current = open;\n\n const toggle = useCallback(() => {\n setOpen((prev) => !prev);\n }, []);\n\n const close = useCallback(() => {\n setOpen(false);\n }, []);\n\n const renderedChildren =\n typeof initialChildren === 'function'\n ? initialChildren({ close, open, toggle })\n : initialChildren;\n\n const { label, children } = useSlots(renderedChildren, ['label']);\n\n useEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const items = containerRef.current.querySelectorAll(\n '.dropdown-panel a[href], .dropdown-panel [data-dropdown-item]',\n );\n const listeners = Array.from(items, (item) => {\n const handleItemClick = () => {\n close();\n };\n item.addEventListener('click', handleItemClick);\n return { handleItemClick, item };\n });\n\n return () => {\n listeners.forEach(({ handleItemClick, item }) => {\n item.removeEventListener('click', handleItemClick);\n });\n };\n }, [close, renderedChildren]);\n\n // Close overlay when clicking outside using composedPath\n useEffect(() => {\n if (!open) {\n return;\n }\n\n const handleOutsideClick = (event: PointerEvent) => {\n if (!containerRef.current || event.composedPath().includes(containerRef.current)) {\n return;\n }\n\n close();\n };\n\n document.addEventListener('click', handleOutsideClick);\n return () => {\n document.removeEventListener('click', handleOutsideClick);\n };\n }, [close, open]);\n\n return {\n children,\n close,\n containerRef,\n isLeaving,\n label,\n open,\n toggle,\n };\n}\n\nexport function Dropdown({\n icon = 'ArrowOutlinedDown',\n className,\n children: initialChildren,\n ...attrs\n}: DropdownProps) {\n const { children, containerRef, isLeaving, label, open, toggle } = useDropdown(initialChildren);\n\n return (\n <div ref={containerRef} className={twMerge('flex items-center gap-8 relative', className)}>\n <button\n tabIndex={-1}\n {...attrs}\n className=\"flex gap-8 items-center relative\"\n onClick={toggle}\n >\n {label}\n\n <Icon name={icon} className=\"w-30\" />\n </button>\n\n <div\n className={twMerge(\n clsx(\n 'dropdown-panel z-5 flex items-center gap-12 bg-white rounded-16 border-1 border-lightGrey absolute top-[calc(100%+8px)] right-0 text-black p-20 min-w-[120px] origin-center will-change[transform,opacity]',\n {\n 'animate-zoom-in': open,\n 'animate-zoom-out': !open && isLeaving,\n 'opacity-0 scale-90 pointer-events-none': !open && !isLeaving,\n },\n ),\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,EAAY,GAAoC;CAC9D,IAAM,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,IAAe,EAAuB,KAAK,EAC3C,IAAgB,EAAO,EAAK,EAC5B,IAAa,EAAc,SAC3B,IAAY,CAAC,KAAQ;AAG3B,GAAc,UAAU;CAExB,IAAM,IAAS,QAAkB;AAC/B,KAAS,MAAS,CAAC,EAAK;IACvB,EAAE,CAAC,EAEA,IAAQ,QAAkB;AAC9B,IAAQ,GAAM;IACb,EAAE,CAAC,EAEA,IACJ,OAAO,KAAoB,aACvB,EAAgB;EAAE;EAAO;EAAM;EAAQ,CAAC,GACxC,GAEA,EAAE,UAAO,gBAAa,EAAS,GAAkB,CAAC,QAAQ,CAAC;AA6CjE,QA3CA,QAAgB;AACd,MAAI,CAAC,EAAa,QAChB;EAGF,IAAM,IAAQ,EAAa,QAAQ,iBACjC,gEACD,EACK,IAAY,MAAM,KAAK,IAAQ,MAAS;GAC5C,IAAM,UAAwB;AAC5B,OAAO;;AAGT,UADA,EAAK,iBAAiB,SAAS,EAAgB,EACxC;IAAE;IAAiB;IAAM;IAChC;AAEF,eAAa;AACX,KAAU,SAAS,EAAE,oBAAiB,cAAW;AAC/C,MAAK,oBAAoB,SAAS,EAAgB;KAClD;;IAEH,CAAC,GAAO,EAAiB,CAAC,EAG7B,QAAgB;AACd,MAAI,CAAC,EACH;EAGF,IAAM,KAAsB,MAAwB;AAC9C,IAAC,EAAa,WAAW,EAAM,cAAc,CAAC,SAAS,EAAa,QAAQ,IAIhF,GAAO;;AAIT,SADA,SAAS,iBAAiB,SAAS,EAAmB,QACzC;AACX,YAAS,oBAAoB,SAAS,EAAmB;;IAE1D,CAAC,GAAO,EAAK,CAAC,EAEV;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACD;;AAGH,SAAgB,EAAS,EACvB,UAAO,qBACP,cACA,UAAU,GACV,GAAG,KACa;CAChB,IAAM,EAAE,aAAU,iBAAc,cAAW,UAAO,SAAM,cAAW,EAAY,EAAgB;AAE/F,QACE,kBAAC,OAAD;EAAK,KAAK;EAAc,WAAW,EAAQ,oCAAoC,EAAU;YAAzF,CACE,kBAAC,UAAD;GACE,UAAU;GACV,GAAI;GACJ,WAAU;GACV,SAAS;aAJX,CAMG,GAED,kBAAC,GAAD;IAAM,MAAM;IAAM,WAAU;IAAS,CAAA,CAC9B;MAET,kBAAC,OAAD;GACE,WAAW,EACT,EACE,8MACA;IACE,mBAAmB;IACnB,oBAAoB,CAAC,KAAQ;IAC7B,0CAA0C,CAAC,KAAQ,CAAC;IACrD,CACF,CACF;GAEA;GACG,CAAA,CACF"}
|