@magiclabs/ui-components 1.48.2 → 1.48.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/primitives/dropdown-selector.js +1 -1
- package/dist/cjs/components/primitives/dropdown-selector.js.map +1 -1
- package/dist/es/components/primitives/dropdown-selector.js +1 -1
- package/dist/es/components/primitives/dropdown-selector.js.map +1 -1
- package/dist/types/components/primitives/dropdown-selector.d.ts +4 -2
- package/dist/types/components/primitives/dropdown-selector.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var t=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";var t=require("react/jsx-runtime"),j=require("@styled/tokens"),U=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"),r=require("react"),m=require("@styled/jsx"),z=require("@styled/css");require("../feedback/callout.js"),require("../feedback/progress-bar.js"),require("./button.js"),require("./checkbox.js"),require("./popover.js"),require("./radio.js"),require("./segmented-control.js"),require("./switch.js");var S=require("./text.js");require("./portal.js"),require("../../hooks/useToast.js"),require("../../recipes/toast.js");var Q=require("../feedback/tooltip.js"),y=require("react-aria");const H={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}},P=r.createContext({selectedOption:null,setSelectedOption:()=>{}}),A=({value:n,label:a,size:d="lg",isFocused:k,optionHoverColor:h})=>{const{selectedOption:v,setSelectedOption:p}=r.useContext(P),i=v?.value===n,s=H[d],C=r.useCallback(()=>{p({value:n,label:a})},[p,n,a]);return t.jsxs(m.HStack,{py:1.5,gap:2,bg:i?"brand.base":k?"brand.lightest":"",_hover:i?{}:{bg:h||"brand.lightest"},onClick:C,style:{paddingLeft:s.width,paddingRight:s.width},children:[t.jsx(m.Box,{style:{minWidth:s.width},children:i&&t.jsx(M.default,{width:s.check,height:s.check,color:j.token("colors.text.quaternary")})}),t.jsx(S.default,{size:d,fontWeight:"medium",fontColor:i?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:a})]})},W=({children:n,onSelect:a,label:d,placeholder:k="Select one",selectedValue:h,size:v="lg",tooltipContent:p,disabled:i,viewMax:s=5,optionHoverColor:C,...F})=>{const[f,x]=r.useState(!1),[o,b]=r.useState(null),g=r.useRef(null),q=r.useRef(null),u=H[v],R=s*u.mult+1,B=r.useCallback(()=>{x(e=>!e),f||(b(null),setTimeout(()=>{var e;return(e=q.current)===null||e===void 0?void 0:e.focus()}))},[f]),L=r.useCallback(e=>{a(e.value),x(!1)},[a]),D=r.useMemo(()=>{const e=r.Children.toArray(n).find(l=>l.props.value===h);return e?e.props.label:k},[h,n]),{buttonProps:N}=y.useButton({...F,isDisabled:i,onPress:B},g),{focusProps:_,isFocusVisible:I}=y.useFocusRing(),{keyboardProps:K}=y.useKeyboard({onKeyDown:e=>{var l,c;if(!f)return;let w=o;const O=r.Children.toArray(n);switch(e.key){case"ArrowUp":e.preventDefault(),o===null?b(r.Children.count(n)-1):(w=o>0?o-1:r.Children.count(n)-1,b(w));break;case"ArrowDown":e.preventDefault(),o===null?b(0):(w=o<r.Children.count(n)-1?o+1:0,b(w));break;case"Enter":if(e.preventDefault(),(l=g.current)===null||l===void 0||l.focus(),o===null)return;if(o>=0&&o<O.length){const E=O[o];E&&a(E.props.value)}break;case"Escape":x(!1),(c=g.current)===null||c===void 0||c.focus();break}}});return r.useEffect(()=>{const e=l=>{var c;!((c=q.current)===null||c===void 0)&&c.contains(l.target)||x(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),t.jsx(P.Provider,{value:{selectedOption:{value:h??"",label:D},setSelectedOption:L},children:t.jsxs(m.VStack,{gap:2,w:"full",alignItems:"flex-start",children:[(d||p)&&t.jsxs(m.HStack,{gap:2,pointerEvents:i?"none":"auto",opacity:i?.3:"",transition:"all linear 120ms",children:[d&&t.jsx(S.default,{size:"sm",fontWeight:"medium",children:d}),p&&t.jsx(Q.default,{content:p,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:g,...y.mergeProps(N,_,K),children:[t.jsxs(m.HStack,{w:"full",p:4,justifyContent:"space-between",style:{height:u.height},children:[t.jsx(S.default,{truncate:!0,size:v,fontColor:h?"text.primary":"text.tertiary",children:D}),f?t.jsx(V.default,{width:u.caret,height:u.caret,color:j.token("colors.brand.base")}):t.jsx(U.default,{width:u.caret,height:u.caret,color:j.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:`${R}rem`,top:u.top},overflowY:"auto",outline:"none",zIndex:"max",children:r.Children.map(n,(e,l)=>r.cloneElement(e,{isFocused:l===o,size:v,optionHoverColor:C}))})]})]})})};A.displayName="DropdownOption",W.displayName="DropdownSelector",exports.DropdownOption=A,exports.DropdownSelector=W;
|
|
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\n gap={2}\n pointerEvents={disabled ? 'none' : 'auto'}\n opacity={disabled ? 0.3 : ''}\n transition={'all linear 120ms'}\n >\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
|
+
{"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 optionHoverColor?: string;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n optionHoverColor?: string;\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, optionHoverColor }: 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: optionHoverColor || '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 optionHoverColor,\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\n gap={2}\n pointerEvents={disabled ? 'none' : 'auto'}\n opacity={disabled ? 0.3 : ''}\n transition={'all linear 120ms'}\n >\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 optionHoverColor,\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","optionHoverColor","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{jsxs as
|
|
1
|
+
import{jsxs as g,jsx as o}from"react/jsx-runtime";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{createContext as Q,useContext as X,useCallback as D,useState as W,useRef as A,useMemo as Z,Children as m,useEffect as ee,cloneElement as te}from"react";import{HStack as E,Box as B,VStack as re}from"@styled/jsx";import{css as F}from"@styled/css";import"../feedback/callout.js";import"../feedback/progress-bar.js";import"./button.js";import"./checkbox.js";import"./popover.js";import"./radio.js";import"./segmented-control.js";import"./switch.js";import O from"./text.js";import"./portal.js";import"../../hooks/useToast.js";import"../../recipes/toast.js";import oe from"../feedback/tooltip.js";import{useButton as ne,useFocusRing as le,useKeyboard as ie,mergeProps as se}from"react-aria";const L={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}},N=Q({selectedOption:null,setSelectedOption:()=>{}}),_=({value:r,label:i,size:u="lg",isFocused:x,optionHoverColor:d})=>{const{selectedOption:h,setSelectedOption:p}=X(N),l=h?.value===r,s=L[u],k=D(()=>{p({value:r,label:i})},[p,r,i]);return g(E,{py:1.5,gap:2,bg:l?"brand.base":x?"brand.lightest":"",_hover:l?{}:{bg:d||"brand.lightest"},onClick:k,style:{paddingLeft:s.width,paddingRight:s.width},children:[o(B,{style:{minWidth:s.width},children:l&&o(G,{width:s.check,height:s.check,color:S("colors.text.quaternary")})}),o(O,{size:u,fontWeight:"medium",fontColor:l?"text.quaternary":"text.primary",styles:{textAlign:"left"},children:i})]})},j=({children:r,onSelect:i,label:u,placeholder:x="Select one",selectedValue:d,size:h="lg",tooltipContent:p,disabled:l,viewMax:s=5,optionHoverColor:k,...q})=>{const[f,v]=W(!1),[t,b]=W(null),w=A(null),C=A(null),a=L[h],I=s*a.mult+1,K=D(()=>{v(e=>!e),f||(b(null),setTimeout(()=>{var e;return(e=C.current)===null||e===void 0?void 0:e.focus()}))},[f]),R=D(e=>{i(e.value),v(!1)},[i]),z=Z(()=>{const e=m.toArray(r).find(n=>n.props.value===d);return e?e.props.label:x},[d,r]),{buttonProps:V}=ne({...q,isDisabled:l,onPress:K},w),{focusProps:$,isFocusVisible:M}=le(),{keyboardProps:T}=ie({onKeyDown:e=>{var n,c;if(!f)return;let y=t;const P=m.toArray(r);switch(e.key){case"ArrowUp":e.preventDefault(),t===null?b(m.count(r)-1):(y=t>0?t-1:m.count(r)-1,b(y));break;case"ArrowDown":e.preventDefault(),t===null?b(0):(y=t<m.count(r)-1?t+1:0,b(y));break;case"Enter":if(e.preventDefault(),(n=w.current)===null||n===void 0||n.focus(),t===null)return;if(t>=0&&t<P.length){const H=P[t];H&&i(H.props.value)}break;case"Escape":v(!1),(c=w.current)===null||c===void 0||c.focus();break}}});return ee(()=>{const e=n=>{var c;!((c=C.current)===null||c===void 0)&&c.contains(n.target)||v(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[]),o(N.Provider,{value:{selectedOption:{value:d??"",label:z},setSelectedOption:R},children:g(re,{gap:2,w:"full",alignItems:"flex-start",children:[(u||p)&&g(E,{gap:2,pointerEvents:l?"none":"auto",opacity:l?.3:"",transition:"all linear 120ms",children:[u&&o(O,{size:"sm",fontWeight:"medium",children:u}),p&&o(oe,{content:p,children:o(J,{className:F({w:4,h:4,color:"neutral.primary"})})})]}),g("button",{className:F({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:w,...se(V,$,T),children:[g(E,{w:"full",p:4,justifyContent:"space-between",style:{height:a.height},children:[o(O,{truncate:!0,size:h,fontColor:d?"text.primary":"text.tertiary",children:z}),f?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")})]}),f&&o(B,{ref:C,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:`${I}rem`,top:a.top},overflowY:"auto",outline:"none",zIndex:"max",children:m.map(r,(e,n)=>te(e,{isFocused:n===t,size:h,optionHoverColor:k}))})]})]})})};_.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\n gap={2}\n pointerEvents={disabled ? 'none' : 'auto'}\n opacity={disabled ? 0.3 : ''}\n transition={'all linear 120ms'}\n >\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
|
+
{"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 optionHoverColor?: string;\n}\n\nexport interface DropdownOptionProps {\n value: string;\n label: string;\n isFocused?: boolean;\n size?: DropdownSelectorProps['size'];\n optionHoverColor?: string;\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, optionHoverColor }: 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: optionHoverColor || '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 optionHoverColor,\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\n gap={2}\n pointerEvents={disabled ? 'none' : 'auto'}\n opacity={disabled ? 0.3 : ''}\n transition={'all linear 120ms'}\n >\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 optionHoverColor,\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","optionHoverColor","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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"}
|
|
@@ -10,12 +10,14 @@ export interface DropdownSelectorProps extends AriaButtonProps {
|
|
|
10
10
|
tooltipContent?: string;
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
viewMax?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
13
|
+
optionHoverColor?: string;
|
|
13
14
|
}
|
|
14
15
|
export interface DropdownOptionProps {
|
|
15
16
|
value: string;
|
|
16
17
|
label: string;
|
|
17
18
|
isFocused?: boolean;
|
|
18
19
|
size?: DropdownSelectorProps['size'];
|
|
20
|
+
optionHoverColor?: string;
|
|
19
21
|
}
|
|
20
22
|
interface OptionData {
|
|
21
23
|
value: string;
|
|
@@ -26,11 +28,11 @@ export interface DropdownContextType {
|
|
|
26
28
|
setSelectedOption: (option: OptionData) => void;
|
|
27
29
|
}
|
|
28
30
|
export declare const DropdownOption: {
|
|
29
|
-
({ value, label, size, isFocused }: DropdownOptionProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
({ value, label, size, isFocused, optionHoverColor }: DropdownOptionProps): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
displayName: string;
|
|
31
33
|
};
|
|
32
34
|
export declare const DropdownSelector: {
|
|
33
|
-
({ children, onSelect, label, placeholder, selectedValue, size, tooltipContent, disabled, viewMax, ...props }: DropdownSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
({ children, onSelect, label, placeholder, selectedValue, size, tooltipContent, disabled, viewMax, optionHoverColor, ...props }: DropdownSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
34
36
|
displayName: string;
|
|
35
37
|
};
|
|
36
38
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-selector.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"names":[],"mappings":"AAMA,OAAO,EAKL,SAAS,EAOV,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAoD,MAAM,YAAY,CAAC;AAE/F,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"dropdown-selector.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/dropdown-selector.tsx"],"names":[],"mappings":"AAMA,OAAO,EAKL,SAAS,EAOV,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAoD,MAAM,YAAY,CAAC;AAE/F,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,UAAU,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACjD;AAaD,eAAO,MAAM,cAAc;0DAAgE,mBAAmB;;CAiC7G,CAAC;AAEF,eAAO,MAAM,gBAAgB;qIAY1B,qBAAqB;;CA4LvB,CAAC"}
|