{"version":3,"file":"Option.cjs","sources":["../../../../src/components/select/Option.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport {\n    type ComponentPropsWithoutRef,\n    type MouseEvent,\n    type RefObject,\n    forwardRef,\n    useCallback,\n    useEffect,\n    useRef,\n} from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\nimport { Flex } from \"../flex/Flex.js\";\nimport { Text } from \"../typography/Text.js\";\n\nexport type OptionProps = Omit<\n    ComponentPropsWithoutRef<\"button\">,\n    \"aria-selected\" | \"children\" | \"role\" | \"type\" | \"value\"\n> &\n    ValuePair & {\n        multiple?: boolean;\n        selected?: boolean;\n        selectRef: RefObject<HTMLSelectElement>;\n    };\n\nexport const Option = forwardRef<HTMLButtonElement, OptionProps>(\n    function Option(props, ref) {\n        const {\n            className = \"\",\n            multiple = false,\n            selected = false,\n            selectRef,\n            label,\n            description,\n            media,\n            value,\n            ...rest\n        } = props;\n\n        const mediaRef = useRef<HTMLSpanElement>(null);\n        const labelRef = useRef<HTMLSpanElement>(null);\n\n        const syncValueToSelect = useCallback(\n            (event: KeyboardEvent | MouseEvent) => {\n                const button = (\n                    event.target as HTMLElement\n                ).closest<HTMLButtonElement>(\"button\");\n                if (!button || !selectRef.current || selectRef.current.disabled)\n                    return;\n\n                const option = Array.from(selectRef.current.options).find(\n                    (option) => option.value === button.value,\n                );\n                if (!option) return;\n\n                option.selected = multiple ? !option.selected : true;\n                selectRef.current.dispatchEvent(\n                    new Event(\"change\", { bubbles: true }),\n                );\n            },\n            [selectRef, multiple],\n        );\n\n        useEffect(() => {\n            if (!media || !labelRef.current || !mediaRef.current) return;\n            const labelElement = labelRef.current;\n            const mediaElement = mediaRef.current;\n            const observer = new ResizeObserver(() => {\n                mediaElement.style.setProperty(\n                    \"--media-size\",\n                    `${labelElement.offsetHeight}px`,\n                );\n            });\n            observer.observe(labelElement);\n            return () => observer.disconnect();\n        }, [media]);\n\n        return (\n            <button\n                ref={ref}\n                // biome-ignore lint/a11y/useSemanticElements: vi kan ikke style option-elementet\n                role=\"option\"\n                type=\"button\"\n                className={clsx(\"jkl-option\", className)}\n                value={value}\n                data-multiple={multiple || undefined}\n                aria-selected={selected}\n                {...rest}\n                onClick={(event) => {\n                    rest.onClick?.(event);\n                    syncValueToSelect(event);\n                }}\n            >\n                <Flex\n                    as=\"span\"\n                    direction=\"column\"\n                    gap=\"4\"\n                    className=\"jkl-option__label\"\n                    ref={labelRef}\n                >\n                    <Text short as=\"span\">\n                        {label}\n                    </Text>\n                    {description && (\n                        <Text short subdued as=\"span\" size=\"xs\">\n                            {description}\n                        </Text>\n                    )}\n                </Flex>\n                {media && (\n                    <span className=\"jkl-option__media\" ref={mediaRef}>\n                        {media}\n                    </span>\n                )}\n            </button>\n        );\n    },\n);\n"],"names":["Option","forwardRef","props","ref","className","multiple","selected","selectRef","label","description","media","value","rest","mediaRef","useRef","labelRef","syncValueToSelect","useCallback","event","button","target","closest","current","disabled","option","Array","from","options","find","dispatchEvent","Event","bubbles","useEffect","labelElement","mediaElement","observer","ResizeObserver","style","setProperty","offsetHeight","observe","disconnect","jsxs","role","type","clsx","onClick","children","Flex","as","direction","gap","jsx","Text","short","subdued","size"],"mappings":"kPAwBaA,EAASC,EAAAA,WAClB,SAAgBC,EAAOC,GACnB,MACIC,UAAAA,EAAY,GACZC,SAAAA,GAAW,EACXC,SAAAA,GAAW,EACXC,UAAAA,EACAC,MAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAC,MAAAA,KACGC,GACHV,EAEEW,EAAWC,EAAAA,OAAwB,MACnCC,EAAWD,EAAAA,OAAwB,MAEnCE,EAAoBC,EAAAA,YACrBC,IACG,MAAMC,EACFD,EAAME,OACRC,QAA2B,UAC7B,IAAKF,IAAWZ,EAAUe,SAAWf,EAAUe,QAAQC,SACnD,OAEJ,MAAMC,EAASC,MAAMC,KAAKnB,EAAUe,QAAQK,SAASC,KAChDJ,GAAWA,EAAOb,QAAUQ,EAAOR,OAEnCa,IAELA,EAAOlB,UAAWD,IAAYmB,EAAOlB,SACrCC,EAAUe,QAAQO,cACd,IAAIC,MAAM,SAAU,CAAEC,SAAS,OAGvC,CAACxB,EAAWF,IAGhB2B,OAAAA,EAAAA,UAAU,KACN,IAAKtB,IAAUK,EAASO,UAAYT,EAASS,QAAS,OACtD,MAAMW,EAAelB,EAASO,QACxBY,EAAerB,EAASS,QACxBa,EAAW,IAAIC,eAAe,KAChCF,EAAaG,MAAMC,YACf,eACA,GAAGL,EAAaM,oBAGxB,OAAAJ,EAASK,QAAQP,GACV,IAAME,EAASM,cACvB,CAAC/B,IAGAgC,EAAAA,KAAC,SAAA,CACGvC,IAAAA,EAEAwC,KAAK,SACLC,KAAK,SACLxC,UAAWyC,EAAAA,KAAK,aAAczC,GAC9BO,MAAAA,EACA,gBAAeN,QAAY,EAC3B,gBAAeC,KACXM,EACJkC,QAAU5B,IACNN,EAAKkC,UAAU5B,GACfF,EAAkBE,IAGtB6B,SAAA,CAAAL,EAAAA,KAACM,EAAAA,KAAA,CACGC,GAAG,OACHC,UAAU,SACVC,IAAI,IACJ/C,UAAU,oBACVD,IAAKY,EAELgC,SAAA,CAAAK,MAACC,EAAAA,KAAA,CAAKC,OAAK,EAACL,GAAG,OACVF,SAAAvC,IAEJC,GACG2C,EAAAA,IAACC,EAAAA,KAAA,CAAKC,OAAK,EAACC,SAAO,EAACN,GAAG,OAAOO,KAAK,KAC9BT,SAAAtC,OAIZC,GACG0C,EAAAA,IAAC,OAAA,CAAKhD,UAAU,oBAAoBD,IAAKU,EACpCkC,SAAArC,MAKrB"}