@fremtind/jokul 0.37.8 → 0.37.10

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.
Files changed (66) hide show
  1. package/build/build-stats.html +1 -1
  2. package/build/cjs/components/accordion/AccordionItem.cjs +1 -1
  3. package/build/cjs/components/accordion/AccordionItem.cjs.map +1 -1
  4. package/build/cjs/components/select/Select.cjs +1 -1
  5. package/build/cjs/components/select/Select.cjs.map +1 -1
  6. package/build/cjs/components/text-input/BaseTextInput.cjs.map +1 -1
  7. package/build/cjs/components/text-input/BaseTextInput.d.cts +10 -1
  8. package/build/cjs/components/tooltip/PopupTip.cjs +1 -1
  9. package/build/cjs/components/tooltip/PopupTip.cjs.map +1 -1
  10. package/build/cjs/components/tooltip/Tooltip.cjs +1 -1
  11. package/build/cjs/components/tooltip/Tooltip.cjs.map +1 -1
  12. package/build/cjs/components/tooltip/TooltipContent.cjs +1 -1
  13. package/build/cjs/components/tooltip/TooltipContent.cjs.map +1 -1
  14. package/build/cjs/components/tooltip/TooltipContent.d.cts +3 -1
  15. package/build/es/components/accordion/AccordionItem.js +1 -1
  16. package/build/es/components/accordion/AccordionItem.js.map +1 -1
  17. package/build/es/components/select/Select.js +1 -1
  18. package/build/es/components/select/Select.js.map +1 -1
  19. package/build/es/components/text-input/BaseTextInput.d.ts +10 -1
  20. package/build/es/components/text-input/BaseTextInput.js.map +1 -1
  21. package/build/es/components/tooltip/PopupTip.js +1 -1
  22. package/build/es/components/tooltip/PopupTip.js.map +1 -1
  23. package/build/es/components/tooltip/Tooltip.js +1 -1
  24. package/build/es/components/tooltip/Tooltip.js.map +1 -1
  25. package/build/es/components/tooltip/TooltipContent.d.ts +3 -1
  26. package/build/es/components/tooltip/TooltipContent.js +1 -1
  27. package/build/es/components/tooltip/TooltipContent.js.map +1 -1
  28. package/package.json +2 -2
  29. package/styles/components/accordion/accordion.css +6 -0
  30. package/styles/components/accordion/accordion.min.css +2 -2
  31. package/styles/components/accordion/accordion.scss +6 -0
  32. package/styles/components/button/button.css +2 -2
  33. package/styles/components/button/button.min.css +1 -1
  34. package/styles/components/card/card.css +1 -0
  35. package/styles/components/card/card.min.css +1 -1
  36. package/styles/components/card/card.scss +1 -0
  37. package/styles/components/checkbox/checkbox.css +4 -4
  38. package/styles/components/checkbox/checkbox.min.css +1 -1
  39. package/styles/components/feedback/feedback.css +2 -2
  40. package/styles/components/feedback/feedback.min.css +1 -1
  41. package/styles/components/input-group/input-group.css +2 -2
  42. package/styles/components/input-group/input-group.min.css +1 -1
  43. package/styles/components/input-panel/checkbox-panel.css +2 -2
  44. package/styles/components/input-panel/checkbox-panel.min.css +1 -1
  45. package/styles/components/input-panel/radio-panel.css +2 -2
  46. package/styles/components/input-panel/radio-panel.min.css +1 -1
  47. package/styles/components/loader/loader.css +6 -6
  48. package/styles/components/loader/loader.min.css +1 -1
  49. package/styles/components/loader/skeleton-loader.css +5 -5
  50. package/styles/components/loader/skeleton-loader.min.css +1 -1
  51. package/styles/components/message/message.css +2 -2
  52. package/styles/components/message/message.min.css +1 -1
  53. package/styles/components/progress-bar/progress-bar.css +2 -2
  54. package/styles/components/progress-bar/progress-bar.min.css +1 -1
  55. package/styles/components/radio-button/radio-button.css +2 -2
  56. package/styles/components/radio-button/radio-button.min.css +1 -1
  57. package/styles/components/system-message/system-message.css +2 -2
  58. package/styles/components/system-message/system-message.min.css +1 -1
  59. package/styles/components/toast/toast.css +4 -4
  60. package/styles/components/toast/toast.min.css +1 -1
  61. package/styles/components/tooltip/_index.scss +1 -0
  62. package/styles/components/tooltip/popuptip.css +3 -0
  63. package/styles/components/tooltip/popuptip.min.css +1 -0
  64. package/styles/components/tooltip/popuptip.scss +5 -0
  65. package/styles/styles.css +48 -37
  66. package/styles/styles.min.css +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n ChangeEvent,\n CSSProperties,\n FocusEvent,\n forwardRef,\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DataTestAutoId, Density } from \"../../core/types.js\";\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 { getValuePair, ValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup, InputGroupProps } from \"../input-group/InputGroup.js\";\nimport { LabelProps } from \"../input-group/Label.js\";\nimport type { PopupTipProps } from \"../tooltip/PopupTip.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\n\nexport interface SelectPartialChangeEvent\n extends Partial<Omit<ChangeEvent<HTMLSelectElement>, \"target\">> {\n /** Kreves av react-hook-form, det skjer ulike ting avhengig av om det er blur eller change */\n type: \"change\" | \"blur\";\n target: {\n /** Kreves av react-hook-form for å vite hvilket skjemafelt som ble endret */\n name: string;\n value: string;\n };\n}\n\nexport type SelectChangeEventHandler = (\n event: SelectPartialChangeEvent,\n) => void;\n\ninterface Option extends ValuePair {\n visible: boolean;\n}\n\nexport interface SelectProps\n extends Omit<InputGroupProps, \"children\">,\n DataTestAutoId {\n id?: string;\n name: string;\n label: string;\n labelProps?: Omit<\n LabelProps,\n \"children\" | \"density\" | \"htmlFor\" | \"standAlone\"\n >;\n items: Array<string | ValuePair>;\n /**\n * @default false\n */\n inline?: boolean;\n /**\n * @default \"Velg\"\n */\n defaultPrompt?: string;\n className?: string;\n value?: string;\n helpLabel?: string;\n errorLabel?: string;\n /**\n * @default false\n */\n searchable?:\n | boolean\n | ((searchValue: string, searchItem: string | ValuePair) => boolean);\n density?: Density;\n width?: string;\n onChange?: SelectChangeEventHandler;\n onBlur?: SelectChangeEventHandler;\n onFocus?: SelectChangeEventHandler;\n /**\n * Merk som ugyldig uten å sende inn en errorLabel.\n * NB! Brukes kun i tilfeller der valideringsfeil dukker opp andre steder, for eksempel i en FieldGroup.\n */\n invalid?: boolean;\n /**\n * Hvor mange valg skal vises i listen før den begynner å scrolle.\n * @default 5\n */\n maxShownOptions?: number;\n}\n\nconst noop = () => {\n return;\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 density,\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 [selectRef, 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 }, [setSelectedValue, value, previousValue, valueIsInItems]);\n\n const selectOption = useCallback(\n (item: Option) => {\n const nextValue = item.value;\n setSearchValue(\"\");\n setSelectedValue(nextValue);\n toggleListVisibility();\n },\n [setSearchValue, setSelectedValue, 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>) => {\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 }, [\n onBlur,\n setSearchValue,\n setShown,\n isSearchable,\n name,\n selectedValue,\n ]);\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 &&\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 &&\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 &&\n componentRootElement.contains(\n ev.relatedTarget as Node,\n ) &&\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 [setShown, 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 [\n setShown,\n dropdownRef,\n selectedValue,\n isSearchable,\n dropdownIsShown,\n ],\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 [setShown, 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 }, [setShown, 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=\"\"></option>{\" \"}\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 density={density}\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 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 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","density","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","_a","find","selectRef","useRef","unifiedSelectRef","instance","current","usePreviousValue","useEffect","selectOption","nextValue","previousSelectedValue","type","target","dispatchEvent","Event","bubbles","componentRootElementRef","focusInsideRef","searchFieldRef","buttonRef","handleFocusPlacement","isOpen","ref","listElement","focusSelected","focus","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","close","handleBlur","e","componentRootElement","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","searchField","button","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","_b","call","srOnly","htmlFor","render","ariaInvalid","inputProps","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","every","i","onMouseOver","description","ArrowVerticalAnimated","variant","pointingDown","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"Select.js","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n ChangeEvent,\n CSSProperties,\n FocusEvent,\n forwardRef,\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DataTestAutoId, Density } from \"../../core/types.js\";\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 { getValuePair, ValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup, InputGroupProps } from \"../input-group/InputGroup.js\";\nimport { LabelProps } from \"../input-group/Label.js\";\nimport type { PopupTipProps } from \"../tooltip/PopupTip.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\n\nexport interface SelectPartialChangeEvent\n extends Partial<Omit<ChangeEvent<HTMLSelectElement>, \"target\">> {\n /** Kreves av react-hook-form, det skjer ulike ting avhengig av om det er blur eller change */\n type: \"change\" | \"blur\";\n target: {\n /** Kreves av react-hook-form for å vite hvilket skjemafelt som ble endret */\n name: string;\n value: string;\n };\n}\n\nexport type SelectChangeEventHandler = (\n event: SelectPartialChangeEvent,\n) => void;\n\ninterface Option extends ValuePair {\n visible: boolean;\n}\n\nexport interface SelectProps\n extends Omit<InputGroupProps, \"children\">,\n DataTestAutoId {\n id?: string;\n name: string;\n label: string;\n labelProps?: Omit<\n LabelProps,\n \"children\" | \"density\" | \"htmlFor\" | \"standAlone\"\n >;\n items: Array<string | ValuePair>;\n /**\n * @default false\n */\n inline?: boolean;\n /**\n * @default \"Velg\"\n */\n defaultPrompt?: string;\n className?: string;\n value?: string;\n helpLabel?: string;\n errorLabel?: string;\n /**\n * @default false\n */\n searchable?:\n | boolean\n | ((searchValue: string, searchItem: string | ValuePair) => boolean);\n density?: Density;\n width?: string;\n onChange?: SelectChangeEventHandler;\n onBlur?: SelectChangeEventHandler;\n onFocus?: SelectChangeEventHandler;\n /**\n * Merk som ugyldig uten å sende inn en errorLabel.\n * NB! Brukes kun i tilfeller der valideringsfeil dukker opp andre steder, for eksempel i en FieldGroup.\n */\n invalid?: boolean;\n /**\n * Hvor mange valg skal vises i listen før den begynner å scrolle.\n * @default 5\n */\n maxShownOptions?: number;\n}\n\nconst noop = () => {\n return;\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 density,\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 [selectRef, 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 }, [setSelectedValue, 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 [setSearchValue, setSelectedValue, 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>) => {\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 }, [\n onBlur,\n setSearchValue,\n setShown,\n isSearchable,\n name,\n selectedValue,\n ]);\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 &&\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 &&\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 &&\n componentRootElement.contains(\n ev.relatedTarget as Node,\n ) &&\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 [setShown, 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 [\n setShown,\n dropdownRef,\n selectedValue,\n isSearchable,\n dropdownIsShown,\n ],\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 [setShown, 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 }, [setShown, 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=\"\"></option>{\" \"}\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 density={density}\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 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 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","density","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","_a","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","componentRootElement","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","searchField","button","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","_b","call","srOnly","htmlFor","render","ariaInvalid","inputProps","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","every","i","onMouseOver","description","ArrowVerticalAnimated","variant","pointingDown","displayName"],"mappings":"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"}
@@ -15,7 +15,7 @@ export interface ActionSubmit extends ActionBaseProps {
15
15
  onClick?: MouseEventHandler<HTMLButtonElement>;
16
16
  }
17
17
  export type Action = ActionButton | ActionSubmit;
18
- export interface BaseTextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "children"> {
18
+ export interface BaseTextInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "children" | "maxLength"> {
19
19
  /**
20
20
  * Brukes til inputfelter hvor det brukes maskering, for formatering av store tall. Brukes typisk bare til valuta.
21
21
  * @default "left"
@@ -37,6 +37,15 @@ export interface BaseTextInputProps extends Omit<InputHTMLAttributes<HTMLInputEl
37
37
  * Element som vises til høyre for inputfeltet. Brukes typisk til å trigge en handling som f.eks. å vise/skjule passord.
38
38
  */
39
39
  actionButton?: React.ReactElement<IconProps>;
40
+ /**
41
+ * Setter maxlength attributtet og justerer bredden på feltet til å passe det tallet som settes
42
+ *
43
+ * Merk: I noen Android-browsere vil dette ikke fungere som forventet. Det er gjort sånn
44
+ * pga begrensninger med hvordan software-tastaturet fungerer og er ikke en bug. Dersom
45
+ * man er veldig avhengig av at maxLength håndteres på alle plattformer anbefales det
46
+ * å bruke input-feltet som en controlled input og selv begrense lengden på verdien.
47
+ */
48
+ maxLength?: number | undefined;
40
49
  }
41
50
  export declare const BaseTextInput: React.ForwardRefExoticComponent<BaseTextInputProps & React.RefAttributes<HTMLInputElement>>;
42
51
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTextInput.js","sources":["../../../../src/components/text-input/BaseTextInput.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type CSSProperties,\n forwardRef,\n HTMLProps,\n InputHTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { Density } from \"../../core/types.js\";\nimport { IconProps } from \"../icon/types.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\n\nfunction getWidthAsStyle(\n width?: string,\n maxLength?: number,\n): CSSProperties | undefined {\n if (width) {\n return { width }; // prioritize width prop\n }\n\n if (maxLength) {\n // adapt to maxLength, but capped at 40ch\n const length = `${Math.min(maxLength, 40)}ch`;\n const padding = \"24px\"; // left + right padding\n return { width: `calc(${length} + ${padding})` };\n }\n\n return undefined;\n}\n\ninterface ActionBaseProps\n extends Exclude<HTMLProps<HTMLButtonElement>, \"disabled\"> {\n icon: React.ReactElement<IconProps>;\n label: string;\n buttonRef?: React.Ref<HTMLButtonElement>;\n}\n\nexport interface ActionButton extends ActionBaseProps {\n type?: \"button\" | \"reset\";\n onClick: MouseEventHandler<HTMLButtonElement>;\n}\n\nexport interface ActionSubmit extends ActionBaseProps {\n type: \"submit\";\n onClick?: MouseEventHandler<HTMLButtonElement>;\n}\n\nexport type Action = ActionButton | ActionSubmit;\n\nexport interface BaseTextInputProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"children\"> {\n /**\n * Brukes til inputfelter hvor det brukes maskering, for formatering av store tall. Brukes typisk bare til valuta.\n * @default \"left\"\n */\n align?: \"left\" | \"right\";\n /**\n * @deprecated Bruk heller actionButton\n *\n */\n action?: Action;\n density?: Density;\n /**\n * Benevnelse for feltet. Unngå å bruke både benevnelse og handling samtidig\n * @example \"kr\"\n * */\n unit?: ReactNode;\n width?: string;\n /**\n * Element som vises til høyre for inputfeltet. Brukes typisk til å trigge en handling som f.eks. å vise/skjule passord.\n */\n actionButton?: React.ReactElement<IconProps>;\n}\n\nexport const BaseTextInput = forwardRef<HTMLInputElement, BaseTextInputProps>(\n (props, ref) => {\n const {\n action,\n align = \"left\",\n \"aria-invalid\": ariaInvalid,\n className = \"\",\n density,\n maxLength,\n style,\n type = \"text\",\n unit,\n width,\n actionButton,\n ...rest\n } = props;\n\n return (\n <div\n className=\"jkl-text-input-wrapper\"\n data-invalid={ariaInvalid}\n style={{ ...style, ...getWidthAsStyle(width, maxLength) }}\n >\n <input\n aria-invalid={ariaInvalid}\n ref={ref}\n className={clsx(\"jkl-text-input__input\", className, {\n \"jkl-text-input__input--align-right\": align === \"right\",\n })}\n maxLength={maxLength}\n type={type}\n {...rest}\n />\n {unit && <span className=\"jkl-text-input__unit\">{unit}</span>}\n {!action &&\n actionButton &&\n React.cloneElement(actionButton, {\n className: clsx(\n \"jkl-text-input-action-button\",\n actionButton.props.className,\n ),\n })}\n {action && !actionButton && (\n <IconButton\n density={density}\n className={clsx(\n \"jkl-text-input-action-button\",\n action.className,\n )}\n title={action.label}\n onClick={action.onClick}\n onFocus={action.onFocus}\n onBlur={action.onBlur}\n ref={action.buttonRef}\n type={action.type || \"button\"}\n >\n {action.icon}\n </IconButton>\n )}\n </div>\n );\n },\n);\n\nBaseTextInput.displayName = \"BaseInputField\";\n"],"names":["getWidthAsStyle","width","maxLength","Math","min","BaseTextInput","forwardRef","props","ref","action","align","ariaInvalid","className","density","style","type","unit","actionButton","rest","jsxs","children","jsx","clsx","React","cloneElement","IconButton","title","label","onClick","onFocus","onBlur","buttonRef","icon","displayName"],"mappings":"gMAaA,SAASA,EACLC,EACAC,GAEID,OAAAA,EACO,CAAEA,MAAAA,GAGTC,EAIO,CAAED,MAAO,QAFEE,KAAKC,IAAIF,EAAW,sBAFtCA,CAQR,CA8CO,MAAMG,EAAgBC,GACzB,CAACC,EAAOC,KACE,MACFC,OAAAA,EACAC,MAAAA,EAAQ,OACR,eAAgBC,EAChBC,UAAAA,EAAY,GACZC,QAAAA,EACAX,UAAAA,EACAY,MAAAA,EACAC,KAAAA,EAAO,OACPC,KAAAA,EACAf,MAAAA,EACAgB,aAAAA,KACGC,GACHX,EAGA,OAAAY,EAAC,MAAA,CACGP,UAAU,yBACV,eAAcD,EACdG,MAAO,IAAKA,KAAUd,EAAgBC,EAAOC,IAE7CkB,SAAA,CAAAC,EAAC,QAAA,CACG,eAAcV,EACdH,IAAAA,EACAI,UAAWU,EAAK,wBAAyBV,EAAW,CAChD,qCAAgD,UAAVF,IAE1CR,UAAAA,EACAa,KAAAA,KACIG,IAEPF,GAAQK,EAAC,OAAK,CAAAT,UAAU,uBAAwBQ,SAAKJ,KACpDP,GACEQ,GACAM,EAAMC,aAAaP,EAAc,CAC7BL,UAAWU,EACP,+BACAL,EAAaV,MAAMK,aAG9BH,IAAWQ,GACRI,EAACI,EAAA,CACGZ,QAAAA,EACAD,UAAWU,EACP,+BACAb,EAAOG,WAEXc,MAAOjB,EAAOkB,MACdC,QAASnB,EAAOmB,QAChBC,QAASpB,EAAOoB,QAChBC,OAAQrB,EAAOqB,OACftB,IAAKC,EAAOsB,UACZhB,KAAMN,EAAOM,MAAQ,SAEpBK,SAAOX,EAAAuB,SACZ,IAOpB3B,EAAc4B,YAAc"}
1
+ {"version":3,"file":"BaseTextInput.js","sources":["../../../../src/components/text-input/BaseTextInput.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type CSSProperties,\n forwardRef,\n HTMLProps,\n InputHTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { Density } from \"../../core/types.js\";\nimport { IconProps } from \"../icon/types.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\n\nfunction getWidthAsStyle(\n width?: string,\n maxLength?: number,\n): CSSProperties | undefined {\n if (width) {\n return { width }; // prioritize width prop\n }\n\n if (maxLength) {\n // adapt to maxLength, but capped at 40ch\n const length = `${Math.min(maxLength, 40)}ch`;\n const padding = \"24px\"; // left + right padding\n return { width: `calc(${length} + ${padding})` };\n }\n\n return undefined;\n}\n\ninterface ActionBaseProps\n extends Exclude<HTMLProps<HTMLButtonElement>, \"disabled\"> {\n icon: React.ReactElement<IconProps>;\n label: string;\n buttonRef?: React.Ref<HTMLButtonElement>;\n}\n\nexport interface ActionButton extends ActionBaseProps {\n type?: \"button\" | \"reset\";\n onClick: MouseEventHandler<HTMLButtonElement>;\n}\n\nexport interface ActionSubmit extends ActionBaseProps {\n type: \"submit\";\n onClick?: MouseEventHandler<HTMLButtonElement>;\n}\n\nexport type Action = ActionButton | ActionSubmit;\n\nexport interface BaseTextInputProps\n extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"maxLength\"\n > {\n /**\n * Brukes til inputfelter hvor det brukes maskering, for formatering av store tall. Brukes typisk bare til valuta.\n * @default \"left\"\n */\n align?: \"left\" | \"right\";\n /**\n * @deprecated Bruk heller actionButton\n *\n */\n action?: Action;\n density?: Density;\n /**\n * Benevnelse for feltet. Unngå å bruke både benevnelse og handling samtidig\n * @example \"kr\"\n * */\n unit?: ReactNode;\n width?: string;\n /**\n * Element som vises til høyre for inputfeltet. Brukes typisk til å trigge en handling som f.eks. å vise/skjule passord.\n */\n actionButton?: React.ReactElement<IconProps>;\n /**\n * Setter maxlength attributtet og justerer bredden på feltet til å passe det tallet som settes\n *\n * Merk: I noen Android-browsere vil dette ikke fungere som forventet. Det er gjort sånn\n * pga begrensninger med hvordan software-tastaturet fungerer og er ikke en bug. Dersom\n * man er veldig avhengig av at maxLength håndteres på alle plattformer anbefales det\n * å bruke input-feltet som en controlled input og selv begrense lengden på verdien.\n */\n maxLength?: number | undefined;\n}\n\nexport const BaseTextInput = forwardRef<HTMLInputElement, BaseTextInputProps>(\n (props, ref) => {\n const {\n action,\n align = \"left\",\n \"aria-invalid\": ariaInvalid,\n className = \"\",\n density,\n maxLength,\n style,\n type = \"text\",\n unit,\n width,\n actionButton,\n ...rest\n } = props;\n\n return (\n <div\n className=\"jkl-text-input-wrapper\"\n data-invalid={ariaInvalid}\n style={{ ...style, ...getWidthAsStyle(width, maxLength) }}\n >\n <input\n aria-invalid={ariaInvalid}\n ref={ref}\n className={clsx(\"jkl-text-input__input\", className, {\n \"jkl-text-input__input--align-right\": align === \"right\",\n })}\n maxLength={maxLength}\n type={type}\n {...rest}\n />\n {unit && <span className=\"jkl-text-input__unit\">{unit}</span>}\n {!action &&\n actionButton &&\n React.cloneElement(actionButton, {\n className: clsx(\n \"jkl-text-input-action-button\",\n actionButton.props.className,\n ),\n })}\n {action && !actionButton && (\n <IconButton\n density={density}\n className={clsx(\n \"jkl-text-input-action-button\",\n action.className,\n )}\n title={action.label}\n onClick={action.onClick}\n onFocus={action.onFocus}\n onBlur={action.onBlur}\n ref={action.buttonRef}\n type={action.type || \"button\"}\n >\n {action.icon}\n </IconButton>\n )}\n </div>\n );\n },\n);\n\nBaseTextInput.displayName = \"BaseInputField\";\n"],"names":["getWidthAsStyle","width","maxLength","Math","min","BaseTextInput","forwardRef","props","ref","action","align","ariaInvalid","className","density","style","type","unit","actionButton","rest","jsxs","children","jsx","clsx","React","cloneElement","IconButton","title","label","onClick","onFocus","onBlur","buttonRef","icon","displayName"],"mappings":"gMAaA,SAASA,EACLC,EACAC,GAEID,OAAAA,EACO,CAAEA,MAAAA,GAGTC,EAIO,CAAED,MAAO,QAFEE,KAAKC,IAAIF,EAAW,sBAFtCA,CAQR,CA0DO,MAAMG,EAAgBC,GACzB,CAACC,EAAOC,KACE,MACFC,OAAAA,EACAC,MAAAA,EAAQ,OACR,eAAgBC,EAChBC,UAAAA,EAAY,GACZC,QAAAA,EACAX,UAAAA,EACAY,MAAAA,EACAC,KAAAA,EAAO,OACPC,KAAAA,EACAf,MAAAA,EACAgB,aAAAA,KACGC,GACHX,EAGA,OAAAY,EAAC,MAAA,CACGP,UAAU,yBACV,eAAcD,EACdG,MAAO,IAAKA,KAAUd,EAAgBC,EAAOC,IAE7CkB,SAAA,CAAAC,EAAC,QAAA,CACG,eAAcV,EACdH,IAAAA,EACAI,UAAWU,EAAK,wBAAyBV,EAAW,CAChD,qCAAgD,UAAVF,IAE1CR,UAAAA,EACAa,KAAAA,KACIG,IAEPF,GAAQK,EAAC,OAAK,CAAAT,UAAU,uBAAwBQ,SAAKJ,KACpDP,GACEQ,GACAM,EAAMC,aAAaP,EAAc,CAC7BL,UAAWU,EACP,+BACAL,EAAaV,MAAMK,aAG9BH,IAAWQ,GACRI,EAACI,EAAA,CACGZ,QAAAA,EACAD,UAAWU,EACP,+BACAb,EAAOG,WAEXc,MAAOjB,EAAOkB,MACdC,QAASnB,EAAOmB,QAChBC,QAASpB,EAAOoB,QAChBC,OAAQrB,EAAOqB,OACftB,IAAKC,EAAOsB,UACZhB,KAAMN,EAAOM,MAAQ,SAEpBK,SAAOX,EAAAuB,SACZ,IAOpB3B,EAAc4B,YAAc"}
@@ -1,2 +1,2 @@
1
- import{jsxs as o,jsx as t}from"react/jsx-runtime";import{c as i}from"../../../clsx-BeLtu-UY.js";import{useState as s}from"react";import{QuestionIcon as r}from"../icon/icons/QuestionIcon.js";import{Tooltip as n}from"./Tooltip.js";import{TooltipContent as e}from"./TooltipContent.js";import{TooltipTrigger as l}from"./TooltipTrigger.js";const a=({content:a,triggerProps:p,...c})=>{const[m,u]=s(!1);return o(n,{onOpenChange:u,triggerOn:"click",...c,children:[t(l,{children:o("button",{...p,type:"button",className:i("jkl-tooltip-question-button",null==p?void 0:p.className),"data-testid":"jkl-tooltip-question-button",children:[t(r,{variant:"inherit",bold:m}),t("span",{className:"jkl-sr-only",children:"Vis hjelpetekst"})]})}),t(e,{children:a})]})};export{a as PopupTip};
1
+ import{jsxs as t,jsx as o}from"react/jsx-runtime";import{c as i}from"../../../clsx-BeLtu-UY.js";import{useState as s}from"react";import{QuestionIcon as n}from"../icon/icons/QuestionIcon.js";import{Tooltip as r}from"./Tooltip.js";import{TooltipContent as e}from"./TooltipContent.js";import{TooltipTrigger as p}from"./TooltipTrigger.js";const a=({content:a,triggerProps:l,...c})=>{const[m,u]=s(!1);return t(r,{onOpenChange:u,triggerOn:"click",...c,children:[o(p,{children:t("button",{...l,type:"button",className:i("jkl-tooltip-question-button",null==l?void 0:l.className),"data-testid":"jkl-tooltip-question-button",children:[o(n,{variant:"inherit",bold:m}),o("span",{className:"jkl-sr-only",children:"Vis hjelpetekst"})]})}),o(e,{"data-ispopup":!0,children:o("div",{className:"jkl-popuptip__content-wrapper",tabIndex:0,children:a})})]})};export{a as PopupTip};
2
2
  //# sourceMappingURL=PopupTip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PopupTip.js","sources":["../../../../src/components/tooltip/PopupTip.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { HTMLProps, useState, type FC, type ReactNode } from \"react\";\nimport { QuestionIcon } from \"../icon/icons/QuestionIcon.js\";\nimport { Tooltip, type TooltipProps } from \"./Tooltip.js\";\nimport { TooltipContent } from \"./TooltipContent.js\";\nimport { TooltipTrigger } from \"./TooltipTrigger.js\";\n\nexport interface PopupTipProps\n extends Omit<TooltipProps, \"triggerOn\" | \"children\"> {\n /**\n * Innholdet i tooltipet som vises\n */\n content: ReactNode;\n /**\n * Eventuelle props du vil sette på trigger-knappen for tooltipet\n */\n triggerProps?: Omit<HTMLProps<HTMLButtonElement>, \"children\" | \"type\">;\n}\n\nexport const PopupTip: FC<PopupTipProps> = ({\n content,\n triggerProps,\n ...tooltipProps\n}) => {\n const [isBold, setIsBold] = useState(false);\n\n return (\n <Tooltip onOpenChange={setIsBold} triggerOn=\"click\" {...tooltipProps}>\n <TooltipTrigger>\n <button\n {...triggerProps}\n type=\"button\"\n className={clsx(\n \"jkl-tooltip-question-button\",\n triggerProps?.className,\n )}\n data-testid=\"jkl-tooltip-question-button\"\n >\n <QuestionIcon variant=\"inherit\" bold={isBold} />\n <span className=\"jkl-sr-only\">Vis hjelpetekst</span>\n </button>\n </TooltipTrigger>\n <TooltipContent>{content}</TooltipContent>\n </Tooltip>\n );\n};\n"],"names":["PopupTip","content","triggerProps","tooltipProps","isBold","setIsBold","useState","Tooltip","onOpenChange","triggerOn","children","jsx","TooltipTrigger","jsxs","type","className","clsx","QuestionIcon","variant","bold","TooltipContent"],"mappings":"+UAmBO,MAAMA,EAA8B,EACvCC,QAAAA,EACAC,aAAAA,KACGC,MAEH,MAAOC,EAAQC,GAAaC,GAAS,YAGhCC,EAAQ,CAAAC,aAAcH,EAAWI,UAAU,WAAYN,EACpDO,SAAA,CAAAC,EAACC,EACG,CAAAF,SAAAG,EAAC,SAAA,IACOX,EACJY,KAAK,SACLC,UAAWC,EACP,8BACA,MAAAd,SAAAA,EAAca,WAElB,cAAY,8BAEZL,SAAA,CAAAC,EAACM,EAAa,CAAAC,QAAQ,UAAUC,KAAMf,IACrCO,EAAA,OAAA,CAAKI,UAAU,cAAcL,SAAe,yBAGrDC,EAACS,GAAgBV,SAAQT,MAC7B"}
1
+ {"version":3,"file":"PopupTip.js","sources":["../../../../src/components/tooltip/PopupTip.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { HTMLProps, useState, type FC, type ReactNode } from \"react\";\nimport { QuestionIcon } from \"../icon/icons/QuestionIcon.js\";\nimport { Tooltip, type TooltipProps } from \"./Tooltip.js\";\nimport { TooltipContent } from \"./TooltipContent.js\";\nimport { TooltipTrigger } from \"./TooltipTrigger.js\";\n\nexport interface PopupTipProps\n extends Omit<TooltipProps, \"triggerOn\" | \"children\"> {\n /**\n * Innholdet i tooltipet som vises\n */\n content: ReactNode;\n /**\n * Eventuelle props du vil sette på trigger-knappen for tooltipet\n */\n triggerProps?: Omit<HTMLProps<HTMLButtonElement>, \"children\" | \"type\">;\n}\n\nexport const PopupTip: FC<PopupTipProps> = ({\n content,\n triggerProps,\n ...tooltipProps\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <Tooltip onOpenChange={setIsOpen} triggerOn=\"click\" {...tooltipProps}>\n <TooltipTrigger>\n <button\n {...triggerProps}\n type=\"button\"\n className={clsx(\n \"jkl-tooltip-question-button\",\n triggerProps?.className,\n )}\n data-testid=\"jkl-tooltip-question-button\"\n >\n <QuestionIcon variant=\"inherit\" bold={isOpen} />\n <span className=\"jkl-sr-only\">Vis hjelpetekst</span>\n </button>\n </TooltipTrigger>\n\n <TooltipContent data-ispopup={true}>\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}\n <div className=\"jkl-popuptip__content-wrapper\" tabIndex={0}>\n {content}\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"names":["PopupTip","content","triggerProps","tooltipProps","isOpen","setIsOpen","useState","Tooltip","onOpenChange","triggerOn","children","jsx","TooltipTrigger","jsxs","type","className","clsx","QuestionIcon","variant","bold","TooltipContent","tabIndex"],"mappings":"+UAmBO,MAAMA,EAA8B,EACvCC,QAAAA,EACAC,aAAAA,KACGC,MAEH,MAAOC,EAAQC,GAAaC,GAAS,YAGhCC,EAAQ,CAAAC,aAAcH,EAAWI,UAAU,WAAYN,EACpDO,SAAA,CAAAC,EAACC,EACG,CAAAF,SAAAG,EAAC,SAAA,IACOX,EACJY,KAAK,SACLC,UAAWC,EACP,8BACA,MAAAd,SAAAA,EAAca,WAElB,cAAY,8BAEZL,SAAA,CAAAC,EAACM,EAAa,CAAAC,QAAQ,UAAUC,KAAMf,IACrCO,EAAA,OAAA,CAAKI,UAAU,cAAcL,SAAe,yBAIrDC,EAACS,EAAe,CAAA,gBAAc,EAE1BV,SAAAC,EAAC,MAAI,CAAAI,UAAU,gCAAgCM,SAAU,EACpDX,SAAAT,QAGb"}
@@ -1,2 +1,2 @@
1
- import{jsx as e}from"react/jsx-runtime";import{useFloating as t,autoUpdate as n,offset as o,flip as s,shift as r,arrow as a,useRole as i,useDismiss as l,useClick as u,useHover as c,useFocus as p,useInteractions as d}from"@floating-ui/react";import{createContext as m,useContext as f,useState as x,useRef as g}from"react";const h=m(null),k=h.Provider,O=()=>{const e=f(h);if(null===e)throw new Error("Tooltip-komponentene kan kun brukes inne i <Tooltip />");return e},v=({children:m,...f})=>{const h=(({initialOpen:e=!1,placement:m="top",delay:f=250,triggerOn:h="hover",onOpenChange:k})=>{const[O,v]=x(e),w=g(null),C=g(null),T=t({open:O,onOpenChange:e=>{null==k||k(e),v(e)},placement:m,whileElementsMounted:n,middleware:[o(16),s(),r({padding:16}),a({element:w,padding:8})]}),b=i(T.context,{role:"tooltip"}),E=l(T.context),j=u(T.context,{enabled:"click"===h}),y=c(T.context,{enabled:"hover"===h,delay:O?0:f}),D=p(T.context,{enabled:"click"!==h||O}),F=d([E,D,b,j,y]);return{triggerOn:h,isOpen:O,setOpen:v,arrowElement:w,...T,refs:{...T.refs,description:C,setDescription:e=>C.current=e},...F}})(f);return e(k,{value:h,children:m})};export{v as Tooltip,k as TooltipProvider,O as useTooltipContext};
1
+ import{jsx as e}from"react/jsx-runtime";import{useFloating as t,autoUpdate as n,offset as o,flip as s,shift as r,arrow as a,useRole as i,useDismiss as l,useClick as u,useHover as p,useFocus as c,useInteractions as d}from"@floating-ui/react";import{createContext as m,useContext as f,useState as x,useRef as g}from"react";const h=m(null),v=h.Provider,O=()=>{const e=f(h);if(null===e)throw new Error("Tooltip-komponentene kan kun brukes inne i <Tooltip />");return e},k=({children:m,...f})=>{const h=(({initialOpen:e=!1,placement:m="top",delay:f=250,triggerOn:h="hover",onOpenChange:v})=>{const[O,k]=x(e),w=g(null),C=g(null),T=t({open:O,onOpenChange:e=>{null==v||v(e),k(e)},placement:m,whileElementsMounted:n,middleware:[o(16),s(),r({padding:16}),a({element:w,padding:8})]}),b=i(T.context,{role:"tooltip"}),E=l(T.context),j=u(T.context,{enabled:"click"===h}),y=p(T.context,{enabled:"hover"===h,delay:O?0:f}),D=c(T.context,{enabled:"hover"===h}),F=d([E,D,b,j,y]);return{triggerOn:h,isOpen:O,setOpen:k,arrowElement:w,...T,refs:{...T.refs,description:C,setDescription:e=>C.current=e},...F}})(f);return e(v,{value:h,children:m})};export{k as Tooltip,v as TooltipProvider,O as useTooltipContext};
2
2
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/tooltip/Tooltip.tsx"],"sourcesContent":["import {\n type Placement,\n type UseFloatingReturn,\n arrow,\n autoUpdate,\n flip,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useInteractions,\n useRole,\n} from \"@floating-ui/react\";\nimport React, { FC, createContext, useContext, useRef, useState } from \"react\";\nimport { type WithChildren } from \"../../core/types.js\";\n\nexport type TooltipPlacement = Extract<\n Placement,\n \"top-start\" | \"top-end\" | \"left\" | \"right\" | \"top\"\n>;\n\nexport interface TooltipProps {\n /**\n * Sett til true dersom du ønsker at tooltipen skal være åpen som default\n * @default false\n */\n initialOpen?: boolean;\n /**\n * En funksjon som skal kalles når Tooltip åpnes eller lukkes\n * @param open Hvorvidt tooltip endres til å være åpen eller ikke\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Plassering av tooltipen i forhold til triggeren. Tooltipen vil automatisk\n * bytte posisjon dersom det ikke er plass.\n * @default \"top\"\n */\n placement?: TooltipPlacement;\n /**\n * Valgfri forsinkelse før tooltipen åpner. Ignoreres dersom triggerOn er satt til \"click\"\n * @default 250\n */\n delay?: number;\n /**\n * Angir om tooltipen skal åpnes ved klikk eller hover\n * @default \"hover\"\n */\n triggerOn?: \"click\" | \"hover\";\n}\n\ntype UseTooltipReturn = {\n triggerOn: NonNullable<TooltipProps[\"triggerOn\"]>;\n isOpen: boolean;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n arrowElement: React.RefObject<SVGSVGElement>;\n refs: {\n description: React.MutableRefObject<HTMLElement | null>;\n setDescription: (element: HTMLElement | null) => void;\n } & UseFloatingReturn[\"refs\"];\n} & UseFloatingReturn &\n ReturnType<typeof useInteractions>;\n\nconst useTooltip = ({\n initialOpen = false,\n placement = \"top\",\n delay = 250,\n triggerOn = \"hover\",\n onOpenChange,\n}: TooltipProps): UseTooltipReturn => {\n const [isOpen, setOpen] = useState(initialOpen);\n const arrowElement = useRef<SVGSVGElement>(null);\n const description = useRef<HTMLElement | null>(null);\n const setDescription = (element: HTMLElement | null) =>\n (description.current = element);\n\n const data = useFloating({\n open: isOpen,\n onOpenChange: (open) => {\n onOpenChange?.(open);\n setOpen(open);\n },\n placement,\n whileElementsMounted: autoUpdate,\n middleware: [\n offset(16),\n flip(),\n shift({ padding: 16 }),\n arrow({ element: arrowElement, padding: 8 }),\n ],\n });\n\n const role = useRole(data.context, { role: \"tooltip\" });\n const dismiss = useDismiss(data.context);\n const click = useClick(data.context, {\n enabled: triggerOn === \"click\",\n });\n const hover = useHover(data.context, {\n enabled: triggerOn === \"hover\",\n delay: isOpen ? 0 : delay,\n });\n const focus = useFocus(data.context, {\n enabled: triggerOn === \"click\" ? isOpen : true,\n });\n\n const interactions = useInteractions([dismiss, focus, role, click, hover]);\n\n return {\n triggerOn,\n isOpen,\n setOpen,\n arrowElement,\n ...data,\n refs: {\n ...data.refs,\n description,\n setDescription,\n },\n ...interactions,\n };\n};\n\nexport type TooltipContext = ReturnType<typeof useTooltip> | null;\n\nconst tooltipContext = createContext<TooltipContext>(null);\n\nexport const TooltipProvider = tooltipContext.Provider;\n\nexport const useTooltipContext = () => {\n const context = useContext(tooltipContext);\n\n if (context === null) {\n throw new Error(\n \"Tooltip-komponentene kan kun brukes inne i <Tooltip />\",\n );\n }\n\n return context;\n};\n\nexport const Tooltip: FC<TooltipProps & WithChildren> = ({\n children,\n ...options\n}) => {\n const tooltip = useTooltip(options);\n\n return <TooltipProvider value={tooltip}>{children}</TooltipProvider>;\n};\n"],"names":["tooltipContext","createContext","TooltipProvider","Provider","useTooltipContext","context","useContext","Error","Tooltip","children","options","tooltip","initialOpen","placement","delay","triggerOn","onOpenChange","isOpen","setOpen","useState","arrowElement","useRef","description","data","useFloating","open","whileElementsMounted","autoUpdate","middleware","offset","flip","shift","padding","arrow","element","role","useRole","dismiss","useDismiss","click","useClick","enabled","hover","useHover","focus","useFocus","interactions","useInteractions","refs","setDescription","current","useTooltip","jsx","value"],"mappings":"iUAiEA,MA6DMA,EAAiBC,EAA8B,MAExCC,EAAkBF,EAAeG,SAEjCC,EAAoB,KACvBC,MAAAA,EAAUC,EAAWN,GAE3B,GAAgB,OAAZK,EACA,MAAM,IAAIE,MACN,0DAIDF,OAAAA,CAAAA,EAGEG,EAA2C,EACpDC,SAAAA,KACGC,MAEGC,MAAAA,EAjFS,GACfC,YAAAA,GAAc,EACdC,UAAAA,EAAY,MACZC,MAAAA,EAAQ,IACRC,UAAAA,EAAY,QACZC,aAAAA,MAEM,MAACC,EAAQC,GAAWC,EAASP,GAC7BQ,EAAeC,EAAsB,MACrCC,EAAcD,EAA2B,MAIzCE,EAAOC,EAAY,CACrBC,KAAMR,EACND,aAAeS,IACX,MAAAT,GAAAA,EAAeS,GACfP,EAAQO,EAAI,EAEhBZ,UAAAA,EACAa,qBAAsBC,EACtBC,WAAY,CACRC,EAAO,IACPC,IACAC,EAAM,CAAEC,QAAS,KACjBC,EAAM,CAAEC,QAASd,EAAcY,QAAS,OAI1CG,EAAOC,EAAQb,EAAKlB,QAAS,CAAE8B,KAAM,YACrCE,EAAUC,EAAWf,EAAKlB,SAC1BkC,EAAQC,EAASjB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,IAEP2B,EAAQC,EAASpB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,EACTD,MAAOG,EAAS,EAAIH,IAElB8B,EAAQC,EAAStB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,GAAwBE,IAG/B6B,EAAeC,EAAgB,CAACV,EAASO,EAAOT,EAAMI,EAAOG,IAE5D,MAAA,CACH3B,UAAAA,EACAE,OAAAA,EACAC,QAAAA,EACAE,aAAAA,KACGG,EACHyB,KAAM,IACCzB,EAAKyB,KACR1B,YAAAA,EACA2B,eA3CgBf,GACnBZ,EAAY4B,QAAUhB,MA4CpBY,EAAA,EA0BSK,CAAWzC,GAEnB,OAAA0C,EAAAlD,EAAA,CAAgBmD,MAAO1C,EAAUF,SAAAA,GAAS"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../../../src/components/tooltip/Tooltip.tsx"],"sourcesContent":["import {\n type Placement,\n type UseFloatingReturn,\n arrow,\n autoUpdate,\n flip,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useInteractions,\n useRole,\n} from \"@floating-ui/react\";\nimport React, { FC, createContext, useContext, useRef, useState } from \"react\";\nimport { type WithChildren } from \"../../core/types.js\";\n\nexport type TooltipPlacement = Extract<\n Placement,\n \"top-start\" | \"top-end\" | \"left\" | \"right\" | \"top\"\n>;\n\nexport interface TooltipProps {\n /**\n * Sett til true dersom du ønsker at tooltipen skal være åpen som default\n * @default false\n */\n initialOpen?: boolean;\n /**\n * En funksjon som skal kalles når Tooltip åpnes eller lukkes\n * @param open Hvorvidt tooltip endres til å være åpen eller ikke\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Plassering av tooltipen i forhold til triggeren. Tooltipen vil automatisk\n * bytte posisjon dersom det ikke er plass.\n * @default \"top\"\n */\n placement?: TooltipPlacement;\n /**\n * Valgfri forsinkelse før tooltipen åpner. Ignoreres dersom triggerOn er satt til \"click\"\n * @default 250\n */\n delay?: number;\n /**\n * Angir om tooltipen skal åpnes ved klikk eller hover\n * @default \"hover\"\n */\n triggerOn?: \"click\" | \"hover\";\n}\n\ntype UseTooltipReturn = {\n triggerOn: NonNullable<TooltipProps[\"triggerOn\"]>;\n isOpen: boolean;\n setOpen: React.Dispatch<React.SetStateAction<boolean>>;\n arrowElement: React.RefObject<SVGSVGElement>;\n refs: {\n description: React.MutableRefObject<HTMLElement | null>;\n setDescription: (element: HTMLElement | null) => void;\n } & UseFloatingReturn[\"refs\"];\n} & UseFloatingReturn &\n ReturnType<typeof useInteractions>;\n\nconst useTooltip = ({\n initialOpen = false,\n placement = \"top\",\n delay = 250,\n triggerOn = \"hover\",\n onOpenChange,\n}: TooltipProps): UseTooltipReturn => {\n const [isOpen, setOpen] = useState(initialOpen);\n const arrowElement = useRef<SVGSVGElement>(null);\n const description = useRef<HTMLElement | null>(null);\n const setDescription = (element: HTMLElement | null) =>\n (description.current = element);\n\n const data = useFloating({\n open: isOpen,\n onOpenChange: (open) => {\n onOpenChange?.(open);\n setOpen(open);\n },\n placement,\n whileElementsMounted: autoUpdate,\n middleware: [\n offset(16),\n flip(),\n shift({ padding: 16 }),\n arrow({ element: arrowElement, padding: 8 }),\n ],\n });\n\n const role = useRole(data.context, { role: \"tooltip\" });\n const dismiss = useDismiss(data.context);\n const click = useClick(data.context, {\n enabled: triggerOn === \"click\",\n });\n const hover = useHover(data.context, {\n enabled: triggerOn === \"hover\",\n delay: isOpen ? 0 : delay,\n });\n const focus = useFocus(data.context, {\n enabled: triggerOn === \"hover\",\n });\n\n const interactions = useInteractions([dismiss, focus, role, click, hover]);\n\n return {\n triggerOn,\n isOpen,\n setOpen,\n arrowElement,\n ...data,\n refs: {\n ...data.refs,\n description,\n setDescription,\n },\n ...interactions,\n };\n};\n\nexport type TooltipContext = ReturnType<typeof useTooltip> | null;\n\nconst tooltipContext = createContext<TooltipContext>(null);\n\nexport const TooltipProvider = tooltipContext.Provider;\n\nexport const useTooltipContext = () => {\n const context = useContext(tooltipContext);\n\n if (context === null) {\n throw new Error(\n \"Tooltip-komponentene kan kun brukes inne i <Tooltip />\",\n );\n }\n\n return context;\n};\n\nexport const Tooltip: FC<TooltipProps & WithChildren> = ({\n children,\n ...options\n}) => {\n const tooltip = useTooltip(options);\n\n return <TooltipProvider value={tooltip}>{children}</TooltipProvider>;\n};\n"],"names":["tooltipContext","createContext","TooltipProvider","Provider","useTooltipContext","context","useContext","Error","Tooltip","children","options","tooltip","initialOpen","placement","delay","triggerOn","onOpenChange","isOpen","setOpen","useState","arrowElement","useRef","description","data","useFloating","open","whileElementsMounted","autoUpdate","middleware","offset","flip","shift","padding","arrow","element","role","useRole","dismiss","useDismiss","click","useClick","enabled","hover","useHover","focus","useFocus","interactions","useInteractions","refs","setDescription","current","useTooltip","jsx","value"],"mappings":"iUAiEA,MA6DMA,EAAiBC,EAA8B,MAExCC,EAAkBF,EAAeG,SAEjCC,EAAoB,KACvBC,MAAAA,EAAUC,EAAWN,GAE3B,GAAgB,OAAZK,EACA,MAAM,IAAIE,MACN,0DAIDF,OAAAA,CAAAA,EAGEG,EAA2C,EACpDC,SAAAA,KACGC,MAEGC,MAAAA,EAjFS,GACfC,YAAAA,GAAc,EACdC,UAAAA,EAAY,MACZC,MAAAA,EAAQ,IACRC,UAAAA,EAAY,QACZC,aAAAA,MAEM,MAACC,EAAQC,GAAWC,EAASP,GAC7BQ,EAAeC,EAAsB,MACrCC,EAAcD,EAA2B,MAIzCE,EAAOC,EAAY,CACrBC,KAAMR,EACND,aAAeS,IACX,MAAAT,GAAAA,EAAeS,GACfP,EAAQO,EAAI,EAEhBZ,UAAAA,EACAa,qBAAsBC,EACtBC,WAAY,CACRC,EAAO,IACPC,IACAC,EAAM,CAAEC,QAAS,KACjBC,EAAM,CAAEC,QAASd,EAAcY,QAAS,OAI1CG,EAAOC,EAAQb,EAAKlB,QAAS,CAAE8B,KAAM,YACrCE,EAAUC,EAAWf,EAAKlB,SAC1BkC,EAAQC,EAASjB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,IAEP2B,EAAQC,EAASpB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,EACTD,MAAOG,EAAS,EAAIH,IAElB8B,EAAQC,EAAStB,EAAKlB,QAAS,CACjCoC,QAAuB,UAAd1B,IAGP+B,EAAeC,EAAgB,CAACV,EAASO,EAAOT,EAAMI,EAAOG,IAE5D,MAAA,CACH3B,UAAAA,EACAE,OAAAA,EACAC,QAAAA,EACAE,aAAAA,KACGG,EACHyB,KAAM,IACCzB,EAAKyB,KACR1B,YAAAA,EACA2B,eA3CgBf,GACnBZ,EAAY4B,QAAUhB,MA4CpBY,EAAA,EA0BSK,CAAWzC,GAEnB,OAAA0C,EAAAlD,EAAA,CAAgBmD,MAAO1C,EAAUF,SAAAA,GAAS"}
@@ -1,2 +1,4 @@
1
1
  import { default as React } from 'react';
2
- export declare const TooltipContent: React.ForwardRefExoticComponent<Omit<React.HTMLProps<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
2
+ export declare const TooltipContent: React.ForwardRefExoticComponent<Omit<React.HTMLProps<HTMLDivElement> & {
3
+ "data-ispopup"?: boolean | undefined;
4
+ }, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useMergeRefs as r,useTransitionStyles as s,FloatingPortal as o,FloatingArrow as a}from"@floating-ui/react";import{c as i}from"../../../clsx-BeLtu-UY.js";import{forwardRef as n}from"react";import{useBrowserPreferences as l}from"../../hooks/useBrowserPreferences/useBrowserPreferences.js";import{useId as c}from"../../hooks/useId/useId.js";import{getThemeAndDensity as p}from"../../utilities/getThemeAndDensity.js";import{useTooltipContext as d}from"./Tooltip.js";function m(e,t=0){switch(e){case"top":default:return`0 ${t}px`;case"left":return`${t}px 0`;case"bottom":return`0 ${-t}px`;case"right":return-t+"px 0"}}const f=n((function({className:n,children:f,...u},h){const{triggerOn:g,arrowElement:x,getFloatingProps:y,placement:j,floatingStyles:w,refs:k,context:T}=d(),v=r([h,k.setFloating]),P=c("jkl-tooltip-content"),{prefersReducedMotion:$}=l(),{isMounted:F,styles:A}=s(T,{duration:{open:$?0:250,close:$?0:150},initial:({side:e})=>({opacity:0,translate:m(e,5)}),open:({side:e})=>({opacity:1,translate:m(e,0)}),close:({side:e})=>({opacity:0,translate:m(e,-5)})}),{density:B,theme:D}=p(k.reference.current);return e(o,{children:["hover"===g&&t("span",{ref:k.setDescription,hidden:!0,children:f},`${P}-trigger`),F&&t("span",{className:"jkl",children:e("span",{ref:v,"data-placement":j,"aria-live":"click"===g?"assertive":void 0,"data-theme":D,"data-layout-density":B,className:i("jkl-tooltip-content",n),...y({...u,id:P}),style:{...w,...A},children:[f,t(a,{context:T,ref:x,width:24,height:12,fill:"var(--background-color)"})]},P)},`${P}-wrapper`)]})}));export{f as TooltipContent};
1
+ import{jsx as e,jsxs as t,Fragment as s}from"react/jsx-runtime";import{useMergeRefs as r,useTransitionStyles as o,FloatingPortal as a,FloatingFocusManager as n,FloatingArrow as i}from"@floating-ui/react";import{c}from"../../../clsx-BeLtu-UY.js";import{forwardRef as l}from"react";import{useBrowserPreferences as p}from"../../hooks/useBrowserPreferences/useBrowserPreferences.js";import{useId as d}from"../../hooks/useId/useId.js";import{getThemeAndDensity as u}from"../../utilities/getThemeAndDensity.js";import{useTooltipContext as m}from"./Tooltip.js";function f(e,t=0){switch(e){case"top":default:return`0 ${t}px`;case"left":return`${t}px 0`;case"bottom":return`0 ${-t}px`;case"right":return-t+"px 0"}}const g=l((function({className:l,children:g,"data-ispopup":h,...x},y){const{triggerOn:j,arrowElement:F,getFloatingProps:w,placement:k,floatingStyles:T,refs:P,context:$}=m(),M=r([y,P.setFloating]),A=d("jkl-tooltip-content"),{prefersReducedMotion:B}=p(),{isMounted:D,styles:I}=o($,{duration:{open:B?0:250,close:B?0:150},initial:({side:e})=>({opacity:0,translate:f(e,5)}),open:({side:e})=>({opacity:1,translate:f(e,0)}),close:({side:e})=>({opacity:0,translate:f(e,-5)})}),{density:N,theme:O}=u(P.reference.current);return e(a,{children:e(n,{initialFocus:"click"===j?0:-1,returnFocus:!0,context:$,modal:!1,closeOnFocusOut:!0,children:t(s,{children:["hover"===j&&e("span",{ref:P.setDescription,hidden:!0,children:g},`${A}-trigger`),D&&e("span",{className:"jkl",children:t("span",{ref:M,"data-placement":k,"data-testid":"tooltip-content","data-theme":O,"data-layout-density":N,className:c("jkl-tooltip-content",l),...w({...x,id:A}),style:{...T,...I},children:[g,e(i,{context:$,ref:F,width:24,height:12,fill:"var(--background-color)"})]},A)},`${A}-wrapper`)]})})})}));export{g as TooltipContent};
2
2
  //# sourceMappingURL=TooltipContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TooltipContent.js","sources":["../../../../src/components/tooltip/TooltipContent.tsx"],"sourcesContent":["import {\n FloatingArrow,\n FloatingPortal,\n type Side,\n useMergeRefs,\n useTransitionStyles,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport React, { HTMLProps, forwardRef } from \"react\";\nimport { useBrowserPreferences } from \"../../hooks/useBrowserPreferences/useBrowserPreferences.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { getThemeAndDensity } from \"../../utilities/getThemeAndDensity.js\";\nimport { useTooltipContext } from \"./Tooltip.js\";\n\nfunction getTranslation(side: Side, value: number = 0) {\n switch (side) {\n case \"top\":\n return `0 ${value}px`;\n case \"left\":\n return `${value}px 0`;\n case \"bottom\":\n return `0 ${-value}px`;\n case \"right\":\n return `${-value}px 0`;\n\n default:\n return `0 ${value}px`;\n }\n}\n\nexport const TooltipContent = forwardRef<\n HTMLDivElement,\n HTMLProps<HTMLDivElement>\n>(function TooltipContent({ className, children, ...props }, forwardedRef) {\n const {\n triggerOn,\n arrowElement,\n getFloatingProps,\n placement,\n floatingStyles,\n refs,\n context,\n } = useTooltipContext();\n const ref = useMergeRefs([forwardedRef, refs.setFloating]);\n const contentId = useId(\"jkl-tooltip-content\");\n const { prefersReducedMotion } = useBrowserPreferences();\n const { isMounted, styles: animationStyles } = useTransitionStyles(\n context,\n {\n duration: {\n open: prefersReducedMotion ? 0 : 250,\n close: prefersReducedMotion ? 0 : 150,\n },\n initial: ({ side }) => ({\n opacity: 0,\n translate: getTranslation(side, 5),\n }),\n open: ({ side }) => ({\n opacity: 1,\n translate: getTranslation(side, 0),\n }),\n close: ({ side }) => ({\n opacity: 0,\n translate: getTranslation(side, -5),\n }),\n },\n );\n\n // Siden tooltipet rendres på rot må vi hente lokal dark/light-verdi fra triggeren\n // Vi må gjøre dette for å ta hensyn til at tema kan styres lokalt for deler av UIet\n const { density, theme } = getThemeAndDensity(\n refs.reference.current as HTMLElement,\n );\n\n return (\n <FloatingPortal>\n {/* For å kunne bruke tekstinnholdet i tooltip som beskrivende tekst, selv når ikke\n tooltip er synlig, må vi rendre et skjult element å referere til for å hente innholdet. */}\n {triggerOn === \"hover\" && (\n <span\n ref={refs.setDescription}\n hidden\n key={`${contentId}-trigger`}\n >\n {children}\n </span>\n )}\n {isMounted && (\n <span className=\"jkl\" key={`${contentId}-wrapper`}>\n <span\n key={contentId}\n ref={ref}\n data-placement={placement}\n aria-live={\n triggerOn === \"click\" ? \"assertive\" : undefined\n }\n data-theme={theme}\n data-layout-density={density}\n className={clsx(\"jkl-tooltip-content\", className)}\n {...getFloatingProps({\n ...props,\n id: contentId,\n })}\n style={{ ...floatingStyles, ...animationStyles }}\n >\n {children}\n <FloatingArrow\n context={context}\n ref={arrowElement}\n width={24}\n height={12}\n fill=\"var(--background-color)\"\n />\n </span>\n </span>\n )}\n </FloatingPortal>\n );\n});\n"],"names":["getTranslation","side","value","TooltipContent","forwardRef","className","children","props","forwardedRef","triggerOn","arrowElement","getFloatingProps","placement","floatingStyles","refs","context","useTooltipContext","ref","useMergeRefs","setFloating","contentId","useId","prefersReducedMotion","useBrowserPreferences","isMounted","styles","animationStyles","useTransitionStyles","duration","open","close","initial","opacity","translate","density","theme","getThemeAndDensity","reference","current","FloatingPortal","jsx","setDescription","hidden","jsxs","clsx","id","style","FloatingArrow","width","height","fill"],"mappings":"ugBAcA,SAASA,EAAeC,EAAYC,EAAgB,GAChD,OAAQD,GACJ,IAAK,MASL,QACI,MAAO,KAAKC,MARhB,IAAK,OACD,MAAO,GAAGA,QACd,IAAK,SACM,MAAA,MAAMA,MACjB,IAAK,QACM,OAAIA,EAAJ,OAKnB,CAEa,MAAAC,EAAiBC,GAG5B,UAA0BC,UAAAA,EAAWC,SAAAA,KAAaC,GAASC,GACnD,MACFC,UAAAA,EACAC,aAAAA,EACAC,iBAAAA,EACAC,UAAAA,EACAC,eAAAA,EACAC,KAAAA,EACAC,QAAAA,GACAC,IACEC,EAAMC,EAAa,CAACV,EAAcM,EAAKK,cACvCC,EAAYC,EAAM,wBAChBC,qBAAAA,GAAyBC,KACzBC,UAAAA,EAAWC,OAAQC,GAAoBC,EAC3CZ,EACA,CACIa,SAAU,CACNC,KAAMP,EAAuB,EAAI,IACjCQ,MAAOR,EAAuB,EAAI,KAEtCS,QAAS,EAAG9B,KAAAA,MAAY,CACpB+B,QAAS,EACTC,UAAWjC,EAAeC,EAAM,KAEpC4B,KAAM,EAAG5B,KAAAA,MAAY,CACjB+B,QAAS,EACTC,UAAWjC,EAAeC,EAAM,KAEpC6B,MAAO,EAAG7B,KAAAA,MAAY,CAClB+B,QAAS,EACTC,UAAWjC,EAAeC,GAAQ,QAOtCiC,QAAAA,EAASC,MAAAA,GAAUC,EACvBtB,EAAKuB,UAAUC,SAGnB,SACKC,EAGI,CAAAjC,SAAA,CAAc,UAAdG,GACG+B,EAAC,OAAA,CACGvB,IAAKH,EAAK2B,eACVC,QAAM,EAGLpC,SAAAA,GAFI,GAAGc,aAKfI,GACGgB,EAAC,OAAK,CAAAnC,UAAU,MACZC,SAAAqC,EAAC,OAAA,CAEG1B,IAAAA,EACA,iBAAgBL,EAChB,YACkB,UAAdH,EAAwB,iBAAc,EAE1C,aAAY0B,EACZ,sBAAqBD,EACrB7B,UAAWuC,EAAK,sBAAuBvC,MACnCM,EAAiB,IACdJ,EACHsC,GAAIzB,IAER0B,MAAO,IAAKjC,KAAmBa,GAE9BpB,SAAA,CAAAA,EACDkC,EAACO,EAAA,CACGhC,QAAAA,EACAE,IAAKP,EACLsC,MAAO,GACPC,OAAQ,GACRC,KAAK,8BArBJ9B,IAFc,GAAGA,eA8B9C"}
1
+ {"version":3,"file":"TooltipContent.js","sources":["../../../../src/components/tooltip/TooltipContent.tsx"],"sourcesContent":["import {\n FloatingArrow,\n FloatingFocusManager,\n FloatingPortal,\n type Side,\n useMergeRefs,\n useTransitionStyles,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport React, { HTMLProps, forwardRef } from \"react\";\nimport { useBrowserPreferences } from \"../../hooks/useBrowserPreferences/useBrowserPreferences.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { getThemeAndDensity } from \"../../utilities/getThemeAndDensity.js\";\nimport { useTooltipContext } from \"./Tooltip.js\";\n\nfunction getTranslation(side: Side, value: number = 0) {\n switch (side) {\n case \"top\":\n return `0 ${value}px`;\n case \"left\":\n return `${value}px 0`;\n case \"bottom\":\n return `0 ${-value}px`;\n case \"right\":\n return `${-value}px 0`;\n\n default:\n return `0 ${value}px`;\n }\n}\n\nexport const TooltipContent = forwardRef<\n HTMLDivElement,\n HTMLProps<HTMLDivElement> & { \"data-ispopup\"?: boolean }\n>(function TooltipContent(\n { className, children, [\"data-ispopup\"]: isPopup, ...props },\n forwardedRef,\n) {\n const {\n triggerOn,\n arrowElement,\n getFloatingProps,\n placement,\n floatingStyles,\n refs,\n context,\n } = useTooltipContext();\n const ref = useMergeRefs([forwardedRef, refs.setFloating]);\n const contentId = useId(\"jkl-tooltip-content\");\n const { prefersReducedMotion } = useBrowserPreferences();\n const { isMounted, styles: animationStyles } = useTransitionStyles(\n context,\n {\n duration: {\n open: prefersReducedMotion ? 0 : 250,\n close: prefersReducedMotion ? 0 : 150,\n },\n initial: ({ side }) => ({\n opacity: 0,\n translate: getTranslation(side, 5),\n }),\n open: ({ side }) => ({\n opacity: 1,\n translate: getTranslation(side, 0),\n }),\n close: ({ side }) => ({\n opacity: 0,\n translate: getTranslation(side, -5),\n }),\n },\n );\n\n // Siden tooltipet rendres på rot må vi hente lokal dark/light-verdi fra triggeren\n // Vi må gjøre dette for å ta hensyn til at tema kan styres lokalt for deler av UIet\n const { density, theme } = getThemeAndDensity(\n refs.reference.current as HTMLElement,\n );\n\n return (\n <FloatingPortal>\n <FloatingFocusManager\n initialFocus={triggerOn === \"click\" ? 0 : -1}\n returnFocus={true}\n context={context}\n modal={false}\n closeOnFocusOut={true}\n >\n <>\n {/* For å kunne bruke tekstinnholdet i tooltip som beskrivende tekst, selv når ikke\n tooltip er synlig, må vi rendre et skjult element å referere til for å hente innholdet. */}\n {triggerOn === \"hover\" && (\n <span\n ref={refs.setDescription}\n hidden\n key={`${contentId}-trigger`}\n >\n {children}\n </span>\n )}\n {isMounted && (\n <span className=\"jkl\" key={`${contentId}-wrapper`}>\n <span\n key={contentId}\n ref={ref}\n data-placement={placement}\n data-testid={\"tooltip-content\"}\n data-theme={theme}\n data-layout-density={density}\n className={clsx(\n \"jkl-tooltip-content\",\n className,\n )}\n {...getFloatingProps({\n ...props,\n id: contentId,\n })}\n style={{\n ...floatingStyles,\n ...animationStyles,\n }}\n >\n {children}\n <FloatingArrow\n context={context}\n ref={arrowElement}\n width={24}\n height={12}\n fill=\"var(--background-color)\"\n />\n </span>\n </span>\n )}\n </>\n </FloatingFocusManager>\n </FloatingPortal>\n );\n});\n"],"names":["getTranslation","side","value","TooltipContent","forwardRef","className","children","isPopup","props","forwardedRef","triggerOn","arrowElement","getFloatingProps","placement","floatingStyles","refs","context","useTooltipContext","ref","useMergeRefs","setFloating","contentId","useId","prefersReducedMotion","useBrowserPreferences","isMounted","styles","animationStyles","useTransitionStyles","duration","open","close","initial","opacity","translate","density","theme","getThemeAndDensity","reference","current","FloatingPortal","jsx","FloatingFocusManager","initialFocus","returnFocus","modal","closeOnFocusOut","jsxs","Fragment","setDescription","hidden","clsx","id","style","FloatingArrow","width","height","fill"],"mappings":"0iBAeA,SAASA,EAAeC,EAAYC,EAAgB,GAChD,OAAQD,GACJ,IAAK,MASL,QACI,MAAO,KAAKC,MARhB,IAAK,OACD,MAAO,GAAGA,QACd,IAAK,SACM,MAAA,MAAMA,MACjB,IAAK,QACM,OAAIA,EAAJ,OAKnB,CAEO,MAAMC,EAAiBC,GAG5B,UACIC,UAAAA,EAAWC,SAAAA,EAAU,eAAkBC,KAAYC,GACrDC,GAEM,MACFC,UAAAA,EACAC,aAAAA,EACAC,iBAAAA,EACAC,UAAAA,EACAC,eAAAA,EACAC,KAAAA,EACAC,QAAAA,GACAC,IACEC,EAAMC,EAAa,CAACV,EAAcM,EAAKK,cACvCC,EAAYC,EAAM,wBAChBC,qBAAAA,GAAyBC,KACzBC,UAAAA,EAAWC,OAAQC,GAAoBC,EAC3CZ,EACA,CACIa,SAAU,CACNC,KAAMP,EAAuB,EAAI,IACjCQ,MAAOR,EAAuB,EAAI,KAEtCS,QAAS,EAAG/B,KAAAA,MAAY,CACpBgC,QAAS,EACTC,UAAWlC,EAAeC,EAAM,KAEpC6B,KAAM,EAAG7B,KAAAA,MAAY,CACjBgC,QAAS,EACTC,UAAWlC,EAAeC,EAAM,KAEpC8B,MAAO,EAAG9B,KAAAA,MAAY,CAClBgC,QAAS,EACTC,UAAWlC,EAAeC,GAAQ,QAOtCkC,QAAAA,EAASC,MAAAA,GAAUC,EACvBtB,EAAKuB,UAAUC,SAGnB,SACKC,EACG,CAAAlC,SAAAmC,EAACC,EAAA,CACGC,aAA4B,UAAdjC,EAAwB,GAAI,EAC1CkC,aAAa,EACb5B,QAAAA,EACA6B,OAAO,EACPC,iBAAiB,EAEjBxC,SAGKyC,EAAAC,EAAA,CAAA1C,SAAA,CAAc,UAAdI,GACG+B,EAAC,OAAA,CACGvB,IAAKH,EAAKkC,eACVC,QAAM,EAGL5C,SAAAA,GAFI,GAAGe,aAKfI,GACGgB,EAAC,OAAK,CAAApC,UAAU,MACZC,SAAAyC,EAAC,OAAA,CAEG7B,IAAAA,EACA,iBAAgBL,EAChB,cAAa,kBACb,aAAYuB,EACZ,sBAAqBD,EACrB9B,UAAW8C,EACP,sBACA9C,MAEAO,EAAiB,IACdJ,EACH4C,GAAI/B,IAERgC,MAAO,IACAvC,KACAa,GAGNrB,SAAA,CAAAA,EACDmC,EAACa,EAAA,CACGtC,QAAAA,EACAE,IAAKP,EACL4C,MAAO,GACPC,OAAQ,GACRC,KAAK,8BAzBJpC,IAFc,GAAGA,mBAoCtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fremtind/jokul",
3
- "version": "0.37.8",
3
+ "version": "0.37.10",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -602,5 +602,5 @@
602
602
  "@babel/preset-react"
603
603
  ]
604
604
  },
605
- "gitHead": "42a3e269ce785b658e225fdf86c275f7df3d99f9"
605
+ "gitHead": "1c7317e35f6aee493518e158d0d1a030a27e4fe7"
606
606
  }
@@ -12,6 +12,8 @@
12
12
  --jkl-accordion-arrow-right: var(--jkl-spacing-12);
13
13
  --jkl-accordion-content-padding: var(--jkl-spacing-8) var(--jkl-spacing-16)
14
14
  var(--jkl-spacing-16);
15
+ --jkl-accordion-icon-opsz: 24;
16
+ --jkl-accordion-icon-size: 1.5rem;
15
17
  --title-font-size: var(--jkl-body-font-size);
16
18
  --title-line-height: var(--jkl-body-line-height);
17
19
  --title-font-weight: var(--jkl-body-font-weight);
@@ -40,6 +42,8 @@
40
42
  --jkl-accordion-arrow-top: var(--jkl-spacing-8);
41
43
  --jkl-accordion-arrow-right: var(--jkl-spacing-4);
42
44
  --jkl-accordion-content-padding: var(--jkl-spacing-8);
45
+ --jkl-accordion-icon-opsz: 20;
46
+ --jkl-accordion-icon-size: 1.25rem;
43
47
  --title-font-size: var(--jkl-small-font-size);
44
48
  --title-line-height: var(--jkl-small-line-height);
45
49
  --title-font-weight: var(--jkl-small-font-weight);
@@ -57,6 +61,8 @@
57
61
  --text-color: var(--jkl-color-text-default);
58
62
  --title-text-color: var(--jkl-color-text-interactive);
59
63
  --border-color: var(--jkl-color-border-separator);
64
+ --jkl-icon-opsz: var(--jkl-accordion-icon-opsz);
65
+ --jkl-icon-size: var(--jkl-accordion-icon-size);
60
66
  background-color: var(--background);
61
67
  color: var(--text-color);
62
68
  border-bottom: 0.0625rem solid var(--border-color);
@@ -1,7 +1,7 @@
1
1
  :root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-accordion-title-padding:var(--jkl-spacing-16) 3rem var(
2
2
  --jkl-spacing-16
3
- ) var(--jkl-spacing-16);--jkl-accordion-arrow-top:1.25rem;--jkl-accordion-arrow-right:var(--jkl-spacing-12);--jkl-accordion-content-padding:var(--jkl-spacing-8) var(--jkl-spacing-16) var(--jkl-spacing-16);--title-font-size:var(--jkl-body-font-size);--title-line-height:var(--jkl-body-line-height);--title-font-weight:var(--jkl-body-font-weight);--content-font-size:var(--jkl-body-font-size);--content-line-height:var(--jkl-body-line-height);--content-font-weight:var(--jkl-body-font-weight)}@media (width >= 0) and (max-width:679px){:root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-accordion-title-padding:var(--jkl-spacing-12) 2.75rem var(
3
+ ) var(--jkl-spacing-16);--jkl-accordion-arrow-top:1.25rem;--jkl-accordion-arrow-right:var(--jkl-spacing-12);--jkl-accordion-content-padding:var(--jkl-spacing-8) var(--jkl-spacing-16) var(--jkl-spacing-16);--jkl-accordion-icon-opsz:24;--jkl-accordion-icon-size:1.5rem;--title-font-size:var(--jkl-body-font-size);--title-line-height:var(--jkl-body-line-height);--title-font-weight:var(--jkl-body-font-weight);--content-font-size:var(--jkl-body-font-size);--content-line-height:var(--jkl-body-line-height);--content-font-weight:var(--jkl-body-font-weight)}@media (width >= 0) and (max-width:679px){:root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-accordion-title-padding:var(--jkl-spacing-12) 2.75rem var(
4
4
  --jkl-spacing-12
5
5
  ) var(--jkl-spacing-12);--jkl-accordion-content-padding:var(--jkl-spacing-8) var(--jkl-spacing-12) var(--jkl-spacing-16) var(--jkl-spacing-12);--jkl-accordion-arrow-top:1.4375rem}}[data-density=compact],[data-layout-density=compact]{--jkl-accordion-title-padding:var(--jkl-spacing-8) 2rem var(
6
6
  --jkl-spacing-8
7
- ) var(--jkl-spacing-8);--jkl-accordion-arrow-top:var(--jkl-spacing-8);--jkl-accordion-arrow-right:var(--jkl-spacing-4);--jkl-accordion-content-padding:var(--jkl-spacing-8);--title-font-size:var(--jkl-small-font-size);--title-line-height:var(--jkl-small-line-height);--title-font-weight:var(--jkl-small-font-weight);--content-font-size:var(--jkl-small-font-size);--content-line-height:var(--jkl-small-line-height);--content-font-weight:var(--jkl-small-font-weight)}.jkl-accordion{width:100%}.jkl-accordion-item{--background:transparent;--text-color:var(--jkl-color-text-default);--title-text-color:var(--jkl-color-text-interactive);--border-color:var(--jkl-color-border-separator);background-color:var(--background);border-bottom:.0625rem solid var(--border-color);color:var(--text-color);transition-duration:.1s;transition-property:border-color;transition-timing-function:ease}.jkl-accordion-item:hover{--border-color:var(--jkl-color-border-separator-hover)}.jkl-accordion-item:hover:not(:first-child){border-top:.0625rem solid var(--border-color)}.jkl-accordion-item:has(+:hover),.jkl-accordion-item:has(+[open]){border-bottom:none}.jkl-accordion-item[open]{--background:var(--jkl-color-background-container-high);border-top:.0625rem solid var(--border-color)}.jkl-accordion-item[open] .jkl-accordion-item__title{--jkl-icon-weight:500;font-weight:700;letter-spacing:-.014em}.jkl-accordion-item__title{background-color:transparent;border-style:none;box-sizing:border-box;color:var(--title-text-color);cursor:pointer;font-size:var(--title-font-size);font-weight:var(--title-font-weight);line-height:var(--title-line-height);list-style:none;outline:0;outline-style:none;padding:var(--jkl-accordion-title-padding);position:relative;text-align:left;width:100%}.jkl-accordion-item__title:active,.jkl-accordion-item__title:focus,.jkl-accordion-item__title:hover{outline:0;outline-style:none}@media screen and (forced-colors:active){.jkl-accordion-item__title{border-style:revert;outline:revert;outline-style:revert}.jkl-accordion-item__title:active,.jkl-accordion-item__title:focus,.jkl-accordion-item__title:hover{outline:revert;outline-style:revert}}.jkl-accordion-item__title::-webkit-details-marker{display:none}.jkl-accordion-item__title:hover{--title-text-color:var(--jkl-color-text-interactive-hover)}.jkl-accordion-item__title:hover .jkl-accordion-item__arrow{translate:0 .25rem}.jkl-accordion-item__title:focus-visible{outline:2px solid var(--jkl-color-border-action);outline-offset:0}.jkl-accordion-item__arrow{pointer-events:none;position:absolute;right:var(--jkl-accordion-arrow-right);top:var(--jkl-accordion-arrow-top);transition-duration:.1s;transition-property:translate;transition-timing-function:ease}@media screen and (forced-colors:active){.jkl-accordion-item__arrow,.jkl-accordion-item__arrow path,.jkl-accordion-item__arrow svg{stroke:ButtonText;fill:ButtonText}}.jkl-accordion-item__content-wrapper{transition-duration:.15s;transition-property:height;transition-timing-function:ease}.jkl-accordion-item__content{font-size:var(--content-font-size);font-weight:var(--content-font-weight);height:auto;line-height:var(--content-line-height);padding:var(--jkl-accordion-content-padding)}@media screen and (forced-colors:active){.jkl-accordion-item:nth-child(n){border-top:.125rem solid ButtonText}.jkl-accordion-item:nth-child(n):hover{border-top:.125rem solid ButtonText}.jkl-accordion-item:nth-child(n):hover+.jkl-accordion-item{border-top:.125rem solid ButtonText}.jkl-accordion-item:last-child{border-bottom:.125rem solid ButtonText}.jkl-accordion-item:last-child:hover{border-bottom:.125rem solid ButtonText}.jkl-accordion-item__title{background-color:ButtonFace;outline:revert}}
7
+ ) var(--jkl-spacing-8);--jkl-accordion-arrow-top:var(--jkl-spacing-8);--jkl-accordion-arrow-right:var(--jkl-spacing-4);--jkl-accordion-content-padding:var(--jkl-spacing-8);--jkl-accordion-icon-opsz:20;--jkl-accordion-icon-size:1.25rem;--title-font-size:var(--jkl-small-font-size);--title-line-height:var(--jkl-small-line-height);--title-font-weight:var(--jkl-small-font-weight);--content-font-size:var(--jkl-small-font-size);--content-line-height:var(--jkl-small-line-height);--content-font-weight:var(--jkl-small-font-weight)}.jkl-accordion{width:100%}.jkl-accordion-item{--background:transparent;--text-color:var(--jkl-color-text-default);--title-text-color:var(--jkl-color-text-interactive);--border-color:var(--jkl-color-border-separator);--jkl-icon-opsz:var(--jkl-accordion-icon-opsz);--jkl-icon-size:var(--jkl-accordion-icon-size);background-color:var(--background);border-bottom:.0625rem solid var(--border-color);color:var(--text-color);transition-duration:.1s;transition-property:border-color;transition-timing-function:ease}.jkl-accordion-item:hover{--border-color:var(--jkl-color-border-separator-hover)}.jkl-accordion-item:hover:not(:first-child){border-top:.0625rem solid var(--border-color)}.jkl-accordion-item:has(+:hover),.jkl-accordion-item:has(+[open]){border-bottom:none}.jkl-accordion-item[open]{--background:var(--jkl-color-background-container-high);border-top:.0625rem solid var(--border-color)}.jkl-accordion-item[open] .jkl-accordion-item__title{--jkl-icon-weight:500;font-weight:700;letter-spacing:-.014em}.jkl-accordion-item__title{background-color:transparent;border-style:none;box-sizing:border-box;color:var(--title-text-color);cursor:pointer;font-size:var(--title-font-size);font-weight:var(--title-font-weight);line-height:var(--title-line-height);list-style:none;outline:0;outline-style:none;padding:var(--jkl-accordion-title-padding);position:relative;text-align:left;width:100%}.jkl-accordion-item__title:active,.jkl-accordion-item__title:focus,.jkl-accordion-item__title:hover{outline:0;outline-style:none}@media screen and (forced-colors:active){.jkl-accordion-item__title{border-style:revert;outline:revert;outline-style:revert}.jkl-accordion-item__title:active,.jkl-accordion-item__title:focus,.jkl-accordion-item__title:hover{outline:revert;outline-style:revert}}.jkl-accordion-item__title::-webkit-details-marker{display:none}.jkl-accordion-item__title:hover{--title-text-color:var(--jkl-color-text-interactive-hover)}.jkl-accordion-item__title:hover .jkl-accordion-item__arrow{translate:0 .25rem}.jkl-accordion-item__title:focus-visible{outline:2px solid var(--jkl-color-border-action);outline-offset:0}.jkl-accordion-item__arrow{pointer-events:none;position:absolute;right:var(--jkl-accordion-arrow-right);top:var(--jkl-accordion-arrow-top);transition-duration:.1s;transition-property:translate;transition-timing-function:ease}@media screen and (forced-colors:active){.jkl-accordion-item__arrow,.jkl-accordion-item__arrow path,.jkl-accordion-item__arrow svg{stroke:ButtonText;fill:ButtonText}}.jkl-accordion-item__content-wrapper{transition-duration:.15s;transition-property:height;transition-timing-function:ease}.jkl-accordion-item__content{font-size:var(--content-font-size);font-weight:var(--content-font-weight);height:auto;line-height:var(--content-line-height);padding:var(--jkl-accordion-content-padding)}@media screen and (forced-colors:active){.jkl-accordion-item:nth-child(n){border-top:.125rem solid ButtonText}.jkl-accordion-item:nth-child(n):hover{border-top:.125rem solid ButtonText}.jkl-accordion-item:nth-child(n):hover+.jkl-accordion-item{border-top:.125rem solid ButtonText}.jkl-accordion-item:last-child{border-bottom:.125rem solid ButtonText}.jkl-accordion-item:last-child:hover{border-bottom:.125rem solid ButtonText}.jkl-accordion-item__title{background-color:ButtonFace;outline:revert}}
@@ -9,6 +9,8 @@
9
9
  --jkl-accordion-arrow-right: var(--jkl-spacing-12);
10
10
  --jkl-accordion-content-padding: var(--jkl-spacing-8) var(--jkl-spacing-16)
11
11
  var(--jkl-spacing-16);
12
+ --jkl-accordion-icon-opsz: 24;
13
+ --jkl-accordion-icon-size: 1.5rem;
12
14
  @include jkl.declare-font-variables("title", "body");
13
15
  @include jkl.declare-font-variables("content", "body");
14
16
 
@@ -29,6 +31,8 @@
29
31
  --jkl-accordion-arrow-top: var(--jkl-spacing-8);
30
32
  --jkl-accordion-arrow-right: var(--jkl-spacing-4);
31
33
  --jkl-accordion-content-padding: var(--jkl-spacing-8);
34
+ --jkl-accordion-icon-opsz: 20;
35
+ --jkl-accordion-icon-size: 1.25rem;
32
36
  @include jkl.declare-font-variables("title", "small");
33
37
  @include jkl.declare-font-variables("content", "small");
34
38
  }
@@ -44,6 +48,8 @@
44
48
  --text-color: var(--jkl-color-text-default);
45
49
  --title-text-color: var(--jkl-color-text-interactive);
46
50
  --border-color: var(--jkl-color-border-separator);
51
+ --jkl-icon-opsz: var(--jkl-accordion-icon-opsz);
52
+ --jkl-icon-size: var(--jkl-accordion-icon-size);
47
53
 
48
54
  background-color: var(--background);
49
55
  color: var(--text-color);
@@ -135,7 +135,7 @@
135
135
  height: 1rem;
136
136
  }
137
137
  html[data-touchnavigation] .jkl-button.jkl-button--pressed::before {
138
- animation: cubic-bezier(0.6, 0.2, 0.35, 1) 250ms jkl-tertiary-flash-u9pua6n;
138
+ animation: cubic-bezier(0.6, 0.2, 0.35, 1) 250ms jkl-tertiary-flash-ufx5j0u;
139
139
  }
140
140
  :not([data-touchnavigation]) .jkl-button--primary:hover, :not([data-touchnavigation]) .jkl-button--secondary:hover, :not([data-touchnavigation]) .jkl-button--tertiary:hover {
141
141
  scale: 1.05;
@@ -179,7 +179,7 @@ html[data-touchnavigation] .jkl-button.jkl-button--pressed::before {
179
179
  --background-color: var(--jkl-color-background-interactive-hover);
180
180
  }
181
181
 
182
- @keyframes jkl-tertiary-flash-u9pua6n {
182
+ @keyframes jkl-tertiary-flash-ufx5j0u {
183
183
  0% {
184
184
  opacity: 0.5;
185
185
  scale: 1;
@@ -1 +1 @@
1
- :root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-button-padding-block:0.5rem;--jkl-button-padding-text:1.5rem;--jkl-button-padding-icon:1rem;--jkl-button-padding-icon-button:0.5rem;--jkl-button-padding-tertiary-inline:0.25rem;--jkl-button-padding-ghost-inline:0.5rem;--jkl-button-font-size:1.125rem;--jkl-button-line-height:1.75rem}@media (min-width:680px){:root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-button-font-size:1.25rem;--jkl-button-line-height:2rem}}[data-density=compact],[data-layout-density=compact]{--jkl-button-padding-block:0.25rem;--jkl-button-padding-text:0.75rem;--jkl-button-padding-icon:0.5rem;--jkl-button-padding-icon-button:0.25rem;--jkl-button-padding-tertiary-inline:0.125rem;--jkl-button-padding-ghost-inline:0.25rem;--jkl-button-font-size:1rem;--jkl-button-line-height:1.5rem}@media (min-width:680px){[data-density=compact],[data-layout-density=compact]{--jkl-button-font-size:1rem;--jkl-button-line-height:1.5rem;--jkl-button-icon-weight:500}}.jkl-button{--jkl-icon-weight:var(--jkl-button-icon-weight,initial);--text-color:var(--jkl-color-text-default);--background-color:transparent;--border-radius:0;--border-width:0.0625rem;background-color:var(--background-color);border:unset;color:var(--text-color);cursor:pointer;display:inline-block;font-size:var(--jkl-button-font-size);font-weight:700;line-height:var(--jkl-button-line-height);text-decoration:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;border-radius:var(--border-radius);max-width:100%;overflow:hidden;padding-block:var(--jkl-button-padding-block);padding-inline:var(--jkl-button-padding-text);position:relative;transition-duration:.15s;transition-property:scale;transition-timing-function:ease}.jkl-button:has(.jkl-icon:first-child){padding-inline-start:var(--jkl-button-padding-icon)}.jkl-button:has(.jkl-icon:last-child){padding-inline-end:var(--jkl-button-padding-icon)}.jkl-button:has(.jkl-icon:first-child):has(.jkl-icon:last-child){padding-inline:var(--jkl-button-padding-icon-button)}.jkl-button__label{align-items:center;display:flex;flex-direction:row;gap:.125rem;pointer-events:none;transition-duration:.25s;transition-property:translate;transition-timing-function:ease;width:100%}.jkl-button__loader{left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transition-duration:.25s;transition-property:opacity,translate;transition-timing-function:ease;translate:-50% 350%}.jkl-button__text{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.jkl-button[data-loading=true] .jkl-button__label{translate:0 -120%}.jkl-button[data-loading=true] .jkl-button__loader{opacity:1;translate:-50% -50%}.jkl-button:focus-visible{outline:2px solid var(--jkl-color-border-action);outline-offset:2px}.jkl-button:before{background-color:var(--text-color);border-radius:9999px;content:"";display:block;height:1rem;left:var(--jkl-touch-xcoord,50%);opacity:0;pointer-events:none;position:absolute;top:var(--jkl-touch-ycoord,50%);transform-origin:center;translate:-100%,-100%;width:1rem}html[data-touchnavigation] .jkl-button.jkl-button--pressed:before{animation:jkl-tertiary-flash-u9pua6n .25s cubic-bezier(.6,.2,.35,1)}:not([data-touchnavigation]) .jkl-button--primary:hover,:not([data-touchnavigation]) .jkl-button--secondary:hover,:not([data-touchnavigation]) .jkl-button--tertiary:hover{scale:1.05;transform-origin:center}.jkl-button--primary,.jkl-button--secondary{--border-radius:999px}.jkl-button--primary{--background-color:var(--jkl-color-background-action);--text-color:var(--jkl-color-text-on-action)}.jkl-button--secondary:after{border:var(--border-width) solid var(--text-color);border-radius:var(--border-radius);content:"";inset:0;position:absolute}.jkl-button--tertiary,.jkl-button--tertiary:has(.jkl-icon:first-child),.jkl-button--tertiary:has(.jkl-icon:last-child){padding-inline:var(--jkl-button-padding-tertiary-inline)}.jkl-button--tertiary:after,.jkl-button--tertiary:has(.jkl-icon:first-child):after,.jkl-button--tertiary:has(.jkl-icon:last-child):after{border-bottom:var(--border-width) solid var(--text-color);border-radius:var(--border-radius);content:"";inset:0;position:absolute}.jkl-button--tertiary:focus-visible,.jkl-button--tertiary:has(.jkl-icon:first-child):focus-visible,.jkl-button--tertiary:has(.jkl-icon:first-child):hover,.jkl-button--tertiary:has(.jkl-icon:last-child):focus-visible,.jkl-button--tertiary:has(.jkl-icon:last-child):hover,.jkl-button--tertiary:hover{--border-width:0.125rem}.jkl-button--ghost,.jkl-button--ghost:has(.jkl-icon:first-child),.jkl-button--ghost:has(.jkl-icon:last-child){border-radius:.25rem;padding-inline:var(--jkl-button-padding-ghost-inline);transition-duration:.15s;transition-property:background-color;transition-timing-function:ease}.jkl-button--ghost:has(.jkl-icon:first-child):hover,.jkl-button--ghost:has(.jkl-icon:last-child):hover,.jkl-button--ghost:hover{--background-color:var(--jkl-color-background-interactive-hover)}@keyframes jkl-tertiary-flash-u9pua6n{0%{opacity:.5;scale:1}to{opacity:0;scale:8}}
1
+ :root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-button-padding-block:0.5rem;--jkl-button-padding-text:1.5rem;--jkl-button-padding-icon:1rem;--jkl-button-padding-icon-button:0.5rem;--jkl-button-padding-tertiary-inline:0.25rem;--jkl-button-padding-ghost-inline:0.5rem;--jkl-button-font-size:1.125rem;--jkl-button-line-height:1.75rem}@media (min-width:680px){:root,[data-density=comfortable],[data-layout-density=comfortable]{--jkl-button-font-size:1.25rem;--jkl-button-line-height:2rem}}[data-density=compact],[data-layout-density=compact]{--jkl-button-padding-block:0.25rem;--jkl-button-padding-text:0.75rem;--jkl-button-padding-icon:0.5rem;--jkl-button-padding-icon-button:0.25rem;--jkl-button-padding-tertiary-inline:0.125rem;--jkl-button-padding-ghost-inline:0.25rem;--jkl-button-font-size:1rem;--jkl-button-line-height:1.5rem}@media (min-width:680px){[data-density=compact],[data-layout-density=compact]{--jkl-button-font-size:1rem;--jkl-button-line-height:1.5rem;--jkl-button-icon-weight:500}}.jkl-button{--jkl-icon-weight:var(--jkl-button-icon-weight,initial);--text-color:var(--jkl-color-text-default);--background-color:transparent;--border-radius:0;--border-width:0.0625rem;background-color:var(--background-color);border:unset;color:var(--text-color);cursor:pointer;display:inline-block;font-size:var(--jkl-button-font-size);font-weight:700;line-height:var(--jkl-button-line-height);text-decoration:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;border-radius:var(--border-radius);max-width:100%;overflow:hidden;padding-block:var(--jkl-button-padding-block);padding-inline:var(--jkl-button-padding-text);position:relative;transition-duration:.15s;transition-property:scale;transition-timing-function:ease}.jkl-button:has(.jkl-icon:first-child){padding-inline-start:var(--jkl-button-padding-icon)}.jkl-button:has(.jkl-icon:last-child){padding-inline-end:var(--jkl-button-padding-icon)}.jkl-button:has(.jkl-icon:first-child):has(.jkl-icon:last-child){padding-inline:var(--jkl-button-padding-icon-button)}.jkl-button__label{align-items:center;display:flex;flex-direction:row;gap:.125rem;pointer-events:none;transition-duration:.25s;transition-property:translate;transition-timing-function:ease;width:100%}.jkl-button__loader{left:50%;opacity:0;pointer-events:none;position:absolute;top:50%;transition-duration:.25s;transition-property:opacity,translate;transition-timing-function:ease;translate:-50% 350%}.jkl-button__text{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.jkl-button[data-loading=true] .jkl-button__label{translate:0 -120%}.jkl-button[data-loading=true] .jkl-button__loader{opacity:1;translate:-50% -50%}.jkl-button:focus-visible{outline:2px solid var(--jkl-color-border-action);outline-offset:2px}.jkl-button:before{background-color:var(--text-color);border-radius:9999px;content:"";display:block;height:1rem;left:var(--jkl-touch-xcoord,50%);opacity:0;pointer-events:none;position:absolute;top:var(--jkl-touch-ycoord,50%);transform-origin:center;translate:-100%,-100%;width:1rem}html[data-touchnavigation] .jkl-button.jkl-button--pressed:before{animation:jkl-tertiary-flash-ufx5j0u .25s cubic-bezier(.6,.2,.35,1)}:not([data-touchnavigation]) .jkl-button--primary:hover,:not([data-touchnavigation]) .jkl-button--secondary:hover,:not([data-touchnavigation]) .jkl-button--tertiary:hover{scale:1.05;transform-origin:center}.jkl-button--primary,.jkl-button--secondary{--border-radius:999px}.jkl-button--primary{--background-color:var(--jkl-color-background-action);--text-color:var(--jkl-color-text-on-action)}.jkl-button--secondary:after{border:var(--border-width) solid var(--text-color);border-radius:var(--border-radius);content:"";inset:0;position:absolute}.jkl-button--tertiary,.jkl-button--tertiary:has(.jkl-icon:first-child),.jkl-button--tertiary:has(.jkl-icon:last-child){padding-inline:var(--jkl-button-padding-tertiary-inline)}.jkl-button--tertiary:after,.jkl-button--tertiary:has(.jkl-icon:first-child):after,.jkl-button--tertiary:has(.jkl-icon:last-child):after{border-bottom:var(--border-width) solid var(--text-color);border-radius:var(--border-radius);content:"";inset:0;position:absolute}.jkl-button--tertiary:focus-visible,.jkl-button--tertiary:has(.jkl-icon:first-child):focus-visible,.jkl-button--tertiary:has(.jkl-icon:first-child):hover,.jkl-button--tertiary:has(.jkl-icon:last-child):focus-visible,.jkl-button--tertiary:has(.jkl-icon:last-child):hover,.jkl-button--tertiary:hover{--border-width:0.125rem}.jkl-button--ghost,.jkl-button--ghost:has(.jkl-icon:first-child),.jkl-button--ghost:has(.jkl-icon:last-child){border-radius:.25rem;padding-inline:var(--jkl-button-padding-ghost-inline);transition-duration:.15s;transition-property:background-color;transition-timing-function:ease}.jkl-button--ghost:has(.jkl-icon:first-child):hover,.jkl-button--ghost:has(.jkl-icon:last-child):hover,.jkl-button--ghost:hover{--background-color:var(--jkl-color-background-interactive-hover)}@keyframes jkl-tertiary-flash-ufx5j0u{0%{opacity:.5;scale:1}to{opacity:0;scale:8}}
@@ -273,6 +273,7 @@ html:not([data-mousenavigation]):not([data-touchnavigation]) .jkl-nav-card:focus
273
273
  content: "";
274
274
  position: absolute;
275
275
  inset: 0;
276
+ pointer-events: none;
276
277
  border-radius: var(--border-radius);
277
278
  border: var(--border-width) solid var(--border-color);
278
279
  transition-timing-function: ease;