@helsenorge/designsystem-react 14.9.1 → 14.10.0
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/lib/CHANGELOG.md +14 -0
- package/lib/Checkbox3.js +68 -0
- package/lib/Checkbox3.js.map +1 -0
- package/lib/RadioButton2.js +75 -0
- package/lib/RadioButton2.js.map +1 -0
- package/lib/components/Filter/FilterSort/styles.module.scss +2 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/Checkbox.d.ts +21 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/index.d.ts +3 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/index.js +5 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/index.js.map +1 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/styles.module.scss +133 -0
- package/lib/components/VisualCheckboxCloud/Checkbox/styles.module.scss.d.ts +15 -0
- package/lib/components/VisualCheckboxCloud/VisualCheckboxCloud.d.ts +29 -0
- package/lib/components/VisualCheckboxCloud/index.d.ts +3 -0
- package/lib/components/VisualCheckboxCloud/index.js +38 -0
- package/lib/components/VisualCheckboxCloud/index.js.map +1 -0
- package/lib/components/VisualCheckboxCloud/styles.module.scss +13 -0
- package/lib/components/VisualCheckboxCloud/styles.module.scss.d.ts +9 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/RadioButton.d.ts +23 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/index.d.ts +3 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/index.js +5 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/index.js.map +1 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/styles.module.scss +133 -0
- package/lib/components/VisualRadioButtonCloud/RadioButton/styles.module.scss.d.ts +15 -0
- package/lib/components/VisualRadioButtonCloud/VisualRadioButtonCloud.d.ts +39 -0
- package/lib/components/VisualRadioButtonCloud/index.d.ts +3 -0
- package/lib/components/VisualRadioButtonCloud/index.js +58 -0
- package/lib/components/VisualRadioButtonCloud/index.js.map +1 -0
- package/lib/components/VisualRadioButtonCloud/styles.module.scss +13 -0
- package/lib/components/VisualRadioButtonCloud/styles.module.scss.d.ts +9 -0
- package/package.json +1 -1
package/lib/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
|
|
2
|
+
## [14.10.0](https://github.com/helsenorge/designsystem/compare/v14.9.2...v14.10.0) (2026-05-18)
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* ny komponent visualcheckboxcloud ([4e6ea9c](https://github.com/helsenorge/designsystem/commit/4e6ea9c904f65cf4aedf2cc3f474cbff117c080a)), closes [#376757](https://github.com/helsenorge/designsystem/issues/376757)
|
|
7
|
+
* ny komponent visualradiobuttoncloud ([d14fce7](https://github.com/helsenorge/designsystem/commit/d14fce7e75b9f22397288defc51bfc6158595199)), closes [#376757](https://github.com/helsenorge/designsystem/issues/376757)
|
|
8
|
+
|
|
9
|
+
## [14.9.2](https://github.com/helsenorge/designsystem/compare/v14.9.1...v14.9.2) (2026-05-13)
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **dateandtime:** softerror skal spre seg uten å påvirke naboer ([27db71b](https://github.com/helsenorge/designsystem/commit/27db71b8e65f4d062da6b87f66147451d78be64f)), closes [#377339](https://github.com/helsenorge/designsystem/issues/377339)
|
|
14
|
+
* **filtersort:** første child skal være høyrestilt ([a9acf73](https://github.com/helsenorge/designsystem/commit/a9acf73ff4e65c267025535ec1d9f0ef78545b55)), closes [#376682](https://github.com/helsenorge/designsystem/issues/376682)
|
|
15
|
+
|
|
2
16
|
## [14.9.1](https://github.com/helsenorge/designsystem/compare/v14.9.0...v14.9.1) (2026-05-12)
|
|
3
17
|
|
|
4
18
|
### Bug Fixes
|
package/lib/Checkbox3.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { n as AnalyticsId } from "./constants2.js";
|
|
2
|
+
import { t as useIdWithFallback } from "./useIdWithFallback.js";
|
|
3
|
+
import { t as getAriaDescribedBy } from "./accessibility.js";
|
|
4
|
+
import { t as ErrorWrapper_default } from "./ErrorWrapper.js";
|
|
5
|
+
import classNames from "classnames";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import styles from "./components/VisualCheckboxCloud/Checkbox/styles.module.scss";
|
|
9
|
+
var Checkbox = (props) => {
|
|
10
|
+
const { className, checked, defaultChecked, children, inputId: inputIdProp, errorText, error = !!errorText, errorTextId: errorTextIdProp, errorWrapperClassName, testId, onChange, ref, ...rest } = props;
|
|
11
|
+
const inputId = useIdWithFallback(inputIdProp);
|
|
12
|
+
const errorTextId = useIdWithFallback(errorTextIdProp);
|
|
13
|
+
const [isChecked, setIsChecked] = useState(!!(checked ?? defaultChecked));
|
|
14
|
+
const [prevChecked, setPrevChecked] = useState(checked);
|
|
15
|
+
if (prevChecked !== checked) {
|
|
16
|
+
setPrevChecked(checked);
|
|
17
|
+
if (checked !== void 0 && checked !== isChecked) setIsChecked(checked);
|
|
18
|
+
}
|
|
19
|
+
const handleChange = (e) => {
|
|
20
|
+
setIsChecked(e.target.checked);
|
|
21
|
+
onChange?.(e);
|
|
22
|
+
};
|
|
23
|
+
return /* @__PURE__ */ jsx(ErrorWrapper_default, {
|
|
24
|
+
className: errorWrapperClassName,
|
|
25
|
+
errorText,
|
|
26
|
+
errorTextId,
|
|
27
|
+
children: /* @__PURE__ */ jsxs("label", {
|
|
28
|
+
className: classNames(styles["visual-checkbox"], {
|
|
29
|
+
[styles["visual-checkbox--checked"]]: isChecked,
|
|
30
|
+
[styles["visual-checkbox--invalid"]]: error
|
|
31
|
+
}, className),
|
|
32
|
+
htmlFor: inputId,
|
|
33
|
+
"data-testid": testId,
|
|
34
|
+
"data-analyticsid": AnalyticsId.Checkbox,
|
|
35
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
36
|
+
...rest,
|
|
37
|
+
id: inputId,
|
|
38
|
+
ref,
|
|
39
|
+
className: styles["visual-checkbox__input"],
|
|
40
|
+
type: "checkbox",
|
|
41
|
+
checked: isChecked,
|
|
42
|
+
"aria-invalid": error,
|
|
43
|
+
"aria-describedby": getAriaDescribedBy(props, errorTextId),
|
|
44
|
+
onChange: handleChange
|
|
45
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
46
|
+
className: styles["visual-checkbox__pill"],
|
|
47
|
+
children: [isChecked && /* @__PURE__ */ jsx("span", {
|
|
48
|
+
className: styles["visual-checkbox__icon"],
|
|
49
|
+
"aria-hidden": "true",
|
|
50
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
51
|
+
width: "16",
|
|
52
|
+
height: "12",
|
|
53
|
+
fill: "none",
|
|
54
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
55
|
+
children: /* @__PURE__ */ jsx("path", { d: "m14.754.165 1.08 1.074.166.164-.16.17L6.13 12 .159 5.59 0 5.42l.166-.164 1.08-1.075.165-.164.16.17 4.558 4.896 8.3-8.913.16-.17.165.165Z" })
|
|
56
|
+
})
|
|
57
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
58
|
+
className: styles["visual-checkbox__label"],
|
|
59
|
+
children
|
|
60
|
+
})]
|
|
61
|
+
})]
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
var Checkbox_default = Checkbox;
|
|
66
|
+
export { Checkbox_default as t };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=Checkbox3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox3.js","names":["Checkbox: React.FC<CheckboxProps>"],"sources":["../src/components/VisualCheckboxCloud/Checkbox/Checkbox.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport ErrorWrapper from '../../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport interface CheckboxProps\n extends ErrorWrapperClassNameProps, Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'id' | 'className' | 'children' | 'size'> {\n /** Adds custom classes to the root element. */\n className?: string;\n /** Label text shown inside the pill. */\n children: React.ReactNode;\n /** input id of the underlying checkbox */\n inputId?: string;\n /** Activates error styling. Can be true while errorText is empty (e.g. when used 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 /** Ref forwarded to the underlying input element. */\n ref?: React.Ref<HTMLInputElement | null>;\n}\n\nconst Checkbox: React.FC<CheckboxProps> = props => {\n const {\n className,\n checked,\n defaultChecked,\n children,\n inputId: inputIdProp,\n errorText,\n error = !!errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n testId,\n onChange,\n ref,\n ...rest\n } = props;\n\n const inputId = useIdWithFallback(inputIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const [isChecked, setIsChecked] = useState<boolean>(!!(checked ?? defaultChecked));\n const [prevChecked, setPrevChecked] = useState<boolean | undefined>(checked);\n if (prevChecked !== checked) {\n setPrevChecked(checked);\n if (checked !== undefined && checked !== isChecked) {\n setIsChecked(checked);\n }\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n setIsChecked(e.target.checked);\n onChange?.(e);\n };\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <label\n className={classNames(\n styles['visual-checkbox'],\n {\n [styles['visual-checkbox--checked']]: isChecked,\n [styles['visual-checkbox--invalid']]: error,\n },\n className\n )}\n htmlFor={inputId}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Checkbox}\n >\n <input\n {...rest}\n id={inputId}\n ref={ref}\n className={styles['visual-checkbox__input']}\n type=\"checkbox\"\n checked={isChecked}\n aria-invalid={error}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n onChange={handleChange}\n />\n <span className={styles['visual-checkbox__pill']}>\n {isChecked && (\n <span className={styles['visual-checkbox__icon']} aria-hidden=\"true\">\n <svg width=\"16\" height=\"12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"m14.754.165 1.08 1.074.166.164-.16.17L6.13 12 .159 5.59 0 5.42l.166-.164 1.08-1.075.165-.164.16.17 4.558 4.896 8.3-8.913.16-.17.165.165Z\" />\n </svg>\n </span>\n )}\n <span className={styles['visual-checkbox__label']}>{children}</span>\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default Checkbox;\n"],"mappings":";;;;;;;;AAiCA,IAAMA,YAAoC,UAAS;CACjD,MAAM,EACJ,WACA,SACA,gBACA,UACA,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,UACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,YAAY;CAC9C,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAkB,CAAC,EAAE,WAAW,gBAAgB;CAClF,MAAM,CAAC,aAAa,kBAAkB,SAA8B,QAAQ;AAC5E,KAAI,gBAAgB,SAAS;AAC3B,iBAAe,QAAQ;AACvB,MAAI,YAAY,KAAA,KAAa,YAAY,UACvC,cAAa,QAAQ;;CAIzB,MAAM,gBAAgB,MAAiD;AACrE,eAAa,EAAE,OAAO,QAAQ;AAC9B,aAAW,EAAE;;AAGf,QACE,oBAAC,sBAAA;EAAa,WAAW;EAAkC;EAAwB;YACjF,qBAAC,SAAA;GACC,WAAW,WACT,OAAO,oBACP;KACG,OAAO,8BAA8B;KACrC,OAAO,8BAA8B;IACvC,EACD,UACD;GACD,SAAS;GACT,eAAa;GACb,oBAAkB,YAAY;cAE9B,oBAAC,SAAA;IACC,GAAI;IACJ,IAAI;IACC;IACL,WAAW,OAAO;IAClB,MAAK;IACL,SAAS;IACT,gBAAc;IACd,oBAAkB,mBAAmB,OAAO,YAAY;IACxD,UAAU;KACV,EACF,qBAAC,QAAA;IAAK,WAAW,OAAO;eACrB,aACC,oBAAC,QAAA;KAAK,WAAW,OAAO;KAA0B,eAAY;eAC5D,oBAAC,OAAA;MAAI,OAAM;MAAK,QAAO;MAAK,MAAK;MAAO,OAAM;gBAC5C,oBAAC,QAAA,EAAK,GAAE,4IAAA,CAA6I;OACjJ;MACD,EAET,oBAAC,QAAA;KAAK,WAAW,OAAO;KAA4B;MAAgB,CAAA;KAC/D,CAAA;IACD;GACK;;AAInB,IAAA,mBAAe"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { n as AnalyticsId } from "./constants2.js";
|
|
2
|
+
import { t as useIsMobileBreakpoint } from "./useIsMobileBreakpoint.js";
|
|
3
|
+
import { t as useIdWithFallback } from "./useIdWithFallback.js";
|
|
4
|
+
import { t as getAriaDescribedBy } from "./accessibility.js";
|
|
5
|
+
import { t as ErrorWrapper_default } from "./ErrorWrapper.js";
|
|
6
|
+
import classNames from "classnames";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import styles from "./components/VisualRadioButtonCloud/RadioButton/styles.module.scss";
|
|
10
|
+
var RadioButton = (props) => {
|
|
11
|
+
const { className, checked, defaultChecked, children, inputId: inputIdProp, errorText, error = !!errorText, errorTextId: errorTextIdProp, errorWrapperClassName, testId, onChange, ref, ...rest } = props;
|
|
12
|
+
const inputId = useIdWithFallback(inputIdProp);
|
|
13
|
+
const errorTextId = useIdWithFallback(errorTextIdProp);
|
|
14
|
+
const isMobile = useIsMobileBreakpoint();
|
|
15
|
+
const [isChecked, setIsChecked] = useState(!!(checked ?? defaultChecked));
|
|
16
|
+
const [prevChecked, setPrevChecked] = useState(checked);
|
|
17
|
+
if (prevChecked !== checked) {
|
|
18
|
+
setPrevChecked(checked);
|
|
19
|
+
if (checked !== void 0 && checked !== isChecked) setIsChecked(checked);
|
|
20
|
+
}
|
|
21
|
+
const handleChange = (e) => {
|
|
22
|
+
setIsChecked(e.target.checked);
|
|
23
|
+
onChange?.(e);
|
|
24
|
+
};
|
|
25
|
+
return /* @__PURE__ */ jsx(ErrorWrapper_default, {
|
|
26
|
+
className: errorWrapperClassName,
|
|
27
|
+
errorText,
|
|
28
|
+
errorTextId,
|
|
29
|
+
children: /* @__PURE__ */ jsxs("label", {
|
|
30
|
+
className: classNames(styles["visual-radio-button"], {
|
|
31
|
+
[styles["visual-radio-button--checked"]]: isChecked,
|
|
32
|
+
[styles["visual-radio-button--invalid"]]: error
|
|
33
|
+
}, className),
|
|
34
|
+
htmlFor: inputId,
|
|
35
|
+
"data-testid": testId,
|
|
36
|
+
"data-analyticsid": AnalyticsId.RadioButton,
|
|
37
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
38
|
+
...rest,
|
|
39
|
+
id: inputId,
|
|
40
|
+
ref,
|
|
41
|
+
className: styles["visual-radio-button__input"],
|
|
42
|
+
type: "radio",
|
|
43
|
+
checked: isChecked,
|
|
44
|
+
"aria-describedby": getAriaDescribedBy(props, errorTextId),
|
|
45
|
+
onChange: handleChange
|
|
46
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
47
|
+
className: styles["visual-radio-button__pill"],
|
|
48
|
+
children: [isChecked && /* @__PURE__ */ jsx("span", {
|
|
49
|
+
className: styles["visual-radio-button__icon"],
|
|
50
|
+
"aria-hidden": "true",
|
|
51
|
+
children: isMobile ? /* @__PURE__ */ jsx("svg", {
|
|
52
|
+
width: "8",
|
|
53
|
+
height: "8",
|
|
54
|
+
fill: "none",
|
|
55
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
56
|
+
children: /* @__PURE__ */ jsx("path", { d: "M4 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z" })
|
|
57
|
+
}) : /* @__PURE__ */ jsx("svg", {
|
|
58
|
+
width: "12",
|
|
59
|
+
height: "12",
|
|
60
|
+
fill: "none",
|
|
61
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
62
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 12A6 6 0 1 0 6 0a6 6 0 0 0 0 12Z" })
|
|
63
|
+
})
|
|
64
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
65
|
+
className: styles["visual-radio-button__label"],
|
|
66
|
+
children
|
|
67
|
+
})]
|
|
68
|
+
})]
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
var RadioButton_default = RadioButton;
|
|
73
|
+
export { RadioButton_default as t };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=RadioButton2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioButton2.js","names":["RadioButton: React.FC<RadioButtonProps>"],"sources":["../src/components/VisualRadioButtonCloud/RadioButton/RadioButton.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { useIsMobileBreakpoint } from '../../../hooks/useIsMobileBreakpoint';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport ErrorWrapper from '../../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport interface RadioButtonProps\n extends\n ErrorWrapperClassNameProps,\n Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'id' | 'className' | 'children' | 'size' | 'value'> {\n /** Adds custom classes to the root element. */\n className?: string;\n /** Label text shown inside the pill. */\n children: React.ReactNode;\n /** Value identifying this radio inside its group. Required. */\n value: string;\n /** input id of the underlying radio */\n inputId?: string;\n /** Activates error styling. Can be true while errorText is empty (e.g. when used in a cloud). */\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 /** Ref forwarded to the underlying input element. */\n ref?: React.Ref<HTMLInputElement | null>;\n}\n\nconst RadioButton: React.FC<RadioButtonProps> = props => {\n const {\n className,\n checked,\n defaultChecked,\n children,\n inputId: inputIdProp,\n errorText,\n error = !!errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n testId,\n onChange,\n ref,\n ...rest\n } = props;\n\n const inputId = useIdWithFallback(inputIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const isMobile = useIsMobileBreakpoint();\n const [isChecked, setIsChecked] = useState<boolean>(!!(checked ?? defaultChecked));\n const [prevChecked, setPrevChecked] = useState<boolean | undefined>(checked);\n if (prevChecked !== checked) {\n setPrevChecked(checked);\n if (checked !== undefined && checked !== isChecked) {\n setIsChecked(checked);\n }\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {\n setIsChecked(e.target.checked);\n onChange?.(e);\n };\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <label\n className={classNames(\n styles['visual-radio-button'],\n {\n [styles['visual-radio-button--checked']]: isChecked,\n [styles['visual-radio-button--invalid']]: error,\n },\n className\n )}\n htmlFor={inputId}\n data-testid={testId}\n data-analyticsid={AnalyticsId.RadioButton}\n >\n <input\n {...rest}\n id={inputId}\n ref={ref}\n className={styles['visual-radio-button__input']}\n type=\"radio\"\n checked={isChecked}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n onChange={handleChange}\n />\n <span className={styles['visual-radio-button__pill']}>\n {isChecked && (\n <span className={styles['visual-radio-button__icon']} aria-hidden=\"true\">\n {isMobile ? (\n <svg width=\"8\" height=\"8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 8a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z\" />\n </svg>\n ) : (\n <svg width=\"12\" height=\"12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 12A6 6 0 1 0 6 0a6 6 0 0 0 0 12Z\" />\n </svg>\n )}\n </span>\n )}\n <span className={styles['visual-radio-button__label']}>{children}</span>\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default RadioButton;\n"],"mappings":";;;;;;;;;AAsCA,IAAMA,eAA0C,UAAS;CACvD,MAAM,EACJ,WACA,SACA,gBACA,UACA,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,UACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,YAAY;CAC9C,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,WAAW,uBAAuB;CACxC,MAAM,CAAC,WAAW,gBAAgB,SAAkB,CAAC,EAAE,WAAW,gBAAgB;CAClF,MAAM,CAAC,aAAa,kBAAkB,SAA8B,QAAQ;AAC5E,KAAI,gBAAgB,SAAS;AAC3B,iBAAe,QAAQ;AACvB,MAAI,YAAY,KAAA,KAAa,YAAY,UACvC,cAAa,QAAQ;;CAIzB,MAAM,gBAAgB,MAAiD;AACrE,eAAa,EAAE,OAAO,QAAQ;AAC9B,aAAW,EAAE;;AAGf,QACE,oBAAC,sBAAA;EAAa,WAAW;EAAkC;EAAwB;YACjF,qBAAC,SAAA;GACC,WAAW,WACT,OAAO,wBACP;KACG,OAAO,kCAAkC;KACzC,OAAO,kCAAkC;IAC3C,EACD,UACD;GACD,SAAS;GACT,eAAa;GACb,oBAAkB,YAAY;cAE9B,oBAAC,SAAA;IACC,GAAI;IACJ,IAAI;IACC;IACL,WAAW,OAAO;IAClB,MAAK;IACL,SAAS;IACT,oBAAkB,mBAAmB,OAAO,YAAY;IACxD,UAAU;KACV,EACF,qBAAC,QAAA;IAAK,WAAW,OAAO;eACrB,aACC,oBAAC,QAAA;KAAK,WAAW,OAAO;KAA8B,eAAY;eAC/D,WACC,oBAAC,OAAA;MAAI,OAAM;MAAI,QAAO;MAAI,MAAK;MAAO,OAAM;gBAC1C,oBAAC,QAAA,EAAK,GAAE,qCAAA,CAAsC;OAC1C,GAEN,oBAAC,OAAA;MAAI,OAAM;MAAK,QAAO;MAAK,MAAK;MAAO,OAAM;gBAC5C,oBAAC,QAAA,EAAK,GAAE,uCAAA,CAAwC;OAC5C;MAEH,EAET,oBAAC,QAAA;KAAK,WAAW,OAAO;KAAgC;MAAgB,CAAA;KACnE,CAAA;IACD;GACK;;AAInB,IAAA,sBAAe"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
select {
|
|
7
7
|
outline: none;
|
|
8
8
|
text-align: right;
|
|
9
|
+
text-align-last: right;
|
|
9
10
|
color: var(--color-action-text-onlight);
|
|
10
11
|
padding-right: 3rem;
|
|
11
12
|
height: 2.75rem;
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
|
|
18
19
|
select option {
|
|
19
20
|
text-align: left;
|
|
21
|
+
direction: ltr;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
&__wrapper {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ErrorWrapperClassNameProps } from '../../ErrorWrapper';
|
|
2
|
+
export interface CheckboxProps extends ErrorWrapperClassNameProps, Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'id' | 'className' | 'children' | 'size'> {
|
|
3
|
+
/** Adds custom classes to the root element. */
|
|
4
|
+
className?: string;
|
|
5
|
+
/** Label text shown inside the pill. */
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
/** input id of the underlying checkbox */
|
|
8
|
+
inputId?: string;
|
|
9
|
+
/** Activates error styling. Can be true while errorText is empty (e.g. when used in a FormGroup). */
|
|
10
|
+
error?: boolean;
|
|
11
|
+
/** Error text to show above the component. */
|
|
12
|
+
errorText?: string;
|
|
13
|
+
/** Error text id */
|
|
14
|
+
errorTextId?: string;
|
|
15
|
+
/** Sets the data-testid attribute. */
|
|
16
|
+
testId?: string;
|
|
17
|
+
/** Ref forwarded to the underlying input element. */
|
|
18
|
+
ref?: React.Ref<HTMLInputElement | null>;
|
|
19
|
+
}
|
|
20
|
+
declare const Checkbox: React.FC<CheckboxProps>;
|
|
21
|
+
export default Checkbox;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/VisualCheckboxCloud/Checkbox/index.ts"],"sourcesContent":["import Checkbox from './Checkbox';\nexport * from './Checkbox';\nexport default Checkbox;\n"],"mappings":";AAEA,IAAA,mBAAe"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../../scss/screen-reader' as *;
|
|
3
|
+
@use '../../../scss/breakpoints' as breakpoints;
|
|
4
|
+
@use '../../../scss/font-mixins' as fonts;
|
|
5
|
+
@import '../../../scss/supernova/styles/colors.css';
|
|
6
|
+
@import '../../../scss/supernova/styles/spacers.css';
|
|
7
|
+
|
|
8
|
+
.visual-checkbox {
|
|
9
|
+
position: relative;
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: stretch;
|
|
12
|
+
min-height: 2.75rem;
|
|
13
|
+
padding: 0.313rem 0;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
|
|
16
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
17
|
+
padding: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&__input {
|
|
21
|
+
// Hides input while making sure screen reader outline wraps the entire component
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
position: absolute;
|
|
24
|
+
z-index: 0;
|
|
25
|
+
inset: 0;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
outline: none;
|
|
29
|
+
appearance: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&__pill {
|
|
33
|
+
position: relative;
|
|
34
|
+
z-index: 1;
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: var(--core-space-2xs);
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
min-height: var(--core-space-l);
|
|
40
|
+
padding: var(--core-space-3xs) 1.75rem;
|
|
41
|
+
border-radius: 100px;
|
|
42
|
+
background-color: var(--color-action-background-ondark);
|
|
43
|
+
border: 1px solid var(--color-action-border-onlight);
|
|
44
|
+
color: var(--color-base-text-onlight);
|
|
45
|
+
|
|
46
|
+
@include fonts.title6;
|
|
47
|
+
|
|
48
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
49
|
+
min-height: var(--core-space-xl);
|
|
50
|
+
padding: var(--core-space-3xs) var(--core-space-l);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:hover &__pill {
|
|
55
|
+
background-color: var(--color-action-background-ondark-hover);
|
|
56
|
+
border-color: var(--color-action-border-onlight-hover);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&:active &__pill {
|
|
60
|
+
background-color: var(--color-action-background-ondark-selected);
|
|
61
|
+
border-color: var(--color-action-border-onlight-hover);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&--checked &__pill {
|
|
65
|
+
background-color: var(--color-action-background-onlight);
|
|
66
|
+
color: var(--color-action-text-ondark);
|
|
67
|
+
border-color: var(--color-action-background-onlight);
|
|
68
|
+
padding: var(--core-space-3xs) var(--core-space-s);
|
|
69
|
+
|
|
70
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
71
|
+
padding: var(--core-space-3xs) 1.25rem;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&--checked:hover &__pill {
|
|
76
|
+
background-color: var(--color-action-graphics-onlight-hover);
|
|
77
|
+
border-color: var(--color-action-graphics-onlight-hover);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&--checked:active &__pill {
|
|
81
|
+
background-color: var(--color-action-background-onlight-active);
|
|
82
|
+
border-color: var(--color-action-background-onlight-active);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&--invalid &__pill {
|
|
86
|
+
background-color: var(--color-action-background-ondark);
|
|
87
|
+
border-color: var(--color-destructive-border-normal);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&--invalid:hover &__pill {
|
|
91
|
+
background-color: var(--color-destructive-background-normal);
|
|
92
|
+
border-color: var(--color-destructive-border-normal);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&--invalid:active &__pill {
|
|
96
|
+
background-color: var(--color-destructive-background-emphasized);
|
|
97
|
+
border-color: var(--color-destructive-border-normal);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&--invalid#{&}--checked &__pill {
|
|
101
|
+
background-color: var(--color-destructive-graphics-normal);
|
|
102
|
+
border-color: var(--color-destructive-graphics-normal);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&--invalid#{&}--checked:hover &__pill {
|
|
106
|
+
background-color: var(--color-destructive-graphics-hover);
|
|
107
|
+
border-color: var(--color-destructive-graphics-hover);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&--invalid#{&}--checked:active &__pill {
|
|
111
|
+
background-color: var(--color-destructive-graphics-emphasized-onlight);
|
|
112
|
+
border-color: var(--color-destructive-graphics-emphasized-onlight);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&__input:focus-visible + &__pill {
|
|
116
|
+
outline: 3px solid var(--color-action-border-onlight-focus);
|
|
117
|
+
border-color: var(--color-action-border-ondark);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&__icon {
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
|
|
125
|
+
svg {
|
|
126
|
+
fill: var(--color-action-graphics-ondark);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&__label {
|
|
131
|
+
text-box: trim-both cap alphabetic;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Styles = {
|
|
2
|
+
'visual-checkbox': string;
|
|
3
|
+
'visual-checkbox__icon': string;
|
|
4
|
+
'visual-checkbox__input': string;
|
|
5
|
+
'visual-checkbox__label': string;
|
|
6
|
+
'visual-checkbox__pill': string;
|
|
7
|
+
'visual-checkbox--checked': string;
|
|
8
|
+
'visual-checkbox--invalid': string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ClassNames = keyof Styles;
|
|
12
|
+
|
|
13
|
+
declare const styles: Styles;
|
|
14
|
+
|
|
15
|
+
export default styles;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { default as Checkbox } from './Checkbox/Checkbox';
|
|
3
|
+
export interface VisualCheckboxCloudProps {
|
|
4
|
+
/** Items in the cloud. Should be VisualCheckboxCloud.Checkbox elements. */
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
/** Name shared by all child Checkbox elements (overridable per child) */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Error message shown above the cloud */
|
|
9
|
+
error?: string;
|
|
10
|
+
/** Error text id (auto-generated if omitted) */
|
|
11
|
+
errorTextId?: string;
|
|
12
|
+
/** Renders the error component (Default: true) */
|
|
13
|
+
renderError?: boolean;
|
|
14
|
+
/** Ref passed to the error message element */
|
|
15
|
+
errorMessageRef?: React.Ref<HTMLDivElement | null>;
|
|
16
|
+
/** Adds custom classes to the root element. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Adds custom classes to the errorWrapper */
|
|
19
|
+
errorWrapperClassName?: string;
|
|
20
|
+
/** Sets the data-testid attribute. */
|
|
21
|
+
testId?: string;
|
|
22
|
+
/** Sets the data-testid attribute for the error wrapper */
|
|
23
|
+
errorWrapperTestId?: string;
|
|
24
|
+
}
|
|
25
|
+
interface VisualCheckboxCloudComponent extends React.FC<VisualCheckboxCloudProps> {
|
|
26
|
+
Checkbox: typeof Checkbox;
|
|
27
|
+
}
|
|
28
|
+
export declare const VisualCheckboxCloud: VisualCheckboxCloudComponent;
|
|
29
|
+
export default VisualCheckboxCloud;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { t as isComponent } from "../../component.js";
|
|
2
|
+
import { t as useIdWithFallback } from "../../useIdWithFallback.js";
|
|
3
|
+
import { t as ErrorWrapper_default } from "../../ErrorWrapper.js";
|
|
4
|
+
import { t as Checkbox_default } from "../../Checkbox3.js";
|
|
5
|
+
import classNames from "classnames";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import styles from "./styles.module.scss";
|
|
9
|
+
const VisualCheckboxCloud = (props) => {
|
|
10
|
+
const { children, name, error, errorTextId: errorTextIdProp, renderError = true, errorMessageRef, className, errorWrapperClassName, testId, errorWrapperTestId } = props;
|
|
11
|
+
const errorTextId = useIdWithFallback(errorTextIdProp);
|
|
12
|
+
const mapChild = (child) => {
|
|
13
|
+
if (isComponent(child, Checkbox_default)) return React.cloneElement(child, {
|
|
14
|
+
name: child.props.name ?? name,
|
|
15
|
+
error: !!error || child.props.error,
|
|
16
|
+
errorTextId: child.props.errorTextId ?? errorTextId
|
|
17
|
+
});
|
|
18
|
+
return child;
|
|
19
|
+
};
|
|
20
|
+
return /* @__PURE__ */ jsx(ErrorWrapper_default, {
|
|
21
|
+
className: classNames(errorWrapperClassName, className),
|
|
22
|
+
errorText: error,
|
|
23
|
+
errorTextId,
|
|
24
|
+
renderError,
|
|
25
|
+
errorMessageRef,
|
|
26
|
+
testId: errorWrapperTestId,
|
|
27
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
28
|
+
className: styles["visual-checkbox-cloud"],
|
|
29
|
+
"data-testid": testId,
|
|
30
|
+
children: React.Children.map(children, mapChild)
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
VisualCheckboxCloud.Checkbox = Checkbox_default;
|
|
35
|
+
var VisualCheckboxCloud_default = VisualCheckboxCloud;
|
|
36
|
+
export { VisualCheckboxCloud, VisualCheckboxCloud_default as default };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["VisualCheckboxCloud: VisualCheckboxCloudComponent"],"sources":["../../../src/components/VisualCheckboxCloud/VisualCheckboxCloud.tsx","../../../src/components/VisualCheckboxCloud/index.ts"],"sourcesContent":["import React from 'react';\n\nimport classNames from 'classnames';\n\nimport type { CheckboxProps } from './Checkbox/Checkbox';\n\nimport Checkbox from './Checkbox/Checkbox';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { isComponent } from '../../utils/component';\nimport ErrorWrapper from '../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualCheckboxCloudProps {\n /** Items in the cloud. Should be VisualCheckboxCloud.Checkbox elements. */\n children?: React.ReactNode;\n /** Name shared by all child Checkbox elements (overridable per child) */\n name?: string;\n /** Error message shown above the cloud */\n error?: string;\n /** Error text id (auto-generated if omitted) */\n errorTextId?: string;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n /** Ref passed to the error message element */\n errorMessageRef?: React.Ref<HTMLDivElement | null>;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Adds custom classes to the errorWrapper */\n errorWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error wrapper */\n errorWrapperTestId?: string;\n}\n\ninterface VisualCheckboxCloudComponent extends React.FC<VisualCheckboxCloudProps> {\n Checkbox: typeof Checkbox;\n}\n\nexport const VisualCheckboxCloud: VisualCheckboxCloudComponent = props => {\n const {\n children,\n name,\n error,\n errorTextId: errorTextIdProp,\n renderError = true,\n errorMessageRef,\n className,\n errorWrapperClassName,\n testId,\n errorWrapperTestId,\n } = props;\n\n const errorTextId = useIdWithFallback(errorTextIdProp);\n\n const mapChild = (child: React.ReactNode): React.ReactNode => {\n if (isComponent<CheckboxProps>(child, Checkbox)) {\n return React.cloneElement(child, {\n name: child.props.name ?? name,\n error: !!error || child.props.error,\n errorTextId: child.props.errorTextId ?? errorTextId,\n });\n }\n return child;\n };\n\n return (\n <ErrorWrapper\n className={classNames(errorWrapperClassName, className)}\n errorText={error}\n errorTextId={errorTextId}\n renderError={renderError}\n errorMessageRef={errorMessageRef}\n testId={errorWrapperTestId}\n >\n <div className={styles['visual-checkbox-cloud']} data-testid={testId}>\n {React.Children.map(children, mapChild)}\n </div>\n </ErrorWrapper>\n );\n};\n\nVisualCheckboxCloud.Checkbox = Checkbox;\n\nexport default VisualCheckboxCloud;\n","import VisualCheckboxCloud from './VisualCheckboxCloud';\nexport * from './VisualCheckboxCloud';\nexport default VisualCheckboxCloud;\n"],"mappings":";;;;;;;;AAwCA,MAAaA,uBAAoD,UAAS;CACxE,MAAM,EACJ,UACA,MACA,OACA,aAAa,iBACb,cAAc,MACd,iBACA,WACA,uBACA,QACA,uBACE;CAEJ,MAAM,cAAc,kBAAkB,gBAAgB;CAEtD,MAAM,YAAY,UAA4C;AAC5D,MAAI,YAA2B,OAAO,iBAAS,CAC7C,QAAO,MAAM,aAAa,OAAO;GAC/B,MAAM,MAAM,MAAM,QAAQ;GAC1B,OAAO,CAAC,CAAC,SAAS,MAAM,MAAM;GAC9B,aAAa,MAAM,MAAM,eAAe;GACzC,CAAC;AAEJ,SAAO;;AAGT,QACE,oBAAC,sBAAA;EACC,WAAW,WAAW,uBAAuB,UAAU;EACvD,WAAW;EACE;EACA;EACI;EACjB,QAAQ;YAER,oBAAC,OAAA;GAAI,WAAW,OAAO;GAA0B,eAAa;aAC3D,MAAM,SAAS,IAAI,UAAU,SAAS;IACnC;GACO;;AAInB,oBAAoB,WAAW;ACjF/B,IAAA,8BDmFe"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../scss/breakpoints' as breakpoints;
|
|
3
|
+
@import '../../scss/supernova/styles/spacers.css';
|
|
4
|
+
|
|
5
|
+
.visual-checkbox-cloud {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-flow: row wrap;
|
|
8
|
+
gap: var(--core-space-4xs) var(--core-space-xs);
|
|
9
|
+
|
|
10
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
11
|
+
gap: var(--core-space-m) var(--core-space-s);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ErrorWrapperClassNameProps } from '../../ErrorWrapper';
|
|
2
|
+
export interface RadioButtonProps extends ErrorWrapperClassNameProps, Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'id' | 'className' | 'children' | 'size' | 'value'> {
|
|
3
|
+
/** Adds custom classes to the root element. */
|
|
4
|
+
className?: string;
|
|
5
|
+
/** Label text shown inside the pill. */
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
/** Value identifying this radio inside its group. Required. */
|
|
8
|
+
value: string;
|
|
9
|
+
/** input id of the underlying radio */
|
|
10
|
+
inputId?: string;
|
|
11
|
+
/** Activates error styling. Can be true while errorText is empty (e.g. when used in a cloud). */
|
|
12
|
+
error?: boolean;
|
|
13
|
+
/** Error text to show above the component. */
|
|
14
|
+
errorText?: string;
|
|
15
|
+
/** Error text id */
|
|
16
|
+
errorTextId?: string;
|
|
17
|
+
/** Sets the data-testid attribute. */
|
|
18
|
+
testId?: string;
|
|
19
|
+
/** Ref forwarded to the underlying input element. */
|
|
20
|
+
ref?: React.Ref<HTMLInputElement | null>;
|
|
21
|
+
}
|
|
22
|
+
declare const RadioButton: React.FC<RadioButtonProps>;
|
|
23
|
+
export default RadioButton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/VisualRadioButtonCloud/RadioButton/index.ts"],"sourcesContent":["import RadioButton from './RadioButton';\nexport * from './RadioButton';\nexport default RadioButton;\n"],"mappings":";AAEA,IAAA,sBAAe"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../../scss/screen-reader' as *;
|
|
3
|
+
@use '../../../scss/breakpoints' as breakpoints;
|
|
4
|
+
@use '../../../scss/font-mixins' as fonts;
|
|
5
|
+
@import '../../../scss/supernova/styles/colors.css';
|
|
6
|
+
@import '../../../scss/supernova/styles/spacers.css';
|
|
7
|
+
|
|
8
|
+
.visual-radio-button {
|
|
9
|
+
position: relative;
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: stretch;
|
|
12
|
+
min-height: 2.75rem;
|
|
13
|
+
padding: 0.313rem 0;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
|
|
16
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
17
|
+
padding: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&__input {
|
|
21
|
+
// Hides input while making sure screen reader outline wraps the entire component
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
position: absolute;
|
|
24
|
+
z-index: 0;
|
|
25
|
+
inset: 0;
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
outline: none;
|
|
29
|
+
appearance: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&__pill {
|
|
33
|
+
position: relative;
|
|
34
|
+
z-index: 1;
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
gap: var(--core-space-2xs);
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
min-height: var(--core-space-l);
|
|
40
|
+
padding: var(--core-space-3xs) var(--core-space-m);
|
|
41
|
+
border-radius: 100px;
|
|
42
|
+
background-color: var(--color-action-background-ondark);
|
|
43
|
+
border: 1px solid var(--color-action-border-onlight);
|
|
44
|
+
color: var(--color-base-text-onlight);
|
|
45
|
+
|
|
46
|
+
@include fonts.title6;
|
|
47
|
+
|
|
48
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
49
|
+
min-height: var(--core-space-xl);
|
|
50
|
+
padding: var(--core-space-3xs) var(--core-space-l);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:hover &__pill {
|
|
55
|
+
background-color: var(--color-action-background-ondark-hover);
|
|
56
|
+
border-color: var(--color-action-border-onlight-hover);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&:active &__pill {
|
|
60
|
+
background-color: var(--color-action-background-ondark-selected);
|
|
61
|
+
border-color: var(--color-action-border-onlight-hover);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&--checked &__pill {
|
|
65
|
+
background-color: var(--color-action-background-onlight);
|
|
66
|
+
color: var(--color-action-text-ondark);
|
|
67
|
+
border-color: var(--color-action-background-onlight);
|
|
68
|
+
padding: var(--core-space-3xs) var(--core-space-s);
|
|
69
|
+
|
|
70
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
71
|
+
padding: var(--core-space-3xs) var(--core-space-m) var(--core-space-3xs) 1.25rem;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&--checked:hover &__pill {
|
|
76
|
+
background-color: var(--color-action-graphics-onlight-hover);
|
|
77
|
+
border-color: var(--color-action-graphics-onlight-hover);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&--checked:active &__pill {
|
|
81
|
+
background-color: var(--color-action-background-onlight-active);
|
|
82
|
+
border-color: var(--color-action-background-onlight-active);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
&--invalid &__pill {
|
|
86
|
+
background-color: var(--color-action-background-ondark);
|
|
87
|
+
border-color: var(--color-destructive-border-normal);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&--invalid:hover &__pill {
|
|
91
|
+
background-color: var(--color-destructive-background-normal);
|
|
92
|
+
border-color: var(--color-destructive-border-normal);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
&--invalid:active &__pill {
|
|
96
|
+
background-color: var(--color-destructive-background-emphasized);
|
|
97
|
+
border-color: var(--color-destructive-border-normal);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
&--invalid#{&}--checked &__pill {
|
|
101
|
+
background-color: var(--color-destructive-graphics-normal);
|
|
102
|
+
border-color: var(--color-destructive-graphics-normal);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&--invalid#{&}--checked:hover &__pill {
|
|
106
|
+
background-color: var(--color-destructive-graphics-hover);
|
|
107
|
+
border-color: var(--color-destructive-graphics-hover);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&--invalid#{&}--checked:active &__pill {
|
|
111
|
+
background-color: var(--color-destructive-graphics-emphasized-onlight);
|
|
112
|
+
border-color: var(--color-destructive-graphics-emphasized-onlight);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&__input:focus-visible + &__pill {
|
|
116
|
+
outline: 3px solid var(--color-action-border-onlight-focus);
|
|
117
|
+
border-color: var(--color-action-border-ondark);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&__icon {
|
|
121
|
+
display: inline-flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
|
|
125
|
+
svg {
|
|
126
|
+
fill: var(--color-action-graphics-ondark);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&__label {
|
|
131
|
+
text-box: trim-both cap alphabetic;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Styles = {
|
|
2
|
+
'visual-radio-button': string;
|
|
3
|
+
'visual-radio-button__icon': string;
|
|
4
|
+
'visual-radio-button__input': string;
|
|
5
|
+
'visual-radio-button__label': string;
|
|
6
|
+
'visual-radio-button__pill': string;
|
|
7
|
+
'visual-radio-button--checked': string;
|
|
8
|
+
'visual-radio-button--invalid': string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ClassNames = keyof Styles;
|
|
12
|
+
|
|
13
|
+
declare const styles: Styles;
|
|
14
|
+
|
|
15
|
+
export default styles;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { default as RadioButton } from './RadioButton/RadioButton';
|
|
3
|
+
export interface VisualRadioButtonCloudProps {
|
|
4
|
+
/** Items in the cloud. Should be VisualRadioButtonCloud.RadioButton elements. */
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
/** Name shared by all child RadioButton elements (overridable per child). Required for native form grouping. */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Selected value (controlled). */
|
|
9
|
+
value?: string;
|
|
10
|
+
/** Initial selected value (uncontrolled). */
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
/** Called when the selected value changes. */
|
|
13
|
+
onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void;
|
|
14
|
+
/** Error message shown above the cloud */
|
|
15
|
+
error?: string;
|
|
16
|
+
/** Error text id (auto-generated if omitted) */
|
|
17
|
+
errorTextId?: string;
|
|
18
|
+
/** Renders the error component (Default: true) */
|
|
19
|
+
renderError?: boolean;
|
|
20
|
+
/** Ref passed to the error message element */
|
|
21
|
+
errorMessageRef?: React.Ref<HTMLDivElement | null>;
|
|
22
|
+
/** Adds custom classes to the root element. */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Adds custom classes to the errorWrapper */
|
|
25
|
+
errorWrapperClassName?: string;
|
|
26
|
+
/** Sets the data-testid attribute. */
|
|
27
|
+
testId?: string;
|
|
28
|
+
/** Sets the data-testid attribute for the error wrapper */
|
|
29
|
+
errorWrapperTestId?: string;
|
|
30
|
+
/** Accessible label for the radiogroup. Use this or `aria-labelledby` when no external `<legend>` labels the group. */
|
|
31
|
+
'aria-label'?: string;
|
|
32
|
+
/** Id of element labelling the radiogroup (e.g. an external Title/legend). */
|
|
33
|
+
'aria-labelledby'?: string;
|
|
34
|
+
}
|
|
35
|
+
interface VisualRadioButtonCloudComponent extends React.FC<VisualRadioButtonCloudProps> {
|
|
36
|
+
RadioButton: typeof RadioButton;
|
|
37
|
+
}
|
|
38
|
+
export declare const VisualRadioButtonCloud: VisualRadioButtonCloudComponent;
|
|
39
|
+
export default VisualRadioButtonCloud;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { t as isComponent } from "../../component.js";
|
|
2
|
+
import { t as useIdWithFallback } from "../../useIdWithFallback.js";
|
|
3
|
+
import { t as ErrorWrapper_default } from "../../ErrorWrapper.js";
|
|
4
|
+
import { t as RadioButton_default } from "../../RadioButton2.js";
|
|
5
|
+
import classNames from "classnames";
|
|
6
|
+
import React, { useState } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import styles from "./styles.module.scss";
|
|
9
|
+
const VisualRadioButtonCloud = (props) => {
|
|
10
|
+
const { children, name, value, defaultValue, onChange, error, errorTextId: errorTextIdProp, renderError = true, errorMessageRef, className, errorWrapperClassName, testId, errorWrapperTestId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy } = props;
|
|
11
|
+
const errorTextId = useIdWithFallback(errorTextIdProp);
|
|
12
|
+
const [selectedValue, setSelectedValue] = useState(value ?? defaultValue);
|
|
13
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
14
|
+
if (prevValue !== value) {
|
|
15
|
+
setPrevValue(value);
|
|
16
|
+
if (value !== void 0 && value !== selectedValue) setSelectedValue(value);
|
|
17
|
+
}
|
|
18
|
+
const mapChild = (child) => {
|
|
19
|
+
if (isComponent(child, RadioButton_default)) {
|
|
20
|
+
const isSelected = selectedValue !== void 0 && child.props.value === selectedValue;
|
|
21
|
+
return React.cloneElement(child, {
|
|
22
|
+
name: child.props.name ?? name,
|
|
23
|
+
checked: isSelected,
|
|
24
|
+
error: !!error || child.props.error,
|
|
25
|
+
errorTextId: child.props.errorTextId ?? errorTextId,
|
|
26
|
+
onChange: (e) => {
|
|
27
|
+
setSelectedValue(child.props.value);
|
|
28
|
+
child.props.onChange?.(e);
|
|
29
|
+
onChange?.(e, child.props.value);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return child;
|
|
34
|
+
};
|
|
35
|
+
return /* @__PURE__ */ jsx(ErrorWrapper_default, {
|
|
36
|
+
className: classNames(errorWrapperClassName, className),
|
|
37
|
+
errorText: error,
|
|
38
|
+
errorTextId,
|
|
39
|
+
renderError,
|
|
40
|
+
errorMessageRef,
|
|
41
|
+
testId: errorWrapperTestId,
|
|
42
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
43
|
+
role: "radiogroup",
|
|
44
|
+
"aria-label": ariaLabel,
|
|
45
|
+
"aria-labelledby": ariaLabelledBy,
|
|
46
|
+
"aria-invalid": error ? true : void 0,
|
|
47
|
+
"aria-describedby": error ? errorTextId : void 0,
|
|
48
|
+
className: styles["visual-radio-button-cloud"],
|
|
49
|
+
"data-testid": testId,
|
|
50
|
+
children: React.Children.map(children, mapChild)
|
|
51
|
+
})
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
VisualRadioButtonCloud.RadioButton = RadioButton_default;
|
|
55
|
+
var VisualRadioButtonCloud_default = VisualRadioButtonCloud;
|
|
56
|
+
export { VisualRadioButtonCloud, VisualRadioButtonCloud_default as default };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["VisualRadioButtonCloud: VisualRadioButtonCloudComponent"],"sources":["../../../src/components/VisualRadioButtonCloud/VisualRadioButtonCloud.tsx","../../../src/components/VisualRadioButtonCloud/index.ts"],"sourcesContent":["import React, { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { RadioButtonProps } from './RadioButton/RadioButton';\n\nimport RadioButton from './RadioButton/RadioButton';\nimport { useIdWithFallback } from '../../hooks/useIdWithFallback';\nimport { isComponent } from '../../utils/component';\nimport ErrorWrapper from '../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualRadioButtonCloudProps {\n /** Items in the cloud. Should be VisualRadioButtonCloud.RadioButton elements. */\n children?: React.ReactNode;\n /** Name shared by all child RadioButton elements (overridable per child). Required for native form grouping. */\n name?: string;\n /** Selected value (controlled). */\n value?: string;\n /** Initial selected value (uncontrolled). */\n defaultValue?: string;\n /** Called when the selected value changes. */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void;\n /** Error message shown above the cloud */\n error?: string;\n /** Error text id (auto-generated if omitted) */\n errorTextId?: string;\n /** Renders the error component (Default: true) */\n renderError?: boolean;\n /** Ref passed to the error message element */\n errorMessageRef?: React.Ref<HTMLDivElement | null>;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Adds custom classes to the errorWrapper */\n errorWrapperClassName?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n /** Sets the data-testid attribute for the error wrapper */\n errorWrapperTestId?: string;\n /** Accessible label for the radiogroup. Use this or `aria-labelledby` when no external `<legend>` labels the group. */\n 'aria-label'?: string;\n /** Id of element labelling the radiogroup (e.g. an external Title/legend). */\n 'aria-labelledby'?: string;\n}\n\ninterface VisualRadioButtonCloudComponent extends React.FC<VisualRadioButtonCloudProps> {\n RadioButton: typeof RadioButton;\n}\n\nexport const VisualRadioButtonCloud: VisualRadioButtonCloudComponent = props => {\n const {\n children,\n name,\n value,\n defaultValue,\n onChange,\n error,\n errorTextId: errorTextIdProp,\n renderError = true,\n errorMessageRef,\n className,\n errorWrapperClassName,\n testId,\n errorWrapperTestId,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n } = props;\n\n const errorTextId = useIdWithFallback(errorTextIdProp);\n const [selectedValue, setSelectedValue] = useState<string | undefined>(value ?? defaultValue);\n const [prevValue, setPrevValue] = useState<string | undefined>(value);\n if (prevValue !== value) {\n setPrevValue(value);\n if (value !== undefined && value !== selectedValue) {\n setSelectedValue(value);\n }\n }\n\n const mapChild = (child: React.ReactNode): React.ReactNode => {\n if (isComponent<RadioButtonProps>(child, RadioButton)) {\n const isSelected = selectedValue !== undefined && child.props.value === selectedValue;\n return React.cloneElement(child, {\n name: child.props.name ?? name,\n checked: isSelected,\n error: !!error || child.props.error,\n errorTextId: child.props.errorTextId ?? errorTextId,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n setSelectedValue(child.props.value);\n child.props.onChange?.(e);\n onChange?.(e, child.props.value);\n },\n });\n }\n return child;\n };\n\n return (\n <ErrorWrapper\n className={classNames(errorWrapperClassName, className)}\n errorText={error}\n errorTextId={errorTextId}\n renderError={renderError}\n errorMessageRef={errorMessageRef}\n testId={errorWrapperTestId}\n >\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? errorTextId : undefined}\n className={styles['visual-radio-button-cloud']}\n data-testid={testId}\n >\n {React.Children.map(children, mapChild)}\n </div>\n </ErrorWrapper>\n );\n};\n\nVisualRadioButtonCloud.RadioButton = RadioButton;\n\nexport default VisualRadioButtonCloud;\n","import VisualRadioButtonCloud from './VisualRadioButtonCloud';\nexport * from './VisualRadioButtonCloud';\nexport default VisualRadioButtonCloud;\n"],"mappings":";;;;;;;;AAkDA,MAAaA,0BAA0D,UAAS;CAC9E,MAAM,EACJ,UACA,MACA,OACA,cACA,UACA,OACA,aAAa,iBACb,cAAc,MACd,iBACA,WACA,uBACA,QACA,oBACA,cAAc,WACd,mBAAmB,mBACjB;CAEJ,MAAM,cAAc,kBAAkB,gBAAgB;CACtD,MAAM,CAAC,eAAe,oBAAoB,SAA6B,SAAS,aAAa;CAC7F,MAAM,CAAC,WAAW,gBAAgB,SAA6B,MAAM;AACrE,KAAI,cAAc,OAAO;AACvB,eAAa,MAAM;AACnB,MAAI,UAAU,KAAA,KAAa,UAAU,cACnC,kBAAiB,MAAM;;CAI3B,MAAM,YAAY,UAA4C;AAC5D,MAAI,YAA8B,OAAO,oBAAY,EAAE;GACrD,MAAM,aAAa,kBAAkB,KAAA,KAAa,MAAM,MAAM,UAAU;AACxE,UAAO,MAAM,aAAa,OAAO;IAC/B,MAAM,MAAM,MAAM,QAAQ;IAC1B,SAAS;IACT,OAAO,CAAC,CAAC,SAAS,MAAM,MAAM;IAC9B,aAAa,MAAM,MAAM,eAAe;IACxC,WAAW,MAA2C;AACpD,sBAAiB,MAAM,MAAM,MAAM;AACnC,WAAM,MAAM,WAAW,EAAE;AACzB,gBAAW,GAAG,MAAM,MAAM,MAAM;;IAEnC,CAAC;;AAEJ,SAAO;;AAGT,QACE,oBAAC,sBAAA;EACC,WAAW,WAAW,uBAAuB,UAAU;EACvD,WAAW;EACE;EACA;EACI;EACjB,QAAQ;YAER,oBAAC,OAAA;GACC,MAAK;GACL,cAAY;GACZ,mBAAiB;GACjB,gBAAc,QAAQ,OAAO,KAAA;GAC7B,oBAAkB,QAAQ,cAAc,KAAA;GACxC,WAAW,OAAO;GAClB,eAAa;aAEZ,MAAM,SAAS,IAAI,UAAU,SAAS;IACnC;GACO;;AAInB,uBAAuB,cAAc;ACvHrC,IAAA,iCDyHe"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../scss/breakpoints' as breakpoints;
|
|
3
|
+
@import '../../scss/supernova/styles/spacers.css';
|
|
4
|
+
|
|
5
|
+
.visual-radio-button-cloud {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-flow: row wrap;
|
|
8
|
+
gap: var(--core-space-4xs) var(--core-space-xs);
|
|
9
|
+
|
|
10
|
+
@media (min-width: map.get(breakpoints.$grid-breakpoints, md)) {
|
|
11
|
+
gap: var(--core-space-m) var(--core-space-s);
|
|
12
|
+
}
|
|
13
|
+
}
|
package/package.json
CHANGED