@helsenorge/designsystem-react 12.10.0 → 12.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/RadioButton.js +1 -0
- package/RadioButton.js.map +1 -1
- package/Toast.js +21 -2
- package/Toast.js.map +1 -1
- package/components/Button/styles.module.scss +59 -24
- package/components/Checkbox/styles.module.scss +11 -0
- package/components/Dropdown/index.js +12 -6
- package/components/Dropdown/index.js.map +1 -1
- package/components/Dropdown/styles.module.scss +2 -1
- package/components/RadioButton/styles.module.scss +4 -0
- package/components/RadioButton/styles.module.scss.d.ts +1 -0
- package/components/Toast/styles.module.scss +26 -6
- package/components/Toggle/styles.module.scss +9 -0
- package/docs/Tokens/TokensExample.d.ts +7 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
## [12.11.1](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.11.0&targetVersion=GTv12.11.1) (2025-11-04)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **dropdown:** krymper med høyden igjen
|
|
6
|
+
([07d9baf](https://github.com/helsenorge/designsystem/commit/07d9baf51824dff93a5c45766f59a2fdf9285caa)), closes
|
|
7
|
+
[#363493](https://github.com/helsenorge/designsystem/issues/363493)
|
|
8
|
+
- **dropdown:** listen flyttes ikke i y aksen av viewport
|
|
9
|
+
([357ea4f](https://github.com/helsenorge/designsystem/commit/357ea4ff08fc405bc8004c83ab5c0f9cb2b56145)), closes
|
|
10
|
+
[#363493](https://github.com/helsenorge/designsystem/issues/363493)
|
|
11
|
+
|
|
12
|
+
## [12.11.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.10.0&targetVersion=GTv12.11.0) (2025-11-03)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- tydeligere focus state for noen komponenter
|
|
17
|
+
([412e779](https://github.com/helsenorge/designsystem/commit/412e779f6e01a11fcc593ed57dbfd32168a3241e)), closes
|
|
18
|
+
[#357133](https://github.com/helsenorge/designsystem/issues/357133)
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- **button:** align tekst til venstre ved flere linjer
|
|
23
|
+
([b47f1e0](https://github.com/helsenorge/designsystem/commit/b47f1e0e137230a3c8017b07e7671d063e91d86a))
|
|
24
|
+
- **button:** fiks padding rundt tekst når den går over flere linjer
|
|
25
|
+
([7ff8f63](https://github.com/helsenorge/designsystem/commit/7ff8f63f305291c56f77ec3a25334f74b2205dfb))
|
|
26
|
+
- **button:** oppdatert padding på borderless variant
|
|
27
|
+
([be2b683](https://github.com/helsenorge/designsystem/commit/be2b6833591625a90b235e48e7682f6eb722bbf6))
|
|
28
|
+
- **dropdown:** aligner og krymper riktig ved mindre plass
|
|
29
|
+
([4b28673](https://github.com/helsenorge/designsystem/commit/4b286731a9dae975e29e8d17c0c200099405e789)), closes
|
|
30
|
+
[#363493](https://github.com/helsenorge/designsystem/issues/363493)
|
|
31
|
+
- **toast:** fiks størrelse på ikon og plassering i grid
|
|
32
|
+
([cf38ba8](https://github.com/helsenorge/designsystem/commit/cf38ba8c399bd66f2f24c7f64fa88688cc639656)), closes
|
|
33
|
+
[#357838](https://github.com/helsenorge/designsystem/issues/357838)
|
|
34
|
+
- **toast:** legg til litt spacing mellom innhold
|
|
35
|
+
([1c900de](https://github.com/helsenorge/designsystem/commit/1c900de13b3c1d19d3326bf15ec7e0f34c2fc530)), closes
|
|
36
|
+
[#357838](https://github.com/helsenorge/designsystem/issues/357838)
|
|
37
|
+
- **toast:** liten justering av tekst
|
|
38
|
+
([481834f](https://github.com/helsenorge/designsystem/commit/481834f15ed31e4eb02788db58f795079fd07877)), closes
|
|
39
|
+
[#357838](https://github.com/helsenorge/designsystem/issues/357838)
|
|
40
|
+
|
|
1
41
|
## [12.10.0](https://github.com/helsenorge/designsystem/branchCompare?baseVersion=GTv12.9.0&targetVersion=GTv12.10.0) (2025-10-30)
|
|
2
42
|
|
|
3
43
|
### Features
|
package/RadioButton.js
CHANGED
|
@@ -64,6 +64,7 @@ const RadioButton = React__default.forwardRef((props, ref) => {
|
|
|
64
64
|
[radioButtonStyles["radio-button-label--on-dark"]]: onDark,
|
|
65
65
|
[radioButtonStyles["radio-button-label--invalid"]]: invalid,
|
|
66
66
|
[radioButtonStyles["radio-button-label__large"]]: isLarge,
|
|
67
|
+
[radioButtonStyles["radio-button-label__large--focused"]]: isFocused,
|
|
67
68
|
[radioButtonStyles["radio-button-label__large--disabled"]]: isLarge && disabled
|
|
68
69
|
},
|
|
69
70
|
labelClassNames
|
package/RadioButton.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioButton.js","sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { isMutableRefObject, mergeRefs } from '../../utils/refs';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport { getLabelText, renderLabelAsParent } from '../Label';\n\nimport radioButtonStyles from './styles.module.scss';\n\nexport interface RadioButtonProps\n extends ErrorWrapperClassNameProps,\n Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'aria-describedby' | 'name' | 'value' | 'disabled' | 'checked' | 'defaultChecked' | 'required' | 'onChange'\n > {\n /** Adds custom classes to the element. */\n className?: string;\n /** The <Label/> next to the radioButton - sublabels kan ikke kombineres med large variant */\n label: React.ReactNode;\n /** Adds custom classes to the label element. */\n labelClassNames?: string;\n /** input id of the radioButton */\n inputId?: string;\n /** Changes the visuals of the radioButton */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the radioButton. Large version only works when used inside a FormGroup wrapper. */\n size?: keyof typeof FormSize;\n /** Activates Error style for the radioButton - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getRadioLabelClasses = (\n radioId: string,\n onColor: FormOnColor,\n large: boolean,\n checkedRadioId?: string\n): string | undefined => {\n const onCherry = onColor === 'oninvalid';\n const checked = radioId === checkedRadioId;\n\n return classNames({\n [radioButtonStyles['radio-button-label__large--on-grey']]: large && onColor === 'ongrey' && !checked,\n [radioButtonStyles['radio-button-label__large--on-blueberry']]: onColor === 'onblueberry' && !checked && large,\n [radioButtonStyles['radio-button-label__large--selected']]: large && checked && !onCherry,\n [radioButtonStyles['radio-button-label__large--selected-invalid']]: large && checked && onCherry,\n });\n};\n\nexport const RadioButton = React.forwardRef((props: RadioButtonProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultChecked,\n onChange,\n disabled,\n label,\n inputId = uuid(),\n onColor = FormOnColor.onwhite,\n name = inputId,\n size,\n errorText,\n error = !!errorText,\n errorTextId,\n errorWrapperClassName,\n value = getLabelText(label),\n testId,\n required,\n labelClassNames,\n ...rest\n } = props;\n const invalid = error || onColor === FormOnColor.oninvalid;\n const onDark = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const onCherry = onColor === FormOnColor.oninvalid;\n const isLarge = size === FormSize.large;\n const [checked, changeChecked] = useState<boolean>();\n const { refObject, isFocused } = usePseudoClasses<HTMLInputElement>(isMutableRefObject(ref) ? ref : null);\n const mergedRefs = mergeRefs([ref, refObject]);\n const errorTextUuid = useUuid(errorTextId);\n\n const radioButtonWrapperClasses = classNames(radioButtonStyles['radio-button-wrapper'], {\n [radioButtonStyles['radio-button-wrapper__large']]: isLarge,\n [radioButtonStyles['radio-button-wrapper__large--focused']]: isLarge && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--selected']]: isLarge && checked && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--invalid']]: isLarge && onCherry && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--on-blueberry']]: isLarge && onBlueberry && isFocused,\n });\n const radioButtonLabelClasses = classNames(\n radioButtonStyles['radio-button-label'],\n {\n [radioButtonStyles['radio-button-label--disabled']]: disabled,\n [radioButtonStyles['radio-button-label--on-dark']]: onDark,\n [radioButtonStyles['radio-button-label--invalid']]: invalid,\n [radioButtonStyles['radio-button-label__large']]: isLarge,\n [radioButtonStyles['radio-button-label__large--disabled']]: isLarge && disabled,\n },\n labelClassNames\n );\n const radioButtonClasses = classNames(\n radioButtonStyles['radio-button'],\n {\n [radioButtonStyles['radio-button--on-dark']]: onDark,\n [radioButtonStyles['radio-button--disabled']]: disabled,\n [radioButtonStyles['radio-button--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button--invalid']]: invalid,\n [radioButtonStyles['radio-button__large']]: isLarge,\n [radioButtonStyles['radio-button__large--disabled']]: isLarge && disabled,\n [radioButtonStyles['radio-button__large--invalid']]: isLarge && invalid,\n },\n className\n );\n\n const change = (e: React.ChangeEvent<HTMLInputElement>): void => {\n changeChecked(e.target.checked);\n if (onChange) onChange(e);\n };\n\n const getLabelContent = (): React.ReactNode => (\n <input\n {...rest}\n id={inputId}\n name={name}\n className={radioButtonClasses}\n type=\"radio\"\n disabled={disabled}\n value={value}\n ref={mergedRefs}\n defaultChecked={defaultChecked}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\n required={required}\n onChange={(e): void => change(e)}\n />\n );\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.RadioButton} className={radioButtonWrapperClasses}>\n {renderLabelAsParent(\n label,\n getLabelContent(),\n inputId,\n onColor as FormOnColor,\n radioButtonLabelClasses,\n undefined,\n radioButtonStyles['radiobutton-sublabel-wrapper'],\n isLarge\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nRadioButton.displayName = 'RadioButton';\n\nexport default RadioButton;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RadioButton.js","sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport { AnalyticsId, FormOnColor, FormSize } from '../../constants';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\nimport { useUuid } from '../../hooks/useUuid';\nimport { getAriaDescribedBy } from '../../utils/accessibility';\nimport { isMutableRefObject, mergeRefs } from '../../utils/refs';\nimport { uuid } from '../../utils/uuid';\nimport ErrorWrapper, { ErrorWrapperClassNameProps } from '../ErrorWrapper';\nimport { getLabelText, renderLabelAsParent } from '../Label';\n\nimport radioButtonStyles from './styles.module.scss';\n\nexport interface RadioButtonProps\n extends ErrorWrapperClassNameProps,\n Pick<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'aria-describedby' | 'name' | 'value' | 'disabled' | 'checked' | 'defaultChecked' | 'required' | 'onChange'\n > {\n /** Adds custom classes to the element. */\n className?: string;\n /** The <Label/> next to the radioButton - sublabels kan ikke kombineres med large variant */\n label: React.ReactNode;\n /** Adds custom classes to the label element. */\n labelClassNames?: string;\n /** input id of the radioButton */\n inputId?: string;\n /** Changes the visuals of the radioButton */\n onColor?: keyof typeof FormOnColor;\n /** Changes the visuals of the radioButton. Large version only works when used inside a FormGroup wrapper. */\n size?: keyof typeof FormSize;\n /** Activates Error style for the radioButton - This is can be true while errorText is empty, when in a FormGroup */\n error?: boolean;\n /** Error text to show above the component */\n errorText?: string;\n /** Error text id */\n errorTextId?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const getRadioLabelClasses = (\n radioId: string,\n onColor: FormOnColor,\n large: boolean,\n checkedRadioId?: string\n): string | undefined => {\n const onCherry = onColor === 'oninvalid';\n const checked = radioId === checkedRadioId;\n\n return classNames({\n [radioButtonStyles['radio-button-label__large--on-grey']]: large && onColor === 'ongrey' && !checked,\n [radioButtonStyles['radio-button-label__large--on-blueberry']]: onColor === 'onblueberry' && !checked && large,\n [radioButtonStyles['radio-button-label__large--selected']]: large && checked && !onCherry,\n [radioButtonStyles['radio-button-label__large--selected-invalid']]: large && checked && onCherry,\n });\n};\n\nexport const RadioButton = React.forwardRef((props: RadioButtonProps, ref: React.Ref<HTMLInputElement>) => {\n const {\n className,\n defaultChecked,\n onChange,\n disabled,\n label,\n inputId = uuid(),\n onColor = FormOnColor.onwhite,\n name = inputId,\n size,\n errorText,\n error = !!errorText,\n errorTextId,\n errorWrapperClassName,\n value = getLabelText(label),\n testId,\n required,\n labelClassNames,\n ...rest\n } = props;\n const invalid = error || onColor === FormOnColor.oninvalid;\n const onDark = onColor === FormOnColor.ondark;\n const onBlueberry = onColor === FormOnColor.onblueberry;\n const onCherry = onColor === FormOnColor.oninvalid;\n const isLarge = size === FormSize.large;\n const [checked, changeChecked] = useState<boolean>();\n const { refObject, isFocused } = usePseudoClasses<HTMLInputElement>(isMutableRefObject(ref) ? ref : null);\n const mergedRefs = mergeRefs([ref, refObject]);\n const errorTextUuid = useUuid(errorTextId);\n\n const radioButtonWrapperClasses = classNames(radioButtonStyles['radio-button-wrapper'], {\n [radioButtonStyles['radio-button-wrapper__large']]: isLarge,\n [radioButtonStyles['radio-button-wrapper__large--focused']]: isLarge && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--selected']]: isLarge && checked && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--invalid']]: isLarge && onCherry && isFocused,\n [radioButtonStyles['radio-button-wrapper__large--on-blueberry']]: isLarge && onBlueberry && isFocused,\n });\n const radioButtonLabelClasses = classNames(\n radioButtonStyles['radio-button-label'],\n {\n [radioButtonStyles['radio-button-label--disabled']]: disabled,\n [radioButtonStyles['radio-button-label--on-dark']]: onDark,\n [radioButtonStyles['radio-button-label--invalid']]: invalid,\n [radioButtonStyles['radio-button-label__large']]: isLarge,\n [radioButtonStyles['radio-button-label__large--focused']]: isFocused,\n [radioButtonStyles['radio-button-label__large--disabled']]: isLarge && disabled,\n },\n labelClassNames\n );\n const radioButtonClasses = classNames(\n radioButtonStyles['radio-button'],\n {\n [radioButtonStyles['radio-button--on-dark']]: onDark,\n [radioButtonStyles['radio-button--disabled']]: disabled,\n [radioButtonStyles['radio-button--on-blueberry']]: onBlueberry,\n [radioButtonStyles['radio-button--invalid']]: invalid,\n [radioButtonStyles['radio-button__large']]: isLarge,\n [radioButtonStyles['radio-button__large--disabled']]: isLarge && disabled,\n [radioButtonStyles['radio-button__large--invalid']]: isLarge && invalid,\n },\n className\n );\n\n const change = (e: React.ChangeEvent<HTMLInputElement>): void => {\n changeChecked(e.target.checked);\n if (onChange) onChange(e);\n };\n\n const getLabelContent = (): React.ReactNode => (\n <input\n {...rest}\n id={inputId}\n name={name}\n className={radioButtonClasses}\n type=\"radio\"\n disabled={disabled}\n value={value}\n ref={mergedRefs}\n defaultChecked={defaultChecked}\n aria-describedby={getAriaDescribedBy(props, errorTextUuid)}\n required={required}\n onChange={(e): void => change(e)}\n />\n );\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextUuid}>\n <div data-testid={testId} data-analyticsid={AnalyticsId.RadioButton} className={radioButtonWrapperClasses}>\n {renderLabelAsParent(\n label,\n getLabelContent(),\n inputId,\n onColor as FormOnColor,\n radioButtonLabelClasses,\n undefined,\n radioButtonStyles['radiobutton-sublabel-wrapper'],\n isLarge\n )}\n </div>\n </ErrorWrapper>\n );\n});\n\nRadioButton.displayName = 'RadioButton';\n\nexport default RadioButton;\n"],"names":["React"],"mappings":"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"}
|
package/Toast.js
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import classNames from "classnames";
|
|
3
|
+
import { useIsMobileBreakpoint } from "./hooks/useIsMobileBreakpoint.js";
|
|
2
4
|
import { C as Close } from "./Close.js";
|
|
3
5
|
import { I as Icon } from "./Icon.js";
|
|
6
|
+
import { IconSize } from "./constants.js";
|
|
4
7
|
import CheckFill from "./components/Icons/CheckFill.js";
|
|
5
8
|
import styles from "./components/Toast/styles.module.scss";
|
|
6
9
|
const Toast = ({ testId, title, message, onClose }) => {
|
|
10
|
+
const isMobile = useIsMobileBreakpoint();
|
|
7
11
|
const handleClose = () => {
|
|
8
12
|
if (onClose) {
|
|
9
13
|
onClose();
|
|
10
14
|
}
|
|
11
15
|
};
|
|
12
16
|
return /* @__PURE__ */ jsxs("output", { className: styles["toast"], "data-testid": testId, children: [
|
|
13
|
-
/* @__PURE__ */ jsx(
|
|
17
|
+
/* @__PURE__ */ jsx(
|
|
18
|
+
Icon,
|
|
19
|
+
{
|
|
20
|
+
size: isMobile ? IconSize.XSmall : IconSize.Small,
|
|
21
|
+
svgIcon: CheckFill,
|
|
22
|
+
className: classNames(styles["toast__icon"], styles["toast__icon--check"])
|
|
23
|
+
}
|
|
24
|
+
),
|
|
14
25
|
/* @__PURE__ */ jsxs("div", { className: styles["toast__text-container"], children: [
|
|
15
26
|
/* @__PURE__ */ jsx("span", { className: styles["toast__title"], children: title }),
|
|
16
27
|
message && /* @__PURE__ */ jsx("span", { className: styles["toast__description"], children: message })
|
|
17
28
|
] }),
|
|
18
|
-
/* @__PURE__ */ jsx(
|
|
29
|
+
/* @__PURE__ */ jsx(
|
|
30
|
+
Close,
|
|
31
|
+
{
|
|
32
|
+
onClick: handleClose,
|
|
33
|
+
color: "black",
|
|
34
|
+
className: classNames(styles["toast__icon"], styles["toast__icon--close"]),
|
|
35
|
+
testId: `${testId}-close`
|
|
36
|
+
}
|
|
37
|
+
)
|
|
19
38
|
] });
|
|
20
39
|
};
|
|
21
40
|
export {
|
package/Toast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.js","sources":["../src/components/Toast/Toast.tsx"],"sourcesContent":["import React from 'react';\n\nimport Close from '../Close';\nimport Icon from '../Icon';\nimport CheckFill from '../Icons/CheckFill';\n\nimport styles from './styles.module.scss';\n\nexport interface ToastProps {\n /** Sets the data-testid attribute. */\n testId?: string;\n /** The title to display in the toast */\n title: string;\n /** The message to display in the toast */\n message?: string;\n /** Callback when toast is closed */\n onClose?: () => void;\n}\n\nconst Toast: React.FC<ToastProps> = ({ testId, title, message, onClose }) => {\n const handleClose = (): void => {\n if (onClose) {\n onClose();\n }\n };\n\n return (\n <output className={styles['toast']} data-testid={testId}>\n <Icon svgIcon={CheckFill}
|
|
1
|
+
{"version":3,"file":"Toast.js","sources":["../src/components/Toast/Toast.tsx"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport Close from '../Close';\nimport Icon, { IconSize } from '../Icon';\nimport CheckFill from '../Icons/CheckFill';\n\nimport styles from './styles.module.scss';\n\nexport interface ToastProps {\n /** Sets the data-testid attribute. */\n testId?: string;\n /** The title to display in the toast */\n title: string;\n /** The message to display in the toast */\n message?: string;\n /** Callback when toast is closed */\n onClose?: () => void;\n}\n\nconst Toast: React.FC<ToastProps> = ({ testId, title, message, onClose }) => {\n const isMobile = useIsMobileBreakpoint();\n\n const handleClose = (): void => {\n if (onClose) {\n onClose();\n }\n };\n\n return (\n <output className={styles['toast']} data-testid={testId}>\n <Icon\n size={isMobile ? IconSize.XSmall : IconSize.Small}\n svgIcon={CheckFill}\n className={classNames(styles['toast__icon'], styles['toast__icon--check'])}\n />\n <div className={styles['toast__text-container']}>\n <span className={styles['toast__title']}>{title}</span>\n {message && <span className={styles['toast__description']}>{message}</span>}\n </div>\n <Close\n onClick={handleClose}\n color=\"black\"\n className={classNames(styles['toast__icon'], styles['toast__icon--close'])}\n testId={`${testId}-close`}\n />\n </output>\n );\n};\n\nexport default Toast;\n"],"names":[],"mappings":";;;;;;;;AAsBA,MAAM,QAA8B,CAAC,EAAE,QAAQ,OAAO,SAAS,cAAc;AAC3E,QAAM,WAAW,sBAAA;AAEjB,QAAM,cAAc,MAAY;AAC9B,QAAI,SAAS;AACX,cAAA;AAAA,IACF;AAAA,EACF;AAEA,8BACG,UAAA,EAAO,WAAW,OAAO,OAAO,GAAG,eAAa,QAC/C,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAM,WAAW,SAAS,SAAS,SAAS;AAAA,QAC5C,SAAS;AAAA,QACT,WAAW,WAAW,OAAO,aAAa,GAAG,OAAO,oBAAoB,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,IAE3E,qBAAC,OAAA,EAAI,WAAW,OAAO,uBAAuB,GAC5C,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,WAAW,OAAO,cAAc,GAAI,UAAA,OAAM;AAAA,MAC/C,WAAW,oBAAC,QAAA,EAAK,WAAW,OAAO,oBAAoB,GAAI,UAAA,QAAA,CAAQ;AAAA,IAAA,GACtE;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS;AAAA,QACT,OAAM;AAAA,QACN,WAAW,WAAW,OAAO,aAAa,GAAG,OAAO,oBAAoB,CAAC;AAAA,QACzE,QAAQ,GAAG,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EACnB,GACF;AAEJ;"}
|
|
@@ -39,12 +39,24 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
39
39
|
@include text-color(var(--color-action-text-onlight-hover), var(--color-action-text-onlight-hover));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
@mixin focus-shadow {
|
|
42
|
+
@mixin focus-shadow($with-uu-border: true) {
|
|
43
43
|
box-shadow: 0 0 0 spacers.getSpacer(3xs) palette.$black;
|
|
44
|
+
|
|
45
|
+
@if $with-uu-border {
|
|
46
|
+
border: 1px solid var(--color-action-border-ondark-focus);
|
|
47
|
+
} @else {
|
|
48
|
+
border: none;
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
@mixin focus-shadow-on-dark {
|
|
52
|
+
@mixin focus-shadow-on-dark($with-uu-border: true) {
|
|
47
53
|
box-shadow: 0 0 0 spacers.getSpacer(3xs) palette.$white;
|
|
54
|
+
|
|
55
|
+
@if $with-uu-border {
|
|
56
|
+
border: 1px solid var(--color-action-border-onlight-focus);
|
|
57
|
+
} @else {
|
|
58
|
+
border: none;
|
|
59
|
+
}
|
|
48
60
|
}
|
|
49
61
|
|
|
50
62
|
@mixin outline-borderless-background($background-color, $hover-background-color) {
|
|
@@ -102,16 +114,6 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
102
114
|
background-color: $background-color;
|
|
103
115
|
}
|
|
104
116
|
|
|
105
|
-
:focus > & {
|
|
106
|
-
@include focus-shadow-on-dark;
|
|
107
|
-
|
|
108
|
-
&:hover {
|
|
109
|
-
@include focus-shadow-on-dark;
|
|
110
|
-
|
|
111
|
-
background-color: palette.$white;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
117
|
/* stylelint-disable-next-line */
|
|
116
118
|
:disabled > & {
|
|
117
119
|
background-color: $dark-mode-disabled-transparrent;
|
|
@@ -129,6 +131,16 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
129
131
|
@mixin on-dark {
|
|
130
132
|
&--on-dark {
|
|
131
133
|
@include fill-on-dark(var(--color-action-background-ondark-hover));
|
|
134
|
+
|
|
135
|
+
:focus > & {
|
|
136
|
+
@include focus-shadow-on-dark(true);
|
|
137
|
+
|
|
138
|
+
&:hover {
|
|
139
|
+
@include focus-shadow-on-dark(true);
|
|
140
|
+
|
|
141
|
+
background-color: palette.$white;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
132
144
|
}
|
|
133
145
|
&--on-dark#{&}--destructive {
|
|
134
146
|
@include fill-on-dark(palette.$cherry50);
|
|
@@ -139,8 +151,14 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
139
151
|
&--on-dark#{&}--borderless#{&}--destructive {
|
|
140
152
|
background-color: transparent;
|
|
141
153
|
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
:focus > & {
|
|
155
|
+
@include focus-shadow-on-dark(false);
|
|
156
|
+
|
|
157
|
+
&:hover {
|
|
158
|
+
@include focus-shadow-on-dark(false);
|
|
159
|
+
|
|
160
|
+
background-color: palette.$inverted-hover;
|
|
161
|
+
}
|
|
144
162
|
}
|
|
145
163
|
}
|
|
146
164
|
&--on-dark#{&}--outline {
|
|
@@ -285,9 +303,25 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
285
303
|
}
|
|
286
304
|
}
|
|
287
305
|
|
|
306
|
+
:focus > & {
|
|
307
|
+
@include focus-shadow;
|
|
308
|
+
|
|
309
|
+
&:hover {
|
|
310
|
+
@include focus-shadow;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
288
314
|
&--outline,
|
|
289
315
|
&--borderless {
|
|
290
316
|
@include outline-borderless-background(transparent, var(--color-action-background-transparent-onlight-hover));
|
|
317
|
+
|
|
318
|
+
:focus > & {
|
|
319
|
+
@include focus-shadow(false);
|
|
320
|
+
|
|
321
|
+
&:hover {
|
|
322
|
+
@include focus-shadow(false);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
291
325
|
}
|
|
292
326
|
&--outline#{&}--destructive,
|
|
293
327
|
&--borderless#{&}--destructive {
|
|
@@ -301,12 +335,6 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
301
335
|
@include outline(palette.$cherry700, palette.$cherry50);
|
|
302
336
|
}
|
|
303
337
|
|
|
304
|
-
/* stylelint-disable-next-line */
|
|
305
|
-
&--borderless:not(.button--only-icon) {
|
|
306
|
-
padding: 0 spacers.getSpacer(3xs);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/* stylelint-disable-next-line */
|
|
310
338
|
&--borderless {
|
|
311
339
|
border-radius: 0;
|
|
312
340
|
|
|
@@ -319,11 +347,15 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
319
347
|
}
|
|
320
348
|
}
|
|
321
349
|
|
|
322
|
-
:
|
|
323
|
-
|
|
350
|
+
&--borderless:not(.button--only-icon) {
|
|
351
|
+
padding: 0 spacers.getSpacer(2xs);
|
|
324
352
|
|
|
325
|
-
&:
|
|
326
|
-
|
|
353
|
+
&:has(.button__left-icon) {
|
|
354
|
+
padding-left: 0;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
&:has(.button__right-icon) {
|
|
358
|
+
padding-right: 0;
|
|
327
359
|
}
|
|
328
360
|
}
|
|
329
361
|
|
|
@@ -335,9 +367,12 @@ $with-icons: // icon-class, size-class, padding-left, padding-right, padding-lef
|
|
|
335
367
|
display: flex;
|
|
336
368
|
align-items: center;
|
|
337
369
|
justify-content: center;
|
|
370
|
+
text-align: left;
|
|
371
|
+
padding: 0.4375rem 0;
|
|
338
372
|
|
|
339
373
|
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
340
374
|
margin: 0 auto 0 0;
|
|
375
|
+
padding: 0.625rem 0;
|
|
341
376
|
}
|
|
342
377
|
|
|
343
378
|
&--ellipsis {
|
|
@@ -410,8 +410,17 @@ $padding-clickable-area-left: 8px;
|
|
|
410
410
|
box-shadow: 0 0 0 spacers.getSpacer(3xs);
|
|
411
411
|
color: palette.$black;
|
|
412
412
|
|
|
413
|
+
&__regular--checked {
|
|
414
|
+
border: 1px solid var(--color-action-border-ondark-focus);
|
|
415
|
+
|
|
416
|
+
& + .checkbox__icon-wrapper__regular--on-dark {
|
|
417
|
+
border: 1px solid var(--color-action-border-onlight-focus);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
413
421
|
&--on-dark {
|
|
414
422
|
color: palette.$white;
|
|
423
|
+
border: 1px solid var(--color-action-border-onlight-focus);
|
|
415
424
|
}
|
|
416
425
|
|
|
417
426
|
&--invalid {
|
|
@@ -423,11 +432,13 @@ $padding-clickable-area-left: 8px;
|
|
|
423
432
|
background-color: palette.$blueberry200;
|
|
424
433
|
box-shadow: 0 0 0 spacers.getSpacer(3xs);
|
|
425
434
|
color: palette.$white;
|
|
435
|
+
border: 1px solid var(--color-action-border-onlight-focus);
|
|
426
436
|
|
|
427
437
|
// komboklasser fungerer ikke i nested struktur
|
|
428
438
|
&--invalid {
|
|
429
439
|
background-color: palette.$cherry500;
|
|
430
440
|
color: palette.$black;
|
|
441
|
+
border: 1px solid var(--color-action-border-ondark-focus);
|
|
431
442
|
}
|
|
432
443
|
|
|
433
444
|
&--disabled {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React__default, { useRef, useId, useEffect } from "react";
|
|
3
|
-
import { u as useFloating, f as autoUpdate, o as offset, s as shift, j as size } from "../../floating-ui.react.js";
|
|
3
|
+
import { u as useFloating, f as autoUpdate, o as offset, g as flip, s as shift, j as size } from "../../floating-ui.react.js";
|
|
4
4
|
import classNames from "classnames";
|
|
5
5
|
import "../../theme/grid.js";
|
|
6
6
|
import "../../hooks/useBreakpoint.js";
|
|
@@ -60,6 +60,7 @@ const DropdownBase = (props) => {
|
|
|
60
60
|
const isMobile = useIsMobileBreakpoint();
|
|
61
61
|
const triggerActualMinWidth = variant !== "borderless" && typeof triggerMinWidth != "undefined" ? `${triggerMinWidth}px` : "auto";
|
|
62
62
|
const triggerMinWidthLimit = isMobile ? 96 : 112;
|
|
63
|
+
const dropdownFloatingPadding = 15;
|
|
63
64
|
const maxWidth = isMobile ? 384 : 400;
|
|
64
65
|
const toggleTextId = useId();
|
|
65
66
|
const optionIdPrefix = useId();
|
|
@@ -90,18 +91,23 @@ const DropdownBase = (props) => {
|
|
|
90
91
|
const contentClasses = classNames(styles.dropdown__content, isOpen && styles["dropdown__content--open"]);
|
|
91
92
|
const listItemClasses = classNames(styles["dropdown__list-item"], { [styles["dropdown__list-item--single-select"]]: isSingleSelect });
|
|
92
93
|
const { refs, floatingStyles } = useFloating({
|
|
93
|
-
|
|
94
|
+
strategy: "fixed",
|
|
95
|
+
placement: "bottom-start",
|
|
94
96
|
middleware: [
|
|
95
97
|
offset(8),
|
|
96
|
-
|
|
98
|
+
// Hvis det ikke er plass på høyre side flipper vi dropdownlisten fra bottom-start til bottom-end
|
|
99
|
+
flip({ mainAxis: false, fallbackPlacements: ["bottom-end"], padding: dropdownFloatingPadding }),
|
|
100
|
+
// Shift fungerer som en fallback for flip og unngår at availableWidth ikke oppdaterer seg ved skjermbreddeendring
|
|
101
|
+
shift({ padding: dropdownFloatingPadding }),
|
|
102
|
+
// Hvis det ikke er plass på noen av sidene krymper vi bredden på listen med size
|
|
97
103
|
size({
|
|
104
|
+
padding: dropdownFloatingPadding,
|
|
98
105
|
apply({ availableWidth, availableHeight, elements, rects }) {
|
|
99
106
|
const triggerW = rects.reference.width;
|
|
100
107
|
const minProp = typeof dropdownMinWidth !== "undefined" ? clamp(0, maxWidth, dropdownMinWidth) : 0;
|
|
101
108
|
const targetW = Math.max(triggerW, minProp);
|
|
102
|
-
const finalW = Math.min(availableWidth, targetW);
|
|
103
109
|
Object.assign(elements.floating.style, {
|
|
104
|
-
|
|
110
|
+
maxWidth: `${Math.min(targetW, availableWidth)}px`,
|
|
105
111
|
maxHeight: `${availableHeight}px`,
|
|
106
112
|
overflowY: "auto",
|
|
107
113
|
overflowX: "hidden"
|
|
@@ -109,7 +115,7 @@ const DropdownBase = (props) => {
|
|
|
109
115
|
}
|
|
110
116
|
})
|
|
111
117
|
],
|
|
112
|
-
whileElementsMounted: autoUpdate
|
|
118
|
+
whileElementsMounted: isOpen ? autoUpdate : void 0
|
|
113
119
|
});
|
|
114
120
|
const handleOpen = (isKeyboard) => {
|
|
115
121
|
openedByKeyboard.current = isKeyboard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses<HTMLButtonElement>(buttonRef);\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const maxWidth = isMobile ? 384 : 400;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n placement: 'bottom',\n middleware: [\n offset(8),\n shift({ padding: 8 }),\n size({\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n const finalW = Math.min(availableWidth, targetW);\n\n Object.assign(elements.floating.style, {\n width: `${finalW}px`,\n maxHeight: `${availableHeight}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdate,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n if (!isOpen) return;\n\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["import { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemDropdown => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import React, { useEffect, useRef, useId, ComponentType } from 'react';\n\nimport { autoUpdate, offset, shift, size, useFloating, flip } from '@floating-ui/react';\nimport classNames from 'classnames';\nimport { clamp } from 'motion/react';\n\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { SingleSelectItem, SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { HNDesignsystemDropdown } from '../../resources/Resources';\nimport { isComponent } from '../../utils/component';\nimport { useLanguage } from '../../utils/language';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox, { CheckboxProps } from '../Checkbox';\nimport Icon, { SvgIcon } from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport { IconName } from '../Icons/IconNames';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label, { LabelProps } from '../Label';\nimport LazyIcon from '../LazyIcon';\nimport { SingleSelect } from './SingleSelect/SingleSelect';\n\nimport styles from './styles.module.scss';\n\ntype DropdownVariants = 'fill' | 'transparent' | 'borderless';\n\nexport interface DropdownProps {\n /** Text on the trigger button that opens the dropdown */\n triggerText: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button. */\n dropdownMinWidth?: number;\n /** Minimum width for the trigger in pixels. Does not apply for borderless variant */\n triggerMinWidth?: number;\n /** Disables rendring of the close button in the list */\n noCloseButton?: boolean;\n /** Called when dropdown is open/closed */\n onToggle?: (isOpen: boolean) => void;\n /** Whether the dropdown is open or not */\n open?: boolean;\n /** Makes the dropdown disabled */\n disabled?: boolean;\n /** Sets the data-testid attribute on the dropdown button */\n testId?: string;\n /** Overrides the default z-index of the DropDownContent */\n zIndex?: number;\n /** Resources for component */\n resources?: Partial<HNDesignsystemDropdown>;\n /** Adds an icon to the trigger */\n svgIcon?: SvgIcon | IconName;\n /** Sets the visual variant of the Dropdown */\n variant?: DropdownVariants;\n}\n\nexport const DropdownBase: React.FC<DropdownProps> = props => {\n const {\n triggerText,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n triggerMinWidth,\n open = false,\n children,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n svgIcon,\n variant = 'fill',\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const childrenRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const { isHovered } = usePseudoClasses<HTMLButtonElement>(buttonRef);\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const isMobile = useIsMobileBreakpoint();\n const triggerActualMinWidth = variant !== 'borderless' && typeof triggerMinWidth != 'undefined' ? `${triggerMinWidth}px` : 'auto';\n const triggerMinWidthLimit = isMobile ? 96 : 112;\n const dropdownFloatingPadding = 15;\n const maxWidth = isMobile ? 384 : 400;\n const toggleTextId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const leftIconProps = {\n className: styles['dropdown__left-icon'],\n size: IconSize.XSmall,\n isHovered: !disabled && isHovered,\n };\n\n const isSingleSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<SingleSelectItemProps>(child, SingleSelectItem)\n );\n const isMultiSelect = React.Children.toArray(children).every(\n child => React.isValidElement(child) && isComponent<CheckboxProps>(child, Checkbox)\n );\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n };\n\n const toggleClasses = classNames(styles.dropdown__toggle, {\n [styles['dropdown__toggle--open']]: isOpen && !disabled,\n [styles['dropdown__toggle--with-icon']]: typeof svgIcon !== 'undefined',\n [styles['dropdown__toggle--transparent']]: variant === 'transparent',\n [styles['dropdown__toggle--borderless']]: variant === 'borderless',\n });\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n const listItemClasses = classNames(styles['dropdown__list-item'], { [styles['dropdown__list-item--single-select']]: isSingleSelect });\n\n const { refs, floatingStyles } = useFloating({\n strategy: 'fixed',\n placement: 'bottom-start',\n middleware: [\n offset(8),\n // Hvis det ikke er plass på høyre side flipper vi dropdownlisten fra bottom-start til bottom-end\n flip({ mainAxis: false, fallbackPlacements: ['bottom-end'], padding: dropdownFloatingPadding }),\n // Shift fungerer som en fallback for flip og unngår at availableWidth ikke oppdaterer seg ved skjermbreddeendring\n shift({ padding: dropdownFloatingPadding }),\n // Hvis det ikke er plass på noen av sidene krymper vi bredden på listen med size\n size({\n padding: dropdownFloatingPadding,\n apply({ availableWidth, availableHeight, elements, rects }) {\n const triggerW = rects.reference.width;\n const minProp = typeof dropdownMinWidth !== 'undefined' ? clamp(0, maxWidth, dropdownMinWidth) : 0;\n const targetW = Math.max(triggerW, minProp);\n\n Object.assign(elements.floating.style, {\n maxWidth: `${Math.min(targetW, availableWidth)}px`,\n maxHeight: `${availableHeight}px`,\n overflowY: 'auto',\n overflowX: 'hidden',\n });\n },\n }),\n ],\n whileElementsMounted: isOpen ? autoUpdate : undefined,\n });\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n if (!isOpen) return;\n\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = childrenRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const focusByIndex = (nextIndex: number): void => {\n childrenRefList.current?.[nextIndex]?.current?.focus();\n };\n\n const isListNavKey = (key: string): boolean =>\n key === KeyboardEventKey.ArrowDown || key === KeyboardEventKey.ArrowUp || key === KeyboardEventKey.Home || key === KeyboardEventKey.End;\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!childrenRefList.current) return;\n\n const key = event.key as KeyboardEventKey;\n\n if (key === KeyboardEventKey.Escape) {\n if (isOpen) {\n event.preventDefault();\n handleClose();\n }\n return;\n }\n\n if (!isOpen) {\n if (isListNavKey(key)) {\n event.preventDefault();\n handleOpen(true);\n }\n return;\n }\n\n if (!isListNavKey(key)) {\n return;\n }\n\n const index = childrenRefList.current.findIndex(x => x.current === (event.target as HTMLElement));\n let nextIndex = index;\n\n if (key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (key === KeyboardEventKey.End) {\n nextIndex = childrenRefList.current.length - 1;\n } else if (key === KeyboardEventKey.ArrowDown && index < childrenRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n }\n\n if (nextIndex !== -1) {\n event.preventDefault();\n focusByIndex(nextIndex);\n }\n };\n\n useKeyboardEvent(dropdownRef, handleKeyboardNavigation, [\n KeyboardEventKey.ArrowDown,\n KeyboardEventKey.ArrowUp,\n KeyboardEventKey.End,\n KeyboardEventKey.Enter,\n KeyboardEventKey.Escape,\n KeyboardEventKey.Home,\n KeyboardEventKey.Space,\n ]);\n\n useOutsideEvent(dropdownRef, () => isOpen && handleClose());\n\n const renderChildren = React.Children.map(children, (child, index) => {\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(child) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n const baseProps: { ref: React.Ref<HTMLElement> } = {\n ref: mergeRefs([child.props.ref, childrenRefList.current[index]]),\n };\n\n if (isMultiSelect) {\n const label = (child.props as CheckboxProps).label as React.ReactNode;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(child as React.ReactElement<CheckboxProps>, {\n ...baseProps,\n label: React.cloneElement(label, {\n labelClassName: classNames((label.props as LabelProps)?.labelClassName, styles['dropdown__multiselect-item']),\n }),\n });\n }\n }\n\n return React.cloneElement(child as React.ReactElement<Record<string, unknown>>, baseProps);\n })()\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={mergeRefs([buttonRef, refs.setReference])}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleTextId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n style={{\n width: triggerActualMinWidth,\n maxWidth: '100%',\n minWidth: `${triggerMinWidthLimit}px`,\n }}\n >\n {svgIcon && (\n <>\n {typeof svgIcon === 'string' ? (\n <LazyIcon {...leftIconProps} iconName={svgIcon} />\n ) : (\n <Icon {...leftIconProps} svgIcon={svgIcon} />\n )}\n </>\n )}\n <span id={toggleTextId} className={styles.dropdown__toggle__text}>\n {triggerText}\n </span>\n <Icon\n svgIcon={!isSingleSelect ? PlusSmall : isOpen ? ChevronUp : ChevronDown}\n className={styles['dropdown__right-icon']}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n key={dropdownMinWidth ?? 'auto'}\n id={contentId}\n className={contentClasses}\n ref={refs.setFloating}\n style={{\n ...floatingStyles,\n zIndex: zIndex,\n }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={toggleTextId} tabIndex={-1} ref={optionsRef}>\n {isSingleSelect && <SingleSelect onValueChange={() => handleClose()}>{renderChildren}</SingleSelect>}\n {isMultiSelect && renderChildren}\n </ul>\n {!isSingleSelect && !noCloseButton && (\n <div className={styles.dropdown__close}>\n <Button onClick={handleClose}>{mergedResources.closeText}</Button>\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport interface DropdownCompound extends React.FC<DropdownProps> {\n SingleSelectItem: ComponentType<SingleSelectItemProps>;\n}\nconst Dropdown = DropdownBase as DropdownCompound;\nDropdown.SingleSelectItem = SingleSelectItem;\nDropdownBase.displayName = 'Dropdown';\n\nexport default Dropdown;\n"],"names":["React"],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ export type Styles = {
|
|
|
11
11
|
'radio-button-label': string;
|
|
12
12
|
'radio-button-label__large': string;
|
|
13
13
|
'radio-button-label__large--disabled': string;
|
|
14
|
+
'radio-button-label__large--focused': string;
|
|
14
15
|
'radio-button-label__large--on-blueberry': string;
|
|
15
16
|
'radio-button-label__large--on-grey': string;
|
|
16
17
|
'radio-button-label__large--selected': string;
|
|
@@ -11,24 +11,42 @@
|
|
|
11
11
|
border-radius: 0.25rem;
|
|
12
12
|
background-color: var(--core-color-kiwi-50);
|
|
13
13
|
border: 2px solid var(--core-color-kiwi-900);
|
|
14
|
-
display: flex;
|
|
15
|
-
flex-direction: row;
|
|
16
|
-
align-items: center;
|
|
17
|
-
gap: 0.25rem;
|
|
18
14
|
pointer-events: auto;
|
|
15
|
+
display: grid;
|
|
16
|
+
grid-template:
|
|
17
|
+
'check text close' 2.375rem
|
|
18
|
+
'. text .' auto /
|
|
19
|
+
calc(38px + 4px) auto calc(38px + 10px);
|
|
20
|
+
|
|
21
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
22
|
+
grid-template:
|
|
23
|
+
'check text close' 2.75rem
|
|
24
|
+
'. text .' auto /
|
|
25
|
+
calc(48px + 4px) auto calc(48px + 9px);
|
|
26
|
+
}
|
|
19
27
|
|
|
20
28
|
&__icon {
|
|
21
|
-
align-self: flex-start;
|
|
22
29
|
fill: var(--core-color-kiwi-900);
|
|
30
|
+
align-self: center;
|
|
31
|
+
|
|
32
|
+
&--check {
|
|
33
|
+
grid-area: check;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&--close {
|
|
37
|
+
grid-area: close;
|
|
38
|
+
justify-self: end;
|
|
39
|
+
}
|
|
23
40
|
}
|
|
24
41
|
|
|
25
42
|
&__text-container {
|
|
26
43
|
--margin-top: 0;
|
|
27
44
|
|
|
28
|
-
|
|
45
|
+
grid-area: text;
|
|
29
46
|
display: flex;
|
|
30
47
|
flex-direction: column;
|
|
31
48
|
gap: 0.25rem;
|
|
49
|
+
align-self: center;
|
|
32
50
|
margin-top: var(--margin-top);
|
|
33
51
|
|
|
34
52
|
&:has(.toast__description) {
|
|
@@ -42,6 +60,8 @@
|
|
|
42
60
|
|
|
43
61
|
&__title {
|
|
44
62
|
@include fonts.title6;
|
|
63
|
+
|
|
64
|
+
padding-top: 0.125rem;
|
|
45
65
|
}
|
|
46
66
|
|
|
47
67
|
&__description {
|
|
@@ -147,6 +147,15 @@
|
|
|
147
147
|
&:focus-visible + .toggle-container__toggle {
|
|
148
148
|
border-color: var(--color-action-border-onlight-focus);
|
|
149
149
|
outline: 2px solid var(--color-action-border-onlight-focus);
|
|
150
|
+
|
|
151
|
+
&::after {
|
|
152
|
+
content: '';
|
|
153
|
+
display: block;
|
|
154
|
+
width: 100%;
|
|
155
|
+
height: 100%;
|
|
156
|
+
border-radius: 60px;
|
|
157
|
+
border: 1px solid var(--color-action-border-ondark-focus);
|
|
158
|
+
}
|
|
150
159
|
}
|
|
151
160
|
}
|
|
152
161
|
}
|