@magiclabs/ui-components 1.24.7 → 1.25.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.
@@ -1,2 +1,2 @@
1
- "use strict";var t=require("react/jsx-runtime");require("../feedback/callout.js");var z=require("@styled/css"),m=require("@styled/jsx");require("../feedback/progress-bar.js");var C=require("@styled/tokens"),L=require("../icons/ico-caret-down.js"),V=require("../icons/ico-caret-up.js"),M=require("../icons/ico-checkmark.js"),T=require("../icons/ico-question-circle-fill.js");require("./button.js"),require("./checkbox.js"),require("./popover.js"),require("./radio.js"),require("./segmented-control.js"),require("./switch.js");var j=require("./text.js");require("./portal.js");var r=require("react");require("../../hooks/useToast.js"),require("../../recipes/toast.js");var U=require("../feedback/tooltip.js"),w=require("react-aria");const E={sm:{caret:16,check:14,height:"2.625rem",top:48,width:"0.75rem",mult:2.25},md:{caret:17,check:15,height:"2.8125rem",top:52,width:"0.85rem",mult:2.25},lg:{caret:18,check:16,height:"3rem",top:55,width:"1rem",mult:2.5}},A=r.createContext({selectedOption:null,setSelectedOption:()=>{}}),P=({value:i,label:a,size:d="lg",isFocused:y})=>{const{selectedOption:h,setSelectedOption:p}=r.useContext(A),s=h?.value===i,o=E[d],k=r.useCallback(()=>{p({value:i,label:a})},[p,i,a]);return t.jsxs(m.HStack,{py:1.5,gap:2,bg:s?"brand.base":y?"brand.lightest":"",_hover:s?{}:{bg:"brand.lightest"},onClick:k,style:{paddingLeft:o.width,paddingRight:o.width},children:[t.jsx(m.Box,{style:{minWidth:o.width},children:s&&t.jsx(M.default,{width:o.check,height:o.check,color:C.token("colors.text.quaternary")})}),t.jsx(j.default,{size:d,fontWeight:"medium",fontColor:s?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:a})]})},R=({children:i,onSelect:a,label:d,placeholder:y="Select one",selectedValue:h,size:p="lg",tooltipContent:s,disabled:o,viewMax:k=5,...W})=>{const[b,v]=r.useState(!1),[l,f]=r.useState(null),x=r.useRef(null),q=r.useRef(null),u=E[p],F=k*u.mult+1,H=r.useCallback(()=>{v(e=>!e),b||(f(null),setTimeout(()=>{var e;return(e=q.current)===null||e===void 0?void 0:e.focus()}))},[b]),N=r.useCallback(e=>{a(e.value),v(!1)},[a]),S=r.useMemo(()=>{const e=r.Children.toArray(i).find(n=>n.props.value===h);return e?e.props.label:y},[h,i]),{buttonProps:B}=w.useButton({...W,isDisabled:o,onPress:H},x),{focusProps:_,isFocusVisible:I}=w.useFocusRing(),{keyboardProps:K}=w.useKeyboard({onKeyDown:e=>{var n,c;if(!b)return;let g=l;const D=r.Children.toArray(i);switch(e.key){case"ArrowUp":e.preventDefault(),l===null?f(r.Children.count(i)-1):(g=l>0?l-1:r.Children.count(i)-1,f(g));break;case"ArrowDown":e.preventDefault(),l===null?f(0):(g=l<r.Children.count(i)-1?l+1:0,f(g));break;case"Enter":if(e.preventDefault(),(n=x.current)===null||n===void 0||n.focus(),l===null)return;if(l>=0&&l<D.length){const O=D[l];O&&a(O.props.value)}break;case"Escape":v(!1),(c=x.current)===null||c===void 0||c.focus();break}}});return r.useEffect(()=>{const e=n=>{var c;!((c=q.current)===null||c===void 0)&&c.contains(n.target)||v(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),t.jsx(A.Provider,{value:{selectedOption:{value:h??"",label:S},setSelectedOption:N},children:t.jsxs(m.VStack,{gap:2,w:"full",alignItems:"flex-start",children:[(d||s)&&t.jsxs(m.HStack,{gap:2,opacity:o?.3:"",transition:"all linear 120ms",children:[d&&t.jsx(j.default,{size:"sm",fontWeight:"medium",children:d}),s&&t.jsx(U.default,{isDisabled:o,content:s,children:t.jsx(T.default,{className:z.css({w:4,h:4,color:"neutral.primary"})})})]}),t.jsxs("button",{className:z.css({w:"full",h:"fit-content",bg:"surface.primary",borderWidth:"thin",borderColor:"neutral.secondary",rounded:"xl",transition:"all linear 120ms",position:"relative",cursor:"pointer",outlineColor:"brand.base",outlineStyle:I?"solid":"none",outlineWidth:"thick",outlineOffset:.5,_hover:{borderColor:"neutral.primary"},_disabled:{opacity:.3,pointerEvents:"none"}}),ref:x,...w.mergeProps(B,_,K),children:[t.jsxs(m.HStack,{w:"full",p:4,justifyContent:"space-between",style:{height:u.height},children:[t.jsx(j.default,{truncate:!0,size:p,fontColor:h?"text.primary":"text.tertiary",children:S}),b?t.jsx(V.default,{width:u.caret,height:u.caret,color:C.token("colors.brand.base")}):t.jsx(L.default,{width:u.caret,height:u.caret,color:C.token("colors.brand.base")})]}),b&&t.jsx(m.Box,{ref:q,tabIndex:-1,py:2,bg:"surface.primary",position:"absolute",w:"full",rounded:"input",boxShadow:"4px 8px 20px 0px rgba(0, 0, 0, 0.15)",style:{maxHeight:`${F}rem`,top:u.top},overflowY:"auto",outline:"none",zIndex:"max",children:r.Children.map(i,(e,n)=>r.cloneElement(e,{isFocused:n===l,size:p}))})]})]})})};P.displayName="DropdownOption",R.displayName="DropdownSelector",exports.DropdownOption=P,exports.DropdownSelector=R;
1
+ "use strict";var t=require("react/jsx-runtime");require("../feedback/callout.js");var z=require("@styled/css"),m=require("@styled/jsx");require("../feedback/progress-bar.js");var C=require("@styled/tokens"),L=require("../icons/ico-caret-down.js"),V=require("../icons/ico-caret-up.js"),M=require("../icons/ico-checkmark.js"),T=require("../icons/ico-question-circle-fill.js");require("./button.js"),require("./checkbox.js"),require("./popover.js"),require("./radio.js"),require("./segmented-control.js"),require("./switch.js");var j=require("./text.js");require("./portal.js");var r=require("react");require("../../hooks/useToast.js"),require("../../recipes/toast.js");var U=require("../feedback/tooltip.js"),w=require("react-aria");const E={sm:{caret:16,check:14,height:"2.625rem",top:48,width:"0.75rem",mult:2.25},md:{caret:17,check:15,height:"2.8125rem",top:52,width:"0.85rem",mult:2.25},lg:{caret:18,check:16,height:"3rem",top:55,width:"1rem",mult:2.5}},A=r.createContext({selectedOption:null,setSelectedOption:()=>{}}),P=({value:i,label:a,size:d="lg",isFocused:y})=>{const{selectedOption:h,setSelectedOption:p}=r.useContext(A),n=h?.value===i,s=E[d],k=r.useCallback(()=>{p({value:i,label:a})},[p,i,a]);return t.jsxs(m.HStack,{py:1.5,gap:2,bg:n?"brand.base":y?"brand.lightest":"",_hover:n?{}:{bg:"brand.lightest"},onClick:k,style:{paddingLeft:s.width,paddingRight:s.width},children:[t.jsx(m.Box,{style:{minWidth:s.width},children:n&&t.jsx(M.default,{width:s.check,height:s.check,color:C.token("colors.text.quaternary")})}),t.jsx(j.default,{size:d,fontWeight:"medium",fontColor:n?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:a})]})},R=({children:i,onSelect:a,label:d,placeholder:y="Select one",selectedValue:h,size:p="lg",tooltipContent:n,disabled:s,viewMax:k=5,...W})=>{const[f,v]=r.useState(!1),[l,b]=r.useState(null),x=r.useRef(null),q=r.useRef(null),u=E[p],F=k*u.mult+1,H=r.useCallback(()=>{v(e=>!e),f||(b(null),setTimeout(()=>{var e;return(e=q.current)===null||e===void 0?void 0:e.focus()}))},[f]),N=r.useCallback(e=>{a(e.value),v(!1)},[a]),S=r.useMemo(()=>{const e=r.Children.toArray(i).find(o=>o.props.value===h);return e?e.props.label:y},[h,i]),{buttonProps:B}=w.useButton({...W,isDisabled:s,onPress:H},x),{focusProps:_,isFocusVisible:I}=w.useFocusRing(),{keyboardProps:K}=w.useKeyboard({onKeyDown:e=>{var o,c;if(!f)return;let g=l;const D=r.Children.toArray(i);switch(e.key){case"ArrowUp":e.preventDefault(),l===null?b(r.Children.count(i)-1):(g=l>0?l-1:r.Children.count(i)-1,b(g));break;case"ArrowDown":e.preventDefault(),l===null?b(0):(g=l<r.Children.count(i)-1?l+1:0,b(g));break;case"Enter":if(e.preventDefault(),(o=x.current)===null||o===void 0||o.focus(),l===null)return;if(l>=0&&l<D.length){const O=D[l];O&&a(O.props.value)}break;case"Escape":v(!1),(c=x.current)===null||c===void 0||c.focus();break}}});return r.useEffect(()=>{const e=o=>{var c;!((c=q.current)===null||c===void 0)&&c.contains(o.target)||v(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),t.jsx(A.Provider,{value:{selectedOption:{value:h??"",label:S},setSelectedOption:N},children:t.jsxs(m.VStack,{gap:2,w:"full",alignItems:"flex-start",children:[(d||n)&&t.jsxs(m.HStack,{gap:2,opacity:s?.3:"",transition:"all linear 120ms",children:[d&&t.jsx(j.default,{size:"sm",fontWeight:"medium",children:d}),n&&t.jsx(U.default,{content:n,children:t.jsx(T.default,{className:z.css({w:4,h:4,color:"neutral.primary"})})})]}),t.jsxs("button",{className:z.css({w:"full",h:"fit-content",bg:"surface.primary",borderWidth:"thin",borderColor:"neutral.secondary",rounded:"xl",transition:"all linear 120ms",position:"relative",cursor:"pointer",outlineColor:"brand.base",outlineStyle:I?"solid":"none",outlineWidth:"thick",outlineOffset:.5,_hover:{borderColor:"neutral.primary"},_disabled:{opacity:.3,pointerEvents:"none"}}),ref:x,...w.mergeProps(B,_,K),children:[t.jsxs(m.HStack,{w:"full",p:4,justifyContent:"space-between",style:{height:u.height},children:[t.jsx(j.default,{truncate:!0,size:p,fontColor:h?"text.primary":"text.tertiary",children:S}),f?t.jsx(V.default,{width:u.caret,height:u.caret,color:C.token("colors.brand.base")}):t.jsx(L.default,{width:u.caret,height:u.caret,color:C.token("colors.brand.base")})]}),f&&t.jsx(m.Box,{ref:q,tabIndex:-1,py:2,bg:"surface.primary",position:"absolute",w:"full",rounded:"input",boxShadow:"4px 8px 20px 0px rgba(0, 0, 0, 0.15)",style:{maxHeight:`${F}rem`,top:u.top},overflowY:"auto",outline:"none",zIndex:"max",children:r.Children.map(i,(e,o)=>r.cloneElement(e,{isFocused:o===l,size:p}))})]})]})})};P.displayName="DropdownOption",R.displayName="DropdownSelector",exports.DropdownOption=P,exports.DropdownSelector=R;
2
2
  //# sourceMappingURL=dropdown-selector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-selector.js","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"sourcesContent":["import { Tooltip } from '@components/feedback';\nimport { IcoCaretDown, IcoCaretUp, IcoCheckmark, IcoQuestionCircleFill } from '@components/icons';\nimport { Text } from '@components/primitives';\nimport { css } from '@styled/css';\nimport { Box, HStack, VStack } from '@styled/jsx';\nimport { token } from '@styled/tokens';\nimport {\n Children,\n cloneElement,\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { AriaButtonProps, mergeProps, useButton, useFocusRing, useKeyboard } from 'react-aria';\n\nexport interface DropdownSelectorProps extends AriaButtonProps {\n children: ReactNode;\n onSelect: (value: string) => void;\n label?: string;\n placeholder?: string;\n selectedValue?: string;\n size?: 'sm' | 'md' | 'lg';\n tooltipContent?: string;\n disabled?: boolean;\n viewMax?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n}\n\ninterface OptionData {\n value: string;\n label: string;\n}\n\nexport interface DropdownContextType {\n selectedOption: OptionData | null;\n setSelectedOption: (option: OptionData) => void;\n}\n\nconst SIZES = {\n sm: { caret: 16, check: 14, height: '2.625rem', top: 48, width: '0.75rem', mult: 2.25 },\n md: { caret: 17, check: 15, height: '2.8125rem', top: 52, width: '0.85rem', mult: 2.25 },\n lg: { caret: 18, check: 16, height: '3rem', top: 55, width: '1rem', mult: 2.5 },\n};\n\nconst DropdownContext = createContext<DropdownContextType>({\n selectedOption: null,\n setSelectedOption: () => {},\n});\n\nexport const DropdownOption = ({ value, label, size = 'lg', isFocused }: DropdownOptionProps) => {\n const { selectedOption, setSelectedOption } = useContext(DropdownContext);\n const isSelected = selectedOption?.value === value;\n const sizeProps = SIZES[size];\n\n const handleSelectOption = useCallback(() => {\n setSelectedOption({ value, label });\n }, [setSelectedOption, value, label]);\n\n return (\n <HStack\n py={1.5}\n gap={2}\n bg={isSelected ? 'brand.base' : isFocused ? 'brand.lightest' : ''}\n _hover={!isSelected ? { bg: 'brand.lightest' } : {}}\n onClick={handleSelectOption}\n style={{ paddingLeft: sizeProps.width, paddingRight: sizeProps.width }}\n >\n <Box style={{ minWidth: sizeProps.width }}>\n {isSelected && (\n <IcoCheckmark width={sizeProps.check} height={sizeProps.check} color={token('colors.text.quaternary')} />\n )}\n </Box>\n <Text\n size={size}\n fontWeight=\"medium\"\n fontColor={isSelected ? 'text.quaternary' : 'text.primary'}\n styles={{ textAlign: 'left' }}\n >\n {label}\n </Text>\n </HStack>\n );\n};\n\nexport const DropdownSelector = ({\n children,\n onSelect,\n label,\n placeholder = 'Select one',\n selectedValue,\n size = 'lg',\n tooltipContent,\n disabled,\n viewMax = 5,\n ...props\n}: DropdownSelectorProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const sizeProps = SIZES[size];\n const maxHeight = viewMax * sizeProps.mult + 1;\n\n const toggleDropdown = useCallback(() => {\n setIsOpen(prev => !prev);\n if (!isOpen) {\n setFocusedIndex(null);\n setTimeout(() => dropdownRef.current?.focus());\n }\n }, [isOpen]);\n\n const handleSelect = useCallback(\n (option: OptionData) => {\n onSelect(option.value);\n setIsOpen(false);\n },\n [onSelect],\n );\n\n const selectedLabel = useMemo(() => {\n const childElements = Children.toArray(children) as ReactElement<DropdownOptionProps>[];\n const matchedChild = childElements.find(child => child.props.value === selectedValue);\n return matchedChild ? matchedChild.props.label : placeholder;\n }, [selectedValue, children]);\n\n const { buttonProps } = useButton(\n {\n ...props,\n isDisabled: disabled,\n onPress: toggleDropdown,\n },\n buttonRef,\n );\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n const { keyboardProps } = useKeyboard({\n onKeyDown: event => {\n if (!isOpen) return;\n\n let newFocusedIndex = focusedIndex;\n const childArray = Children.toArray(children);\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(Children.count(children) - 1);\n } else {\n newFocusedIndex = focusedIndex > 0 ? focusedIndex - 1 : Children.count(children) - 1;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(0);\n } else {\n newFocusedIndex = focusedIndex < Children.count(children) - 1 ? focusedIndex + 1 : 0;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'Enter':\n event.preventDefault();\n buttonRef.current?.focus();\n if (focusedIndex === null) return;\n if (focusedIndex >= 0 && focusedIndex < childArray.length) {\n const selectedChild = childArray[focusedIndex] as ReactElement<DropdownOptionProps>;\n if (selectedChild) {\n onSelect(selectedChild.props.value);\n }\n }\n break;\n case 'Escape':\n setIsOpen(false);\n buttonRef.current?.focus();\n break;\n default:\n break;\n }\n },\n });\n\n useEffect(() => {\n const handleClick = (event: MouseEvent) => {\n if (!dropdownRef.current?.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClick);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n };\n }, []);\n\n return (\n <DropdownContext.Provider\n value={{ selectedOption: { value: selectedValue ?? '', label: selectedLabel }, setSelectedOption: handleSelect }}\n >\n <VStack gap={2} w=\"full\" alignItems=\"flex-start\">\n {(label || tooltipContent) && (\n <HStack gap={2} opacity={disabled ? 0.3 : ''} transition={'all linear 120ms'}>\n {label && (\n <Text size=\"sm\" fontWeight=\"medium\">\n {label}\n </Text>\n )}\n\n {tooltipContent && (\n <Tooltip isDisabled={disabled} content={tooltipContent}>\n <IcoQuestionCircleFill className={css({ w: 4, h: 4, color: 'neutral.primary' })} />\n </Tooltip>\n )}\n </HStack>\n )}\n\n <button\n className={css({\n w: 'full',\n h: 'fit-content',\n bg: 'surface.primary',\n borderWidth: 'thin',\n borderColor: 'neutral.secondary',\n rounded: 'xl',\n transition: 'all linear 120ms',\n position: 'relative',\n cursor: 'pointer',\n outlineColor: 'brand.base',\n outlineStyle: isFocusVisible ? 'solid' : 'none',\n outlineWidth: 'thick',\n outlineOffset: 0.5,\n _hover: { borderColor: 'neutral.primary' },\n _disabled: { opacity: 0.3, pointerEvents: 'none' },\n })}\n ref={buttonRef}\n {...mergeProps(buttonProps, focusProps, keyboardProps)}\n >\n <HStack w=\"full\" p={4} justifyContent=\"space-between\" style={{ height: sizeProps.height }}>\n <Text truncate size={size} fontColor={selectedValue ? 'text.primary' : 'text.tertiary'}>\n {selectedLabel}\n </Text>\n {isOpen ? (\n <IcoCaretUp width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n ) : (\n <IcoCaretDown width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n )}\n </HStack>\n\n {isOpen && (\n <Box\n ref={dropdownRef}\n tabIndex={-1}\n py={2}\n bg=\"surface.primary\"\n position=\"absolute\"\n w=\"full\"\n rounded=\"input\"\n boxShadow=\"4px 8px 20px 0px rgba(0, 0, 0, 0.15)\"\n style={{ maxHeight: `${maxHeight}rem`, top: sizeProps.top }}\n overflowY=\"auto\"\n outline=\"none\"\n zIndex=\"max\"\n >\n {Children.map(children, (child, index) =>\n cloneElement(child as ReactElement<DropdownOptionProps>, {\n isFocused: index === focusedIndex,\n size,\n }),\n )}\n </Box>\n )}\n </button>\n </VStack>\n </DropdownContext.Provider>\n );\n};\n\nDropdownOption.displayName = 'DropdownOption';\nDropdownSelector.displayName = 'DropdownSelector';\n"],"names":["SIZES","DropdownContext","createContext","DropdownOption","value","label","size","isFocused","selectedOption","setSelectedOption","useContext","isSelected","sizeProps","handleSelectOption","useCallback","_jsxs","HStack","_jsx","Box","IcoCheckmark","token","Text","DropdownSelector","children","onSelect","placeholder","selectedValue","tooltipContent","disabled","viewMax","props","isOpen","setIsOpen","useState","focusedIndex","setFocusedIndex","buttonRef","useRef","dropdownRef","maxHeight","toggleDropdown","prev","_a","handleSelect","option","selectedLabel","useMemo","matchedChild","Children","child","buttonProps","useButton","focusProps","isFocusVisible","useFocusRing","keyboardProps","useKeyboard","event","newFocusedIndex","childArray","selectedChild","_b","useEffect","handleClick","VStack","Tooltip","IcoQuestionCircleFill","css","mergeProps","IcoCaretUp","IcoCaretDown","index","cloneElement"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-selector.js","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"sourcesContent":["import { Tooltip } from '@components/feedback';\nimport { IcoCaretDown, IcoCaretUp, IcoCheckmark, IcoQuestionCircleFill } from '@components/icons';\nimport { Text } from '@components/primitives';\nimport { css } from '@styled/css';\nimport { Box, HStack, VStack } from '@styled/jsx';\nimport { token } from '@styled/tokens';\nimport {\n Children,\n cloneElement,\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { AriaButtonProps, mergeProps, useButton, useFocusRing, useKeyboard } from 'react-aria';\n\nexport interface DropdownSelectorProps extends AriaButtonProps {\n children: ReactNode;\n onSelect: (value: string) => void;\n label?: string;\n placeholder?: string;\n selectedValue?: string;\n size?: 'sm' | 'md' | 'lg';\n tooltipContent?: string;\n disabled?: boolean;\n viewMax?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n}\n\ninterface OptionData {\n value: string;\n label: string;\n}\n\nexport interface DropdownContextType {\n selectedOption: OptionData | null;\n setSelectedOption: (option: OptionData) => void;\n}\n\nconst SIZES = {\n sm: { caret: 16, check: 14, height: '2.625rem', top: 48, width: '0.75rem', mult: 2.25 },\n md: { caret: 17, check: 15, height: '2.8125rem', top: 52, width: '0.85rem', mult: 2.25 },\n lg: { caret: 18, check: 16, height: '3rem', top: 55, width: '1rem', mult: 2.5 },\n};\n\nconst DropdownContext = createContext<DropdownContextType>({\n selectedOption: null,\n setSelectedOption: () => {},\n});\n\nexport const DropdownOption = ({ value, label, size = 'lg', isFocused }: DropdownOptionProps) => {\n const { selectedOption, setSelectedOption } = useContext(DropdownContext);\n const isSelected = selectedOption?.value === value;\n const sizeProps = SIZES[size];\n\n const handleSelectOption = useCallback(() => {\n setSelectedOption({ value, label });\n }, [setSelectedOption, value, label]);\n\n return (\n <HStack\n py={1.5}\n gap={2}\n bg={isSelected ? 'brand.base' : isFocused ? 'brand.lightest' : ''}\n _hover={!isSelected ? { bg: 'brand.lightest' } : {}}\n onClick={handleSelectOption}\n style={{ paddingLeft: sizeProps.width, paddingRight: sizeProps.width }}\n >\n <Box style={{ minWidth: sizeProps.width }}>\n {isSelected && (\n <IcoCheckmark width={sizeProps.check} height={sizeProps.check} color={token('colors.text.quaternary')} />\n )}\n </Box>\n <Text\n size={size}\n fontWeight=\"medium\"\n fontColor={isSelected ? 'text.quaternary' : 'text.primary'}\n styles={{ textAlign: 'left' }}\n >\n {label}\n </Text>\n </HStack>\n );\n};\n\nexport const DropdownSelector = ({\n children,\n onSelect,\n label,\n placeholder = 'Select one',\n selectedValue,\n size = 'lg',\n tooltipContent,\n disabled,\n viewMax = 5,\n ...props\n}: DropdownSelectorProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const sizeProps = SIZES[size];\n const maxHeight = viewMax * sizeProps.mult + 1;\n\n const toggleDropdown = useCallback(() => {\n setIsOpen(prev => !prev);\n if (!isOpen) {\n setFocusedIndex(null);\n setTimeout(() => dropdownRef.current?.focus());\n }\n }, [isOpen]);\n\n const handleSelect = useCallback(\n (option: OptionData) => {\n onSelect(option.value);\n setIsOpen(false);\n },\n [onSelect],\n );\n\n const selectedLabel = useMemo(() => {\n const childElements = Children.toArray(children) as ReactElement<DropdownOptionProps>[];\n const matchedChild = childElements.find(child => child.props.value === selectedValue);\n return matchedChild ? matchedChild.props.label : placeholder;\n }, [selectedValue, children]);\n\n const { buttonProps } = useButton(\n {\n ...props,\n isDisabled: disabled,\n onPress: toggleDropdown,\n },\n buttonRef,\n );\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n const { keyboardProps } = useKeyboard({\n onKeyDown: event => {\n if (!isOpen) return;\n\n let newFocusedIndex = focusedIndex;\n const childArray = Children.toArray(children);\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(Children.count(children) - 1);\n } else {\n newFocusedIndex = focusedIndex > 0 ? focusedIndex - 1 : Children.count(children) - 1;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(0);\n } else {\n newFocusedIndex = focusedIndex < Children.count(children) - 1 ? focusedIndex + 1 : 0;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'Enter':\n event.preventDefault();\n buttonRef.current?.focus();\n if (focusedIndex === null) return;\n if (focusedIndex >= 0 && focusedIndex < childArray.length) {\n const selectedChild = childArray[focusedIndex] as ReactElement<DropdownOptionProps>;\n if (selectedChild) {\n onSelect(selectedChild.props.value);\n }\n }\n break;\n case 'Escape':\n setIsOpen(false);\n buttonRef.current?.focus();\n break;\n default:\n break;\n }\n },\n });\n\n useEffect(() => {\n const handleClick = (event: MouseEvent) => {\n if (!dropdownRef.current?.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClick);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n };\n }, []);\n\n return (\n <DropdownContext.Provider\n value={{ selectedOption: { value: selectedValue ?? '', label: selectedLabel }, setSelectedOption: handleSelect }}\n >\n <VStack gap={2} w=\"full\" alignItems=\"flex-start\">\n {(label || tooltipContent) && (\n <HStack gap={2} opacity={disabled ? 0.3 : ''} transition={'all linear 120ms'}>\n {label && (\n <Text size=\"sm\" fontWeight=\"medium\">\n {label}\n </Text>\n )}\n\n {tooltipContent && (\n <Tooltip content={tooltipContent}>\n <IcoQuestionCircleFill className={css({ w: 4, h: 4, color: 'neutral.primary' })} />\n </Tooltip>\n )}\n </HStack>\n )}\n\n <button\n className={css({\n w: 'full',\n h: 'fit-content',\n bg: 'surface.primary',\n borderWidth: 'thin',\n borderColor: 'neutral.secondary',\n rounded: 'xl',\n transition: 'all linear 120ms',\n position: 'relative',\n cursor: 'pointer',\n outlineColor: 'brand.base',\n outlineStyle: isFocusVisible ? 'solid' : 'none',\n outlineWidth: 'thick',\n outlineOffset: 0.5,\n _hover: { borderColor: 'neutral.primary' },\n _disabled: { opacity: 0.3, pointerEvents: 'none' },\n })}\n ref={buttonRef}\n {...mergeProps(buttonProps, focusProps, keyboardProps)}\n >\n <HStack w=\"full\" p={4} justifyContent=\"space-between\" style={{ height: sizeProps.height }}>\n <Text truncate size={size} fontColor={selectedValue ? 'text.primary' : 'text.tertiary'}>\n {selectedLabel}\n </Text>\n {isOpen ? (\n <IcoCaretUp width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n ) : (\n <IcoCaretDown width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n )}\n </HStack>\n\n {isOpen && (\n <Box\n ref={dropdownRef}\n tabIndex={-1}\n py={2}\n bg=\"surface.primary\"\n position=\"absolute\"\n w=\"full\"\n rounded=\"input\"\n boxShadow=\"4px 8px 20px 0px rgba(0, 0, 0, 0.15)\"\n style={{ maxHeight: `${maxHeight}rem`, top: sizeProps.top }}\n overflowY=\"auto\"\n outline=\"none\"\n zIndex=\"max\"\n >\n {Children.map(children, (child, index) =>\n cloneElement(child as ReactElement<DropdownOptionProps>, {\n isFocused: index === focusedIndex,\n size,\n }),\n )}\n </Box>\n )}\n </button>\n </VStack>\n </DropdownContext.Provider>\n );\n};\n\nDropdownOption.displayName = 'DropdownOption';\nDropdownSelector.displayName = 'DropdownSelector';\n"],"names":["SIZES","DropdownContext","createContext","DropdownOption","value","label","size","isFocused","selectedOption","setSelectedOption","useContext","isSelected","sizeProps","handleSelectOption","useCallback","_jsxs","HStack","_jsx","Box","IcoCheckmark","token","Text","DropdownSelector","children","onSelect","placeholder","selectedValue","tooltipContent","disabled","viewMax","props","isOpen","setIsOpen","useState","focusedIndex","setFocusedIndex","buttonRef","useRef","dropdownRef","maxHeight","toggleDropdown","prev","_a","handleSelect","option","selectedLabel","useMemo","matchedChild","Children","child","buttonProps","useButton","focusProps","isFocusVisible","useFocusRing","keyboardProps","useKeyboard","event","newFocusedIndex","childArray","selectedChild","_b","useEffect","handleClick","VStack","Tooltip","IcoQuestionCircleFill","css","mergeProps","IcoCaretUp","IcoCaretDown","index","cloneElement"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react/jsx-runtime"),T=require("./button.js");require("./checkbox.js"),require("./dropdown-selector.js"),require("./radio.js"),require("./segmented-control.js"),require("./switch.js"),require("./text.js");var K=require("../../hooks/useToggleState.js"),G=require("@styled/css"),g=require("@styled/jsx"),Z=require("@styled/patterns"),J=require("@styled/tokens"),v=require("create-slots"),n=require("react"),c=require("react-aria");const A="bottom left",I=8,Q="hover",O=v.createSlot(({children:l})=>t.jsx(t.Fragment,{children:l})),R=v.createSlot(({children:l,...e})=>t.jsx(g.Center,{children:n.Children.map(l,o=>n.cloneElement(o,e))})),_=v.createSlot(({children:l,...e})=>t.jsx(g.Center,{children:n.Children.map(l,o=>n.cloneElement(o,e))})),D=v.createSlot(({children:l,...e})=>t.jsx(g.Center,{children:n.Children.map(l,o=>n.cloneElement(o,e))})),N=({children:l,...e})=>v.createHost(l,o=>{var E;const{isSelected:B,setSelected:P}=K.useToggleState({isOpen:e.isOpen,defaultSelected:e.defaultOpen,onChange:e.onOpenChange,...e}),h=e.isOpen!==void 0?e.isOpen:B,i=24,S=e.trigger||Q,s=n.useMemo(()=>({isOpen:h,open:()=>{P(!0)},close:()=>{P(!1)},setOpen(r){P(r)},toggle(){}}),[h]),F=o.getProps(O),a=n.useRef(null),{triggerProps:L,overlayProps:H}=c.useOverlayTrigger({type:"dialog"},s,a),d=n.useRef(null),{popoverProps:M,underlayProps:U}=c.usePopover({placement:A,offset:I,popoverRef:d,triggerRef:a,...F},s),m=c.mergeProps(F,M);!((E=m?.style)===null||E===void 0)&&E.zIndex&&(m.style.zIndex=J.token("zIndex.max"));const k=n.useCallback(()=>{s.open()},[s]),j=n.useCallback(r=>{var q,C;const u=(q=a.current)===null||q===void 0?void 0:q.getBoundingClientRect(),p=(C=d.current)===null||C===void 0?void 0:C.getBoundingClientRect();if(u&&p){const z=r.clientX>=u.left-i&&r.clientX<=u.right+i&&r.clientY>=u.top-i&&r.clientY<=u.bottom+i,W=r.clientX>=p.left-i&&r.clientX<=p.right+i&&r.clientY>=p.top-i&&r.clientY<=p.bottom+i;!z&&!W&&s.close()}},[s]),X=()=>{if(d.current){const r=d.current.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');r.length>0&&r[0].focus()}},Y=r=>{r.key==="Enter"&&(r.preventDefault(),h?s.close():(s.open(),setTimeout(X,0)))};n.useEffect(()=>(document.addEventListener("mousemove",j),()=>{document.removeEventListener("mousemove",j)}),[j]);const x=e.size==="sm"?16:24,f=o.get(R),b=o.get(_),y=o.get(D);return t.jsxs(t.Fragment,{children:[f?t.jsx(g.Box,{display:"inline-block",ref:a,...c.mergeProps(L,e),children:f&&{...f,props:{...f.props}}}):t.jsx(g.Box,{display:"inline-block",ref:a,children:t.jsxs(T.default,{...c.mergeProps(L,e),onKeyDown:Y,onHover:()=>S==="hover"&&k(),onPress:()=>S==="click"&&k(),children:[b&&t.jsx(T.default.LeadingIcon,{children:b&&{...b,props:{...b.props,width:x,height:x}}}),y&&t.jsx(T.default.TrailingIcon,{children:y&&{...y,props:{...y.props,width:x,height:x}}})]})}),h&&t.jsxs(c.Overlay,{...H,children:[t.jsx("div",{...U,className:"underlay"}),t.jsx("div",{ref:d,...m,className:G.cx(Z.vstack({bg:"surface.primary",p:3,gap:0,color:"text.secondary",borderWidth:1,borderColor:"neutral.secondary",borderRadius:"xl",boxShadow:"0px 4px 20px 0px rgba(0, 0, 0, 0.10)",maxW:52,alignItems:"start"}),m.className),children:o.get(O)})]})]})}),w=Object.assign(N,{Trigger:R,LeadingIcon:_,TrailingIcon:D,Content:O});exports.DEFAULT_OFFSET=I,exports.DEFAULT_PLACEMENT=A,exports.Popover=w,exports.PopoverHost=N,exports.default=w;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var r=require("react/jsx-runtime"),S=require("./button.js");require("./checkbox.js"),require("./dropdown-selector.js"),require("./radio.js"),require("./segmented-control.js"),require("./switch.js"),require("./text.js");var V=require("../../hooks/useToggleState.js"),Z=require("@styled/css"),v=require("@styled/jsx"),$=require("@styled/patterns"),ee=require("@styled/tokens"),h=require("create-slots"),t=require("react"),m=require("react-aria");const R="bottom left",_=8,re="hover",O=h.createSlot(({children:o})=>r.jsx(r.Fragment,{children:o})),z=h.createSlot(({children:o,...l})=>{const{onPress:n,...a}=l;return r.jsx(v.Center,{children:t.Children.map(o,c=>t.cloneElement(c,a))})}),D=h.createSlot(({children:o,...l})=>r.jsx(v.Center,{children:t.Children.map(o,n=>t.cloneElement(n,l))})),w=h.createSlot(({children:o,...l})=>r.jsx(v.Center,{children:t.Children.map(o,n=>t.cloneElement(n,l))})),H=({children:o,...l})=>h.createHost(o,n=>{var a;const{isOpen:c,defaultOpen:N,onOpenChange:U,trigger:F=re,iconSize:te,onPress:ne,...L}=l,{isSelected:X,setSelected:y}=V.useToggleState({isOpen:c,defaultSelected:N,onChange:U,...l}),E=c!==void 0?c:X,s=24,i=t.useMemo(()=>({isOpen:E,open:()=>{y(!0)},close:()=>{y(!1)},setOpen(e){y(e)},toggle(){}}),[E]),k=n.getProps(O),d=t.useRef(null),{triggerProps:A,overlayProps:Y}=m.useOverlayTrigger({type:"dialog"},i,d),u=t.useRef(null),{popoverProps:B,underlayProps:W}=m.usePopover({placement:R,offset:_,popoverRef:u,triggerRef:d,...k},i),x=m.mergeProps(k,B);!((a=x?.style)===null||a===void 0)&&a.zIndex&&(x.style.zIndex=ee.token("zIndex.max"));const I=t.useCallback(()=>{i.open()},[i]),j=t.useCallback(e=>{var C,T;const p=(C=d.current)===null||C===void 0?void 0:C.getBoundingClientRect(),g=(T=u.current)===null||T===void 0?void 0:T.getBoundingClientRect();if(p&&g){const J=e.clientX>=p.left-s&&e.clientX<=p.right+s&&e.clientY>=p.top-s&&e.clientY<=p.bottom+s,Q=e.clientX>=g.left-s&&e.clientX<=g.right+s&&e.clientY>=g.top-s&&e.clientY<=g.bottom+s;!J&&!Q&&i.close()}},[i]),K=()=>{if(u.current){const e=u.current.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');e.length>0&&e[0].focus()}},G=e=>{e.key==="Enter"&&(e.preventDefault(),c?i.close():(i.open(),setTimeout(K,0)))};t.useEffect(()=>(document.addEventListener("mousemove",j),()=>{document.removeEventListener("mousemove",j)}),[j]);const f=l.size==="sm"?16:24,b=n.get(z),P=n.get(D),q=n.get(w);return r.jsxs(r.Fragment,{children:[b?r.jsx(v.Box,{display:"inline-block",ref:d,...L,children:b&&{...b,props:{...b.props,...A}}}):r.jsx(v.Box,{display:"inline-block",ref:d,children:r.jsxs(S.default,{...m.mergeProps(A,L),onKeyDown:G,onHover:()=>F==="hover"&&I(),onPress:()=>F==="click"&&I(),children:[P&&r.jsx(S.default.LeadingIcon,{children:P&&{...P,props:{...P.props,width:f,height:f}}}),q&&r.jsx(S.default.TrailingIcon,{children:q&&{...q,props:{...q.props,width:f,height:f}}})]})}),E&&r.jsxs(m.Overlay,{...Y,children:[r.jsx("div",{...W,className:"underlay"}),r.jsx("div",{ref:u,...x,className:Z.cx($.vstack({bg:"surface.primary",p:3,gap:0,color:"text.secondary",borderWidth:1,borderColor:"neutral.secondary",borderRadius:"xl",boxShadow:"0px 4px 20px 0px rgba(0, 0, 0, 0.10)",maxW:52,alignItems:"start"}),x.className),children:n.get(O)})]})]})}),M=Object.assign(H,{Trigger:z,LeadingIcon:D,TrailingIcon:w,Content:O});exports.DEFAULT_OFFSET=_,exports.DEFAULT_PLACEMENT=R,exports.Popover=M,exports.PopoverHost=H,exports.default=M;
2
2
  //# sourceMappingURL=popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sources":["../../../../src/components/primitives/popover.tsx"],"sourcesContent":["import { Button, ButtonProps } from '@components/primitives';\nimport { useToggleState } from '@hooks/useToggleState';\nimport { cx } from '@styled/css';\nimport { Box, Center } from '@styled/jsx';\nimport { vstack } from '@styled/patterns';\nimport { token } from '@styled/tokens';\nimport { createHost, createSlot } from 'create-slots';\nimport {\n Children,\n ComponentProps,\n PropsWithChildren,\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport type { AriaPopoverProps, Placement } from 'react-aria';\nimport { Overlay, mergeProps, useOverlayTrigger, usePopover } from 'react-aria';\n\ninterface OverlayTriggerProps extends ButtonProps {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n trigger?: 'click' | 'hover';\n}\n\ninterface OverlayTriggerState {\n readonly isOpen: boolean;\n setOpen(isOpen: boolean): void;\n open(): void;\n close(): void;\n toggle(): void;\n}\n\ntype PopoverContentProps = Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef'> & {\n children?: ReactNode;\n state?: OverlayTriggerState;\n} & ComponentProps<'div'>;\n\nexport const DEFAULT_PLACEMENT: Placement = 'bottom left';\nexport const DEFAULT_OFFSET = 8;\n\nconst DEFAULT_TRIGGER: string = 'hover';\n\nconst PopoverContent = createSlot(({ children }: PopoverContentProps) => <>{children}</>);\n\nconst Trigger = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst LeadingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst TrailingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nexport type PopoverProps = PropsWithChildren<OverlayTriggerProps>;\n\nexport const PopoverHost = ({ children, ...props }: PopoverProps) => {\n return createHost(children, slots => {\n const { isSelected, setSelected: setOpen } = useToggleState({\n isOpen: props.isOpen,\n defaultSelected: props.defaultOpen,\n onChange: props.onOpenChange,\n ...props,\n });\n\n const isOpen = props.isOpen !== undefined ? props.isOpen : isSelected;\n const safeZoneRadius = 24;\n const trigger = props.trigger || DEFAULT_TRIGGER;\n\n const state = useMemo(\n () => ({\n isOpen,\n open: () => {\n setOpen(true);\n },\n close: () => {\n setOpen(false);\n },\n setOpen(value: boolean) {\n setOpen(value);\n },\n toggle() {},\n }),\n [isOpen],\n );\n\n const popoverContentProps = slots.getProps(PopoverContent);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const { triggerProps, overlayProps } = useOverlayTrigger({ type: 'dialog' }, state, triggerRef);\n\n const contentRef = useRef<HTMLDivElement>(null);\n const { popoverProps, underlayProps } = usePopover(\n {\n placement: DEFAULT_PLACEMENT,\n offset: DEFAULT_OFFSET,\n popoverRef: contentRef,\n triggerRef,\n ...popoverContentProps,\n },\n state,\n );\n\n const contentProps = mergeProps(popoverContentProps, popoverProps);\n\n // Need to override zIndex set by react-aria so popover displays over iframe\n if (contentProps?.style?.zIndex) {\n contentProps.style.zIndex = token('zIndex.max');\n }\n\n const handleTrigger = useCallback(() => {\n state.open();\n }, [state]);\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent) => {\n const buttonRect = triggerRef.current?.getBoundingClientRect();\n const popoverRect = contentRef.current?.getBoundingClientRect();\n\n if (buttonRect && popoverRect) {\n const withinButtonSafeZone =\n event.clientX >= buttonRect.left - safeZoneRadius &&\n event.clientX <= buttonRect.right + safeZoneRadius &&\n event.clientY >= buttonRect.top - safeZoneRadius &&\n event.clientY <= buttonRect.bottom + safeZoneRadius;\n\n const withinPopoverSafeZone =\n event.clientX >= popoverRect.left - safeZoneRadius &&\n event.clientX <= popoverRect.right + safeZoneRadius &&\n event.clientY >= popoverRect.top - safeZoneRadius &&\n event.clientY <= popoverRect.bottom + safeZoneRadius;\n\n if (!withinButtonSafeZone && !withinPopoverSafeZone) {\n state.close();\n }\n }\n },\n [state],\n );\n\n const focusFirstInteractiveElement = () => {\n if (contentRef.current) {\n const interactiveElements = contentRef.current.querySelectorAll(\n 'a, button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (interactiveElements.length > 0) {\n (interactiveElements[0] as HTMLElement).focus();\n }\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (isOpen) {\n state.close();\n } else {\n state.open();\n setTimeout(focusFirstInteractiveElement, 0);\n }\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousemove', handleMouseLeave);\n return () => {\n document.removeEventListener('mousemove', handleMouseLeave);\n };\n }, [handleMouseLeave]);\n\n const iconSize = props.size === 'sm' ? 16 : 24;\n const triggerEle = slots.get(Trigger);\n const leadingIcon = slots.get(LeadingIcon);\n const trailingIcon = slots.get(TrailingIcon);\n\n return (\n <>\n {triggerEle ? (\n <Box display=\"inline-block\" ref={triggerRef} {...mergeProps(triggerProps, props)}>\n {triggerEle && { ...triggerEle, props: { ...triggerEle.props } }}\n </Box>\n ) : (\n <Box display=\"inline-block\" ref={triggerRef}>\n <Button\n {...mergeProps(triggerProps, props)}\n onKeyDown={handleKeyDown}\n onHover={() => trigger === 'hover' && handleTrigger()}\n onPress={() => trigger === 'click' && handleTrigger()}\n >\n {leadingIcon && (\n <Button.LeadingIcon>\n {leadingIcon && {\n ...leadingIcon,\n props: { ...leadingIcon.props, width: iconSize, height: iconSize },\n }}\n </Button.LeadingIcon>\n )}\n {trailingIcon && (\n <Button.TrailingIcon>\n {trailingIcon && {\n ...trailingIcon,\n props: { ...trailingIcon.props, width: iconSize, height: iconSize },\n }}\n </Button.TrailingIcon>\n )}\n </Button>\n </Box>\n )}\n {isOpen && (\n <Overlay {...overlayProps}>\n <div {...underlayProps} className=\"underlay\" />\n <div\n ref={contentRef}\n {...contentProps}\n className={cx(\n vstack({\n bg: 'surface.primary',\n p: 3,\n gap: 0,\n color: 'text.secondary',\n borderWidth: 1,\n borderColor: 'neutral.secondary',\n borderRadius: 'xl',\n boxShadow: '0px 4px 20px 0px rgba(0, 0, 0, 0.10)',\n maxW: 52,\n alignItems: 'start',\n }),\n contentProps.className,\n )}\n >\n {slots.get(PopoverContent)}\n </div>\n </Overlay>\n )}\n </>\n );\n });\n};\n\nexport const Popover = Object.assign(PopoverHost, {\n Trigger,\n LeadingIcon,\n TrailingIcon,\n Content: PopoverContent,\n});\n\nexport default Popover;\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET","DEFAULT_TRIGGER","PopoverContent","createSlot","children","_jsx","_Fragment","Trigger","props","Center","Children","child","cloneElement","LeadingIcon","TrailingIcon","PopoverHost","createHost","slots","isSelected","setOpen","useToggleState","isOpen","safeZoneRadius","trigger","state","useMemo","value","popoverContentProps","triggerRef","useRef","triggerProps","overlayProps","useOverlayTrigger","contentRef","popoverProps","underlayProps","usePopover","contentProps","mergeProps","_a","token","handleTrigger","useCallback","handleMouseLeave","event","buttonRect","popoverRect","_b","withinButtonSafeZone","withinPopoverSafeZone","focusFirstInteractiveElement","interactiveElements","handleKeyDown","useEffect","iconSize","triggerEle","leadingIcon","trailingIcon","_jsxs","Box","Button","Overlay","cx","vstack","Popover"],"mappings":"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"}
1
+ {"version":3,"file":"popover.js","sources":["../../../../src/components/primitives/popover.tsx"],"sourcesContent":["import { Button, ButtonProps } from '@components/primitives';\nimport { useToggleState } from '@hooks/useToggleState';\nimport { cx } from '@styled/css';\nimport { Box, Center } from '@styled/jsx';\nimport { vstack } from '@styled/patterns';\nimport { token } from '@styled/tokens';\nimport { createHost, createSlot } from 'create-slots';\nimport {\n Children,\n ComponentProps,\n PropsWithChildren,\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport type { AriaPopoverProps, Placement } from 'react-aria';\nimport { Overlay, mergeProps, useOverlayTrigger, usePopover } from 'react-aria';\n\ninterface OverlayTriggerProps extends ButtonProps {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n trigger?: 'click' | 'hover';\n}\n\ninterface OverlayTriggerState {\n readonly isOpen: boolean;\n setOpen(isOpen: boolean): void;\n open(): void;\n close(): void;\n toggle(): void;\n}\n\ntype PopoverContentProps = Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef'> & {\n children?: ReactNode;\n state?: OverlayTriggerState;\n} & ComponentProps<'div'>;\n\nexport const DEFAULT_PLACEMENT: Placement = 'bottom left';\nexport const DEFAULT_OFFSET = 8;\n\nconst DEFAULT_TRIGGER: string = 'hover';\n\nconst PopoverContent = createSlot(({ children }: PopoverContentProps) => <>{children}</>);\n\nconst Trigger = createSlot(({ children, ...props }) => {\n const { onPress, ...restProps } = props;\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, restProps);\n })}\n </Center>\n );\n});\n\nconst LeadingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst TrailingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nexport type PopoverProps = PropsWithChildren<OverlayTriggerProps>;\n\nexport const PopoverHost = ({ children, ...props }: PopoverProps) => {\n return createHost(children, slots => {\n const { isOpen, defaultOpen, onOpenChange, trigger = DEFAULT_TRIGGER, iconSize, onPress, ...restProps } = props;\n const { isSelected, setSelected: setOpen } = useToggleState({\n isOpen: isOpen,\n defaultSelected: defaultOpen,\n onChange: onOpenChange,\n ...props,\n });\n\n const isPopoverOpen = isOpen !== undefined ? isOpen : isSelected;\n const safeZoneRadius = 24;\n\n const state = useMemo(\n () => ({\n isOpen: isPopoverOpen,\n open: () => {\n setOpen(true);\n },\n close: () => {\n setOpen(false);\n },\n setOpen(value: boolean) {\n setOpen(value);\n },\n toggle() {},\n }),\n [isPopoverOpen],\n );\n\n const popoverContentProps = slots.getProps(PopoverContent);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const { triggerProps, overlayProps } = useOverlayTrigger({ type: 'dialog' }, state, triggerRef);\n\n const contentRef = useRef<HTMLDivElement>(null);\n const { popoverProps, underlayProps } = usePopover(\n {\n placement: DEFAULT_PLACEMENT,\n offset: DEFAULT_OFFSET,\n popoverRef: contentRef,\n triggerRef,\n ...popoverContentProps,\n },\n state,\n );\n\n const contentProps = mergeProps(popoverContentProps, popoverProps);\n\n // Need to override zIndex set by react-aria so popover displays over iframe\n if (contentProps?.style?.zIndex) {\n contentProps.style.zIndex = token('zIndex.max');\n }\n\n const handleTrigger = useCallback(() => {\n state.open();\n }, [state]);\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent) => {\n const buttonRect = triggerRef.current?.getBoundingClientRect();\n const popoverRect = contentRef.current?.getBoundingClientRect();\n\n if (buttonRect && popoverRect) {\n const withinButtonSafeZone =\n event.clientX >= buttonRect.left - safeZoneRadius &&\n event.clientX <= buttonRect.right + safeZoneRadius &&\n event.clientY >= buttonRect.top - safeZoneRadius &&\n event.clientY <= buttonRect.bottom + safeZoneRadius;\n\n const withinPopoverSafeZone =\n event.clientX >= popoverRect.left - safeZoneRadius &&\n event.clientX <= popoverRect.right + safeZoneRadius &&\n event.clientY >= popoverRect.top - safeZoneRadius &&\n event.clientY <= popoverRect.bottom + safeZoneRadius;\n\n if (!withinButtonSafeZone && !withinPopoverSafeZone) {\n state.close();\n }\n }\n },\n [state],\n );\n\n const focusFirstInteractiveElement = () => {\n if (contentRef.current) {\n const interactiveElements = contentRef.current.querySelectorAll(\n 'a, button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (interactiveElements.length > 0) {\n (interactiveElements[0] as HTMLElement).focus();\n }\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (isOpen) {\n state.close();\n } else {\n state.open();\n setTimeout(focusFirstInteractiveElement, 0);\n }\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousemove', handleMouseLeave);\n return () => {\n document.removeEventListener('mousemove', handleMouseLeave);\n };\n }, [handleMouseLeave]);\n\n const size = props.size === 'sm' ? 16 : 24;\n const triggerEle = slots.get(Trigger);\n const leadingIcon = slots.get(LeadingIcon);\n const trailingIcon = slots.get(TrailingIcon);\n\n return (\n <>\n {triggerEle ? (\n <Box display=\"inline-block\" ref={triggerRef} {...restProps}>\n {triggerEle && { ...triggerEle, props: { ...triggerEle.props, ...triggerProps } }}\n </Box>\n ) : (\n <Box display=\"inline-block\" ref={triggerRef}>\n <Button\n {...mergeProps(triggerProps, restProps)}\n onKeyDown={handleKeyDown}\n onHover={() => trigger === 'hover' && handleTrigger()}\n onPress={() => trigger === 'click' && handleTrigger()}\n >\n {leadingIcon && (\n <Button.LeadingIcon>\n {leadingIcon && {\n ...leadingIcon,\n props: { ...leadingIcon.props, width: size, height: size },\n }}\n </Button.LeadingIcon>\n )}\n {trailingIcon && (\n <Button.TrailingIcon>\n {trailingIcon && {\n ...trailingIcon,\n props: { ...trailingIcon.props, width: size, height: size },\n }}\n </Button.TrailingIcon>\n )}\n </Button>\n </Box>\n )}\n {isPopoverOpen && (\n <Overlay {...overlayProps}>\n <div {...underlayProps} className=\"underlay\" />\n <div\n ref={contentRef}\n {...contentProps}\n className={cx(\n vstack({\n bg: 'surface.primary',\n p: 3,\n gap: 0,\n color: 'text.secondary',\n borderWidth: 1,\n borderColor: 'neutral.secondary',\n borderRadius: 'xl',\n boxShadow: '0px 4px 20px 0px rgba(0, 0, 0, 0.10)',\n maxW: 52,\n alignItems: 'start',\n }),\n contentProps.className,\n )}\n >\n {slots.get(PopoverContent)}\n </div>\n </Overlay>\n )}\n </>\n );\n });\n};\n\nexport const Popover = Object.assign(PopoverHost, {\n Trigger,\n LeadingIcon,\n TrailingIcon,\n Content: PopoverContent,\n});\n\nexport default Popover;\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET","DEFAULT_TRIGGER","PopoverContent","createSlot","children","_jsx","_Fragment","Trigger","props","onPress","restProps","Center","Children","child","cloneElement","LeadingIcon","TrailingIcon","PopoverHost","createHost","slots","isOpen","defaultOpen","onOpenChange","trigger","iconSize","isSelected","setOpen","useToggleState","isPopoverOpen","safeZoneRadius","state","useMemo","value","popoverContentProps","triggerRef","useRef","triggerProps","overlayProps","useOverlayTrigger","contentRef","popoverProps","underlayProps","usePopover","contentProps","mergeProps","_a","token","handleTrigger","useCallback","handleMouseLeave","event","buttonRect","popoverRect","_b","withinButtonSafeZone","withinPopoverSafeZone","focusFirstInteractiveElement","interactiveElements","handleKeyDown","useEffect","size","triggerEle","leadingIcon","trailingIcon","_jsxs","Box","Button","Overlay","cx","vstack","Popover"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsxs as b,jsx as o}from"react/jsx-runtime";import"../feedback/callout.js";import{css as W}from"@styled/css";import{HStack as C,Box as A,VStack as $}from"@styled/jsx";import"../feedback/progress-bar.js";import{token as S}from"@styled/tokens";import U from"../icons/ico-caret-down.js";import Y from"../icons/ico-caret-up.js";import G from"../icons/ico-checkmark.js";import J from"../icons/ico-question-circle-fill.js";import"./button.js";import"./checkbox.js";import"./popover.js";import"./radio.js";import"./segmented-control.js";import"./switch.js";import D from"./text.js";import"./portal.js";import{createContext as Q,useContext as X,useCallback as O,useState as N,useRef as B,useMemo as Z,Children as m,useEffect as ee,cloneElement as te}from"react";import"../../hooks/useToast.js";import"../../recipes/toast.js";import re from"../feedback/tooltip.js";import{useButton as oe,useFocusRing as le,useKeyboard as ne,mergeProps as ie}from"react-aria";const F={sm:{caret:16,check:14,height:"2.625rem",top:48,width:"0.75rem",mult:2.25},md:{caret:17,check:15,height:"2.8125rem",top:52,width:"0.85rem",mult:2.25},lg:{caret:18,check:16,height:"3rem",top:55,width:"1rem",mult:2.5}},R=Q({selectedOption:null,setSelectedOption:()=>{}}),_=({value:r,label:s,size:u="lg",isFocused:y})=>{const{selectedOption:d,setSelectedOption:p}=X(R),i=d?.value===r,l=F[u],x=O(()=>{p({value:r,label:s})},[p,r,s]);return b(C,{py:1.5,gap:2,bg:i?"brand.base":y?"brand.lightest":"",_hover:i?{}:{bg:"brand.lightest"},onClick:x,style:{paddingLeft:l.width,paddingRight:l.width},children:[o(A,{style:{minWidth:l.width},children:i&&o(G,{width:l.check,height:l.check,color:S("colors.text.quaternary")})}),o(D,{size:u,fontWeight:"medium",fontColor:i?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:s})]})},j=({children:r,onSelect:s,label:u,placeholder:y="Select one",selectedValue:d,size:p="lg",tooltipContent:i,disabled:l,viewMax:x=5,...q})=>{const[h,g]=N(!1),[t,f]=N(null),v=B(null),k=B(null),a=F[p],H=x*a.mult+1,I=O(()=>{g(e=>!e),h||(f(null),setTimeout(()=>{var e;return(e=k.current)===null||e===void 0?void 0:e.focus()}))},[h]),K=O(e=>{s(e.value),g(!1)},[s]),z=Z(()=>{const e=m.toArray(r).find(n=>n.props.value===d);return e?e.props.label:y},[d,r]),{buttonProps:L}=oe({...q,isDisabled:l,onPress:I},v),{focusProps:V,isFocusVisible:M}=le(),{keyboardProps:T}=ne({onKeyDown:e=>{var n,c;if(!h)return;let w=t;const E=m.toArray(r);switch(e.key){case"ArrowUp":e.preventDefault(),t===null?f(m.count(r)-1):(w=t>0?t-1:m.count(r)-1,f(w));break;case"ArrowDown":e.preventDefault(),t===null?f(0):(w=t<m.count(r)-1?t+1:0,f(w));break;case"Enter":if(e.preventDefault(),(n=v.current)===null||n===void 0||n.focus(),t===null)return;if(t>=0&&t<E.length){const P=E[t];P&&s(P.props.value)}break;case"Escape":g(!1),(c=v.current)===null||c===void 0||c.focus();break}}});return ee(()=>{const e=n=>{var c;!((c=k.current)===null||c===void 0)&&c.contains(n.target)||g(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),o(R.Provider,{value:{selectedOption:{value:d??"",label:z},setSelectedOption:K},children:b($,{gap:2,w:"full",alignItems:"flex-start",children:[(u||i)&&b(C,{gap:2,opacity:l?.3:"",transition:"all linear 120ms",children:[u&&o(D,{size:"sm",fontWeight:"medium",children:u}),i&&o(re,{isDisabled:l,content:i,children:o(J,{className:W({w:4,h:4,color:"neutral.primary"})})})]}),b("button",{className:W({w:"full",h:"fit-content",bg:"surface.primary",borderWidth:"thin",borderColor:"neutral.secondary",rounded:"xl",transition:"all linear 120ms",position:"relative",cursor:"pointer",outlineColor:"brand.base",outlineStyle:M?"solid":"none",outlineWidth:"thick",outlineOffset:.5,_hover:{borderColor:"neutral.primary"},_disabled:{opacity:.3,pointerEvents:"none"}}),ref:v,...ie(L,V,T),children:[b(C,{w:"full",p:4,justifyContent:"space-between",style:{height:a.height},children:[o(D,{truncate:!0,size:p,fontColor:d?"text.primary":"text.tertiary",children:z}),h?o(Y,{width:a.caret,height:a.caret,color:S("colors.brand.base")}):o(U,{width:a.caret,height:a.caret,color:S("colors.brand.base")})]}),h&&o(A,{ref:k,tabIndex:-1,py:2,bg:"surface.primary",position:"absolute",w:"full",rounded:"input",boxShadow:"4px 8px 20px 0px rgba(0, 0, 0, 0.15)",style:{maxHeight:`${H}rem`,top:a.top},overflowY:"auto",outline:"none",zIndex:"max",children:m.map(r,(e,n)=>te(e,{isFocused:n===t,size:p}))})]})]})})};_.displayName="DropdownOption",j.displayName="DropdownSelector";export{_ as DropdownOption,j as DropdownSelector};
1
+ import{jsxs as b,jsx as o}from"react/jsx-runtime";import"../feedback/callout.js";import{css as W}from"@styled/css";import{HStack as C,Box as A,VStack as $}from"@styled/jsx";import"../feedback/progress-bar.js";import{token as S}from"@styled/tokens";import U from"../icons/ico-caret-down.js";import Y from"../icons/ico-caret-up.js";import G from"../icons/ico-checkmark.js";import J from"../icons/ico-question-circle-fill.js";import"./button.js";import"./checkbox.js";import"./popover.js";import"./radio.js";import"./segmented-control.js";import"./switch.js";import D from"./text.js";import"./portal.js";import{createContext as Q,useContext as X,useCallback as O,useState as N,useRef as B,useMemo as Z,Children as m,useEffect as ee,cloneElement as te}from"react";import"../../hooks/useToast.js";import"../../recipes/toast.js";import re from"../feedback/tooltip.js";import{useButton as oe,useFocusRing as ne,useKeyboard as ie,mergeProps as le}from"react-aria";const F={sm:{caret:16,check:14,height:"2.625rem",top:48,width:"0.75rem",mult:2.25},md:{caret:17,check:15,height:"2.8125rem",top:52,width:"0.85rem",mult:2.25},lg:{caret:18,check:16,height:"3rem",top:55,width:"1rem",mult:2.5}},R=Q({selectedOption:null,setSelectedOption:()=>{}}),_=({value:r,label:s,size:u="lg",isFocused:y})=>{const{selectedOption:d,setSelectedOption:p}=X(R),i=d?.value===r,l=F[u],x=O(()=>{p({value:r,label:s})},[p,r,s]);return b(C,{py:1.5,gap:2,bg:i?"brand.base":y?"brand.lightest":"",_hover:i?{}:{bg:"brand.lightest"},onClick:x,style:{paddingLeft:l.width,paddingRight:l.width},children:[o(A,{style:{minWidth:l.width},children:i&&o(G,{width:l.check,height:l.check,color:S("colors.text.quaternary")})}),o(D,{size:u,fontWeight:"medium",fontColor:i?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:s})]})},j=({children:r,onSelect:s,label:u,placeholder:y="Select one",selectedValue:d,size:p="lg",tooltipContent:i,disabled:l,viewMax:x=5,...q})=>{const[h,g]=N(!1),[t,f]=N(null),v=B(null),k=B(null),a=F[p],H=x*a.mult+1,I=O(()=>{g(e=>!e),h||(f(null),setTimeout(()=>{var e;return(e=k.current)===null||e===void 0?void 0:e.focus()}))},[h]),K=O(e=>{s(e.value),g(!1)},[s]),z=Z(()=>{const e=m.toArray(r).find(n=>n.props.value===d);return e?e.props.label:y},[d,r]),{buttonProps:L}=oe({...q,isDisabled:l,onPress:I},v),{focusProps:V,isFocusVisible:M}=ne(),{keyboardProps:T}=ie({onKeyDown:e=>{var n,c;if(!h)return;let w=t;const E=m.toArray(r);switch(e.key){case"ArrowUp":e.preventDefault(),t===null?f(m.count(r)-1):(w=t>0?t-1:m.count(r)-1,f(w));break;case"ArrowDown":e.preventDefault(),t===null?f(0):(w=t<m.count(r)-1?t+1:0,f(w));break;case"Enter":if(e.preventDefault(),(n=v.current)===null||n===void 0||n.focus(),t===null)return;if(t>=0&&t<E.length){const P=E[t];P&&s(P.props.value)}break;case"Escape":g(!1),(c=v.current)===null||c===void 0||c.focus();break}}});return ee(()=>{const e=n=>{var c;!((c=k.current)===null||c===void 0)&&c.contains(n.target)||g(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),o(R.Provider,{value:{selectedOption:{value:d??"",label:z},setSelectedOption:K},children:b($,{gap:2,w:"full",alignItems:"flex-start",children:[(u||i)&&b(C,{gap:2,opacity:l?.3:"",transition:"all linear 120ms",children:[u&&o(D,{size:"sm",fontWeight:"medium",children:u}),i&&o(re,{content:i,children:o(J,{className:W({w:4,h:4,color:"neutral.primary"})})})]}),b("button",{className:W({w:"full",h:"fit-content",bg:"surface.primary",borderWidth:"thin",borderColor:"neutral.secondary",rounded:"xl",transition:"all linear 120ms",position:"relative",cursor:"pointer",outlineColor:"brand.base",outlineStyle:M?"solid":"none",outlineWidth:"thick",outlineOffset:.5,_hover:{borderColor:"neutral.primary"},_disabled:{opacity:.3,pointerEvents:"none"}}),ref:v,...le(L,V,T),children:[b(C,{w:"full",p:4,justifyContent:"space-between",style:{height:a.height},children:[o(D,{truncate:!0,size:p,fontColor:d?"text.primary":"text.tertiary",children:z}),h?o(Y,{width:a.caret,height:a.caret,color:S("colors.brand.base")}):o(U,{width:a.caret,height:a.caret,color:S("colors.brand.base")})]}),h&&o(A,{ref:k,tabIndex:-1,py:2,bg:"surface.primary",position:"absolute",w:"full",rounded:"input",boxShadow:"4px 8px 20px 0px rgba(0, 0, 0, 0.15)",style:{maxHeight:`${H}rem`,top:a.top},overflowY:"auto",outline:"none",zIndex:"max",children:m.map(r,(e,n)=>te(e,{isFocused:n===t,size:p}))})]})]})})};_.displayName="DropdownOption",j.displayName="DropdownSelector";export{_ as DropdownOption,j as DropdownSelector};
2
2
  //# sourceMappingURL=dropdown-selector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-selector.js","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"sourcesContent":["import { Tooltip } from '@components/feedback';\nimport { IcoCaretDown, IcoCaretUp, IcoCheckmark, IcoQuestionCircleFill } from '@components/icons';\nimport { Text } from '@components/primitives';\nimport { css } from '@styled/css';\nimport { Box, HStack, VStack } from '@styled/jsx';\nimport { token } from '@styled/tokens';\nimport {\n Children,\n cloneElement,\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { AriaButtonProps, mergeProps, useButton, useFocusRing, useKeyboard } from 'react-aria';\n\nexport interface DropdownSelectorProps extends AriaButtonProps {\n children: ReactNode;\n onSelect: (value: string) => void;\n label?: string;\n placeholder?: string;\n selectedValue?: string;\n size?: 'sm' | 'md' | 'lg';\n tooltipContent?: string;\n disabled?: boolean;\n viewMax?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n}\n\ninterface OptionData {\n value: string;\n label: string;\n}\n\nexport interface DropdownContextType {\n selectedOption: OptionData | null;\n setSelectedOption: (option: OptionData) => void;\n}\n\nconst SIZES = {\n sm: { caret: 16, check: 14, height: '2.625rem', top: 48, width: '0.75rem', mult: 2.25 },\n md: { caret: 17, check: 15, height: '2.8125rem', top: 52, width: '0.85rem', mult: 2.25 },\n lg: { caret: 18, check: 16, height: '3rem', top: 55, width: '1rem', mult: 2.5 },\n};\n\nconst DropdownContext = createContext<DropdownContextType>({\n selectedOption: null,\n setSelectedOption: () => {},\n});\n\nexport const DropdownOption = ({ value, label, size = 'lg', isFocused }: DropdownOptionProps) => {\n const { selectedOption, setSelectedOption } = useContext(DropdownContext);\n const isSelected = selectedOption?.value === value;\n const sizeProps = SIZES[size];\n\n const handleSelectOption = useCallback(() => {\n setSelectedOption({ value, label });\n }, [setSelectedOption, value, label]);\n\n return (\n <HStack\n py={1.5}\n gap={2}\n bg={isSelected ? 'brand.base' : isFocused ? 'brand.lightest' : ''}\n _hover={!isSelected ? { bg: 'brand.lightest' } : {}}\n onClick={handleSelectOption}\n style={{ paddingLeft: sizeProps.width, paddingRight: sizeProps.width }}\n >\n <Box style={{ minWidth: sizeProps.width }}>\n {isSelected && (\n <IcoCheckmark width={sizeProps.check} height={sizeProps.check} color={token('colors.text.quaternary')} />\n )}\n </Box>\n <Text\n size={size}\n fontWeight=\"medium\"\n fontColor={isSelected ? 'text.quaternary' : 'text.primary'}\n styles={{ textAlign: 'left' }}\n >\n {label}\n </Text>\n </HStack>\n );\n};\n\nexport const DropdownSelector = ({\n children,\n onSelect,\n label,\n placeholder = 'Select one',\n selectedValue,\n size = 'lg',\n tooltipContent,\n disabled,\n viewMax = 5,\n ...props\n}: DropdownSelectorProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const sizeProps = SIZES[size];\n const maxHeight = viewMax * sizeProps.mult + 1;\n\n const toggleDropdown = useCallback(() => {\n setIsOpen(prev => !prev);\n if (!isOpen) {\n setFocusedIndex(null);\n setTimeout(() => dropdownRef.current?.focus());\n }\n }, [isOpen]);\n\n const handleSelect = useCallback(\n (option: OptionData) => {\n onSelect(option.value);\n setIsOpen(false);\n },\n [onSelect],\n );\n\n const selectedLabel = useMemo(() => {\n const childElements = Children.toArray(children) as ReactElement<DropdownOptionProps>[];\n const matchedChild = childElements.find(child => child.props.value === selectedValue);\n return matchedChild ? matchedChild.props.label : placeholder;\n }, [selectedValue, children]);\n\n const { buttonProps } = useButton(\n {\n ...props,\n isDisabled: disabled,\n onPress: toggleDropdown,\n },\n buttonRef,\n );\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n const { keyboardProps } = useKeyboard({\n onKeyDown: event => {\n if (!isOpen) return;\n\n let newFocusedIndex = focusedIndex;\n const childArray = Children.toArray(children);\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(Children.count(children) - 1);\n } else {\n newFocusedIndex = focusedIndex > 0 ? focusedIndex - 1 : Children.count(children) - 1;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(0);\n } else {\n newFocusedIndex = focusedIndex < Children.count(children) - 1 ? focusedIndex + 1 : 0;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'Enter':\n event.preventDefault();\n buttonRef.current?.focus();\n if (focusedIndex === null) return;\n if (focusedIndex >= 0 && focusedIndex < childArray.length) {\n const selectedChild = childArray[focusedIndex] as ReactElement<DropdownOptionProps>;\n if (selectedChild) {\n onSelect(selectedChild.props.value);\n }\n }\n break;\n case 'Escape':\n setIsOpen(false);\n buttonRef.current?.focus();\n break;\n default:\n break;\n }\n },\n });\n\n useEffect(() => {\n const handleClick = (event: MouseEvent) => {\n if (!dropdownRef.current?.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClick);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n };\n }, []);\n\n return (\n <DropdownContext.Provider\n value={{ selectedOption: { value: selectedValue ?? '', label: selectedLabel }, setSelectedOption: handleSelect }}\n >\n <VStack gap={2} w=\"full\" alignItems=\"flex-start\">\n {(label || tooltipContent) && (\n <HStack gap={2} opacity={disabled ? 0.3 : ''} transition={'all linear 120ms'}>\n {label && (\n <Text size=\"sm\" fontWeight=\"medium\">\n {label}\n </Text>\n )}\n\n {tooltipContent && (\n <Tooltip isDisabled={disabled} content={tooltipContent}>\n <IcoQuestionCircleFill className={css({ w: 4, h: 4, color: 'neutral.primary' })} />\n </Tooltip>\n )}\n </HStack>\n )}\n\n <button\n className={css({\n w: 'full',\n h: 'fit-content',\n bg: 'surface.primary',\n borderWidth: 'thin',\n borderColor: 'neutral.secondary',\n rounded: 'xl',\n transition: 'all linear 120ms',\n position: 'relative',\n cursor: 'pointer',\n outlineColor: 'brand.base',\n outlineStyle: isFocusVisible ? 'solid' : 'none',\n outlineWidth: 'thick',\n outlineOffset: 0.5,\n _hover: { borderColor: 'neutral.primary' },\n _disabled: { opacity: 0.3, pointerEvents: 'none' },\n })}\n ref={buttonRef}\n {...mergeProps(buttonProps, focusProps, keyboardProps)}\n >\n <HStack w=\"full\" p={4} justifyContent=\"space-between\" style={{ height: sizeProps.height }}>\n <Text truncate size={size} fontColor={selectedValue ? 'text.primary' : 'text.tertiary'}>\n {selectedLabel}\n </Text>\n {isOpen ? (\n <IcoCaretUp width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n ) : (\n <IcoCaretDown width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n )}\n </HStack>\n\n {isOpen && (\n <Box\n ref={dropdownRef}\n tabIndex={-1}\n py={2}\n bg=\"surface.primary\"\n position=\"absolute\"\n w=\"full\"\n rounded=\"input\"\n boxShadow=\"4px 8px 20px 0px rgba(0, 0, 0, 0.15)\"\n style={{ maxHeight: `${maxHeight}rem`, top: sizeProps.top }}\n overflowY=\"auto\"\n outline=\"none\"\n zIndex=\"max\"\n >\n {Children.map(children, (child, index) =>\n cloneElement(child as ReactElement<DropdownOptionProps>, {\n isFocused: index === focusedIndex,\n size,\n }),\n )}\n </Box>\n )}\n </button>\n </VStack>\n </DropdownContext.Provider>\n );\n};\n\nDropdownOption.displayName = 'DropdownOption';\nDropdownSelector.displayName = 'DropdownSelector';\n"],"names":["SIZES","DropdownContext","createContext","DropdownOption","value","label","size","isFocused","selectedOption","setSelectedOption","useContext","isSelected","sizeProps","handleSelectOption","useCallback","_jsxs","HStack","_jsx","Box","IcoCheckmark","token","Text","DropdownSelector","children","onSelect","placeholder","selectedValue","tooltipContent","disabled","viewMax","props","isOpen","setIsOpen","useState","focusedIndex","setFocusedIndex","buttonRef","useRef","dropdownRef","maxHeight","toggleDropdown","prev","_a","handleSelect","option","selectedLabel","useMemo","matchedChild","Children","child","buttonProps","useButton","focusProps","isFocusVisible","useFocusRing","keyboardProps","useKeyboard","event","newFocusedIndex","childArray","selectedChild","_b","useEffect","handleClick","VStack","Tooltip","IcoQuestionCircleFill","css","mergeProps","IcoCaretUp","IcoCaretDown","index","cloneElement"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-selector.js","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"sourcesContent":["import { Tooltip } from '@components/feedback';\nimport { IcoCaretDown, IcoCaretUp, IcoCheckmark, IcoQuestionCircleFill } from '@components/icons';\nimport { Text } from '@components/primitives';\nimport { css } from '@styled/css';\nimport { Box, HStack, VStack } from '@styled/jsx';\nimport { token } from '@styled/tokens';\nimport {\n Children,\n cloneElement,\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { AriaButtonProps, mergeProps, useButton, useFocusRing, useKeyboard } from 'react-aria';\n\nexport interface DropdownSelectorProps extends AriaButtonProps {\n children: ReactNode;\n onSelect: (value: string) => void;\n label?: string;\n placeholder?: string;\n selectedValue?: string;\n size?: 'sm' | 'md' | 'lg';\n tooltipContent?: string;\n disabled?: boolean;\n viewMax?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n}\n\ninterface OptionData {\n value: string;\n label: string;\n}\n\nexport interface DropdownContextType {\n selectedOption: OptionData | null;\n setSelectedOption: (option: OptionData) => void;\n}\n\nconst SIZES = {\n sm: { caret: 16, check: 14, height: '2.625rem', top: 48, width: '0.75rem', mult: 2.25 },\n md: { caret: 17, check: 15, height: '2.8125rem', top: 52, width: '0.85rem', mult: 2.25 },\n lg: { caret: 18, check: 16, height: '3rem', top: 55, width: '1rem', mult: 2.5 },\n};\n\nconst DropdownContext = createContext<DropdownContextType>({\n selectedOption: null,\n setSelectedOption: () => {},\n});\n\nexport const DropdownOption = ({ value, label, size = 'lg', isFocused }: DropdownOptionProps) => {\n const { selectedOption, setSelectedOption } = useContext(DropdownContext);\n const isSelected = selectedOption?.value === value;\n const sizeProps = SIZES[size];\n\n const handleSelectOption = useCallback(() => {\n setSelectedOption({ value, label });\n }, [setSelectedOption, value, label]);\n\n return (\n <HStack\n py={1.5}\n gap={2}\n bg={isSelected ? 'brand.base' : isFocused ? 'brand.lightest' : ''}\n _hover={!isSelected ? { bg: 'brand.lightest' } : {}}\n onClick={handleSelectOption}\n style={{ paddingLeft: sizeProps.width, paddingRight: sizeProps.width }}\n >\n <Box style={{ minWidth: sizeProps.width }}>\n {isSelected && (\n <IcoCheckmark width={sizeProps.check} height={sizeProps.check} color={token('colors.text.quaternary')} />\n )}\n </Box>\n <Text\n size={size}\n fontWeight=\"medium\"\n fontColor={isSelected ? 'text.quaternary' : 'text.primary'}\n styles={{ textAlign: 'left' }}\n >\n {label}\n </Text>\n </HStack>\n );\n};\n\nexport const DropdownSelector = ({\n children,\n onSelect,\n label,\n placeholder = 'Select one',\n selectedValue,\n size = 'lg',\n tooltipContent,\n disabled,\n viewMax = 5,\n ...props\n}: DropdownSelectorProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [focusedIndex, setFocusedIndex] = useState<number | null>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const sizeProps = SIZES[size];\n const maxHeight = viewMax * sizeProps.mult + 1;\n\n const toggleDropdown = useCallback(() => {\n setIsOpen(prev => !prev);\n if (!isOpen) {\n setFocusedIndex(null);\n setTimeout(() => dropdownRef.current?.focus());\n }\n }, [isOpen]);\n\n const handleSelect = useCallback(\n (option: OptionData) => {\n onSelect(option.value);\n setIsOpen(false);\n },\n [onSelect],\n );\n\n const selectedLabel = useMemo(() => {\n const childElements = Children.toArray(children) as ReactElement<DropdownOptionProps>[];\n const matchedChild = childElements.find(child => child.props.value === selectedValue);\n return matchedChild ? matchedChild.props.label : placeholder;\n }, [selectedValue, children]);\n\n const { buttonProps } = useButton(\n {\n ...props,\n isDisabled: disabled,\n onPress: toggleDropdown,\n },\n buttonRef,\n );\n\n const { focusProps, isFocusVisible } = useFocusRing();\n\n const { keyboardProps } = useKeyboard({\n onKeyDown: event => {\n if (!isOpen) return;\n\n let newFocusedIndex = focusedIndex;\n const childArray = Children.toArray(children);\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(Children.count(children) - 1);\n } else {\n newFocusedIndex = focusedIndex > 0 ? focusedIndex - 1 : Children.count(children) - 1;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (focusedIndex === null) {\n setFocusedIndex(0);\n } else {\n newFocusedIndex = focusedIndex < Children.count(children) - 1 ? focusedIndex + 1 : 0;\n setFocusedIndex(newFocusedIndex);\n }\n break;\n case 'Enter':\n event.preventDefault();\n buttonRef.current?.focus();\n if (focusedIndex === null) return;\n if (focusedIndex >= 0 && focusedIndex < childArray.length) {\n const selectedChild = childArray[focusedIndex] as ReactElement<DropdownOptionProps>;\n if (selectedChild) {\n onSelect(selectedChild.props.value);\n }\n }\n break;\n case 'Escape':\n setIsOpen(false);\n buttonRef.current?.focus();\n break;\n default:\n break;\n }\n },\n });\n\n useEffect(() => {\n const handleClick = (event: MouseEvent) => {\n if (!dropdownRef.current?.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener('mousedown', handleClick);\n\n return () => {\n document.removeEventListener('mousedown', handleClick);\n };\n }, []);\n\n return (\n <DropdownContext.Provider\n value={{ selectedOption: { value: selectedValue ?? '', label: selectedLabel }, setSelectedOption: handleSelect }}\n >\n <VStack gap={2} w=\"full\" alignItems=\"flex-start\">\n {(label || tooltipContent) && (\n <HStack gap={2} opacity={disabled ? 0.3 : ''} transition={'all linear 120ms'}>\n {label && (\n <Text size=\"sm\" fontWeight=\"medium\">\n {label}\n </Text>\n )}\n\n {tooltipContent && (\n <Tooltip content={tooltipContent}>\n <IcoQuestionCircleFill className={css({ w: 4, h: 4, color: 'neutral.primary' })} />\n </Tooltip>\n )}\n </HStack>\n )}\n\n <button\n className={css({\n w: 'full',\n h: 'fit-content',\n bg: 'surface.primary',\n borderWidth: 'thin',\n borderColor: 'neutral.secondary',\n rounded: 'xl',\n transition: 'all linear 120ms',\n position: 'relative',\n cursor: 'pointer',\n outlineColor: 'brand.base',\n outlineStyle: isFocusVisible ? 'solid' : 'none',\n outlineWidth: 'thick',\n outlineOffset: 0.5,\n _hover: { borderColor: 'neutral.primary' },\n _disabled: { opacity: 0.3, pointerEvents: 'none' },\n })}\n ref={buttonRef}\n {...mergeProps(buttonProps, focusProps, keyboardProps)}\n >\n <HStack w=\"full\" p={4} justifyContent=\"space-between\" style={{ height: sizeProps.height }}>\n <Text truncate size={size} fontColor={selectedValue ? 'text.primary' : 'text.tertiary'}>\n {selectedLabel}\n </Text>\n {isOpen ? (\n <IcoCaretUp width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n ) : (\n <IcoCaretDown width={sizeProps.caret} height={sizeProps.caret} color={token('colors.brand.base')} />\n )}\n </HStack>\n\n {isOpen && (\n <Box\n ref={dropdownRef}\n tabIndex={-1}\n py={2}\n bg=\"surface.primary\"\n position=\"absolute\"\n w=\"full\"\n rounded=\"input\"\n boxShadow=\"4px 8px 20px 0px rgba(0, 0, 0, 0.15)\"\n style={{ maxHeight: `${maxHeight}rem`, top: sizeProps.top }}\n overflowY=\"auto\"\n outline=\"none\"\n zIndex=\"max\"\n >\n {Children.map(children, (child, index) =>\n cloneElement(child as ReactElement<DropdownOptionProps>, {\n isFocused: index === focusedIndex,\n size,\n }),\n )}\n </Box>\n )}\n </button>\n </VStack>\n </DropdownContext.Provider>\n );\n};\n\nDropdownOption.displayName = 'DropdownOption';\nDropdownSelector.displayName = 'DropdownSelector';\n"],"names":["SIZES","DropdownContext","createContext","DropdownOption","value","label","size","isFocused","selectedOption","setSelectedOption","useContext","isSelected","sizeProps","handleSelectOption","useCallback","_jsxs","HStack","_jsx","Box","IcoCheckmark","token","Text","DropdownSelector","children","onSelect","placeholder","selectedValue","tooltipContent","disabled","viewMax","props","isOpen","setIsOpen","useState","focusedIndex","setFocusedIndex","buttonRef","useRef","dropdownRef","maxHeight","toggleDropdown","prev","_a","handleSelect","option","selectedLabel","useMemo","matchedChild","Children","child","buttonProps","useButton","focusProps","isFocusVisible","useFocusRing","keyboardProps","useKeyboard","event","newFocusedIndex","childArray","selectedChild","_b","useEffect","handleClick","VStack","Tooltip","IcoQuestionCircleFill","css","mergeProps","IcoCaretUp","IcoCaretDown","index","cloneElement"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as t,Fragment as X,jsxs as E}from"react/jsx-runtime";import C from"./button.js";import"./checkbox.js";import"./dropdown-selector.js";import"./radio.js";import"./segmented-control.js";import"./switch.js";import"./text.js";import{useToggleState as V}from"../../hooks/useToggleState.js";import{cx as ee}from"@styled/css";import{Center as T,Box as Y}from"@styled/jsx";import{vstack as re}from"@styled/patterns";import{token as oe}from"@styled/tokens";import{createSlot as v,createHost as te}from"create-slots";import{Children as k,cloneElement as I,useMemo as ne,useRef as z,useCallback as A,useEffect as ie}from"react";import{useOverlayTrigger as le,usePopover as se,mergeProps as L,Overlay as ce}from"react-aria";const B="bottom left",D=8,pe="hover",S=v(({children:n})=>t(X,{children:n})),H=v(({children:n,...e})=>t(T,{children:k.map(n,o=>I(o,e))})),j=v(({children:n,...e})=>t(T,{children:k.map(n,o=>I(o,e))})),M=v(({children:n,...e})=>t(T,{children:k.map(n,o=>I(o,e))})),U=({children:n,...e})=>te(n,o=>{var x;const{isSelected:_,setSelected:b}=V({isOpen:e.isOpen,defaultSelected:e.defaultOpen,onChange:e.onOpenChange,...e}),a=e.isOpen!==void 0?e.isOpen:_,i=24,F=e.trigger||pe,l=ne(()=>({isOpen:a,open:()=>{b(!0)},close:()=>{b(!1)},setOpen(r){b(r)},toggle(){}}),[a]),R=o.getProps(S),s=z(null),{triggerProps:w,overlayProps:G}=le({type:"dialog"},l,s),c=z(null),{popoverProps:K,underlayProps:q}=se({placement:B,offset:D,popoverRef:c,triggerRef:s,...R},l),m=L(R,K);!((x=m?.style)===null||x===void 0)&&x.zIndex&&(m.style.zIndex=oe("zIndex.max"));const N=A(()=>{l.open()},[l]),y=A(r=>{var O,P;const p=(O=s.current)===null||O===void 0?void 0:O.getBoundingClientRect(),d=(P=c.current)===null||P===void 0?void 0:P.getBoundingClientRect();if(p&&d){const J=r.clientX>=p.left-i&&r.clientX<=p.right+i&&r.clientY>=p.top-i&&r.clientY<=p.bottom+i,Q=r.clientX>=d.left-i&&r.clientX<=d.right+i&&r.clientY>=d.top-i&&r.clientY<=d.bottom+i;!J&&!Q&&l.close()}},[l]),Z=()=>{if(c.current){const r=c.current.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');r.length>0&&r[0].focus()}},$=r=>{r.key==="Enter"&&(r.preventDefault(),a?l.close():(l.open(),setTimeout(Z,0)))};ie(()=>(document.addEventListener("mousemove",y),()=>{document.removeEventListener("mousemove",y)}),[y]);const g=e.size==="sm"?16:24,u=o.get(H),h=o.get(j),f=o.get(M);return E(X,{children:[u?t(Y,{display:"inline-block",ref:s,...L(w,e),children:u&&{...u,props:{...u.props}}}):t(Y,{display:"inline-block",ref:s,children:E(C,{...L(w,e),onKeyDown:$,onHover:()=>F==="hover"&&N(),onPress:()=>F==="click"&&N(),children:[h&&t(C.LeadingIcon,{children:h&&{...h,props:{...h.props,width:g,height:g}}}),f&&t(C.TrailingIcon,{children:f&&{...f,props:{...f.props,width:g,height:g}}})]})}),a&&E(ce,{...G,children:[t("div",{...q,className:"underlay"}),t("div",{ref:c,...m,className:ee(re({bg:"surface.primary",p:3,gap:0,color:"text.secondary",borderWidth:1,borderColor:"neutral.secondary",borderRadius:"xl",boxShadow:"0px 4px 20px 0px rgba(0, 0, 0, 0.10)",maxW:52,alignItems:"start"}),m.className),children:o.get(S)})]})]})}),W=Object.assign(U,{Trigger:H,LeadingIcon:j,TrailingIcon:M,Content:S});export{D as DEFAULT_OFFSET,B as DEFAULT_PLACEMENT,W as Popover,U as PopoverHost,W as default};
1
+ import{jsx as r,Fragment as Y,jsxs as C}from"react/jsx-runtime";import O from"./button.js";import"./checkbox.js";import"./dropdown-selector.js";import"./radio.js";import"./segmented-control.js";import"./switch.js";import"./text.js";import{useToggleState as te}from"../../hooks/useToggleState.js";import{cx as ne}from"@styled/css";import{Center as S,Box as A}from"@styled/jsx";import{vstack as ie}from"@styled/patterns";import{token as le}from"@styled/tokens";import{createSlot as x,createHost as se}from"create-slots";import{Children as k,cloneElement as I,useMemo as ce,useRef as D,useCallback as H,useEffect as pe}from"react";import{useOverlayTrigger as de,usePopover as ae,mergeProps as N,Overlay as me}from"react-aria";const j="bottom left",B=8,ge="hover",L=x(({children:t})=>r(Y,{children:t})),M=x(({children:t,...n})=>{const{onPress:o,...c}=n;return r(S,{children:k.map(t,s=>I(s,c))})}),U=x(({children:t,...n})=>r(S,{children:k.map(t,o=>I(o,n))})),W=x(({children:t,...n})=>r(S,{children:k.map(t,o=>I(o,n))})),_=({children:t,...n})=>se(t,o=>{var c;const{isOpen:s,defaultOpen:G,onOpenChange:K,trigger:z=ge,iconSize:ue,onPress:he,...F}=n,{isSelected:J,setSelected:b}=te({isOpen:s,defaultSelected:G,onChange:K,...n}),y=s!==void 0?s:J,i=24,l=ce(()=>({isOpen:y,open:()=>{b(!0)},close:()=>{b(!1)},setOpen(e){b(e)},toggle(){}}),[y]),R=o.getProps(L),p=D(null),{triggerProps:w,overlayProps:Q}=de({type:"dialog"},l,p),d=D(null),{popoverProps:V,underlayProps:Z}=ae({placement:j,offset:B,popoverRef:d,triggerRef:p,...R},l),g=N(R,V);!((c=g?.style)===null||c===void 0)&&c.zIndex&&(g.style.zIndex=le("zIndex.max"));const X=H(()=>{l.open()},[l]),P=H(e=>{var E,T;const a=(E=p.current)===null||E===void 0?void 0:E.getBoundingClientRect(),m=(T=d.current)===null||T===void 0?void 0:T.getBoundingClientRect();if(a&&m){const oe=e.clientX>=a.left-i&&e.clientX<=a.right+i&&e.clientY>=a.top-i&&e.clientY<=a.bottom+i,re=e.clientX>=m.left-i&&e.clientX<=m.right+i&&e.clientY>=m.top-i&&e.clientY<=m.bottom+i;!oe&&!re&&l.close()}},[l]),$=()=>{if(d.current){const e=d.current.querySelectorAll('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');e.length>0&&e[0].focus()}},ee=e=>{e.key==="Enter"&&(e.preventDefault(),s?l.close():(l.open(),setTimeout($,0)))};pe(()=>(document.addEventListener("mousemove",P),()=>{document.removeEventListener("mousemove",P)}),[P]);const u=n.size==="sm"?16:24,h=o.get(M),f=o.get(U),v=o.get(W);return C(Y,{children:[h?r(A,{display:"inline-block",ref:p,...F,children:h&&{...h,props:{...h.props,...w}}}):r(A,{display:"inline-block",ref:p,children:C(O,{...N(w,F),onKeyDown:ee,onHover:()=>z==="hover"&&X(),onPress:()=>z==="click"&&X(),children:[f&&r(O.LeadingIcon,{children:f&&{...f,props:{...f.props,width:u,height:u}}}),v&&r(O.TrailingIcon,{children:v&&{...v,props:{...v.props,width:u,height:u}}})]})}),y&&C(me,{...Q,children:[r("div",{...Z,className:"underlay"}),r("div",{ref:d,...g,className:ne(ie({bg:"surface.primary",p:3,gap:0,color:"text.secondary",borderWidth:1,borderColor:"neutral.secondary",borderRadius:"xl",boxShadow:"0px 4px 20px 0px rgba(0, 0, 0, 0.10)",maxW:52,alignItems:"start"}),g.className),children:o.get(L)})]})]})}),q=Object.assign(_,{Trigger:M,LeadingIcon:U,TrailingIcon:W,Content:L});export{B as DEFAULT_OFFSET,j as DEFAULT_PLACEMENT,q as Popover,_ as PopoverHost,q as default};
2
2
  //# sourceMappingURL=popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sources":["../../../../src/components/primitives/popover.tsx"],"sourcesContent":["import { Button, ButtonProps } from '@components/primitives';\nimport { useToggleState } from '@hooks/useToggleState';\nimport { cx } from '@styled/css';\nimport { Box, Center } from '@styled/jsx';\nimport { vstack } from '@styled/patterns';\nimport { token } from '@styled/tokens';\nimport { createHost, createSlot } from 'create-slots';\nimport {\n Children,\n ComponentProps,\n PropsWithChildren,\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport type { AriaPopoverProps, Placement } from 'react-aria';\nimport { Overlay, mergeProps, useOverlayTrigger, usePopover } from 'react-aria';\n\ninterface OverlayTriggerProps extends ButtonProps {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n trigger?: 'click' | 'hover';\n}\n\ninterface OverlayTriggerState {\n readonly isOpen: boolean;\n setOpen(isOpen: boolean): void;\n open(): void;\n close(): void;\n toggle(): void;\n}\n\ntype PopoverContentProps = Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef'> & {\n children?: ReactNode;\n state?: OverlayTriggerState;\n} & ComponentProps<'div'>;\n\nexport const DEFAULT_PLACEMENT: Placement = 'bottom left';\nexport const DEFAULT_OFFSET = 8;\n\nconst DEFAULT_TRIGGER: string = 'hover';\n\nconst PopoverContent = createSlot(({ children }: PopoverContentProps) => <>{children}</>);\n\nconst Trigger = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst LeadingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst TrailingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nexport type PopoverProps = PropsWithChildren<OverlayTriggerProps>;\n\nexport const PopoverHost = ({ children, ...props }: PopoverProps) => {\n return createHost(children, slots => {\n const { isSelected, setSelected: setOpen } = useToggleState({\n isOpen: props.isOpen,\n defaultSelected: props.defaultOpen,\n onChange: props.onOpenChange,\n ...props,\n });\n\n const isOpen = props.isOpen !== undefined ? props.isOpen : isSelected;\n const safeZoneRadius = 24;\n const trigger = props.trigger || DEFAULT_TRIGGER;\n\n const state = useMemo(\n () => ({\n isOpen,\n open: () => {\n setOpen(true);\n },\n close: () => {\n setOpen(false);\n },\n setOpen(value: boolean) {\n setOpen(value);\n },\n toggle() {},\n }),\n [isOpen],\n );\n\n const popoverContentProps = slots.getProps(PopoverContent);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const { triggerProps, overlayProps } = useOverlayTrigger({ type: 'dialog' }, state, triggerRef);\n\n const contentRef = useRef<HTMLDivElement>(null);\n const { popoverProps, underlayProps } = usePopover(\n {\n placement: DEFAULT_PLACEMENT,\n offset: DEFAULT_OFFSET,\n popoverRef: contentRef,\n triggerRef,\n ...popoverContentProps,\n },\n state,\n );\n\n const contentProps = mergeProps(popoverContentProps, popoverProps);\n\n // Need to override zIndex set by react-aria so popover displays over iframe\n if (contentProps?.style?.zIndex) {\n contentProps.style.zIndex = token('zIndex.max');\n }\n\n const handleTrigger = useCallback(() => {\n state.open();\n }, [state]);\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent) => {\n const buttonRect = triggerRef.current?.getBoundingClientRect();\n const popoverRect = contentRef.current?.getBoundingClientRect();\n\n if (buttonRect && popoverRect) {\n const withinButtonSafeZone =\n event.clientX >= buttonRect.left - safeZoneRadius &&\n event.clientX <= buttonRect.right + safeZoneRadius &&\n event.clientY >= buttonRect.top - safeZoneRadius &&\n event.clientY <= buttonRect.bottom + safeZoneRadius;\n\n const withinPopoverSafeZone =\n event.clientX >= popoverRect.left - safeZoneRadius &&\n event.clientX <= popoverRect.right + safeZoneRadius &&\n event.clientY >= popoverRect.top - safeZoneRadius &&\n event.clientY <= popoverRect.bottom + safeZoneRadius;\n\n if (!withinButtonSafeZone && !withinPopoverSafeZone) {\n state.close();\n }\n }\n },\n [state],\n );\n\n const focusFirstInteractiveElement = () => {\n if (contentRef.current) {\n const interactiveElements = contentRef.current.querySelectorAll(\n 'a, button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (interactiveElements.length > 0) {\n (interactiveElements[0] as HTMLElement).focus();\n }\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (isOpen) {\n state.close();\n } else {\n state.open();\n setTimeout(focusFirstInteractiveElement, 0);\n }\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousemove', handleMouseLeave);\n return () => {\n document.removeEventListener('mousemove', handleMouseLeave);\n };\n }, [handleMouseLeave]);\n\n const iconSize = props.size === 'sm' ? 16 : 24;\n const triggerEle = slots.get(Trigger);\n const leadingIcon = slots.get(LeadingIcon);\n const trailingIcon = slots.get(TrailingIcon);\n\n return (\n <>\n {triggerEle ? (\n <Box display=\"inline-block\" ref={triggerRef} {...mergeProps(triggerProps, props)}>\n {triggerEle && { ...triggerEle, props: { ...triggerEle.props } }}\n </Box>\n ) : (\n <Box display=\"inline-block\" ref={triggerRef}>\n <Button\n {...mergeProps(triggerProps, props)}\n onKeyDown={handleKeyDown}\n onHover={() => trigger === 'hover' && handleTrigger()}\n onPress={() => trigger === 'click' && handleTrigger()}\n >\n {leadingIcon && (\n <Button.LeadingIcon>\n {leadingIcon && {\n ...leadingIcon,\n props: { ...leadingIcon.props, width: iconSize, height: iconSize },\n }}\n </Button.LeadingIcon>\n )}\n {trailingIcon && (\n <Button.TrailingIcon>\n {trailingIcon && {\n ...trailingIcon,\n props: { ...trailingIcon.props, width: iconSize, height: iconSize },\n }}\n </Button.TrailingIcon>\n )}\n </Button>\n </Box>\n )}\n {isOpen && (\n <Overlay {...overlayProps}>\n <div {...underlayProps} className=\"underlay\" />\n <div\n ref={contentRef}\n {...contentProps}\n className={cx(\n vstack({\n bg: 'surface.primary',\n p: 3,\n gap: 0,\n color: 'text.secondary',\n borderWidth: 1,\n borderColor: 'neutral.secondary',\n borderRadius: 'xl',\n boxShadow: '0px 4px 20px 0px rgba(0, 0, 0, 0.10)',\n maxW: 52,\n alignItems: 'start',\n }),\n contentProps.className,\n )}\n >\n {slots.get(PopoverContent)}\n </div>\n </Overlay>\n )}\n </>\n );\n });\n};\n\nexport const Popover = Object.assign(PopoverHost, {\n Trigger,\n LeadingIcon,\n TrailingIcon,\n Content: PopoverContent,\n});\n\nexport default Popover;\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET","DEFAULT_TRIGGER","PopoverContent","createSlot","children","_jsx","_Fragment","Trigger","props","Center","Children","child","cloneElement","LeadingIcon","TrailingIcon","PopoverHost","createHost","slots","isSelected","setOpen","useToggleState","isOpen","safeZoneRadius","trigger","state","useMemo","value","popoverContentProps","triggerRef","useRef","triggerProps","overlayProps","useOverlayTrigger","contentRef","popoverProps","underlayProps","usePopover","contentProps","mergeProps","_a","token","handleTrigger","useCallback","handleMouseLeave","event","buttonRect","popoverRect","_b","withinButtonSafeZone","withinPopoverSafeZone","focusFirstInteractiveElement","interactiveElements","handleKeyDown","useEffect","iconSize","triggerEle","leadingIcon","trailingIcon","_jsxs","Box","Button","Overlay","cx","vstack","Popover"],"mappings":"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"}
1
+ {"version":3,"file":"popover.js","sources":["../../../../src/components/primitives/popover.tsx"],"sourcesContent":["import { Button, ButtonProps } from '@components/primitives';\nimport { useToggleState } from '@hooks/useToggleState';\nimport { cx } from '@styled/css';\nimport { Box, Center } from '@styled/jsx';\nimport { vstack } from '@styled/patterns';\nimport { token } from '@styled/tokens';\nimport { createHost, createSlot } from 'create-slots';\nimport {\n Children,\n ComponentProps,\n PropsWithChildren,\n cloneElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport type { AriaPopoverProps, Placement } from 'react-aria';\nimport { Overlay, mergeProps, useOverlayTrigger, usePopover } from 'react-aria';\n\ninterface OverlayTriggerProps extends ButtonProps {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n trigger?: 'click' | 'hover';\n}\n\ninterface OverlayTriggerState {\n readonly isOpen: boolean;\n setOpen(isOpen: boolean): void;\n open(): void;\n close(): void;\n toggle(): void;\n}\n\ntype PopoverContentProps = Omit<AriaPopoverProps, 'popoverRef' | 'triggerRef'> & {\n children?: ReactNode;\n state?: OverlayTriggerState;\n} & ComponentProps<'div'>;\n\nexport const DEFAULT_PLACEMENT: Placement = 'bottom left';\nexport const DEFAULT_OFFSET = 8;\n\nconst DEFAULT_TRIGGER: string = 'hover';\n\nconst PopoverContent = createSlot(({ children }: PopoverContentProps) => <>{children}</>);\n\nconst Trigger = createSlot(({ children, ...props }) => {\n const { onPress, ...restProps } = props;\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, restProps);\n })}\n </Center>\n );\n});\n\nconst LeadingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nconst TrailingIcon = createSlot(({ children, ...props }) => {\n return (\n <Center>\n {Children.map(children, child => {\n return cloneElement(child, props);\n })}\n </Center>\n );\n});\n\nexport type PopoverProps = PropsWithChildren<OverlayTriggerProps>;\n\nexport const PopoverHost = ({ children, ...props }: PopoverProps) => {\n return createHost(children, slots => {\n const { isOpen, defaultOpen, onOpenChange, trigger = DEFAULT_TRIGGER, iconSize, onPress, ...restProps } = props;\n const { isSelected, setSelected: setOpen } = useToggleState({\n isOpen: isOpen,\n defaultSelected: defaultOpen,\n onChange: onOpenChange,\n ...props,\n });\n\n const isPopoverOpen = isOpen !== undefined ? isOpen : isSelected;\n const safeZoneRadius = 24;\n\n const state = useMemo(\n () => ({\n isOpen: isPopoverOpen,\n open: () => {\n setOpen(true);\n },\n close: () => {\n setOpen(false);\n },\n setOpen(value: boolean) {\n setOpen(value);\n },\n toggle() {},\n }),\n [isPopoverOpen],\n );\n\n const popoverContentProps = slots.getProps(PopoverContent);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const { triggerProps, overlayProps } = useOverlayTrigger({ type: 'dialog' }, state, triggerRef);\n\n const contentRef = useRef<HTMLDivElement>(null);\n const { popoverProps, underlayProps } = usePopover(\n {\n placement: DEFAULT_PLACEMENT,\n offset: DEFAULT_OFFSET,\n popoverRef: contentRef,\n triggerRef,\n ...popoverContentProps,\n },\n state,\n );\n\n const contentProps = mergeProps(popoverContentProps, popoverProps);\n\n // Need to override zIndex set by react-aria so popover displays over iframe\n if (contentProps?.style?.zIndex) {\n contentProps.style.zIndex = token('zIndex.max');\n }\n\n const handleTrigger = useCallback(() => {\n state.open();\n }, [state]);\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent) => {\n const buttonRect = triggerRef.current?.getBoundingClientRect();\n const popoverRect = contentRef.current?.getBoundingClientRect();\n\n if (buttonRect && popoverRect) {\n const withinButtonSafeZone =\n event.clientX >= buttonRect.left - safeZoneRadius &&\n event.clientX <= buttonRect.right + safeZoneRadius &&\n event.clientY >= buttonRect.top - safeZoneRadius &&\n event.clientY <= buttonRect.bottom + safeZoneRadius;\n\n const withinPopoverSafeZone =\n event.clientX >= popoverRect.left - safeZoneRadius &&\n event.clientX <= popoverRect.right + safeZoneRadius &&\n event.clientY >= popoverRect.top - safeZoneRadius &&\n event.clientY <= popoverRect.bottom + safeZoneRadius;\n\n if (!withinButtonSafeZone && !withinPopoverSafeZone) {\n state.close();\n }\n }\n },\n [state],\n );\n\n const focusFirstInteractiveElement = () => {\n if (contentRef.current) {\n const interactiveElements = contentRef.current.querySelectorAll(\n 'a, button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (interactiveElements.length > 0) {\n (interactiveElements[0] as HTMLElement).focus();\n }\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (isOpen) {\n state.close();\n } else {\n state.open();\n setTimeout(focusFirstInteractiveElement, 0);\n }\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousemove', handleMouseLeave);\n return () => {\n document.removeEventListener('mousemove', handleMouseLeave);\n };\n }, [handleMouseLeave]);\n\n const size = props.size === 'sm' ? 16 : 24;\n const triggerEle = slots.get(Trigger);\n const leadingIcon = slots.get(LeadingIcon);\n const trailingIcon = slots.get(TrailingIcon);\n\n return (\n <>\n {triggerEle ? (\n <Box display=\"inline-block\" ref={triggerRef} {...restProps}>\n {triggerEle && { ...triggerEle, props: { ...triggerEle.props, ...triggerProps } }}\n </Box>\n ) : (\n <Box display=\"inline-block\" ref={triggerRef}>\n <Button\n {...mergeProps(triggerProps, restProps)}\n onKeyDown={handleKeyDown}\n onHover={() => trigger === 'hover' && handleTrigger()}\n onPress={() => trigger === 'click' && handleTrigger()}\n >\n {leadingIcon && (\n <Button.LeadingIcon>\n {leadingIcon && {\n ...leadingIcon,\n props: { ...leadingIcon.props, width: size, height: size },\n }}\n </Button.LeadingIcon>\n )}\n {trailingIcon && (\n <Button.TrailingIcon>\n {trailingIcon && {\n ...trailingIcon,\n props: { ...trailingIcon.props, width: size, height: size },\n }}\n </Button.TrailingIcon>\n )}\n </Button>\n </Box>\n )}\n {isPopoverOpen && (\n <Overlay {...overlayProps}>\n <div {...underlayProps} className=\"underlay\" />\n <div\n ref={contentRef}\n {...contentProps}\n className={cx(\n vstack({\n bg: 'surface.primary',\n p: 3,\n gap: 0,\n color: 'text.secondary',\n borderWidth: 1,\n borderColor: 'neutral.secondary',\n borderRadius: 'xl',\n boxShadow: '0px 4px 20px 0px rgba(0, 0, 0, 0.10)',\n maxW: 52,\n alignItems: 'start',\n }),\n contentProps.className,\n )}\n >\n {slots.get(PopoverContent)}\n </div>\n </Overlay>\n )}\n </>\n );\n });\n};\n\nexport const Popover = Object.assign(PopoverHost, {\n Trigger,\n LeadingIcon,\n TrailingIcon,\n Content: PopoverContent,\n});\n\nexport default Popover;\n"],"names":["DEFAULT_PLACEMENT","DEFAULT_OFFSET","DEFAULT_TRIGGER","PopoverContent","createSlot","children","_jsx","_Fragment","Trigger","props","onPress","restProps","Center","Children","child","cloneElement","LeadingIcon","TrailingIcon","PopoverHost","createHost","slots","isOpen","defaultOpen","onOpenChange","trigger","iconSize","isSelected","setOpen","useToggleState","isPopoverOpen","safeZoneRadius","state","useMemo","value","popoverContentProps","triggerRef","useRef","triggerProps","overlayProps","useOverlayTrigger","contentRef","popoverProps","underlayProps","usePopover","contentProps","mergeProps","_a","token","handleTrigger","useCallback","handleMouseLeave","event","buttonRect","popoverRect","_b","withinButtonSafeZone","withinPopoverSafeZone","focusFirstInteractiveElement","interactiveElements","handleKeyDown","useEffect","size","triggerEle","leadingIcon","trailingIcon","_jsxs","Box","Button","Overlay","cx","vstack","Popover"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO7D,OAAO,EAEL,cAAc,EACd,iBAAiB,EAMjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9D,UAAU,mBAAoB,SAAQ,WAAW;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AAED,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,KAAK,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,YAAY,CAAC,GAAG;IAC/E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AAE1B,eAAO,MAAM,iBAAiB,EAAE,SAAyB,CAAC;AAC1D,eAAO,MAAM,cAAc,IAAI,CAAC;AAoChC,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;AAElE,eAAO,MAAM,WAAW,2BAA4B,YAAY,gBAqL/D,CAAC;AAEF,eAAO,MAAM,OAAO,4BAvLgC,YAAY;;;;4BAlCf,mBAAmB;CA8NlE,CAAC;AAEH,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAO7D,OAAO,EAEL,cAAc,EACd,iBAAiB,EAMjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG9D,UAAU,mBAAoB,SAAQ,WAAW;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC7B;AAED,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,KAAK,mBAAmB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,YAAY,CAAC,GAAG;IAC/E,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AAE1B,eAAO,MAAM,iBAAiB,EAAE,SAAyB,CAAC;AAC1D,eAAO,MAAM,cAAc,IAAI,CAAC;AAqChC,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;AAElE,eAAO,MAAM,WAAW,2BAA4B,YAAY,gBAqL/D,CAAC;AAEF,eAAO,MAAM,OAAO,4BAvLgC,YAAY;;;;4BAnCf,mBAAmB;CA+NlE,CAAC;AAEH,eAAe,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magiclabs/ui-components",
3
- "version": "1.24.7",
3
+ "version": "1.25.0",
4
4
  "description": "💅 A theme-able library of reusable UI components",
5
5
  "author": "Magic Labs <open-source@magic.link>",
6
6
  "repository": {
@@ -60,25 +60,25 @@
60
60
  "@rollup/plugin-commonjs": "^26.0.1",
61
61
  "@rollup/plugin-node-resolve": "^15.2.3",
62
62
  "@rollup/plugin-url": "^8.0.2",
63
- "@storybook/addon-a11y": "^8.1.6",
64
- "@storybook/addon-actions": "^8.1.6",
63
+ "@storybook/addon-a11y": "^8.3.0",
64
+ "@storybook/addon-actions": "^8.3.0",
65
65
  "@storybook/addon-console": "^3.0.0",
66
66
  "@storybook/addon-designs": "^8.0.2",
67
- "@storybook/addon-docs": "^8.1.6",
68
- "@storybook/addon-essentials": "^8.1.6",
69
- "@storybook/addon-interactions": "^8.1.6",
70
- "@storybook/addon-links": "^8.1.6",
71
- "@storybook/manager-api": "^8.1.6",
72
- "@storybook/react": "^8.1.6",
73
- "@storybook/react-vite": "^8.1.6",
74
- "@storybook/test": "^8.1.6",
67
+ "@storybook/addon-docs": "^8.3.0",
68
+ "@storybook/addon-essentials": "^8.3.0",
69
+ "@storybook/addon-interactions": "^8.3.0",
70
+ "@storybook/addon-links": "^8.3.0",
71
+ "@storybook/manager-api": "^8.3.0",
72
+ "@storybook/react": "^8.3.0",
73
+ "@storybook/react-vite": "^8.3.0",
74
+ "@storybook/test": "^8.3.0",
75
75
  "@storybook/test-runner": "^0.18.2",
76
- "@storybook/theming": "^8.1.6",
76
+ "@storybook/theming": "^8.3.0",
77
77
  "@svgr/core": "^8.1.0",
78
78
  "@svgr/plugin-jsx": "^8.1.0",
79
79
  "@svgr/plugin-prettier": "^8.1.0",
80
80
  "@svgr/plugin-svgo": "^8.1.0",
81
- "@swc/core": "^1.5.27",
81
+ "@swc/core": "^1.7.26",
82
82
  "@swc/jest": "^0.2.36",
83
83
  "@testing-library/jest-dom": "^6.4.5",
84
84
  "@testing-library/react": "^16.0.0",
@@ -130,7 +130,7 @@
130
130
  "rollup-plugin-tsc-alias": "^1.1.2",
131
131
  "rollup-plugin-typescript2": "^0.36.0",
132
132
  "rollup-plugin-visualizer": "^5.12.0",
133
- "storybook": "^8.1.6",
133
+ "storybook": "^8.3.0",
134
134
  "storybook-addon-deep-controls": "^0.6.2",
135
135
  "storybook-dark-mode": "^4.0.1",
136
136
  "ts-jest": "^29.1.4",