{"version":3,"file":"Select.cjs","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n    type CSSProperties,\n    type FocusEvent,\n    forwardRef,\n    type KeyboardEvent,\n    type MouseEvent,\n    type RefObject,\n    useCallback,\n    useEffect,\n    useMemo,\n    useRef,\n    useState,\n} from \"react\";\nimport { useAnimatedHeight } from \"../../hooks/useAnimatedHeight/useAnimatedHeight.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport { usePreviousValue } from \"../../hooks/usePreviousValue/usePreviousValue.js\";\nimport { type ValuePair, getValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport type { PopupTipProps } from \"../tooltip/types.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\nimport type { SelectProps } from \"./types.js\";\n\nconst noop = () => {\n    return;\n};\n\ninterface Option extends ValuePair {\n    visible: boolean;\n}\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n    (props, forwardedSelectRef) => {\n        const {\n            id,\n            name,\n            items,\n            value,\n            label,\n            labelProps,\n            onChange,\n            onBlur,\n            onFocus,\n            className,\n            helpLabel,\n            errorLabel,\n            invalid,\n            searchable = false,\n            inline = false,\n            defaultPrompt = \"Velg\",\n            width,\n            maxShownOptions = 5,\n            style,\n            tooltip,\n            ...rest\n        } = props;\n\n        const listId = useId(id || \"jkl-select\", { generateSuffix: !id });\n        const labelId = `${listId}_label`;\n        const buttonId = `${listId}_button`;\n        const searchInputId = `${listId}_search-input`;\n\n        const [dropdownIsShown, setShown] = useState(false);\n        const toggleListVisibility = useCallback(() => {\n            setShown((previousValue) => !previousValue);\n        }, []);\n\n        /// Søk\n\n        const isSearchable = Boolean(searchable);\n        const showSearchInputField = isSearchable && dropdownIsShown;\n        const [searchValue, setSearchValue] = useState(\"\");\n        const searchFn = useCallback(\n            (item: ValuePair) => {\n                if (\n                    item.label.toLowerCase().includes(searchValue.toLowerCase())\n                ) {\n                    return true;\n                }\n\n                if (typeof searchable === \"function\") {\n                    return searchable(searchValue, item);\n                }\n\n                return false;\n            },\n            [searchable, searchValue],\n        );\n        const visibleItems: Option[] = useMemo(\n            () =>\n                items.map(getValuePair).map((item) => {\n                    const visible =\n                        !isSearchable || searchValue === \"\" || searchFn(item);\n                    return { ...item, visible };\n                }),\n            [items, isSearchable, searchValue, searchFn],\n        );\n        const valueIsInItems: boolean = useMemo(() => {\n            if (typeof value === \"undefined\") {\n                return false;\n            }\n            return items.some((item) =>\n                typeof item === \"string\"\n                    ? item === value\n                    : item.value === value,\n            );\n        }, [value, items]);\n\n        /// Valg av <option>\n\n        const [selectedValue, setSelectedValue] = useState<string>(\n            valueIsInItems && value !== undefined ? value : \"\",\n        );\n        const hasSelectedValue = selectedValue !== \"\";\n        const selectedValueLabel = useMemo(\n            () =>\n                visibleItems.find((item) => item.value === selectedValue)\n                    ?.label || defaultPrompt,\n            [visibleItems, selectedValue, defaultPrompt],\n        );\n\n        const selectRef = useRef<HTMLSelectElement | null>(null);\n        // Hjelpefunksjon som gjør det enklere å forwarde refen og å bruke den selv internt\n        const unifiedSelectRef = useCallback(\n            (instance: HTMLSelectElement | null) => {\n                selectRef.current = instance;\n                if (forwardedSelectRef) {\n                    if (typeof forwardedSelectRef === \"function\") {\n                        forwardedSelectRef(instance);\n                    } else {\n                        forwardedSelectRef.current = instance;\n                    }\n                }\n                if (instance) {\n                    setSelectedValue(instance.value);\n                }\n            },\n            [forwardedSelectRef],\n        );\n\n        const previousValue = usePreviousValue(value);\n        useEffect(() => {\n            if (value === previousValue) {\n                return;\n            }\n            if (typeof value === \"undefined\" || !valueIsInItems) {\n                setSelectedValue(\"\");\n            } else {\n                setSelectedValue(value);\n            }\n        }, [value, previousValue, valueIsInItems]);\n\n        const selectOption = useCallback(\n            (item: Option) => {\n                const nextValue = item.value;\n                setSearchValue(\"\");\n                setSelectedValue(nextValue);\n                toggleListVisibility();\n                buttonRef.current?.focus();\n            },\n            [toggleListVisibility],\n        );\n\n        // La komponenten rendre <select> med den valgte verdien før onChange trigges, slik at\n        // react-hook-form@>7.41.1 behandler feltet som at det har en verdi.\n        const previousSelectedValue = usePreviousValue(selectedValue);\n        useEffect(() => {\n            // previousSelectedValue er undefined på første render, men da vil vi ikke ha en onChange uansett\n            if (\n                typeof previousSelectedValue === \"undefined\" ||\n                previousSelectedValue === selectedValue ||\n                selectedValue === value\n            ) {\n                return;\n            }\n            if (onChange) {\n                onChange({\n                    type: \"change\",\n                    target: { name, value: selectedValue },\n                });\n            }\n            if (selectRef.current) {\n                selectRef.current.dispatchEvent(\n                    new Event(\"change\", { bubbles: true }),\n                );\n            }\n        }, [onChange, name, value, selectedValue, previousSelectedValue]);\n\n        /// Fokushåndtering\n\n        const componentRootElementRef = useRef<HTMLDivElement>(null);\n        const focusInsideRef = useRef(false);\n        const searchFieldRef = useRef<HTMLInputElement>(null);\n        const buttonRef = useRef<HTMLButtonElement>(null);\n\n        const handleFocusPlacement = useCallback(\n            (isOpen: boolean, ref: RefObject<HTMLElement | null>) => {\n                if (isOpen && !isSearchable) {\n                    const listElement = ref.current;\n                    if (listElement) {\n                        focusSelected(listElement, selectedValue);\n                    }\n                } else if (isOpen) {\n                    if (searchFieldRef.current) {\n                        searchFieldRef.current.focus();\n                    }\n                } else {\n                    if (focusInsideRef.current && buttonRef.current) {\n                        buttonRef.current.focus();\n                    }\n                }\n            },\n            [isSearchable, selectedValue],\n        );\n\n        const [dropdownRef] = useAnimatedHeight<HTMLDivElement>(\n            dropdownIsShown,\n            {\n                onFirstVisible: handleFocusPlacement,\n                onTransitionEnd: handleFocusPlacement,\n            },\n        );\n\n        useListNavigation({ ref: dropdownRef });\n\n        const close = useCallback(() => {\n            if (isSearchable) {\n                setSearchValue(\"\");\n            }\n            if (onBlur) {\n                onBlur({\n                    type: \"blur\",\n                    target: { name, value: selectedValue },\n                });\n                selectRef.current?.dispatchEvent(\n                    new Event(\"focusout\", { bubbles: true }),\n                );\n            }\n            focusInsideRef.current = false;\n            setShown(false);\n        }, [onBlur, isSearchable, name, selectedValue]);\n\n        const handleBlur = useCallback(\n            (e: FocusEvent<HTMLButtonElement | HTMLInputElement>) => {\n                const componentRootElement = componentRootElementRef.current;\n                // There are known issues in Firefox when using \"relatedTarget\" in onBlur events:\n                // https://github.com/facebook/react/issues/2011\n                // This might be fixed in react 17. Se issue above.\n                const nextFocusIsInsideComponent =\n                    componentRootElement?.contains(e.relatedTarget as Node);\n                if (!nextFocusIsInsideComponent) {\n                    close();\n                }\n            },\n            [close],\n        );\n\n        const handleFocus = useCallback(() => {\n            if (!focusInsideRef.current) {\n                if (onFocus) {\n                    onFocus({\n                        type: \"change\",\n                        target: { name, value: selectedValue },\n                    });\n                }\n                focusInsideRef.current = true;\n            }\n        }, [onFocus, selectedValue, name]);\n\n        const handleMouseOver = useCallback(\n            (e: MouseEvent<HTMLButtonElement>) => {\n                // Ved mouseOver på options flytter vi fokus til dem for å unngå \"dobbel fokus\"\n                // der det ser ut som to forskjellige elementer er fokusert/hovered samtidig\n                (e.target as HTMLButtonElement).focus({ preventScroll: true });\n            },\n            [],\n        );\n\n        // Handle focus and blur of hidden select element\n        useEffect(() => {\n            const select = selectRef.current;\n            const searchField = searchFieldRef.current;\n            const button = buttonRef.current;\n            const componentRootElement = componentRootElementRef.current;\n\n            select?.addEventListener(\"focus\", () => {\n                showSearchInputField ? searchField?.focus() : button?.focus();\n            });\n            select?.addEventListener(\"blur\", function (this, ev) {\n                componentRootElement?.contains(ev.relatedTarget as Node) &&\n                    ev.preventDefault();\n            });\n\n            return () => {\n                select?.removeEventListener(\"focus\", () => {\n                    showSearchInputField\n                        ? searchField?.focus()\n                        : button?.focus();\n                });\n                select?.removeEventListener(\"blur\", function (this, ev) {\n                    componentRootElement?.contains(ev.relatedTarget as Node) &&\n                        ev.preventDefault();\n                });\n            };\n        }, [showSearchInputField]);\n\n        /// Tastaturnavigasjon\n\n        // Add support for opening dropdown with arrowkey down as expected from native select\n        // onKeyDown to stop ArrowDown from scrolling the page\n        const handleOnKeyDown = useCallback(\n            (e: KeyboardEvent<HTMLButtonElement>) => {\n                if (\n                    (e.key === \"ArrowDown\" || e.key === \" \") &&\n                    !dropdownIsShown\n                ) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    setShown(true);\n                } else if (e.key === \"Escape\") {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    setShown(false);\n                }\n            },\n            [dropdownIsShown],\n        );\n\n        // onKeyDown to stop ArrowDown from scrolling the page\n        const handleSearchOnKeyDown = useCallback(\n            (e: KeyboardEvent<HTMLInputElement>) => {\n                if (e.key === \"ArrowDown\") {\n                    e.preventDefault();\n                    e.stopPropagation();\n\n                    const listElement = dropdownRef.current;\n                    if (listElement) {\n                        if (isSearchable) {\n                            // Flytt fokus til det første elementet i listen, ikke det forrige valgte.\n                            // Ved endring i filter er det ikke gitt at vi ønsker å ta utgangspunkt i\n                            // den valgte verdien.\n                            focusSelected(listElement, undefined);\n                        } else {\n                            focusSelected(listElement, selectedValue);\n                        }\n                    }\n                } else if (e.key === \"Escape\") {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    setShown(false);\n                } else if (e.key === \"Tab\" && !e.shiftKey) {\n                    const listElement = dropdownRef.current;\n                    if (listElement) {\n                        e.preventDefault();\n                        e.stopPropagation();\n                        focusSelected(listElement, selectedValue);\n                    }\n                } else if (e.key === \"Enter\" && dropdownIsShown) {\n                    // Should not propagate Enter keyevent because form might submit\n                    e.preventDefault();\n                    e.stopPropagation();\n                }\n            },\n            [dropdownRef, selectedValue, isSearchable, dropdownIsShown],\n        );\n\n        // onKeyDown so this Tab listener isn't triggered by tabbing from search field to option\n        const handleOptionOnKeyDown = useCallback(\n            (e: KeyboardEvent<HTMLButtonElement>) => {\n                if (e.key === \"Tab\") {\n                    e.preventDefault();\n                    e.stopPropagation();\n\n                    if (e.shiftKey && searchFieldRef.current) {\n                        searchFieldRef.current.focus();\n                    } else if (buttonRef.current) {\n                        // Mimic behaviour of Firefox and native select, where Tab selects the current item and closes the menu\n                        setSelectedValue(e.currentTarget.value);\n                        setShown(false);\n                        buttonRef.current.focus();\n                    }\n                } else if (e.key === \"ArrowUp\") {\n                    if (dropdownRef.current && searchFieldRef.current) {\n                        // Can't be based on index since the first item might be filtered out\n                        const firstVisible = dropdownRef.current.querySelector(\n                            '[role=\"option\"]:not([hidden])',\n                        );\n                        if (\n                            e.currentTarget.id === firstVisible?.id &&\n                            searchFieldRef.current\n                        ) {\n                            searchFieldRef.current.focus();\n                        }\n                    }\n                }\n            },\n            [dropdownRef],\n        );\n\n        // Add support for closing the dropdown with Escape like native select. Unfortunately, Escape does not trigger the button onKeyDown.\n        useEffect(() => {\n            const handleEscape = (e: globalThis.KeyboardEvent) => {\n                if (e.key === \"Escape\" && dropdownIsShown) {\n                    setShown(false);\n                }\n            };\n            if (typeof window !== \"undefined\" && dropdownIsShown) {\n                window.addEventListener(\"keydown\", handleEscape);\n            }\n            return () => {\n                if (typeof window !== \"undefined\") {\n                    window.removeEventListener(\"keydown\", handleEscape);\n                }\n            };\n        }, [dropdownIsShown]);\n\n        return (\n            <>\n                <select\n                    name={name}\n                    tabIndex={-1}\n                    data-testid=\"jkl-native-select\"\n                    className=\"jkl-sr-only\"\n                    aria-hidden\n                    ref={unifiedSelectRef}\n                    value={selectedValue}\n                    onChange={noop} // React complains unless we give an onChange handler. This is technically a read-only field, but readOnly isn't an option here.\n                >\n                    <option value=\"\" />{\" \"}\n                    {/* Tom option må være et valg, ellers vil <select> alltid ha en value */}\n                    {visibleItems.map((item) => (\n                        <option\n                            key={`${listId}-opt-${item.value}`}\n                            hidden={!item.visible}\n                            value={item.value}\n                        >\n                            {item.label}\n                        </option>\n                    ))}\n                </select>\n                <InputGroup\n                    ref={componentRootElementRef}\n                    data-testid=\"jkl-select\"\n                    className={clsx(\"jkl-select\", className, {\n                        \"jkl-select--inline\": inline,\n                        \"jkl-select--open\":\n                            dropdownIsShown &&\n                            visibleItems.some((item) => item.visible),\n                        \"jkl-select--no-value\": !hasSelectedValue,\n                        \"jkl-select--invalid\": !!errorLabel || invalid,\n                    })}\n                    tooltip={\n                        tooltip && React.isValidElement<PopupTipProps>(tooltip)\n                            ? React.cloneElement(tooltip, {\n                                  triggerProps: {\n                                      ...tooltip.props.triggerProps,\n                                      onFocus: (\n                                          e: FocusEvent<HTMLButtonElement>,\n                                      ) => {\n                                          tooltip.props.triggerProps?.onFocus?.(\n                                              e,\n                                          );\n                                          close();\n                                      },\n                                  },\n                              })\n                            : null\n                    }\n                    {...rest}\n                    id={isSearchable ? searchInputId : buttonId}\n                    style={\n                        {\n                            \"--jkl-select-max-shown-options\": maxShownOptions,\n                            ...style,\n                        } as CSSProperties\n                    }\n                    label={label}\n                    labelProps={{\n                        id: labelId,\n                        srOnly: inline,\n                        ...labelProps,\n                        htmlFor: isSearchable ? searchInputId : buttonId,\n                    }}\n                    helpLabel={helpLabel}\n                    errorLabel={errorLabel}\n                    render={({\n                        \"aria-invalid\": ariaInvalid,\n                        ...inputProps\n                    }) => (\n                        <div\n                            className=\"jkl-select__outer-wrapper\"\n                            style={{ width }}\n                        >\n                            {isSearchable && (\n                                <input\n                                    {...inputProps}\n                                    aria-invalid={ariaInvalid}\n                                    id={searchInputId}\n                                    hidden={!showSearchInputField}\n                                    ref={searchFieldRef}\n                                    placeholder=\"Søk\"\n                                    value={searchValue}\n                                    onChange={(e) =>\n                                        setSearchValue(e.target.value)\n                                    }\n                                    data-testid=\"jkl-select__search-input\"\n                                    className=\"jkl-select__search-input\"\n                                    aria-autocomplete=\"list\"\n                                    aria-activedescendant={\n                                        hasSelectedValue\n                                            ? `${listId}__${toLower(\n                                                  selectedValue,\n                                              )}`\n                                            : undefined\n                                    }\n                                    aria-controls={listId}\n                                    aria-expanded={dropdownIsShown}\n                                    role=\"combobox\"\n                                    onKeyDown={handleSearchOnKeyDown}\n                                    onBlur={handleBlur}\n                                    onFocus={handleFocus}\n                                    onClick={(e) => {\n                                        e.stopPropagation();\n                                    }}\n                                />\n                            )}\n                            {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}\n                            <button\n                                // Nei dette er ikke i henhold til speccen, men VoiceOver leser den likevel og det er oppførselen vi ønsker\n                                aria-invalid={ariaInvalid}\n                                {...inputProps}\n                                id={buttonId}\n                                ref={buttonRef}\n                                hidden={showSearchInputField}\n                                type=\"button\"\n                                name={`${name}-btn`}\n                                className={clsx(\"jkl-select__button\", {\n                                    \"jkl-select__button--active-value\":\n                                        !!selectedValue,\n                                })}\n                                data-testid=\"jkl-select__button\"\n                                aria-label={`${\n                                    selectedValueLabel || \"Velg\"\n                                },${label}`}\n                                aria-expanded={dropdownIsShown}\n                                aria-controls={listId}\n                                onBlur={handleBlur}\n                                onFocus={handleFocus}\n                                onKeyDown={handleOnKeyDown}\n                                onClick={toggleListVisibility}\n                                onMouseDown={(e) => {\n                                    // Workaround for en Safari-bug hvor e.relatedTarget er null i onBlur\n                                    // https://twitter.com/MilesSorce/status/1278762360669265925\n                                    e.preventDefault();\n                                    buttonRef.current?.focus();\n                                }}\n                            >\n                                {selectedValueLabel}\n                            </button>\n                            <div\n                                id={listId}\n                                ref={dropdownRef}\n                                // biome-ignore lint/a11y/useSemanticElements: Vi reimplementerer select\n                                role=\"listbox\"\n                                className=\"jkl-select__options-menu\"\n                                hidden={\n                                    !dropdownIsShown ||\n                                    visibleItems.every((item) => !item.visible)\n                                }\n                                aria-labelledby={labelId}\n                                tabIndex={-1}\n                                data-focus=\"controlled\" // lar oss styre markering av valg vha focus\n                            >\n                                {visibleItems.map((item, i) =>\n                                    // Det er viktig at vi _fjerner_ elementer som ikke er synlige fra DOMen for at tastaturnavigasjon skal fungere.\n                                    // For eksempel, hvis vi har elementene Apple, Samsung og LG i den rekkefølgen og søker etter \"l\"\n                                    // vil Samsung ikke synes. Om vi bare setter hidden-attributtet på Samsung vil ArrowDown fra Apple ikke fungere.\n                                    // Dette lar seg ikke gjenskape i en enhetstest med JSDOM + user-events, og Cypress lukker Select\n                                    // ved første {downArrow} ¯\\_(ツ)_/¯. Så please test scenariet over manuelt om dette skaper trøbbel for deg.\n                                    item.visible ? (\n                                        <button\n                                            key={`${listId}-${item.value}`}\n                                            hidden={!item.visible}\n                                            type=\"button\"\n                                            id={`${listId}__${toLower(\n                                                item.value,\n                                            )}`}\n                                            className=\"jkl-select__option\"\n                                            data-testid=\"jkl-select__option\"\n                                            aria-selected={\n                                                item.value === selectedValue\n                                            }\n                                            // biome-ignore lint/a11y/useSemanticElements: Vi reimplementerer select\n                                            role=\"option\"\n                                            value={item.value}\n                                            data-testautoid={`jkl-select__option-${i}`}\n                                            onBlur={handleBlur}\n                                            onFocus={handleFocus}\n                                            onKeyDown={handleOptionOnKeyDown}\n                                            onClick={(e) => {\n                                                e.preventDefault();\n                                                selectOption(item);\n                                            }}\n                                            onMouseOver={handleMouseOver}\n                                        >\n                                            {item.label}\n                                            {item.description ? (\n                                                <span className=\"jkl-select__option-description\">\n                                                    {item.description}\n                                                </span>\n                                            ) : null}\n                                        </button>\n                                    ) : null,\n                                )}\n                            </div>\n                            <ArrowVerticalAnimated\n                                variant=\"medium\"\n                                pointingDown={!dropdownIsShown}\n                                className=\"jkl-select__arrow\"\n                            />\n                        </div>\n                    )}\n                />\n            </>\n        );\n    },\n);\n\nSelect.displayName = \"Select\";\n"],"names":["noop","Select","forwardRef","props","forwardedSelectRef","id","name","items","value","label","labelProps","onChange","onBlur","onFocus","className","helpLabel","errorLabel","invalid","searchable","inline","defaultPrompt","width","maxShownOptions","style","tooltip","rest","listId","useId","generateSuffix","labelId","buttonId","searchInputId","dropdownIsShown","setShown","useState","toggleListVisibility","useCallback","previousValue","isSearchable","showSearchInputField","searchValue","setSearchValue","searchFn","item","toLowerCase","includes","visibleItems","useMemo","map","getValuePair","visible","valueIsInItems","some","selectedValue","setSelectedValue","hasSelectedValue","selectedValueLabel","find","selectRef","useRef","unifiedSelectRef","instance","current","usePreviousValue","useEffect","selectOption","nextValue","buttonRef","focus","previousSelectedValue","type","target","dispatchEvent","Event","bubbles","componentRootElementRef","focusInsideRef","searchFieldRef","handleFocusPlacement","isOpen","ref","listElement","focusSelected","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","close","handleBlur","e","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","searchField","button","componentRootElement","addEventListener","ev","preventDefault","removeEventListener","handleOnKeyDown","key","stopPropagation","handleSearchOnKeyDown","shiftKey","handleOptionOnKeyDown","currentTarget","firstVisible","querySelector","handleEscape","window","jsxs","Fragment","children","tabIndex","jsx","hidden","InputGroup","clsx","React","isValidElement","cloneElement","triggerProps","srOnly","htmlFor","render","ariaInvalid","inputProps","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","every","i","onMouseOver","description","ArrowVerticalAnimated","variant","pointingDown","displayName"],"mappings":"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"}