@helsenorge/designsystem-react 15.5.0 → 15.6.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/AnchorLink.js.map +1 -1
- package/lib/Avatar.js.map +1 -1
- package/lib/Button.js.map +1 -1
- package/lib/CHANGELOG.md +21 -0
- package/lib/Checkbox.js +5 -3
- package/lib/Checkbox.js.map +1 -1
- package/lib/Checkbox2.js.map +1 -1
- package/lib/CheckboxMarker.js.map +1 -1
- package/lib/Chip.js.map +1 -1
- package/lib/Close.js.map +1 -1
- package/lib/Drawer.js.map +1 -1
- package/lib/DrawerNavigation.js.map +1 -1
- package/lib/Duolist.js.map +1 -1
- package/lib/ElementHeader.js.map +1 -1
- package/lib/ElementHeaderText.js.map +1 -1
- package/lib/ErrorWrapper.js +2 -1
- package/lib/ErrorWrapper.js.map +1 -1
- package/lib/Expander.js +2 -1
- package/lib/Expander.js.map +1 -1
- package/lib/FilterButton.js.map +1 -1
- package/lib/FilterButtonAndChipsWrapper.js.map +1 -1
- package/lib/FilterDrawer.js.map +1 -1
- package/lib/FilterLinkList.js +2 -1
- package/lib/FilterLinkList.js.map +1 -1
- package/lib/FilterOverviewSearch.js.map +1 -1
- package/lib/FilterResultCountAndSortWrapper.js.map +1 -1
- package/lib/FilterSearch.js.map +1 -1
- package/lib/FormFieldTag.js.map +1 -1
- package/lib/FormGroup.js +9 -2
- package/lib/FormGroup.js.map +1 -1
- package/lib/FormLayout.js +9 -1
- package/lib/FormLayout.js.map +1 -1
- package/lib/HelpDetails.js.map +1 -1
- package/lib/HelpTriggerIcon.js.map +1 -1
- package/lib/HelpTriggerStandalone.js.map +1 -1
- package/lib/Highlighter.js.map +1 -1
- package/lib/HorizontalScroll.js.map +1 -1
- package/lib/Icon.js.map +1 -1
- package/lib/Illustration.js.map +1 -1
- package/lib/Input.js.map +1 -1
- package/lib/LazyIcon.js.map +1 -1
- package/lib/LazyIllustration.js.map +1 -1
- package/lib/LinkList.js +31 -28
- package/lib/LinkList.js.map +1 -1
- package/lib/List.js +4 -2
- package/lib/List.js.map +1 -1
- package/lib/ListEditMode.js +5 -4
- package/lib/ListEditMode.js.map +1 -1
- package/lib/LoaderSpinner.js.map +1 -1
- package/lib/MaxCharacters.js.map +1 -1
- package/lib/PanelTitle.js.map +1 -1
- package/lib/PopOver.js +5 -2
- package/lib/PopOver.js.map +1 -1
- package/lib/Radio.js.map +1 -1
- package/lib/RadioButton.js.map +1 -1
- package/lib/RadioMarker.js +11 -10
- package/lib/RadioMarker.js.map +1 -1
- package/lib/Select.js.map +1 -1
- package/lib/SingleSelectItem.js.map +1 -1
- package/lib/Slider.js +0 -2
- package/lib/Slider.js.map +1 -1
- package/lib/Spacer.js +16 -15
- package/lib/Spacer.js.map +1 -1
- package/lib/StatusDot.js.map +1 -1
- package/lib/StatusDotList.js.map +1 -1
- package/lib/StepButtons.js.map +1 -1
- package/lib/TabList.js.map +1 -1
- package/lib/TabPanel.js +2 -1
- package/lib/TabPanel.js.map +1 -1
- package/lib/TableBody.js +2 -1
- package/lib/TableBody.js.map +1 -1
- package/lib/TableCell.js +2 -1
- package/lib/TableCell.js.map +1 -1
- package/lib/TableExpandedRow.js +6 -3
- package/lib/TableExpandedRow.js.map +1 -1
- package/lib/TableExpanderCell.js +2 -1
- package/lib/TableExpanderCell.js.map +1 -1
- package/lib/TableHead.js +7 -6
- package/lib/TableHead.js.map +1 -1
- package/lib/TableHeadCell.js.map +1 -1
- package/lib/TableRow.js +7 -5
- package/lib/TableRow.js.map +1 -1
- package/lib/Textarea.js.map +1 -1
- package/lib/Title.js +20 -17
- package/lib/Title.js.map +1 -1
- package/lib/Toast.js.map +1 -1
- package/lib/Toggle.js +176 -0
- package/lib/Toggle.js.map +1 -0
- package/lib/VisualCheckbox.js.map +1 -1
- package/lib/VisualRadio.js.map +1 -1
- package/lib/components/ArticleTeaser/index.js.map +1 -1
- package/lib/components/Close/styles.module.scss +2 -2
- package/lib/components/Dropdown/index.js.map +1 -1
- package/lib/components/DropdownOld/index.js.map +1 -1
- package/lib/components/EmptyState/index.js +1 -3
- package/lib/components/EmptyState/index.js.map +1 -1
- package/lib/components/ExpanderHierarchy/index.js +2 -1
- package/lib/components/ExpanderHierarchy/index.js.map +1 -1
- package/lib/components/ExpanderList/index.js +7 -6
- package/lib/components/ExpanderList/index.js.map +1 -1
- package/lib/components/EyebrowHeader/index.js.map +1 -1
- package/lib/components/FavoriteButton/index.js +9 -7
- package/lib/components/FavoriteButton/index.js.map +1 -1
- package/lib/components/FormGroup/styles.module.scss +15 -3
- package/lib/components/FormGroup/styles.module.scss.d.ts +2 -0
- package/lib/components/FormLayout/styles.module.scss +9 -1
- package/lib/components/FormLayout/styles.module.scss.d.ts +2 -0
- package/lib/components/HelpBubble/index.js.map +1 -1
- package/lib/components/HelpExpanderInline/index.js.map +1 -1
- package/lib/components/HelpExpanderStandalone/index.js.map +1 -1
- package/lib/components/HelpPanel/HelpPanel.d.ts +2 -2
- package/lib/components/HelpPanel/index.js +49 -9
- package/lib/components/HelpPanel/index.js.map +1 -1
- package/lib/components/HelpPanel/styles.module.scss +66 -2
- package/lib/components/HelpPanel/styles.module.scss.d.ts +8 -0
- package/lib/components/HelpTeaser/HelpTeaser.d.ts +5 -2
- package/lib/components/HelpTeaser/index.js +59 -14
- package/lib/components/HelpTeaser/index.js.map +1 -1
- package/lib/components/HelpTeaser/styles.module.scss +105 -2
- package/lib/components/HelpTeaser/styles.module.scss.d.ts +6 -0
- package/lib/components/HelpTooltip/index.js +6 -3
- package/lib/components/HelpTooltip/index.js.map +1 -1
- package/lib/components/HelpTriggerInline/index.js.map +1 -1
- package/lib/components/HighlightPanel/index.js +79 -1
- package/lib/components/HighlightPanel/index.js.map +1 -0
- package/lib/components/Icons/AlarmClock.js.map +1 -1
- package/lib/components/Icons/Bus.js.map +1 -1
- package/lib/components/Illustrations/BabyMobile.js +5 -4
- package/lib/components/Illustrations/BabyMobile.js.map +1 -1
- package/lib/components/Illustrations/BabyMobileMedium.js.map +1 -1
- package/lib/components/Illustrations/Child.js +5 -4
- package/lib/components/Illustrations/Child.js.map +1 -1
- package/lib/components/Illustrations/ChildMedium.js.map +1 -1
- package/lib/components/Illustrations/Doctor.js +10 -8
- package/lib/components/Illustrations/Doctor.js.map +1 -1
- package/lib/components/Illustrations/DoctorMedium.js.map +1 -1
- package/lib/components/Illustrations/DoctorSmall.js.map +1 -1
- package/lib/components/Illustrations/EyeContact.js +5 -4
- package/lib/components/Illustrations/EyeContact.js.map +1 -1
- package/lib/components/Illustrations/EyeContactMedium.js.map +1 -1
- package/lib/components/Illustrations/FacialRecognitionFingerprint.js +5 -4
- package/lib/components/Illustrations/FacialRecognitionFingerprint.js.map +1 -1
- package/lib/components/Illustrations/FacialRecognitionFingerprintMedium.js.map +1 -1
- package/lib/components/Illustrations/GiveBabyFood.js +5 -4
- package/lib/components/Illustrations/GiveBabyFood.js.map +1 -1
- package/lib/components/Illustrations/GiveBabyFoodMedium.js.map +1 -1
- package/lib/components/Illustrations/HealthcarePersonnel.js +10 -8
- package/lib/components/Illustrations/HealthcarePersonnel.js.map +1 -1
- package/lib/components/Illustrations/HealthcarePersonnelMedium.js.map +1 -1
- package/lib/components/Illustrations/HealthcarePersonnelSmall.js.map +1 -1
- package/lib/components/Illustrations/ReadLetters.js +5 -4
- package/lib/components/Illustrations/ReadLetters.js.map +1 -1
- package/lib/components/Illustrations/ReadLettersMedium.js.map +1 -1
- package/lib/components/Illustrations/SkinToSkin.js +5 -4
- package/lib/components/Illustrations/SkinToSkin.js.map +1 -1
- package/lib/components/Illustrations/SkinToSkinMedium.js.map +1 -1
- package/lib/components/Illustrations/Stork.js +5 -4
- package/lib/components/Illustrations/Stork.js.map +1 -1
- package/lib/components/Illustrations/StorkMedium.js.map +1 -1
- package/lib/components/Illustrations/Stroller.js +5 -4
- package/lib/components/Illustrations/Stroller.js.map +1 -1
- package/lib/components/Illustrations/StrollerMedium.js.map +1 -1
- package/lib/components/Illustrations/Support2.js +5 -4
- package/lib/components/Illustrations/Support2.js.map +1 -1
- package/lib/components/Illustrations/Support2Medium.js.map +1 -1
- package/lib/components/Illustrations/Thinking.js +5 -4
- package/lib/components/Illustrations/Thinking.js.map +1 -1
- package/lib/components/Illustrations/ThinkingMedium.js.map +1 -1
- package/lib/components/InfoTeaser/index.js +71 -1
- package/lib/components/InfoTeaser/index.js.map +1 -0
- package/lib/components/Loader/index.js +14 -13
- package/lib/components/Loader/index.js.map +1 -1
- package/lib/components/Logo/index.js.map +1 -1
- package/lib/components/Modal/index.js.map +1 -1
- package/lib/components/NotificationPanel/index.js +7 -4
- package/lib/components/NotificationPanel/index.js.map +1 -1
- package/lib/components/Panel/index.js +17 -16
- package/lib/components/Panel/index.js.map +1 -1
- package/lib/components/PanelList/index.js.map +1 -1
- package/lib/components/PopMenu/index.js.map +1 -1
- package/lib/components/Progressbar/index.js +6 -5
- package/lib/components/Progressbar/index.js.map +1 -1
- package/lib/components/PromoPanel/index.js.map +1 -1
- package/lib/components/RadioButton/styles.module.scss +6 -6
- package/lib/components/ServiceMessage/index.js +2 -1
- package/lib/components/ServiceMessage/index.js.map +1 -1
- package/lib/components/SharingStatus/index.js.map +1 -1
- package/lib/components/Step/index.js.map +1 -1
- package/lib/components/Stepper/index.js +4 -2
- package/lib/components/Stepper/index.js.map +1 -1
- package/lib/components/StickyNote/index.js.map +1 -1
- package/lib/components/Table/index.js +2 -5
- package/lib/components/Table/index.js.map +1 -1
- package/lib/components/Tabs/index.js.map +1 -1
- package/lib/components/Tag/index.js +2 -1
- package/lib/components/Tag/index.js.map +1 -1
- package/lib/components/TagList/index.js.map +1 -1
- package/lib/components/Tile/index.js +5 -4
- package/lib/components/Tile/index.js.map +1 -1
- package/lib/components/ToastList/index.js +2 -1
- package/lib/components/ToastList/index.js.map +1 -1
- package/lib/components/Toggle/index.js +1 -172
- package/lib/components/Validation/index.js.map +1 -1
- package/lib/components/VisualCheckboxCloud/index.js.map +1 -1
- package/lib/components/VisualCheckboxGroup/index.js.map +1 -1
- package/lib/components/VisualContentgroupWithImage/index.js.map +1 -1
- package/lib/components/VisualRadioCloud/index.js.map +1 -1
- package/lib/components/VisualRadioGroup/index.js.map +1 -1
- package/lib/floating-ui.react.js +91 -111
- package/lib/floating-ui.react.js.map +1 -1
- package/lib/getFilterChips.js.map +1 -1
- package/lib/resourceHelper2.js +22 -0
- package/lib/resourceHelper2.js.map +1 -0
- package/lib/theme/spacers.js +2 -2
- package/lib/theme/spacers.js.map +1 -1
- package/lib/utils/formSpacing.d.ts +3 -0
- package/lib/utils/formSpacing.js +16 -0
- package/lib/utils/formSpacing.js.map +1 -0
- package/lib/utils2.js.map +1 -1
- package/package.json +1 -1
- package/lib/HighlightPanel.js +0 -80
- package/lib/HighlightPanel.js.map +0 -1
- package/lib/InfoTeaser.js +0 -89
- package/lib/InfoTeaser.js.map +0 -1
- package/lib/components/Toggle/index.js.map +0 -1
package/lib/Toggle.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { AnalyticsId } from "./constants.js";
|
|
2
|
+
import { usePseudoClasses } from "./hooks/usePseudoClasses.js";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import React, { useEffect, useId, useState } from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { useAnimate } from "motion/react";
|
|
7
|
+
import styles from "./components/Toggle/styles.module.scss";
|
|
8
|
+
//#region src/components/Toggle/constants.ts
|
|
9
|
+
var TogglePosition = /* @__PURE__ */ function(TogglePosition) {
|
|
10
|
+
TogglePosition["left"] = "left";
|
|
11
|
+
TogglePosition["right"] = "right";
|
|
12
|
+
return TogglePosition;
|
|
13
|
+
}({});
|
|
14
|
+
var ToggleOnColor = /* @__PURE__ */ function(ToggleOnColor) {
|
|
15
|
+
ToggleOnColor["onwhite"] = "onwhite";
|
|
16
|
+
ToggleOnColor["onneutral"] = "onneutral";
|
|
17
|
+
ToggleOnColor["onblueberry"] = "onblueberry";
|
|
18
|
+
return ToggleOnColor;
|
|
19
|
+
}({});
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/components/Toggle/Toggle.tsx
|
|
22
|
+
var Toggle = ({ checked = false, disabled, label, onChange, onColor = ToggleOnColor.onwhite, statusText, subLabel, togglePosition = TogglePosition.left, testId }) => {
|
|
23
|
+
const [checkedControlledState, setCheckedControlledState] = useState(checked);
|
|
24
|
+
const [checkedState, setCheckedState] = useState(checked);
|
|
25
|
+
const [showToggleAnimation, setShowToggleAnimation] = useState(false);
|
|
26
|
+
const [scope, animate] = useAnimate();
|
|
27
|
+
const baseId = useId();
|
|
28
|
+
const toggleId = "toggle-" + baseId;
|
|
29
|
+
const inputId = "input-" + baseId;
|
|
30
|
+
const labelId = "label-" + baseId;
|
|
31
|
+
const subLabelId = "sublabel-" + baseId;
|
|
32
|
+
const toggleRef = React.useRef(null);
|
|
33
|
+
const toggleDotRef = React.useRef(null);
|
|
34
|
+
const { refObject, isHovered, isActive } = usePseudoClasses(scope);
|
|
35
|
+
const showHoveredStyling = isHovered && !showToggleAnimation;
|
|
36
|
+
const isOnWhite = onColor === ToggleOnColor.onwhite;
|
|
37
|
+
const animationDuration = disabled ? 0 : .2;
|
|
38
|
+
const dotBackgroundColor = disabled ? "var(--color-disabled-graphics)" : checkedState ? "var(--color-action-graphics-ondark)" : "var(--core-color-neutral-700)";
|
|
39
|
+
if (checked !== checkedControlledState && typeof checked !== "undefined") {
|
|
40
|
+
setCheckedControlledState(checked);
|
|
41
|
+
setCheckedState(checked);
|
|
42
|
+
}
|
|
43
|
+
const getBackgroundColor = () => {
|
|
44
|
+
if (disabled) return "transparent";
|
|
45
|
+
else if (checkedState && isActive) return "var(--core-color-blueberry-800)";
|
|
46
|
+
else if (checkedState) return showHoveredStyling ? "var(--color-action-graphics-onlight-hover)" : "var(--color-action-graphics-onlight)";
|
|
47
|
+
else if (isOnWhite && isActive) return "var(--core-color-neutral-400)";
|
|
48
|
+
else if (isOnWhite) return showHoveredStyling ? "var(--core-color-neutral-200)" : "var(--core-color-neutral-50)";
|
|
49
|
+
else if (isActive) return "var(--core-color-neutral-200)";
|
|
50
|
+
else return showHoveredStyling ? "var(--core-color-neutral-50)" : "var(--core-color-white)";
|
|
51
|
+
};
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (showToggleAnimation) {
|
|
54
|
+
const timer = setTimeout(() => setShowToggleAnimation(false), 300);
|
|
55
|
+
return () => clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
}, [showToggleAnimation]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!toggleRef.current || !toggleDotRef.current) return;
|
|
60
|
+
animate(toggleRef.current, { background: getBackgroundColor() }, {
|
|
61
|
+
duration: animationDuration,
|
|
62
|
+
ease: "easeInOut"
|
|
63
|
+
});
|
|
64
|
+
animate(toggleDotRef.current, { background: dotBackgroundColor }, {
|
|
65
|
+
duration: animationDuration,
|
|
66
|
+
ease: "easeInOut"
|
|
67
|
+
});
|
|
68
|
+
animate(toggleDotRef.current, { x: checkedState ? 16 : 0 }, {
|
|
69
|
+
duration: animationDuration,
|
|
70
|
+
ease: "easeInOut"
|
|
71
|
+
});
|
|
72
|
+
animate("svg", { opacity: checkedState ? 1 : 0 }, {
|
|
73
|
+
duration: animationDuration,
|
|
74
|
+
ease: "easeInOut"
|
|
75
|
+
});
|
|
76
|
+
}, [
|
|
77
|
+
checkedState,
|
|
78
|
+
showHoveredStyling,
|
|
79
|
+
isActive,
|
|
80
|
+
disabled
|
|
81
|
+
]);
|
|
82
|
+
const handleChange = (event) => {
|
|
83
|
+
setCheckedState(event.target.checked);
|
|
84
|
+
setShowToggleAnimation(true);
|
|
85
|
+
onChange?.(event);
|
|
86
|
+
};
|
|
87
|
+
const toggleContainerClassNames = classNames(styles["toggle-container"], {
|
|
88
|
+
[styles["toggle-container--position-right"]]: togglePosition === TogglePosition.right,
|
|
89
|
+
[styles["toggle-container--with-status"]]: statusText !== void 0 && statusText !== null,
|
|
90
|
+
[styles["toggle-container--disabled"]]: disabled
|
|
91
|
+
});
|
|
92
|
+
const subLabelClassNames = classNames(styles["toggle-container__sublabel"]);
|
|
93
|
+
const statusTextClassNames = classNames(styles["toggle-container__status"], { [styles["toggle-container__status--checked"]]: checkedState });
|
|
94
|
+
const toggleClassNames = classNames(styles["toggle-container__toggle"], {
|
|
95
|
+
[styles["toggle-container__toggle--ignore-hover"]]: showToggleAnimation,
|
|
96
|
+
[styles["toggle-container__toggle--on-white"]]: onColor === ToggleOnColor.onwhite
|
|
97
|
+
});
|
|
98
|
+
const toggleDotClassNames = classNames(styles["toggle-container__toggle__dot"], { [styles["toggle-container__toggle__dot--ignore-hover"]]: showToggleAnimation });
|
|
99
|
+
const renderToggle = () => /* @__PURE__ */ jsxs("div", {
|
|
100
|
+
className: styles["toggle-container__outer-toggle"],
|
|
101
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
102
|
+
ref: refObject,
|
|
103
|
+
className: styles["toggle-container__toggle-group"],
|
|
104
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
105
|
+
disabled,
|
|
106
|
+
id: inputId,
|
|
107
|
+
type: "checkbox",
|
|
108
|
+
checked: checkedState,
|
|
109
|
+
onChange: handleChange,
|
|
110
|
+
className: styles["toggle-container__input"],
|
|
111
|
+
"aria-label": label.map((l) => l.text).join(" "),
|
|
112
|
+
"aria-describedby": [subLabel ? subLabelId : null, statusText ? toggleId + "-status" : null].filter(Boolean).join(" ") || void 0,
|
|
113
|
+
role: "switch"
|
|
114
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
115
|
+
id: toggleId,
|
|
116
|
+
ref: toggleRef,
|
|
117
|
+
className: toggleClassNames,
|
|
118
|
+
"aria-hidden": "true",
|
|
119
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
120
|
+
ref: toggleDotRef,
|
|
121
|
+
className: toggleDotClassNames,
|
|
122
|
+
"aria-hidden": "true",
|
|
123
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
124
|
+
width: "12",
|
|
125
|
+
height: "12",
|
|
126
|
+
viewBox: "0 0 12 12",
|
|
127
|
+
fill: "none",
|
|
128
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
129
|
+
className: styles["toggle-container__toggle__dot__icon"],
|
|
130
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
131
|
+
d: "M11 2.65247L4.69877 9.34741L1 5.41836",
|
|
132
|
+
strokeWidth: "2.2"
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
})]
|
|
137
|
+
}), statusText && /* @__PURE__ */ jsx("span", {
|
|
138
|
+
className: statusTextClassNames,
|
|
139
|
+
id: toggleId + "-status",
|
|
140
|
+
children: checkedState ? statusText.checked : statusText.unchecked
|
|
141
|
+
})]
|
|
142
|
+
});
|
|
143
|
+
const renderLabelText = () => {
|
|
144
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
145
|
+
className: styles["toggle-container__outer-label"],
|
|
146
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
147
|
+
id: labelId,
|
|
148
|
+
className: styles["toggle-container__label"],
|
|
149
|
+
children: label.map((labelText) => {
|
|
150
|
+
const labelClassNames = classNames({ [styles["toggle-container__label__text--subdued"]]: labelText.type === "subdued" });
|
|
151
|
+
return /* @__PURE__ */ jsx("span", {
|
|
152
|
+
className: labelClassNames,
|
|
153
|
+
children: labelText.text
|
|
154
|
+
}, labelId + labelText.text);
|
|
155
|
+
})
|
|
156
|
+
}), subLabel && /* @__PURE__ */ jsx("div", {
|
|
157
|
+
id: subLabelId,
|
|
158
|
+
className: subLabelClassNames,
|
|
159
|
+
children: subLabel
|
|
160
|
+
})]
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
164
|
+
className: toggleContainerClassNames,
|
|
165
|
+
"data-testid": testId,
|
|
166
|
+
"data-analyticsid": AnalyticsId.Toggle,
|
|
167
|
+
children: [togglePosition === TogglePosition.left && /* @__PURE__ */ jsxs(Fragment, { children: [renderToggle(), renderLabelText()] }), togglePosition === TogglePosition.right && /* @__PURE__ */ jsxs(Fragment, { children: [renderLabelText(), renderToggle()] })]
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/components/Toggle/index.ts
|
|
172
|
+
var Toggle_default = Toggle;
|
|
173
|
+
//#endregion
|
|
174
|
+
export { ToggleOnColor as n, TogglePosition as r, Toggle_default as t };
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=Toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle.js","names":[],"sources":["../src/components/Toggle/constants.ts","../src/components/Toggle/Toggle.tsx","../src/components/Toggle/index.ts"],"sourcesContent":["export enum TogglePosition {\n left = 'left',\n right = 'right',\n}\n\nexport enum ToggleOnColor {\n onwhite = 'onwhite',\n onneutral = 'onneutral',\n onblueberry = 'onblueberry',\n}\n","import React, { useState, useEffect, useId } from 'react';\n\nimport classNames from 'classnames';\nimport { useAnimate } from 'motion/react';\n\nimport { ToggleOnColor, TogglePosition } from './constants';\nimport { AnalyticsId } from '../../constants';\nimport { usePseudoClasses } from '../../hooks/usePseudoClasses';\n\nimport styles from './styles.module.scss';\n\nimport '../../scss/supernova/styles/colors.css';\n\nexport type LabelText = {\n text: string;\n type?: 'subdued' | 'normal';\n};\n\nexport type StatusTextType = {\n checked: string;\n unchecked: string;\n};\n\nexport interface ToggleProps extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'disabled'> {\n /** Determines if the Toggle is checked */\n checked?: boolean;\n /** Sets the label of the Toggle */\n label: LabelText[];\n /** Defines the color of the toggle */\n onColor?: keyof typeof ToggleOnColor;\n /** A text that is shown under the Toggle switch */\n statusText?: StatusTextType;\n /** Sets the sublabel of the Toggle */\n subLabel?: string;\n /** Sets the position of the toggle relative to the label */\n togglePosition?: keyof typeof TogglePosition;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nconst Toggle: React.FC<ToggleProps> = ({\n checked = false,\n disabled,\n label,\n onChange,\n onColor = ToggleOnColor.onwhite,\n statusText,\n subLabel,\n togglePosition = TogglePosition.left,\n testId,\n}: ToggleProps) => {\n const [checkedControlledState, setCheckedControlledState] = useState(checked);\n const [checkedState, setCheckedState] = useState(checked);\n const [showToggleAnimation, setShowToggleAnimation] = useState(false);\n const [scope, animate] = useAnimate();\n const baseId = useId();\n const toggleId = 'toggle-' + baseId;\n const inputId = 'input-' + baseId;\n const labelId = 'label-' + baseId;\n const subLabelId = 'sublabel-' + baseId;\n const toggleRef = React.useRef<HTMLSpanElement>(null);\n const toggleDotRef = React.useRef<HTMLSpanElement>(null);\n const { refObject, isHovered, isActive } = usePseudoClasses<HTMLLabelElement>(scope);\n const showHoveredStyling = isHovered && !showToggleAnimation;\n const isOnWhite = onColor === ToggleOnColor.onwhite;\n const animationDuration = disabled ? 0 : 0.2;\n const dotBackgroundColor = disabled\n ? 'var(--color-disabled-graphics)'\n : checkedState\n ? 'var(--color-action-graphics-ondark)'\n : 'var(--core-color-neutral-700)';\n\n if (checked !== checkedControlledState && typeof checked !== 'undefined') {\n setCheckedControlledState(checked);\n setCheckedState(checked);\n }\n\n const getBackgroundColor = (): string => {\n if (disabled) {\n return 'transparent';\n } else if (checkedState && isActive) {\n return 'var(--core-color-blueberry-800)';\n } else if (checkedState) {\n return showHoveredStyling ? 'var(--color-action-graphics-onlight-hover)' : 'var(--color-action-graphics-onlight)';\n } else if (isOnWhite && isActive) {\n return 'var(--core-color-neutral-400)';\n } else if (isOnWhite) {\n return showHoveredStyling ? 'var(--core-color-neutral-200)' : 'var(--core-color-neutral-50)';\n } else if (isActive) {\n return 'var(--core-color-neutral-200)';\n } else {\n return showHoveredStyling ? 'var(--core-color-neutral-50)' : 'var(--core-color-white)';\n }\n };\n\n useEffect(() => {\n if (showToggleAnimation) {\n const timer = setTimeout(() => setShowToggleAnimation(false), 300);\n return (): void => clearTimeout(timer);\n }\n }, [showToggleAnimation]);\n\n useEffect(() => {\n if (!toggleRef.current || !toggleDotRef.current) return;\n animate(toggleRef.current, { background: getBackgroundColor() }, { duration: animationDuration, ease: 'easeInOut' });\n animate(\n toggleDotRef.current,\n {\n background: dotBackgroundColor,\n },\n { duration: animationDuration, ease: 'easeInOut' }\n );\n animate(toggleDotRef.current, { x: checkedState ? 16 : 0 }, { duration: animationDuration, ease: 'easeInOut' });\n animate('svg', { opacity: checkedState ? 1 : 0 }, { duration: animationDuration, ease: 'easeInOut' });\n }, [checkedState, showHoveredStyling, isActive, disabled]);\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n setCheckedState(event.target.checked);\n setShowToggleAnimation(true);\n onChange?.(event);\n };\n\n const toggleContainerClassNames = classNames(styles['toggle-container'], {\n [styles['toggle-container--position-right']]: togglePosition === TogglePosition.right,\n [styles['toggle-container--with-status']]: statusText !== undefined && statusText !== null,\n [styles['toggle-container--disabled']]: disabled,\n });\n\n const subLabelClassNames = classNames(styles['toggle-container__sublabel']);\n\n const statusTextClassNames = classNames(styles['toggle-container__status'], {\n [styles['toggle-container__status--checked']]: checkedState,\n });\n\n const toggleClassNames = classNames(styles['toggle-container__toggle'], {\n [styles['toggle-container__toggle--ignore-hover']]: showToggleAnimation,\n [styles['toggle-container__toggle--on-white']]: onColor === ToggleOnColor.onwhite,\n });\n\n const toggleDotClassNames = classNames(styles['toggle-container__toggle__dot'], {\n [styles['toggle-container__toggle__dot--ignore-hover']]: showToggleAnimation,\n });\n\n const renderToggle = (): React.ReactElement => (\n <div className={styles['toggle-container__outer-toggle']}>\n <label ref={refObject} className={styles['toggle-container__toggle-group']}>\n <input\n disabled={disabled}\n id={inputId}\n type=\"checkbox\"\n checked={checkedState}\n onChange={handleChange}\n className={styles['toggle-container__input']}\n aria-label={label.map(l => l.text).join(' ')}\n aria-describedby={[subLabel ? subLabelId : null, statusText ? toggleId + '-status' : null].filter(Boolean).join(' ') || undefined}\n role=\"switch\"\n />\n <span id={toggleId} ref={toggleRef} className={toggleClassNames} aria-hidden=\"true\">\n <span ref={toggleDotRef} className={toggleDotClassNames} aria-hidden=\"true\">\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={styles['toggle-container__toggle__dot__icon']}\n >\n <path d=\"M11 2.65247L4.69877 9.34741L1 5.41836\" strokeWidth=\"2.2\" />\n </svg>\n </span>\n </span>\n </label>\n {statusText && (\n <span className={statusTextClassNames} id={toggleId + '-status'}>\n {checkedState ? statusText.checked : statusText.unchecked}\n </span>\n )}\n </div>\n );\n\n const renderLabelText = (): React.ReactElement => {\n return (\n <div className={styles['toggle-container__outer-label']}>\n <span id={labelId} className={styles['toggle-container__label']}>\n {label.map(labelText => {\n const labelClassNames = classNames({\n [styles['toggle-container__label__text--subdued']]: labelText.type === 'subdued',\n });\n\n return (\n <span key={labelId + labelText.text} className={labelClassNames}>\n {labelText.text}\n </span>\n );\n })}\n </span>\n {subLabel && (\n <div id={subLabelId} className={subLabelClassNames}>\n {subLabel}\n </div>\n )}\n </div>\n );\n };\n\n return (\n <div className={toggleContainerClassNames} data-testid={testId} data-analyticsid={AnalyticsId.Toggle}>\n {togglePosition === TogglePosition.left && (\n <>\n {renderToggle()}\n {renderLabelText()}\n </>\n )}\n {togglePosition === TogglePosition.right && (\n <>\n {renderLabelText()}\n {renderToggle()}\n </>\n )}\n </div>\n );\n};\n\nexport default Toggle;\n","import Toggle from './Toggle';\nexport { TogglePosition, ToggleOnColor } from './constants';\nexport * from './Toggle';\nexport default Toggle;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisualCheckbox.js","names":[],"sources":["../src/components/VisualCheckboxGroup/VisualCheckbox/VisualContent.tsx","../src/components/VisualCheckboxGroup/VisualCheckbox/VisualCheckbox.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualContentProps {\n /** Content rendered inside the circular area – typically an <img> or illustration component. */\n children: React.ReactNode;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const VisualContent: React.FC<VisualContentProps> = props => {\n const { children, className, testId } = props;\n\n return (\n <span className={classNames(styles['visual-checkbox__visual-content'], className)} data-testid={testId} aria-hidden=\"true\">\n {children}\n </span>\n );\n};\n\nexport default VisualContent;\n","import { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport VisualContent from './VisualContent';\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport CheckboxMarker from '../../Checkbox/CheckboxMarker/CheckboxMarker';\nimport ErrorWrapper from '../../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport type VisualCheckboxVariant = 'line' | 'rectangle';\n\nexport interface VisualCheckboxProps\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 rendered inside the checkbox frame. */\n children: string;\n /** Content rendered inside the circular visual slot. */\n visualContent: React.ReactNode;\n /** Layout variant. `line` is a thin horizontal pill, `rectangle` is a vertical card. */\n variant?: VisualCheckboxVariant;\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 VisualCheckbox: React.FC<VisualCheckboxProps> = props => {\n const {\n className,\n checked,\n defaultChecked,\n children,\n visualContent,\n variant = 'line',\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 styles[`visual-checkbox--variant-${variant}`],\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 <VisualContent>{visualContent}</VisualContent>\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__frame']}>\n <span className={styles['visual-checkbox__label']}>{children}</span>\n <CheckboxMarker checked={isChecked} error={error} size={'large'} />\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default VisualCheckbox;\n"],"mappings":";;;;;;;;;;AAaA,IAAa,iBAA8C,UAAS;CAClE,MAAM,EAAE,UAAU,WAAW,WAAW;CAExC,OACE,oBAAC,QAAD;EAAM,WAAW,WAAW,OAAO,oCAAoC,SAAS;EAAG,eAAa;EAAQ,eAAY;EACjH;CACG,CAAA;AAEV;;;ACoBA,IAAM,kBAAgD,UAAS;CAC7D,MAAM,EACJ,WACA,SACA,gBACA,UACA,eACA,UAAU,QACV,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,UACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,WAAW;CAC7C,MAAM,cAAc,kBAAkB,eAAe;CACrD,MAAM,CAAC,WAAW,gBAAgB,SAAkB,CAAC,EAAE,WAAW,eAAe;CACjF,MAAM,CAAC,aAAa,kBAAkB,SAA8B,OAAO;CAC3E,IAAI,gBAAgB,SAAS;EAC3B,eAAe,OAAO;EACtB,IAAI,YAAY,KAAA,KAAa,YAAY,WACvC,aAAa,OAAO;CAExB;CAEA,MAAM,gBAAgB,MAAiD;EACrE,aAAa,EAAE,OAAO,OAAO;EAC7B,WAAW,CAAC;CACd;CAEA,OACE,oBAAC,sBAAD;EAAc,WAAW;EAAkC;EAAwB;
|
|
1
|
+
{"version":3,"file":"VisualCheckbox.js","names":[],"sources":["../src/components/VisualCheckboxGroup/VisualCheckbox/VisualContent.tsx","../src/components/VisualCheckboxGroup/VisualCheckbox/VisualCheckbox.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualContentProps {\n /** Content rendered inside the circular area – typically an <img> or illustration component. */\n children: React.ReactNode;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const VisualContent: React.FC<VisualContentProps> = props => {\n const { children, className, testId } = props;\n\n return (\n <span className={classNames(styles['visual-checkbox__visual-content'], className)} data-testid={testId} aria-hidden=\"true\">\n {children}\n </span>\n );\n};\n\nexport default VisualContent;\n","import { useState } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport VisualContent from './VisualContent';\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport CheckboxMarker from '../../Checkbox/CheckboxMarker/CheckboxMarker';\nimport ErrorWrapper from '../../ErrorWrapper';\n\nimport styles from './styles.module.scss';\n\nexport type VisualCheckboxVariant = 'line' | 'rectangle';\n\nexport interface VisualCheckboxProps\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 rendered inside the checkbox frame. */\n children: string;\n /** Content rendered inside the circular visual slot. */\n visualContent: React.ReactNode;\n /** Layout variant. `line` is a thin horizontal pill, `rectangle` is a vertical card. */\n variant?: VisualCheckboxVariant;\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 VisualCheckbox: React.FC<VisualCheckboxProps> = props => {\n const {\n className,\n checked,\n defaultChecked,\n children,\n visualContent,\n variant = 'line',\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 styles[`visual-checkbox--variant-${variant}`],\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 <VisualContent>{visualContent}</VisualContent>\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__frame']}>\n <span className={styles['visual-checkbox__label']}>{children}</span>\n <CheckboxMarker checked={isChecked} error={error} size={'large'} />\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default VisualCheckbox;\n"],"mappings":";;;;;;;;;;AAaA,IAAa,iBAA8C,UAAS;CAClE,MAAM,EAAE,UAAU,WAAW,WAAW;CAExC,OACE,oBAAC,QAAD;EAAM,WAAW,WAAW,OAAO,oCAAoC,SAAS;EAAG,eAAa;EAAQ,eAAY;EACjH;CACG,CAAA;AAEV;;;ACoBA,IAAM,kBAAgD,UAAS;CAC7D,MAAM,EACJ,WACA,SACA,gBACA,UACA,eACA,UAAU,QACV,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,UACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,WAAW;CAC7C,MAAM,cAAc,kBAAkB,eAAe;CACrD,MAAM,CAAC,WAAW,gBAAgB,SAAkB,CAAC,EAAE,WAAW,eAAe;CACjF,MAAM,CAAC,aAAa,kBAAkB,SAA8B,OAAO;CAC3E,IAAI,gBAAgB,SAAS;EAC3B,eAAe,OAAO;EACtB,IAAI,YAAY,KAAA,KAAa,YAAY,WACvC,aAAa,OAAO;CAExB;CAEA,MAAM,gBAAgB,MAAiD;EACrE,aAAa,EAAE,OAAO,OAAO;EAC7B,WAAW,CAAC;CACd;CAEA,OACE,oBAAC,sBAAD;EAAc,WAAW;EAAkC;EAAwB;EACjF,UAAA,qBAAC,SAAD;GACE,WAAW,WACT,OAAO,oBACP,OAAO,4BAA4B,YACnC;KACG,OAAO,8BAA8B;KACrC,OAAO,8BAA8B;GACxC,GACA,SACF;GACA,SAAS;GACT,eAAa;GACb,oBAAkB,YAAY;GAZhC,UAAA;IAcE,oBAAC,eAAD,EAAA,UAAgB,cAA6B,CAAA;IAC7C,oBAAC,SAAD;KACE,GAAI;KACJ,IAAI;KACC;KACL,WAAW,OAAO;KAClB,MAAK;KACL,SAAS;KACT,gBAAc;KACd,oBAAkB,mBAAmB,OAAO,WAAW;KACvD,UAAU;IACX,CAAA;IACD,qBAAC,QAAD;KAAM,WAAW,OAAO;KAAxB,UAAA,CACE,oBAAC,QAAD;MAAM,WAAW,OAAO;MAA4B;KAAe,CAAA,GACnE,oBAAC,gBAAD;MAAgB,SAAS;MAAkB;MAAO,MAAM;KAAU,CAAA,CAC9D;;GACD;;CACK,CAAA;AAElB"}
|
package/lib/VisualRadio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisualRadio.js","names":[],"sources":["../src/components/VisualRadioGroup/VisualRadio/VisualContent.tsx","../src/components/VisualRadioGroup/VisualRadio/VisualRadio.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualContentProps {\n /** Content rendered inside the circular area – typically an <img> or illustration component. */\n children: React.ReactNode;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const VisualContent: React.FC<VisualContentProps> = props => {\n const { children, className, testId } = props;\n\n return (\n <span className={classNames(styles['visual-radio__visual-content'], className)} data-testid={testId} aria-hidden=\"true\">\n {children}\n </span>\n );\n};\n\nexport default VisualContent;\n","import classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport VisualContent from './VisualContent';\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport ErrorWrapper from '../../ErrorWrapper';\nimport RadioMarker from '../../RadioButton/RadioMarker/RadioMarker';\n\nimport styles from './styles.module.scss';\n\nexport type VisualRadioVariant = 'line' | 'rectangle';\n\nexport interface VisualRadioProps\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 rendered inside the radio frame. */\n children: string;\n /** Content rendered inside the circular visual slot. */\n visualContent?: React.ReactNode;\n /** Layout variant. `line` is a thin horizontal pill, `rectangle` is a vertical card. */\n variant?: VisualRadioVariant;\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 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 VisualRadio: React.FC<VisualRadioProps> = props => {\n const {\n className,\n children,\n visualContent,\n variant = 'line',\n inputId: inputIdProp,\n errorText,\n error = !!errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n testId,\n ref,\n ...rest\n } = props;\n\n const inputId = useIdWithFallback(inputIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <label\n className={classNames(\n styles['visual-radio'],\n styles[`visual-radio--variant-${variant}`],\n { [styles['visual-radio--invalid']]: error },\n className\n )}\n htmlFor={inputId}\n data-testid={testId}\n data-analyticsid={AnalyticsId.RadioButton}\n >\n {visualContent !== undefined && <VisualContent>{visualContent}</VisualContent>}\n {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props -- aria-invalid is a global ARIA state, valid on radio inputs */}\n <input\n {...rest}\n id={inputId}\n ref={ref}\n className={styles['visual-radio__input']}\n type=\"radio\"\n checked={rest.checked}\n aria-invalid={error}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n onChange={rest.onChange}\n />\n <span className={styles['visual-radio__frame']}>\n <span className={styles['visual-radio__label']}>{children}</span>\n <RadioMarker error={error} size={'large'} />\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default VisualRadio;\n"],"mappings":";;;;;;;;;AAaA,IAAa,iBAA8C,UAAS;CAClE,MAAM,EAAE,UAAU,WAAW,WAAW;CAExC,OACE,oBAAC,QAAD;EAAM,WAAW,WAAW,OAAO,iCAAiC,SAAS;EAAG,eAAa;EAAQ,eAAY;EAC9G;CACG,CAAA;AAEV;;;ACkBA,IAAM,eAA0C,UAAS;CACvD,MAAM,EACJ,WACA,UACA,eACA,UAAU,QACV,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,WAAW;CAC7C,MAAM,cAAc,kBAAkB,eAAe;CAErD,OACE,oBAAC,sBAAD;EAAc,WAAW;EAAkC;EAAwB;
|
|
1
|
+
{"version":3,"file":"VisualRadio.js","names":[],"sources":["../src/components/VisualRadioGroup/VisualRadio/VisualContent.tsx","../src/components/VisualRadioGroup/VisualRadio/VisualRadio.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport styles from './styles.module.scss';\n\nexport interface VisualContentProps {\n /** Content rendered inside the circular area – typically an <img> or illustration component. */\n children: React.ReactNode;\n /** Adds custom classes to the root element. */\n className?: string;\n /** Sets the data-testid attribute. */\n testId?: string;\n}\n\nexport const VisualContent: React.FC<VisualContentProps> = props => {\n const { children, className, testId } = props;\n\n return (\n <span className={classNames(styles['visual-radio__visual-content'], className)} data-testid={testId} aria-hidden=\"true\">\n {children}\n </span>\n );\n};\n\nexport default VisualContent;\n","import classNames from 'classnames';\n\nimport type { ErrorWrapperClassNameProps } from '../../ErrorWrapper';\n\nimport VisualContent from './VisualContent';\nimport { AnalyticsId } from '../../../constants';\nimport { useIdWithFallback } from '../../../hooks/useIdWithFallback';\nimport { getAriaDescribedBy } from '../../../utils/accessibility';\nimport ErrorWrapper from '../../ErrorWrapper';\nimport RadioMarker from '../../RadioButton/RadioMarker/RadioMarker';\n\nimport styles from './styles.module.scss';\n\nexport type VisualRadioVariant = 'line' | 'rectangle';\n\nexport interface VisualRadioProps\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 rendered inside the radio frame. */\n children: string;\n /** Content rendered inside the circular visual slot. */\n visualContent?: React.ReactNode;\n /** Layout variant. `line` is a thin horizontal pill, `rectangle` is a vertical card. */\n variant?: VisualRadioVariant;\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 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 VisualRadio: React.FC<VisualRadioProps> = props => {\n const {\n className,\n children,\n visualContent,\n variant = 'line',\n inputId: inputIdProp,\n errorText,\n error = !!errorText,\n errorTextId: errorTextIdProp,\n errorWrapperClassName,\n testId,\n ref,\n ...rest\n } = props;\n\n const inputId = useIdWithFallback(inputIdProp);\n const errorTextId = useIdWithFallback(errorTextIdProp);\n\n return (\n <ErrorWrapper className={errorWrapperClassName} errorText={errorText} errorTextId={errorTextId}>\n <label\n className={classNames(\n styles['visual-radio'],\n styles[`visual-radio--variant-${variant}`],\n { [styles['visual-radio--invalid']]: error },\n className\n )}\n htmlFor={inputId}\n data-testid={testId}\n data-analyticsid={AnalyticsId.RadioButton}\n >\n {visualContent !== undefined && <VisualContent>{visualContent}</VisualContent>}\n {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props -- aria-invalid is a global ARIA state, valid on radio inputs */}\n <input\n {...rest}\n id={inputId}\n ref={ref}\n className={styles['visual-radio__input']}\n type=\"radio\"\n checked={rest.checked}\n aria-invalid={error}\n aria-describedby={getAriaDescribedBy(props, errorTextId)}\n onChange={rest.onChange}\n />\n <span className={styles['visual-radio__frame']}>\n <span className={styles['visual-radio__label']}>{children}</span>\n <RadioMarker error={error} size={'large'} />\n </span>\n </label>\n </ErrorWrapper>\n );\n};\n\nexport default VisualRadio;\n"],"mappings":";;;;;;;;;AAaA,IAAa,iBAA8C,UAAS;CAClE,MAAM,EAAE,UAAU,WAAW,WAAW;CAExC,OACE,oBAAC,QAAD;EAAM,WAAW,WAAW,OAAO,iCAAiC,SAAS;EAAG,eAAa;EAAQ,eAAY;EAC9G;CACG,CAAA;AAEV;;;ACkBA,IAAM,eAA0C,UAAS;CACvD,MAAM,EACJ,WACA,UACA,eACA,UAAU,QACV,SAAS,aACT,WACA,QAAQ,CAAC,CAAC,WACV,aAAa,iBACb,uBACA,QACA,KACA,GAAG,SACD;CAEJ,MAAM,UAAU,kBAAkB,WAAW;CAC7C,MAAM,cAAc,kBAAkB,eAAe;CAErD,OACE,oBAAC,sBAAD;EAAc,WAAW;EAAkC;EAAwB;EACjF,UAAA,qBAAC,SAAD;GACE,WAAW,WACT,OAAO,iBACP,OAAO,yBAAyB,YAChC,GAAG,OAAO,2BAA2B,MAAM,GAC3C,SACF;GACA,SAAS;GACT,eAAa;GACb,oBAAkB,YAAY;GAThC,UAAA;IAWG,kBAAkB,KAAA,KAAa,oBAAC,eAAD,EAAA,UAAgB,cAA6B,CAAA;IAE7E,oBAAC,SAAD;KACE,GAAI;KACJ,IAAI;KACC;KACL,WAAW,OAAO;KAClB,MAAK;KACL,SAAS,KAAK;KACd,gBAAc;KACd,oBAAkB,mBAAmB,OAAO,WAAW;KACvD,UAAU,KAAK;IAChB,CAAA;IACD,qBAAC,QAAD;KAAM,WAAW,OAAO;KAAxB,UAAA,CACE,oBAAC,QAAD;MAAM,WAAW,OAAO;MAAyB;KAAe,CAAA,GAChE,oBAAC,aAAD;MAAoB;MAAO,MAAM;KAAU,CAAA,CACvC;;GACD;;CACK,CAAA;AAElB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/resources/HN.Designsystem.ArticleTeaser.en-GB.json","../../../src/resources/HN.Designsystem.ArticleTeaser.nb-NO.json","../../../src/components/ArticleTeaser/resourceHelper.ts","../../../src/components/ArticleTeaser/ArticleTeaser.tsx","../../../src/components/ArticleTeaser/index.ts"],"sourcesContent":["{\n \"expandButtonClose\": \"Show more\",\n \"expandButtonOpen\": \"Show less\"\n}\n","{\n \"expandButtonClose\": \"Vis mer\",\n \"expandButtonOpen\": \"Vis mindre\"\n}\n","import type { HNDesignsystemArticleTeaser } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.ArticleTeaser.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.ArticleTeaser.nb-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemArticleTeaser => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import classNames from 'classnames';\n\nimport type { HNDesignsystemArticleTeaser } from '../../resources/Resources';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { useLanguage } from '../../hooks/useLanguage';\n\nimport styles from './styles.module.scss';\n\nexport type ArticleTeaserTags = 'div' | 'section' | 'aside' | 'article';\n\nexport interface ArticleTeaserProps {\n /** Callback for the button. Should be used for setting the expanded boolean */\n onExpand: () => void;\n /** What's in the box? */\n children: React.ReactNode;\n /** Id of the content, used to set aria-controls */\n contentId: string;\n /** If the component is expanded or not */\n expanded: boolean;\n /** For overriding the height of the collapsed teaser */\n heightCollapsed?: string;\n /** Changes the underlying element of the wrapper */\n htmlMarkup?: ArticleTeaserTags;\n /** Resources for component */\n resources?: Partial<HNDesignsystemArticleTeaser>;\n /** Sets the data-testid attribute */\n testId?: string;\n}\n\nconst ArticleTeaser: React.FC<ArticleTeaserProps> = props => {\n const { onExpand, children, contentId, expanded, htmlMarkup = 'div', resources, testId } = props;\n const WrapperTag = htmlMarkup;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemArticleTeaser = {\n ...defaultResources,\n ...resources,\n };\n\n return (\n <WrapperTag className={classNames(styles.articleteaser)} data-testid={testId} data-analyticsid={AnalyticsId.ArticleTeaser}>\n <div\n className={classNames(styles['articleteaser__content'], {\n [styles['articleteaser__content--collapsed']]: !expanded,\n })}\n style={{\n maxHeight: expanded ? 'none' : props.heightCollapsed,\n }}\n >\n {children}\n </div>\n <button\n type=\"button\"\n className={classNames(styles['articleteaser__button'], {\n [styles['articleteaser__button--expanded']]: expanded,\n })}\n onClick={onExpand}\n aria-expanded={expanded}\n aria-controls={contentId}\n >\n {expanded ? mergedResources.expandButtonOpen : mergedResources.expandButtonClose}\n </button>\n </WrapperTag>\n );\n};\n\nexport default ArticleTeaser;\n","import ArticleTeaser from './ArticleTeaser';\nexport * from './ArticleTeaser';\nexport default ArticleTeaser;\n"],"mappings":";;;;;;;;;;;;;;;AEMA,IAAa,gBAAgB,aAA2D;CACtF,QAAQ,UAAR;EACE,KAAK,gBAAgB,SACnB,OAAO;EACT,KAAK,gBAAgB;EACrB,SACE,OAAO;CACX;AACF;;;ACiBA,IAAM,iBAA8C,UAAS;CAC3D,MAAM,EAAE,UAAU,UAAU,WAAW,UAAU,aAAa,OAAO,WAAW,WAAW;CAC3F,MAAM,aAAa;CAEnB,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAG3E,MAAM,kBAA+C;EACnD,GAHuB,aAAa,QAGjC;EACH,GAAG;CACL;CAEA,OACE,qBAAC,YAAD;EAAY,WAAW,WAAW,OAAO,aAAa;EAAG,eAAa;EAAQ,oBAAkB,YAAY;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/resources/HN.Designsystem.ArticleTeaser.en-GB.json","../../../src/resources/HN.Designsystem.ArticleTeaser.nb-NO.json","../../../src/components/ArticleTeaser/resourceHelper.ts","../../../src/components/ArticleTeaser/ArticleTeaser.tsx","../../../src/components/ArticleTeaser/index.ts"],"sourcesContent":["{\n \"expandButtonClose\": \"Show more\",\n \"expandButtonOpen\": \"Show less\"\n}\n","{\n \"expandButtonClose\": \"Vis mer\",\n \"expandButtonOpen\": \"Vis mindre\"\n}\n","import type { HNDesignsystemArticleTeaser } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.ArticleTeaser.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.ArticleTeaser.nb-NO.json';\n\nexport const getResources = (language: LanguageLocales): HNDesignsystemArticleTeaser => {\n switch (language) {\n case LanguageLocales.ENGLISH:\n return enGB;\n case LanguageLocales.NORWEGIAN:\n default:\n return nbNO;\n }\n};\n","import classNames from 'classnames';\n\nimport type { HNDesignsystemArticleTeaser } from '../../resources/Resources';\n\nimport { getResources } from './resourceHelper';\nimport { AnalyticsId, LanguageLocales } from '../../constants';\nimport { useLanguage } from '../../hooks/useLanguage';\n\nimport styles from './styles.module.scss';\n\nexport type ArticleTeaserTags = 'div' | 'section' | 'aside' | 'article';\n\nexport interface ArticleTeaserProps {\n /** Callback for the button. Should be used for setting the expanded boolean */\n onExpand: () => void;\n /** What's in the box? */\n children: React.ReactNode;\n /** Id of the content, used to set aria-controls */\n contentId: string;\n /** If the component is expanded or not */\n expanded: boolean;\n /** For overriding the height of the collapsed teaser */\n heightCollapsed?: string;\n /** Changes the underlying element of the wrapper */\n htmlMarkup?: ArticleTeaserTags;\n /** Resources for component */\n resources?: Partial<HNDesignsystemArticleTeaser>;\n /** Sets the data-testid attribute */\n testId?: string;\n}\n\nconst ArticleTeaser: React.FC<ArticleTeaserProps> = props => {\n const { onExpand, children, contentId, expanded, htmlMarkup = 'div', resources, testId } = props;\n const WrapperTag = htmlMarkup;\n\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemArticleTeaser = {\n ...defaultResources,\n ...resources,\n };\n\n return (\n <WrapperTag className={classNames(styles.articleteaser)} data-testid={testId} data-analyticsid={AnalyticsId.ArticleTeaser}>\n <div\n className={classNames(styles['articleteaser__content'], {\n [styles['articleteaser__content--collapsed']]: !expanded,\n })}\n style={{\n maxHeight: expanded ? 'none' : props.heightCollapsed,\n }}\n >\n {children}\n </div>\n <button\n type=\"button\"\n className={classNames(styles['articleteaser__button'], {\n [styles['articleteaser__button--expanded']]: expanded,\n })}\n onClick={onExpand}\n aria-expanded={expanded}\n aria-controls={contentId}\n >\n {expanded ? mergedResources.expandButtonOpen : mergedResources.expandButtonClose}\n </button>\n </WrapperTag>\n );\n};\n\nexport default ArticleTeaser;\n","import ArticleTeaser from './ArticleTeaser';\nexport * from './ArticleTeaser';\nexport default ArticleTeaser;\n"],"mappings":";;;;;;;;;;;;;;;AEMA,IAAa,gBAAgB,aAA2D;CACtF,QAAQ,UAAR;EACE,KAAK,gBAAgB,SACnB,OAAO;EACT,KAAK,gBAAgB;EACrB,SACE,OAAO;CACX;AACF;;;ACiBA,IAAM,iBAA8C,UAAS;CAC3D,MAAM,EAAE,UAAU,UAAU,WAAW,UAAU,aAAa,OAAO,WAAW,WAAW;CAC3F,MAAM,aAAa;CAEnB,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAG3E,MAAM,kBAA+C;EACnD,GAHuB,aAAa,QAGjC;EACH,GAAG;CACL;CAEA,OACE,qBAAC,YAAD;EAAY,WAAW,WAAW,OAAO,aAAa;EAAG,eAAa;EAAQ,oBAAkB,YAAY;EAA5G,UAAA,CACE,oBAAC,OAAD;GACE,WAAW,WAAW,OAAO,2BAA2B,GACrD,OAAO,uCAAuC,CAAC,SAClD,CAAC;GACD,OAAO,EACL,WAAW,WAAW,SAAS,MAAM,gBACvC;GAEC;EACE,CAAA,GACL,oBAAC,UAAD;GACE,MAAK;GACL,WAAW,WAAW,OAAO,0BAA0B,GACpD,OAAO,qCAAqC,SAC/C,CAAC;GACD,SAAS;GACT,iBAAe;GACf,iBAAe;GAEd,UAAA,WAAW,gBAAgB,mBAAmB,gBAAgB;EACzD,CAAA,CACE;;AAEhB;;;AClEA,IAAA,wBAAe"}
|
|
@@ -54,7 +54,7 @@ $mobile-outer-size: 2.75rem;
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
:focus-visible > & {
|
|
57
|
-
outline:
|
|
57
|
+
outline: 4px solid var(--color-action-border-onlight-focus);
|
|
58
58
|
border-radius: 0;
|
|
59
59
|
border: 0;
|
|
60
60
|
}
|
|
@@ -69,7 +69,7 @@ $mobile-outer-size: 2.75rem;
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
:focus-visible > & {
|
|
72
|
-
outline:
|
|
72
|
+
outline: 4px solid var(--color-action-border-onlight-focus);
|
|
73
73
|
border-radius: 0;
|
|
74
74
|
border: 0;
|
|
75
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/SingleSelect/SingleSelect.tsx","../../../src/components/Dropdown/Dropdown.tsx","../../../src/components/Dropdown/index.ts"],"sourcesContent":["import type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\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 from 'react';\n\nimport { SingleSelectContext } from './utils';\n\nexport type SingleSelectContextType = {\n name?: string;\n disabled?: boolean;\n required?: boolean;\n value?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n};\n\nexport interface SingleSelectProps {\n name?: string;\n disabled?: boolean;\n defaultValue?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n children: React.ReactNode;\n}\n\nexport const SingleSelect: React.FC<SingleSelectProps> = ({ name, disabled, defaultValue, onValueChange, children }) => {\n const [selected, setSelected] = React.useState<string | undefined>(defaultValue);\n\n const context = React.useMemo<SingleSelectContextType>(\n () => ({\n name,\n disabled,\n value: selected,\n onValueChange: (v, e): void => {\n setSelected(v);\n onValueChange?.(v, e);\n },\n }),\n [name, disabled, selected, onValueChange]\n );\n\n return <SingleSelectContext.Provider value={context}>{children}</SingleSelectContext.Provider>;\n};\n","import type { ComponentType } from 'react';\nimport React, { useEffect, useRef, useId } 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 type { SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport type { HNDesignsystemDropdown } from '../../resources/Resources';\nimport type { CheckboxProps } from '../Checkbox';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\nimport type { LabelProps } from '../Label';\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 } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { isComponent } from '../../utils/component';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox from '../Checkbox';\nimport Icon from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label 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 | null>(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 maxHeight = isMobile ? 384 : 464;\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: `${Math.min(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 const element = child as React.ReactElement<{ ref?: React.Ref<HTMLElement | null> }>;\n\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(element) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n if (isMultiSelect && isComponent<CheckboxProps>(element, Checkbox)) {\n const label = element.props.label;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(element, {\n ref: mergeRefs([element.props.ref, childrenRefList.current[index]]),\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>>, {\n ref: mergeRefs([element.props.ref, childrenRefList.current[index]]),\n });\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","import Dropdown from './Dropdown';\nexport * from './Dropdown';\nexport default Dropdown;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Dropdown/resourceHelper.ts","../../../src/components/Dropdown/SingleSelect/SingleSelect.tsx","../../../src/components/Dropdown/Dropdown.tsx","../../../src/components/Dropdown/index.ts"],"sourcesContent":["import type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\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 from 'react';\n\nimport { SingleSelectContext } from './utils';\n\nexport type SingleSelectContextType = {\n name?: string;\n disabled?: boolean;\n required?: boolean;\n value?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n};\n\nexport interface SingleSelectProps {\n name?: string;\n disabled?: boolean;\n defaultValue?: string;\n onValueChange?: (newValue: string, e?: React.SyntheticEvent) => void;\n children: React.ReactNode;\n}\n\nexport const SingleSelect: React.FC<SingleSelectProps> = ({ name, disabled, defaultValue, onValueChange, children }) => {\n const [selected, setSelected] = React.useState<string | undefined>(defaultValue);\n\n const context = React.useMemo<SingleSelectContextType>(\n () => ({\n name,\n disabled,\n value: selected,\n onValueChange: (v, e): void => {\n setSelected(v);\n onValueChange?.(v, e);\n },\n }),\n [name, disabled, selected, onValueChange]\n );\n\n return <SingleSelectContext.Provider value={context}>{children}</SingleSelectContext.Provider>;\n};\n","import type { ComponentType } from 'react';\nimport React, { useEffect, useRef, useId } 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 type { SingleSelectItemProps } from './SingleSelect/SingleSelectItem';\nimport type { HNDesignsystemDropdown } from '../../resources/Resources';\nimport type { CheckboxProps } from '../Checkbox';\nimport type { SvgIcon } from '../Icon';\nimport type { IconName } from '../Icons/IconNames';\nimport type { LabelProps } from '../Label';\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 } from './SingleSelect/SingleSelectItem';\nimport { useIsMobileBreakpoint } from '../../hooks/useIsMobileBreakpoint';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { isComponent } from '../../utils/component';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Checkbox from '../Checkbox';\nimport Icon from '../Icon';\nimport ChevronDown from '../Icons/ChevronDown';\nimport ChevronUp from '../Icons/ChevronUp';\nimport PlusSmall from '../Icons/PlusSmall';\nimport Label 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 | null>(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 maxHeight = isMobile ? 384 : 464;\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: `${Math.min(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 const element = child as React.ReactElement<{ ref?: React.Ref<HTMLElement | null> }>;\n\n return (\n <li className={listItemClasses} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(element) && childrenRefList.current && childrenRefList.current[index]\n ? ((): React.ReactElement => {\n if (isMultiSelect && isComponent<CheckboxProps>(element, Checkbox)) {\n const label = element.props.label;\n if (React.isValidElement(label) && isComponent<LabelProps>(label, Label)) {\n return React.cloneElement(element, {\n ref: mergeRefs([element.props.ref, childrenRefList.current[index]]),\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>>, {\n ref: mergeRefs([element.props.ref, childrenRefList.current[index]]),\n });\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","import Dropdown from './Dropdown';\nexport * from './Dropdown';\nexport default Dropdown;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/DropdownOld/constants.ts","../../../src/components/DropdownOld/resourceHelper.ts","../../../src/components/DropdownOld/DropdownOld.tsx","../../../src/components/DropdownOld/index.ts"],"sourcesContent":["export enum DropdownOldOnColor {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n","import type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\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 } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { DropdownOldOnColor } from './constants';\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n theme,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport interface DropdownOldProps {\n /** Label for dropdown. Visible for screen readers */\n label: string;\n /** Text on the trigger button that opens the dropdown */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** @deprecated Close button text */\n closeText?: string;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button */\n dropdownMinWidth?: number;\n /** No close button */\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 /** Changes the visuals of the dropdown */\n onColor?: keyof typeof DropdownOldOnColor;\n /** Makes the background of the trigger transparent */\n transparent?: boolean;\n /** Makes the width of the full component adjust to its parent */\n fluid?: 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}\n\nconst DropdownOld: React.FC<DropdownOldProps> = props => {\n const {\n label,\n placeholder,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n open = false,\n children,\n onColor = DropdownOldOnColor.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { refObject: buttonRef, isHovered } = usePseudoClasses<HTMLButtonElement>();\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const labelId = useId();\n const toggleLabelId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n closeText: props.closeText ?? resources?.closeText ?? defaultResources.closeText,\n };\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = inputRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!inputRefList.current) {\n return;\n }\n\n if (event.key === KeyboardEventKey.Escape) {\n if (isOpen) handleClose();\n return;\n }\n\n if (!isOpen) {\n handleOpen(true);\n event.preventDefault();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n\n if (nextIndex !== -1 && event.key !== KeyboardEventKey.Space) {\n event.preventDefault();\n\n inputRefList.current[nextIndex].current?.focus();\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 toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: onColor === DropdownOldOnColor.onwhite,\n [styles['dropdown__toggle--on-grey']]: onColor === DropdownOldOnColor.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: onColor === DropdownOldOnColor.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: onColor === DropdownOldOnColor.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n const renderChildren = React.Children.map(children, (child, index) => {\n const element = child as React.ReactElement<{ children?: React.ReactNode; ref?: React.Ref<HTMLElement | null> }>;\n\n return (\n <li className={styles.dropdown__input} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(element) && inputRefList.current && inputRefList.current[index]\n ? React.cloneElement(element, {\n ref: mergeRefs([element.props.ref, inputRefList.current[index]]),\n })\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral700 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n id={contentId}\n className={contentClasses}\n style={{ width: fluid ? '100%' : `auto`, minWidth: dropdownMinWidth ?? 'auto', zIndex: zIndex }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={labelId} tabIndex={-1} ref={optionsRef}>\n {renderChildren}\n </ul>\n {!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 default DropdownOld;\n","import DropdownOld from './DropdownOld';\nexport { DropdownOldOnColor } from './constants';\nexport * from './DropdownOld';\nexport default DropdownOld;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/DropdownOld/constants.ts","../../../src/components/DropdownOld/resourceHelper.ts","../../../src/components/DropdownOld/DropdownOld.tsx","../../../src/components/DropdownOld/index.ts"],"sourcesContent":["export enum DropdownOldOnColor {\n onwhite = 'onwhite',\n ongrey = 'ongrey',\n onblueberry = 'onblueberry',\n oncherry = 'oncherry',\n}\n","import type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { LanguageLocales } from '../../constants';\nimport enGB from '../../resources/HN.Designsystem.Dropdown.en-GB.json';\nimport nbNO from '../../resources/HN.Designsystem.Dropdown.nb-NO.json';\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 } from 'react';\n\nimport classNames from 'classnames';\n\nimport type { HNDesignsystemDropdown } from '../../resources/Resources';\n\nimport { DropdownOldOnColor } from './constants';\nimport {\n AnalyticsId,\n IconSize,\n KeyboardEventKey,\n LanguageLocales,\n ZIndex,\n theme,\n usePseudoClasses,\n useKeyboardEvent,\n useOutsideEvent,\n useToggle,\n} from '../..';\nimport { getResources } from './resourceHelper';\nimport { useLanguage } from '../../hooks/useLanguage';\nimport { mergeRefs } from '../../utils/refs';\nimport Button from '../Button';\nimport Icon from '../Icon';\nimport PlusSmall from '../Icons/PlusSmall';\n\nimport styles from './styles.module.scss';\n\nexport interface DropdownOldProps {\n /** Label for dropdown. Visible for screen readers */\n label: string;\n /** Text on the trigger button that opens the dropdown */\n placeholder: string;\n /** Sets the dropdown content */\n children: React.ReactNode;\n /** @deprecated Close button text */\n closeText?: string;\n /** Minimum width for the dropdown in pixels. Does not affect trigger button */\n dropdownMinWidth?: number;\n /** No close button */\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 /** Changes the visuals of the dropdown */\n onColor?: keyof typeof DropdownOldOnColor;\n /** Makes the background of the trigger transparent */\n transparent?: boolean;\n /** Makes the width of the full component adjust to its parent */\n fluid?: 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}\n\nconst DropdownOld: React.FC<DropdownOldProps> = props => {\n const {\n label,\n placeholder,\n noCloseButton = false,\n onToggle,\n dropdownMinWidth,\n open = false,\n children,\n onColor = DropdownOldOnColor.onwhite,\n transparent = false,\n fluid = false,\n testId,\n disabled,\n zIndex = ZIndex.PopOver,\n resources,\n } = props;\n\n const dropdownRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLUListElement>(null);\n const { refObject: buttonRef, isHovered } = usePseudoClasses<HTMLButtonElement>();\n const openedByKeyboard = useRef<boolean>(false);\n const { value: isOpen, toggleValue: toggleIsOpen } = useToggle(!disabled && open, onToggle);\n const inputRefList = useRef(React.Children.map(children, () => React.createRef<HTMLElement>()));\n const labelId = useId();\n const toggleLabelId = useId();\n const optionIdPrefix = useId();\n const contentId = useId();\n const { language } = useLanguage<LanguageLocales>(LanguageLocales.NORWEGIAN);\n const defaultResources = getResources(language);\n\n const mergedResources: HNDesignsystemDropdown = {\n ...defaultResources,\n ...resources,\n closeText: props.closeText ?? resources?.closeText ?? defaultResources.closeText,\n };\n\n const handleOpen = (isKeyboard: boolean): void => {\n openedByKeyboard.current = isKeyboard;\n toggleIsOpen();\n };\n\n const handleClose = (): void => {\n toggleIsOpen();\n buttonRef.current?.focus();\n };\n\n useEffect(() => {\n if (isOpen && openedByKeyboard.current) {\n const firstEnabled = inputRefList.current?.find(r => r.current && !r.current.hasAttribute('disabled'));\n firstEnabled?.current?.focus();\n openedByKeyboard.current = false;\n }\n }, [isOpen]);\n\n const handleKeyboardNavigation = (event: KeyboardEvent): void => {\n if (!inputRefList.current) {\n return;\n }\n\n if (event.key === KeyboardEventKey.Escape) {\n if (isOpen) handleClose();\n return;\n }\n\n if (!isOpen) {\n handleOpen(true);\n event.preventDefault();\n return;\n }\n\n const index = inputRefList.current.findIndex(x => x.current === event.target);\n let nextIndex = index;\n\n if (event.key === KeyboardEventKey.Home) {\n nextIndex = 0;\n } else if (event.key === KeyboardEventKey.End) {\n nextIndex = inputRefList.current.length - 1;\n } else if (event.key === KeyboardEventKey.ArrowDown && index < inputRefList.current.length - 1) {\n nextIndex = index + 1;\n } else if (event.key === KeyboardEventKey.ArrowUp && index > 0) {\n nextIndex = index - 1;\n } else if (event.key === KeyboardEventKey.Enter && index !== -1) {\n nextIndex = index;\n }\n\n if (nextIndex !== -1 && event.key !== KeyboardEventKey.Space) {\n event.preventDefault();\n\n inputRefList.current[nextIndex].current?.focus();\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 toggleClasses = classNames(\n styles.dropdown__toggle,\n !disabled && {\n [styles['dropdown__toggle--on-white']]: onColor === DropdownOldOnColor.onwhite,\n [styles['dropdown__toggle--on-grey']]: onColor === DropdownOldOnColor.ongrey,\n [styles['dropdown__toggle--on-blueberry']]: onColor === DropdownOldOnColor.onblueberry,\n [styles['dropdown__toggle--on-cherry']]: onColor === DropdownOldOnColor.oncherry,\n [styles['dropdown__toggle--transparent']]: transparent,\n [styles['dropdown__toggle--fluid']]: fluid,\n [styles['dropdown__toggle--open']]: isOpen,\n }\n );\n\n const contentClasses = classNames(styles.dropdown__content, isOpen && styles['dropdown__content--open']);\n\n const renderChildren = React.Children.map(children, (child, index) => {\n const element = child as React.ReactElement<{ children?: React.ReactNode; ref?: React.Ref<HTMLElement | null> }>;\n\n return (\n <li className={styles.dropdown__input} id={`${optionIdPrefix}-${index}`}>\n {React.isValidElement(element) && inputRefList.current && inputRefList.current[index]\n ? React.cloneElement(element, {\n ref: mergeRefs([element.props.ref, inputRefList.current[index]]),\n })\n : child}\n </li>\n );\n });\n\n return (\n <div className={styles.dropdown} ref={dropdownRef}>\n <span id={labelId} className={styles.dropdown__label}>\n {label}\n </span>\n <button\n type=\"button\"\n onClick={(): false | void => handleOpen(false)}\n className={toggleClasses}\n ref={buttonRef}\n data-testid={testId}\n data-analyticsid={AnalyticsId.Dropdown}\n disabled={disabled}\n aria-labelledby={toggleLabelId}\n aria-haspopup={true}\n aria-controls={contentId}\n aria-expanded={isOpen}\n >\n <span id={toggleLabelId} className={styles.dropdown__toggle__label}>\n {placeholder}\n </span>\n <Icon\n color={disabled ? theme.palette.neutral700 : theme.palette.blueberry600}\n svgIcon={PlusSmall}\n className={styles.dropdown__icon}\n isHovered={!disabled && isHovered}\n size={IconSize.XSmall}\n />\n </button>\n <div\n id={contentId}\n className={contentClasses}\n style={{ width: fluid ? '100%' : `auto`, minWidth: dropdownMinWidth ?? 'auto', zIndex: zIndex }}\n >\n <ul className={styles.dropdown__options} role=\"group\" aria-labelledby={labelId} tabIndex={-1} ref={optionsRef}>\n {renderChildren}\n </ul>\n {!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 default DropdownOld;\n","import DropdownOld from './DropdownOld';\nexport { DropdownOldOnColor } from './constants';\nexport * from './DropdownOld';\nexport default DropdownOld;\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAY,qBAAL,yBAAA,oBAAA;CACL,mBAAA,aAAA;CACA,mBAAA,YAAA;CACA,mBAAA,iBAAA;CACA,mBAAA,cAAA;;AACF,EAAA,CAAA,CAAA;;;ACCA,IAAa,gBAAgB,aAAsD;CACjF,QAAQ,UAAR;EACE,KAAK,gBAAgB,SACnB,OAAO;EACT,KAAK,gBAAgB;EACrB,SACE,OAAO;CACX;AACF;;;AC+CA,IAAM,eAA0C,UAAS;CACvD,MAAM,EACJ,OACA,aACA,gBAAgB,OAChB,UACA,kBACA,OAAO,OACP,UACA,UAAU,mBAAmB,SAC7B,cAAc,OACd,QAAQ,OACR,QACA,UACA,SAAS,OAAO,SAChB,cACE;CAEJ,MAAM,cAAc,OAAuB,IAAI;CAC/C,MAAM,aAAa,OAAyB,IAAI;CAChD,MAAM,EAAE,WAAW,WAAW,cAAc,iBAAoC;CAChF,MAAM,mBAAmB,OAAgB,KAAK;CAC9C,MAAM,EAAE,OAAO,QAAQ,aAAa,iBAAiB,UAAU,CAAC,YAAY,MAAM,QAAQ;CAC1F,MAAM,eAAe,OAAO,MAAM,SAAS,IAAI,gBAAgB,MAAM,UAAuB,CAAC,CAAC;CAC9F,MAAM,UAAU,MAAM;CACtB,MAAM,gBAAgB,MAAM;CAC5B,MAAM,iBAAiB,MAAM;CAC7B,MAAM,YAAY,MAAM;CACxB,MAAM,EAAE,aAAa,YAA6B,gBAAgB,SAAS;CAC3E,MAAM,mBAAmB,aAAa,QAAQ;CAE9C,MAAM,kBAA0C;EAC9C,GAAG;EACH,GAAG;EACH,WAAW,MAAM,aAAa,WAAW,aAAa,iBAAiB;CACzE;CAEA,MAAM,cAAc,eAA8B;EAChD,iBAAiB,UAAU;EAC3B,aAAa;CACf;CAEA,MAAM,oBAA0B;EAC9B,aAAa;EACb,UAAU,SAAS,MAAM;CAC3B;CAEA,gBAAgB;EACd,IAAI,UAAU,iBAAiB,SAAS;GAEtC,CADqB,aAAa,SAAS,MAAK,MAAK,EAAE,WAAW,CAAC,EAAE,QAAQ,aAAa,UAAU,CAAC,EAAA,EACvF,SAAS,MAAM;GAC7B,iBAAiB,UAAU;EAC7B;CACF,GAAG,CAAC,MAAM,CAAC;CAEX,MAAM,4BAA4B,UAA+B;EAC/D,IAAI,CAAC,aAAa,SAChB;EAGF,IAAI,MAAM,QAAQ,iBAAiB,QAAQ;GACzC,IAAI,QAAQ,YAAY;GACxB;EACF;EAEA,IAAI,CAAC,QAAQ;GACX,WAAW,IAAI;GACf,MAAM,eAAe;GACrB;EACF;EAEA,MAAM,QAAQ,aAAa,QAAQ,WAAU,MAAK,EAAE,YAAY,MAAM,MAAM;EAC5E,IAAI,YAAY;EAEhB,IAAI,MAAM,QAAQ,iBAAiB,MACjC,YAAY;OACP,IAAI,MAAM,QAAQ,iBAAiB,KACxC,YAAY,aAAa,QAAQ,SAAS;OACrC,IAAI,MAAM,QAAQ,iBAAiB,aAAa,QAAQ,aAAa,QAAQ,SAAS,GAC3F,YAAY,QAAQ;OACf,IAAI,MAAM,QAAQ,iBAAiB,WAAW,QAAQ,GAC3D,YAAY,QAAQ;OACf,IAAI,MAAM,QAAQ,iBAAiB,SAAS,UAAU,IAC3D,YAAY;EAGd,IAAI,cAAc,MAAM,MAAM,QAAQ,iBAAiB,OAAO;GAC5D,MAAM,eAAe;GAErB,aAAa,QAAQ,UAAU,CAAC,SAAS,MAAM;EACjD;CACF;CAEA,iBAAiB,aAAa,0BAA0B;EACtD,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;EACjB,iBAAiB;CACnB,CAAC;CAED,gBAAgB,mBAAmB,UAAU,YAAY,CAAC;CAE1D,MAAM,gBAAgB,WACpB,OAAO,kBACP,CAAC,YAAY;GACV,OAAO,gCAAgC,YAAY,mBAAmB;GACtE,OAAO,+BAA+B,YAAY,mBAAmB;GACrE,OAAO,oCAAoC,YAAY,mBAAmB;GAC1E,OAAO,iCAAiC,YAAY,mBAAmB;GACvE,OAAO,mCAAmC;GAC1C,OAAO,6BAA6B;GACpC,OAAO,4BAA4B;CACtC,CACF;CAEA,MAAM,iBAAiB,WAAW,OAAO,mBAAmB,UAAU,OAAO,0BAA0B;CAEvG,MAAM,iBAAiB,MAAM,SAAS,IAAI,WAAW,OAAO,UAAU;EACpE,MAAM,UAAU;EAEhB,OACE,oBAAC,MAAD;GAAI,WAAW,OAAO;GAAiB,IAAI,GAAG,eAAe,GAAG;GAC7D,UAAA,MAAM,eAAe,OAAO,KAAK,aAAa,WAAW,aAAa,QAAQ,SAC3E,MAAM,aAAa,SAAS,EAC1B,KAAK,UAAU,CAAC,QAAQ,MAAM,KAAK,aAAa,QAAQ,MAAM,CAAC,EACjE,CAAC,IACD;EACF,CAAA;CAER,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAW,OAAO;EAAU,KAAK;EAAtC,UAAA;GACE,oBAAC,QAAD;IAAM,IAAI;IAAS,WAAW,OAAO;IAClC,UAAA;GACG,CAAA;GACN,qBAAC,UAAD;IACE,MAAK;IACL,eAA6B,WAAW,KAAK;IAC7C,WAAW;IACX,KAAK;IACL,eAAa;IACb,oBAAkB,YAAY;IACpB;IACV,mBAAiB;IACjB,iBAAe;IACf,iBAAe;IACf,iBAAe;IAXjB,UAAA,CAaE,oBAAC,QAAD;KAAM,IAAI;KAAe,WAAW,OAAO;KACxC,UAAA;IACG,CAAA,GACN,oBAAC,cAAD;KACE,OAAO,WAAW,MAAM,QAAQ,aAAa,MAAM,QAAQ;KAC3D,SAAS;KACT,WAAW,OAAO;KAClB,WAAW,CAAC,YAAY;KACxB,MAAM,SAAS;IAChB,CAAA,CACK;;GACR,qBAAC,OAAD;IACE,IAAI;IACJ,WAAW;IACX,OAAO;KAAE,OAAO,QAAQ,SAAS;KAAQ,UAAU,oBAAoB;KAAgB;IAAO;IAHhG,UAAA,CAKE,oBAAC,MAAD;KAAI,WAAW,OAAO;KAAmB,MAAK;KAAQ,mBAAiB;KAAS,UAAU;KAAI,KAAK;KAChG,UAAA;IACC,CAAA,GACH,CAAC,iBACA,oBAAC,OAAD;KAAK,WAAW,OAAO;KACrB,UAAA,oBAAC,gBAAD;MAAQ,SAAS;MAAc,UAAA,gBAAgB;KAAkB,CAAA;IAC9D,CAAA,CAEJ;;EACF;;AAET;;;AC7OA,IAAA,sBAAe"}
|
|
@@ -223,9 +223,7 @@ var EmptyState = (props) => {
|
|
|
223
223
|
case "oncherry":
|
|
224
224
|
color = "cherry";
|
|
225
225
|
break;
|
|
226
|
-
default:
|
|
227
|
-
color = "neutral";
|
|
228
|
-
break;
|
|
226
|
+
default: color = "neutral";
|
|
229
227
|
}
|
|
230
228
|
let illustrationComponent;
|
|
231
229
|
if (size === "compact") illustrationComponent = /* @__PURE__ */ jsx(Icon_default, {
|