@danske/sapphire-react-lab 0.105.2 → 0.106.2
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/build/cjs/index.js +1607 -2284
- package/build/cjs/index.js.map +1 -1
- package/build/esm/Accordion/index.js.map +1 -1
- package/build/esm/Accordion/src/Accordion.js +44 -75
- package/build/esm/Accordion/src/Accordion.js.map +1 -1
- package/build/esm/Accordion/src/AccordionContext.js +3 -1
- package/build/esm/Accordion/src/AccordionContext.js.map +1 -1
- package/build/esm/Accordion/src/AccordionHeading.js +23 -55
- package/build/esm/Accordion/src/AccordionHeading.js.map +1 -1
- package/build/esm/Accordion/src/AccordionItem.js +18 -44
- package/build/esm/Accordion/src/AccordionItem.js.map +1 -1
- package/build/esm/Accordion/src/AccordionPanel.js +28 -45
- package/build/esm/Accordion/src/AccordionPanel.js.map +1 -1
- package/build/esm/Accordion/src/utils.js.map +1 -1
- package/build/esm/Alert/src/Alert.js +27 -65
- package/build/esm/Alert/src/Alert.js.map +1 -1
- package/build/esm/Amount/src/Amount.js +41 -63
- package/build/esm/Amount/src/Amount.js.map +1 -1
- package/build/esm/Amount/src/useGroupAmount.js +4 -1
- package/build/esm/Amount/src/useGroupAmount.js.map +1 -1
- package/build/esm/Autocomplete/i18n/da-DK.json.js +6 -0
- package/build/esm/Autocomplete/i18n/da-DK.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/de-DE.json.js +6 -0
- package/build/esm/Autocomplete/i18n/de-DE.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/en-US.json.js +6 -0
- package/build/esm/Autocomplete/i18n/en-US.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/fi-FI.json.js +6 -0
- package/build/esm/Autocomplete/i18n/fi-FI.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/index.js +9 -9
- package/build/esm/Autocomplete/i18n/index.js.map +1 -1
- package/build/esm/Autocomplete/i18n/nb-NO.json.js +6 -0
- package/build/esm/Autocomplete/i18n/nb-NO.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/pl-PL.json.js +6 -0
- package/build/esm/Autocomplete/i18n/pl-PL.json.js.map +1 -0
- package/build/esm/Autocomplete/i18n/sv-SE.json.js +6 -0
- package/build/esm/Autocomplete/i18n/sv-SE.json.js.map +1 -0
- package/build/esm/Autocomplete/src/Autocomplete.js +57 -76
- package/build/esm/Autocomplete/src/Autocomplete.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItem.js +46 -52
- package/build/esm/Breadcrumbs/src/BreadcrumbItem.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemLink.js +17 -45
- package/build/esm/Breadcrumbs/src/BreadcrumbItemLink.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js +25 -46
- package/build/esm/Breadcrumbs/src/BreadcrumbItemStatic.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbOverflowMenu.js +18 -11
- package/build/esm/Breadcrumbs/src/BreadcrumbOverflowMenu.js.map +1 -1
- package/build/esm/Breadcrumbs/src/Breadcrumbs.js +47 -64
- package/build/esm/Breadcrumbs/src/Breadcrumbs.js.map +1 -1
- package/build/esm/Breadcrumbs/src/BreadcrumbsSeparator.js +8 -6
- package/build/esm/Breadcrumbs/src/BreadcrumbsSeparator.js.map +1 -1
- package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js +6 -6
- package/build/esm/Breadcrumbs/src/useBreadcrumbThreshold.js.map +1 -1
- package/build/esm/FileDropzone/i18n/{da-DK.js → da-DK.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/da-DK.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/{de-DE.js → de-DE.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/de-DE.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/{en-US.js → en-US.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/en-US.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/{fi-FI.js → fi-FI.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/fi-FI.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/index.js +9 -9
- package/build/esm/FileDropzone/i18n/index.js.map +1 -1
- package/build/esm/FileDropzone/i18n/{nb-NO.js → nb-NO.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/nb-NO.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/{pl-PL.js → pl-PL.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/pl-PL.json.js.map +1 -0
- package/build/esm/FileDropzone/i18n/{sv-SE.js → sv-SE.json.js} +3 -3
- package/build/esm/FileDropzone/i18n/sv-SE.json.js.map +1 -0
- package/build/esm/FileDropzone/src/FileDropzone.js +68 -88
- package/build/esm/FileDropzone/src/FileDropzone.js.map +1 -1
- package/build/esm/FileDropzone/src/FileTrigger.js +29 -61
- package/build/esm/FileDropzone/src/FileTrigger.js.map +1 -1
- package/build/esm/FileDropzone/src/utils.js.map +1 -1
- package/build/esm/Filtering/src/FilterDropdown.js +91 -113
- package/build/esm/Filtering/src/FilterDropdown.js.map +1 -1
- package/build/esm/Filtering/src/SearchableSelectFilter.js +53 -70
- package/build/esm/Filtering/src/SearchableSelectFilter.js.map +1 -1
- package/build/esm/Flag/src/Flag.js +5 -37
- package/build/esm/Flag/src/Flag.js.map +1 -1
- package/build/esm/LabeledValue/src/LabeledValue.js +21 -55
- package/build/esm/LabeledValue/src/LabeledValue.js.map +1 -1
- package/build/esm/NumberField/i18n/da-DK.json.js +9 -0
- package/build/esm/NumberField/i18n/da-DK.json.js.map +1 -0
- package/build/esm/NumberField/i18n/de-DE.json.js +9 -0
- package/build/esm/NumberField/i18n/de-DE.json.js.map +1 -0
- package/build/esm/NumberField/i18n/en-US.json.js +9 -0
- package/build/esm/NumberField/i18n/en-US.json.js.map +1 -0
- package/build/esm/NumberField/i18n/fi-FI.json.js +9 -0
- package/build/esm/NumberField/i18n/fi-FI.json.js.map +1 -0
- package/build/esm/NumberField/i18n/index.js +9 -9
- package/build/esm/NumberField/i18n/index.js.map +1 -1
- package/build/esm/NumberField/i18n/nb-NO.json.js +9 -0
- package/build/esm/NumberField/i18n/nb-NO.json.js.map +1 -0
- package/build/esm/NumberField/i18n/pl-PL.json.js +9 -0
- package/build/esm/NumberField/i18n/pl-PL.json.js.map +1 -0
- package/build/esm/NumberField/i18n/sv-SE.json.js +9 -0
- package/build/esm/NumberField/i18n/sv-SE.json.js.map +1 -0
- package/build/esm/NumberField/src/NumberField.js +130 -111
- package/build/esm/NumberField/src/NumberField.js.map +1 -1
- package/build/esm/NumberField/src/StepperButton.js +32 -53
- package/build/esm/NumberField/src/StepperButton.js.map +1 -1
- package/build/esm/NumberField/src/cursorHelpers.js +13 -8
- package/build/esm/NumberField/src/cursorHelpers.js.map +1 -1
- package/build/esm/NumberField/src/formatHelpers.js +15 -18
- package/build/esm/NumberField/src/formatHelpers.js.map +1 -1
- package/build/esm/NumberField/src/keyboardHelpers.js +13 -8
- package/build/esm/NumberField/src/keyboardHelpers.js.map +1 -1
- package/build/esm/NumberField/src/useAutofillStyle.js.map +1 -1
- package/build/esm/NumberField/src/useNumberFieldFormatting.js +79 -45
- package/build/esm/NumberField/src/useNumberFieldFormatting.js.map +1 -1
- package/build/esm/NumberField/src/useSapphireNumberField.js +16 -42
- package/build/esm/NumberField/src/useSapphireNumberField.js.map +1 -1
- package/build/esm/ProgressIndicator/src/ProgressIndicator.js +23 -35
- package/build/esm/ProgressIndicator/src/ProgressIndicator.js.map +1 -1
- package/build/esm/Sidebar/index.js.map +1 -1
- package/build/esm/Sidebar/src/Body.js +19 -44
- package/build/esm/Sidebar/src/Body.js.map +1 -1
- package/build/esm/Sidebar/src/ExpandableItem.js +89 -97
- package/build/esm/Sidebar/src/ExpandableItem.js.map +1 -1
- package/build/esm/Sidebar/src/Header.js +14 -44
- package/build/esm/Sidebar/src/Header.js.map +1 -1
- package/build/esm/Sidebar/src/Item.js +17 -44
- package/build/esm/Sidebar/src/Item.js.map +1 -1
- package/build/esm/Sidebar/src/List.js +14 -43
- package/build/esm/Sidebar/src/List.js.map +1 -1
- package/build/esm/Sidebar/src/Panel.js +56 -69
- package/build/esm/Sidebar/src/Panel.js.map +1 -1
- package/build/esm/Sidebar/src/ResponsiveSidebarContext.js +17 -9
- package/build/esm/Sidebar/src/ResponsiveSidebarContext.js.map +1 -1
- package/build/esm/Sidebar/src/SecondarySidebarContext.js +15 -12
- package/build/esm/Sidebar/src/SecondarySidebarContext.js.map +1 -1
- package/build/esm/Sidebar/src/Section.js +38 -51
- package/build/esm/Sidebar/src/Section.js.map +1 -1
- package/build/esm/Sidebar/src/Sidebar.js +65 -93
- package/build/esm/Sidebar/src/Sidebar.js.map +1 -1
- package/build/esm/Sidebar/src/useSidebar.js.map +1 -1
- package/build/esm/Slider/index.js.map +1 -1
- package/build/esm/Slider/src/Slider.js +46 -71
- package/build/esm/Slider/src/Slider.js.map +1 -1
- package/build/esm/TagGroup/src/Tag.js +71 -86
- package/build/esm/TagGroup/src/Tag.js.map +1 -1
- package/build/esm/TagGroup/src/TagGroup.js +46 -67
- package/build/esm/TagGroup/src/TagGroup.js.map +1 -1
- package/build/esm/TagGroup/src/TagItem.js +1 -1
- package/build/esm/TagGroup/src/TagItem.js.map +1 -1
- package/build/esm/TimeField/i18n/da-DK.json.js +7 -0
- package/build/esm/TimeField/i18n/da-DK.json.js.map +1 -0
- package/build/esm/TimeField/i18n/de-DE.json.js +7 -0
- package/build/esm/TimeField/i18n/de-DE.json.js.map +1 -0
- package/build/esm/TimeField/i18n/en-US.json.js +7 -0
- package/build/esm/TimeField/i18n/en-US.json.js.map +1 -0
- package/build/esm/TimeField/i18n/fi-FI.json.js +7 -0
- package/build/esm/TimeField/i18n/fi-FI.json.js.map +1 -0
- package/build/esm/TimeField/i18n/index.js +7 -7
- package/build/esm/TimeField/i18n/index.js.map +1 -1
- package/build/esm/TimeField/i18n/nb-NO.json.js +7 -0
- package/build/esm/TimeField/i18n/nb-NO.json.js.map +1 -0
- package/build/esm/TimeField/i18n/pl-PL.json.js +7 -0
- package/build/esm/TimeField/i18n/pl-PL.json.js.map +1 -0
- package/build/esm/TimeField/i18n/{sv-SE.js → sv-SE.json.js} +1 -1
- package/build/esm/TimeField/i18n/sv-SE.json.js.map +1 -0
- package/build/esm/TimeField/src/TimeField.js +67 -84
- package/build/esm/TimeField/src/TimeField.js.map +1 -1
- package/build/esm/TimeField/src/TimeFieldSegment.js +25 -37
- package/build/esm/TimeField/src/TimeFieldSegment.js.map +1 -1
- package/build/esm/index.js +1 -1
- package/build/index.d.ts +19 -17
- package/package.json +16 -39
- package/build/esm/Autocomplete/i18n/da-DK.js +0 -6
- package/build/esm/Autocomplete/i18n/da-DK.js.map +0 -1
- package/build/esm/Autocomplete/i18n/de-DE.js +0 -6
- package/build/esm/Autocomplete/i18n/de-DE.js.map +0 -1
- package/build/esm/Autocomplete/i18n/en-US.js +0 -6
- package/build/esm/Autocomplete/i18n/en-US.js.map +0 -1
- package/build/esm/Autocomplete/i18n/fi-FI.js +0 -6
- package/build/esm/Autocomplete/i18n/fi-FI.js.map +0 -1
- package/build/esm/Autocomplete/i18n/nb-NO.js +0 -6
- package/build/esm/Autocomplete/i18n/nb-NO.js.map +0 -1
- package/build/esm/Autocomplete/i18n/pl-PL.js +0 -6
- package/build/esm/Autocomplete/i18n/pl-PL.js.map +0 -1
- package/build/esm/Autocomplete/i18n/sv-SE.js +0 -6
- package/build/esm/Autocomplete/i18n/sv-SE.js.map +0 -1
- package/build/esm/FileDropzone/i18n/da-DK.js.map +0 -1
- package/build/esm/FileDropzone/i18n/de-DE.js.map +0 -1
- package/build/esm/FileDropzone/i18n/en-US.js.map +0 -1
- package/build/esm/FileDropzone/i18n/fi-FI.js.map +0 -1
- package/build/esm/FileDropzone/i18n/nb-NO.js.map +0 -1
- package/build/esm/FileDropzone/i18n/pl-PL.js.map +0 -1
- package/build/esm/FileDropzone/i18n/sv-SE.js.map +0 -1
- package/build/esm/NumberField/i18n/da-DK.js +0 -9
- package/build/esm/NumberField/i18n/da-DK.js.map +0 -1
- package/build/esm/NumberField/i18n/de-DE.js +0 -9
- package/build/esm/NumberField/i18n/de-DE.js.map +0 -1
- package/build/esm/NumberField/i18n/en-US.js +0 -9
- package/build/esm/NumberField/i18n/en-US.js.map +0 -1
- package/build/esm/NumberField/i18n/fi-FI.js +0 -9
- package/build/esm/NumberField/i18n/fi-FI.js.map +0 -1
- package/build/esm/NumberField/i18n/nb-NO.js +0 -9
- package/build/esm/NumberField/i18n/nb-NO.js.map +0 -1
- package/build/esm/NumberField/i18n/pl-PL.js +0 -9
- package/build/esm/NumberField/i18n/pl-PL.js.map +0 -1
- package/build/esm/NumberField/i18n/sv-SE.js +0 -9
- package/build/esm/NumberField/i18n/sv-SE.js.map +0 -1
- package/build/esm/TimeField/i18n/da-DK.js +0 -7
- package/build/esm/TimeField/i18n/da-DK.js.map +0 -1
- package/build/esm/TimeField/i18n/de-DE.js +0 -7
- package/build/esm/TimeField/i18n/de-DE.js.map +0 -1
- package/build/esm/TimeField/i18n/en-US.js +0 -7
- package/build/esm/TimeField/i18n/en-US.js.map +0 -1
- package/build/esm/TimeField/i18n/fi-FI.js +0 -7
- package/build/esm/TimeField/i18n/fi-FI.js.map +0 -1
- package/build/esm/TimeField/i18n/nb-NO.js +0 -7
- package/build/esm/TimeField/i18n/nb-NO.js.map +0 -1
- package/build/esm/TimeField/i18n/pl-PL.js +0 -7
- package/build/esm/TimeField/i18n/pl-PL.js.map +0 -1
- package/build/esm/TimeField/i18n/sv-SE.js.map +0 -1
|
@@ -13,19 +13,28 @@ function useNumberFieldFormatting({
|
|
|
13
13
|
onChange,
|
|
14
14
|
autoFormat
|
|
15
15
|
}) {
|
|
16
|
-
const { groupSeparator, decimalSeparator } = useMemo(
|
|
16
|
+
const { groupSeparator, decimalSeparator } = useMemo(
|
|
17
|
+
() => getSeparators(formatter),
|
|
18
|
+
[formatter]
|
|
19
|
+
);
|
|
17
20
|
const [formattedValue, setFormattedValue] = useState("");
|
|
18
|
-
const symbolInfo = useMemo(
|
|
21
|
+
const symbolInfo = useMemo(
|
|
22
|
+
() => extractSymbol(formatter, prefix, postfix),
|
|
23
|
+
[formatter, prefix, postfix]
|
|
24
|
+
);
|
|
19
25
|
const { extractedPrefix, extractedPostfix, symbol } = symbolInfo;
|
|
20
26
|
const cursorPositionRef = useRef(null);
|
|
21
27
|
const displayValue = useMemo(() => {
|
|
22
|
-
const numericValue = parseNumericValue(
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
const numericValue = parseNumericValue(
|
|
29
|
+
inputValue,
|
|
30
|
+
decimalSeparator,
|
|
31
|
+
formatter
|
|
32
|
+
);
|
|
33
|
+
if (numericValue === null) return inputValue;
|
|
25
34
|
try {
|
|
26
35
|
const trimmedValue = trimSymbol(inputValue, symbol) || inputValue;
|
|
27
36
|
return autoFormat ? formattedValue || trimmedValue : trimmedValue;
|
|
28
|
-
} catch
|
|
37
|
+
} catch {
|
|
29
38
|
return inputValue;
|
|
30
39
|
}
|
|
31
40
|
}, [
|
|
@@ -38,49 +47,74 @@ function useNumberFieldFormatting({
|
|
|
38
47
|
]);
|
|
39
48
|
useLayoutEffect(() => {
|
|
40
49
|
if (cursorPositionRef.current !== null && inputRef.current) {
|
|
41
|
-
inputRef.current.setSelectionRange(
|
|
50
|
+
inputRef.current.setSelectionRange(
|
|
51
|
+
cursorPositionRef.current,
|
|
52
|
+
cursorPositionRef.current
|
|
53
|
+
);
|
|
42
54
|
cursorPositionRef.current = null;
|
|
43
55
|
}
|
|
44
56
|
}, [displayValue, inputRef]);
|
|
45
|
-
const handleInput = useCallback(
|
|
46
|
-
|
|
47
|
-
return;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
const handleInput = useCallback(
|
|
58
|
+
(e) => {
|
|
59
|
+
if (!autoFormat) return;
|
|
60
|
+
const input = e.currentTarget;
|
|
61
|
+
const { value, selectionStart } = input;
|
|
62
|
+
const inputType = e.nativeEvent.inputType || "";
|
|
63
|
+
const shouldStrip = !!symbol;
|
|
64
|
+
const maxFractionDigits = formatter.resolvedOptions().maximumFractionDigits || 0;
|
|
65
|
+
const decimalIndex = value.indexOf(decimalSeparator);
|
|
66
|
+
if (decimalIndex !== -1 && selectionStart !== null) {
|
|
67
|
+
const decimalPart = value.slice(decimalIndex + 1).replace(new RegExp(`[^0-9]`, "g"), "");
|
|
68
|
+
const prevDecimalIndex = displayValue.indexOf(decimalSeparator);
|
|
69
|
+
const prevDecimalLength = prevDecimalIndex !== -1 ? displayValue.slice(prevDecimalIndex + 1).length : 0;
|
|
70
|
+
if (decimalPart.length > maxFractionDigits && selectionStart > decimalIndex + 1 + prevDecimalLength) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
cursorPositionRef.current = decimalIndex + 1 + prevDecimalLength;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
const formattedValue2 = formatNumberString(
|
|
77
|
+
value,
|
|
78
|
+
formatter,
|
|
79
|
+
decimalSeparator,
|
|
80
|
+
shouldStrip,
|
|
81
|
+
symbol
|
|
82
|
+
);
|
|
83
|
+
setFormattedValue(formattedValue2);
|
|
84
|
+
const numericValue = parseNumericValue(
|
|
85
|
+
formattedValue2,
|
|
86
|
+
decimalSeparator,
|
|
87
|
+
formatter
|
|
88
|
+
);
|
|
89
|
+
if (formattedValue2 !== value && formattedValue2 !== "" && selectionStart !== null) {
|
|
90
|
+
const newCursorPosition = calculateCursorPosition(
|
|
91
|
+
value,
|
|
92
|
+
formattedValue2,
|
|
93
|
+
selectionStart,
|
|
94
|
+
inputType,
|
|
95
|
+
decimalSeparator,
|
|
96
|
+
numericValue
|
|
97
|
+
);
|
|
98
|
+
cursorPositionRef.current = newCursorPosition;
|
|
99
|
+
}
|
|
100
|
+
if (numericValue !== null) {
|
|
101
|
+
onChange?.(numericValue);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
[formatter, decimalSeparator, symbol, autoFormat, displayValue, onChange]
|
|
105
|
+
);
|
|
106
|
+
const handleKeyDown = useCallback(
|
|
107
|
+
(e) => {
|
|
108
|
+
handleNumberFieldKeyDown({
|
|
109
|
+
event: e,
|
|
110
|
+
inputRef,
|
|
111
|
+
groupSeparator,
|
|
112
|
+
decimalSeparator,
|
|
113
|
+
onOriginalKeyDown
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
[groupSeparator, decimalSeparator, inputRef, onOriginalKeyDown]
|
|
117
|
+
);
|
|
84
118
|
return {
|
|
85
119
|
displayValue,
|
|
86
120
|
extractedPrefix,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNumberFieldFormatting.js","sources":["../../../../src/NumberField/src/useNumberFieldFormatting.ts"],"sourcesContent":["import {\n useMemo,\n useCallback,\n RefObject,\n ReactNode,\n useRef,\n useLayoutEffect,\n useState,\n} from 'react';\nimport {\n getSeparators,\n parseNumericValue,\n formatNumberString,\n trimSymbol,\n extractSymbol,\n} from './formatHelpers';\nimport { calculateCursorPosition } from './cursorHelpers';\nimport { handleNumberFieldKeyDown } from './keyboardHelpers';\n\ninterface UseNumberFieldFormattingParams {\n inputRef: RefObject<HTMLInputElement>;\n formatter: Intl.NumberFormat;\n inputValue: string;\n prefix?: ReactNode;\n postfix?: ReactNode;\n onOriginalKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: (value: number) => void;\n autoFormat: boolean;\n}\n\ninterface UseNumberFieldFormattingReturn {\n displayValue: string;\n extractedPrefix: ReactNode;\n extractedPostfix: ReactNode;\n handleInput: (e: React.FormEvent<HTMLInputElement>) => void;\n handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\n/**\n * Hook for number field formatting with locale-aware separators and cursor management.\n * Handles currency/unit extraction, number formatting, and maintains correct cursor position.\n * When autoFormat is false, returns original values without any computation.\n */\nexport function useNumberFieldFormatting({\n inputRef,\n formatter,\n inputValue,\n prefix,\n postfix,\n onOriginalKeyDown,\n onChange,\n autoFormat,\n}: UseNumberFieldFormattingParams): UseNumberFieldFormattingReturn {\n const { groupSeparator, decimalSeparator } = useMemo(\n () => getSeparators(formatter),\n [formatter]\n );\n\n const [formattedValue, setFormattedValue] = useState<string>('');\n\n // Extract and position currency/unit symbols\n const symbolInfo = useMemo(\n () => extractSymbol(formatter, prefix, postfix),\n [formatter, prefix, postfix]\n );\n\n const { extractedPrefix, extractedPostfix, symbol } = symbolInfo;\n\n // Track cursor position to restore after React updates the value\n const cursorPositionRef = useRef<number | null>(null);\n\n // Format the input value for display\n const displayValue = useMemo(() => {\n const numericValue = parseNumericValue(\n inputValue,\n decimalSeparator,\n formatter\n );\n if (numericValue === null) return inputValue;\n\n try {\n const trimmedValue = trimSymbol(inputValue, symbol) || inputValue;\n return autoFormat ? formattedValue || trimmedValue : trimmedValue;\n } catch {\n return inputValue;\n }\n }, [\n inputValue,\n symbol,\n formatter,\n decimalSeparator,\n autoFormat,\n formattedValue,\n ]);\n\n // Restore cursor position after value changes\n useLayoutEffect(() => {\n if (cursorPositionRef.current !== null && inputRef.current) {\n inputRef.current.setSelectionRange(\n cursorPositionRef.current,\n cursorPositionRef.current\n );\n cursorPositionRef.current = null;\n }\n }, [displayValue, inputRef]);\n\n // Handle input with formatting and cursor management\n const handleInput = useCallback(\n (e: React.FormEvent<HTMLInputElement>): void => {\n if (!autoFormat) return;\n\n const input = e.currentTarget;\n const { value, selectionStart } = input;\n const inputType = (e.nativeEvent as InputEvent).inputType || '';\n const shouldStrip = !!symbol;\n\n /**\n * Check if we're exceeding maximum decimal places when typing at the end.\n * For example, with max 2 decimals, having \"12,34|\" and typing \"5\" should be prevented.\n */\n //#region Prevent excess decimals\n const maxFractionDigits =\n formatter.resolvedOptions().maximumFractionDigits || 0;\n const decimalIndex = value.indexOf(decimalSeparator);\n\n if (decimalIndex !== -1 && selectionStart !== null) {\n // Count decimal digits in the new value\n const decimalPart = value\n .slice(decimalIndex + 1)\n .replace(new RegExp(`[^0-9]`, 'g'), '');\n const prevDecimalIndex = displayValue.indexOf(decimalSeparator);\n const prevDecimalLength =\n prevDecimalIndex !== -1\n ? displayValue.slice(prevDecimalIndex + 1).length\n : 0;\n\n // If we have more decimals than allowed and cursor was at the end of decimals, prevent and restore\n if (\n decimalPart.length > maxFractionDigits &&\n selectionStart > decimalIndex + 1 + prevDecimalLength\n ) {\n e.preventDefault();\n // Store cursor position to restore after React's update\n cursorPositionRef.current = decimalIndex + 1 + prevDecimalLength;\n return;\n }\n }\n //#endregion Prevent excess decimals\n\n const formattedValue = formatNumberString(\n value,\n formatter,\n decimalSeparator,\n shouldStrip,\n symbol\n );\n\n setFormattedValue(formattedValue);\n\n const numericValue = parseNumericValue(\n formattedValue,\n decimalSeparator,\n formatter\n );\n\n // Calculate and store cursor position for restoration after React's update\n if (\n formattedValue !== value &&\n formattedValue !== '' &&\n selectionStart !== null\n ) {\n const newCursorPosition = calculateCursorPosition(\n value,\n formattedValue,\n selectionStart,\n inputType,\n decimalSeparator,\n numericValue\n );\n\n cursorPositionRef.current = newCursorPosition;\n }\n\n if (numericValue !== null) {\n onChange?.(numericValue);\n }\n },\n [formatter, decimalSeparator, symbol, autoFormat, displayValue, onChange]\n );\n\n // Handle keydown for special key behaviors\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>): void => {\n handleNumberFieldKeyDown({\n event: e,\n inputRef,\n groupSeparator,\n decimalSeparator,\n onOriginalKeyDown,\n });\n },\n [groupSeparator, decimalSeparator, inputRef, onOriginalKeyDown]\n );\n\n return {\n displayValue,\n extractedPrefix,\n extractedPostfix,\n handleInput,\n handleKeyDown,\n };\n}\n"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"useNumberFieldFormatting.js","sources":["../../../../src/NumberField/src/useNumberFieldFormatting.ts"],"sourcesContent":["import {\n useMemo,\n useCallback,\n RefObject,\n ReactNode,\n useRef,\n useLayoutEffect,\n useState,\n} from 'react';\nimport {\n getSeparators,\n parseNumericValue,\n formatNumberString,\n trimSymbol,\n extractSymbol,\n} from './formatHelpers';\nimport { calculateCursorPosition } from './cursorHelpers';\nimport { handleNumberFieldKeyDown } from './keyboardHelpers';\n\ninterface UseNumberFieldFormattingParams {\n inputRef: RefObject<HTMLInputElement>;\n formatter: Intl.NumberFormat;\n inputValue: string;\n prefix?: ReactNode;\n postfix?: ReactNode;\n onOriginalKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: (value: number) => void;\n autoFormat: boolean;\n}\n\ninterface UseNumberFieldFormattingReturn {\n displayValue: string;\n extractedPrefix: ReactNode;\n extractedPostfix: ReactNode;\n handleInput: (e: React.FormEvent<HTMLInputElement>) => void;\n handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\n/**\n * Hook for number field formatting with locale-aware separators and cursor management.\n * Handles currency/unit extraction, number formatting, and maintains correct cursor position.\n * When autoFormat is false, returns original values without any computation.\n */\nexport function useNumberFieldFormatting({\n inputRef,\n formatter,\n inputValue,\n prefix,\n postfix,\n onOriginalKeyDown,\n onChange,\n autoFormat,\n}: UseNumberFieldFormattingParams): UseNumberFieldFormattingReturn {\n const { groupSeparator, decimalSeparator } = useMemo(\n () => getSeparators(formatter),\n [formatter]\n );\n\n const [formattedValue, setFormattedValue] = useState<string>('');\n\n // Extract and position currency/unit symbols\n const symbolInfo = useMemo(\n () => extractSymbol(formatter, prefix, postfix),\n [formatter, prefix, postfix]\n );\n\n const { extractedPrefix, extractedPostfix, symbol } = symbolInfo;\n\n // Track cursor position to restore after React updates the value\n const cursorPositionRef = useRef<number | null>(null);\n\n // Format the input value for display\n const displayValue = useMemo(() => {\n const numericValue = parseNumericValue(\n inputValue,\n decimalSeparator,\n formatter\n );\n if (numericValue === null) return inputValue;\n\n try {\n const trimmedValue = trimSymbol(inputValue, symbol) || inputValue;\n return autoFormat ? formattedValue || trimmedValue : trimmedValue;\n } catch {\n return inputValue;\n }\n }, [\n inputValue,\n symbol,\n formatter,\n decimalSeparator,\n autoFormat,\n formattedValue,\n ]);\n\n // Restore cursor position after value changes\n useLayoutEffect(() => {\n if (cursorPositionRef.current !== null && inputRef.current) {\n inputRef.current.setSelectionRange(\n cursorPositionRef.current,\n cursorPositionRef.current\n );\n cursorPositionRef.current = null;\n }\n }, [displayValue, inputRef]);\n\n // Handle input with formatting and cursor management\n const handleInput = useCallback(\n (e: React.FormEvent<HTMLInputElement>): void => {\n if (!autoFormat) return;\n\n const input = e.currentTarget;\n const { value, selectionStart } = input;\n const inputType = (e.nativeEvent as InputEvent).inputType || '';\n const shouldStrip = !!symbol;\n\n /**\n * Check if we're exceeding maximum decimal places when typing at the end.\n * For example, with max 2 decimals, having \"12,34|\" and typing \"5\" should be prevented.\n */\n //#region Prevent excess decimals\n const maxFractionDigits =\n formatter.resolvedOptions().maximumFractionDigits || 0;\n const decimalIndex = value.indexOf(decimalSeparator);\n\n if (decimalIndex !== -1 && selectionStart !== null) {\n // Count decimal digits in the new value\n const decimalPart = value\n .slice(decimalIndex + 1)\n .replace(new RegExp(`[^0-9]`, 'g'), '');\n const prevDecimalIndex = displayValue.indexOf(decimalSeparator);\n const prevDecimalLength =\n prevDecimalIndex !== -1\n ? displayValue.slice(prevDecimalIndex + 1).length\n : 0;\n\n // If we have more decimals than allowed and cursor was at the end of decimals, prevent and restore\n if (\n decimalPart.length > maxFractionDigits &&\n selectionStart > decimalIndex + 1 + prevDecimalLength\n ) {\n e.preventDefault();\n // Store cursor position to restore after React's update\n cursorPositionRef.current = decimalIndex + 1 + prevDecimalLength;\n return;\n }\n }\n //#endregion Prevent excess decimals\n\n const formattedValue = formatNumberString(\n value,\n formatter,\n decimalSeparator,\n shouldStrip,\n symbol\n );\n\n setFormattedValue(formattedValue);\n\n const numericValue = parseNumericValue(\n formattedValue,\n decimalSeparator,\n formatter\n );\n\n // Calculate and store cursor position for restoration after React's update\n if (\n formattedValue !== value &&\n formattedValue !== '' &&\n selectionStart !== null\n ) {\n const newCursorPosition = calculateCursorPosition(\n value,\n formattedValue,\n selectionStart,\n inputType,\n decimalSeparator,\n numericValue\n );\n\n cursorPositionRef.current = newCursorPosition;\n }\n\n if (numericValue !== null) {\n onChange?.(numericValue);\n }\n },\n [formatter, decimalSeparator, symbol, autoFormat, displayValue, onChange]\n );\n\n // Handle keydown for special key behaviors\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>): void => {\n handleNumberFieldKeyDown({\n event: e,\n inputRef,\n groupSeparator,\n decimalSeparator,\n onOriginalKeyDown,\n });\n },\n [groupSeparator, decimalSeparator, inputRef, onOriginalKeyDown]\n );\n\n return {\n displayValue,\n extractedPrefix,\n extractedPostfix,\n handleInput,\n handleKeyDown,\n };\n}\n"],"names":["formattedValue"],"mappings":"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"}
|
|
@@ -1,48 +1,22 @@
|
|
|
1
|
-
import { useNumberField } from '
|
|
2
|
-
import { useNumberFieldState } from '
|
|
3
|
-
import { useLocale } from '
|
|
1
|
+
import { useNumberField } from 'react-aria/useNumberField';
|
|
2
|
+
import { useNumberFieldState } from 'react-stately/useNumberFieldState';
|
|
3
|
+
import { useLocale } from 'react-aria/I18nProvider';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
var __defProps = Object.defineProperties;
|
|
7
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
8
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
-
var __spreadValues = (a, b) => {
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
22
|
-
};
|
|
23
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
-
var __objRest = (source, exclude) => {
|
|
25
|
-
var target = {};
|
|
26
|
-
for (var prop in source)
|
|
27
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
-
target[prop] = source[prop];
|
|
29
|
-
if (source != null && __getOwnPropSymbols)
|
|
30
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
-
target[prop] = source[prop];
|
|
33
|
-
}
|
|
34
|
-
return target;
|
|
35
|
-
};
|
|
36
|
-
const useSapphireNumberField = (_a, ref) => {
|
|
37
|
-
var _b = _a, { error } = _b, numberFieldProps = __objRest(_b, ["error"]);
|
|
5
|
+
const useSapphireNumberField = ({ error, ...numberFieldProps }, ref) => {
|
|
38
6
|
const { locale } = useLocale();
|
|
39
|
-
const numberFieldState = useNumberFieldState(
|
|
7
|
+
const numberFieldState = useNumberFieldState({
|
|
8
|
+
...numberFieldProps,
|
|
40
9
|
locale
|
|
41
|
-
})
|
|
42
|
-
const numberFieldAria = useNumberField(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
10
|
+
});
|
|
11
|
+
const numberFieldAria = useNumberField(
|
|
12
|
+
{
|
|
13
|
+
...numberFieldProps,
|
|
14
|
+
validationState: error === false || error === void 0 ? void 0 : "invalid"
|
|
15
|
+
},
|
|
16
|
+
numberFieldState,
|
|
17
|
+
ref
|
|
18
|
+
);
|
|
19
|
+
return { ...numberFieldAria, state: numberFieldState };
|
|
46
20
|
};
|
|
47
21
|
|
|
48
22
|
export { useSapphireNumberField };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSapphireNumberField.js","sources":["../../../../src/NumberField/src/useSapphireNumberField.ts"],"sourcesContent":["import React, { RefObject } from 'react';\nimport {\n AriaNumberFieldProps,\n NumberFieldAria,\n useNumberField,\n} from '
|
|
1
|
+
{"version":3,"file":"useSapphireNumberField.js","sources":["../../../../src/NumberField/src/useSapphireNumberField.ts"],"sourcesContent":["import React, { RefObject } from 'react';\nimport {\n AriaNumberFieldProps,\n NumberFieldAria,\n useNumberField,\n} from 'react-aria/useNumberField';\nimport { useNumberFieldState } from 'react-stately/useNumberFieldState';\nimport { useLocale } from 'react-aria/I18nProvider';\n\nexport interface SapphireNumberFieldProps\n // TODO: when this is moved to `core`, we can replace the picked props with `ValueBasePropsKeys`\n extends Pick<\n AriaNumberFieldProps,\n | 'label'\n | 'isDisabled'\n | 'isRequired'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'incrementAriaLabel'\n | 'decrementAriaLabel'\n | 'onFocus'\n | 'onBlur'\n | 'formatOptions'\n | 'step'\n | 'minValue'\n | 'maxValue'\n | 'placeholder'\n | 'isReadOnly'\n | 'autoFocus'\n | 'onFocusChange'\n | 'onKeyUp'\n | 'onKeyDown'\n > {\n /**\n * Whether the input should render as having an error and an error message.\n * This also sets the appropriate `aria` attributes on the input.\n *\n * A `boolean` sets the error state.\n * A `ReactNode` sets the error state with an additional error message.\n *\n * **An error message is strongly recommended because an error should always have an explanation about how to fix it.**\n */\n error?: boolean | React.ReactNode;\n}\n\nexport const useSapphireNumberField = (\n { error, ...numberFieldProps }: SapphireNumberFieldProps,\n ref: RefObject<HTMLInputElement>\n): NumberFieldAria & { state: ReturnType<typeof useNumberFieldState> } => {\n const { locale } = useLocale();\n const numberFieldState = useNumberFieldState({\n ...numberFieldProps,\n locale,\n });\n const numberFieldAria = useNumberField(\n {\n ...numberFieldProps,\n validationState:\n error === false || error === undefined ? undefined : 'invalid',\n },\n numberFieldState,\n ref\n );\n\n return { ...numberFieldAria, state: numberFieldState };\n};\n"],"names":[],"mappings":";;;;AA8CO,MAAM,yBAAyB,CACpC,EAAE,OAAO,GAAG,gBAAA,IACZ,GAAA,KACwE;AACxE,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,mBAAmB,mBAAA,CAAoB;AAAA,IAC3C,GAAG,gBAAA;AAAA,IACH;AAAA,GACD,CAAA;AACD,EAAA,MAAM,eAAA,GAAkB,cAAA;AAAA,IACtB;AAAA,MACE,GAAG,gBAAA;AAAA,MACH,eAAA,EACE,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,SAAY,MAAA,GAAY;AAAA,KACzD;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,GAAG,eAAA,EAAiB,KAAA,EAAO,gBAAA,EAAiB;AACvD;;;;"}
|
|
@@ -2,28 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';
|
|
4
4
|
import { useThemeCheck, useSapphireStyleProps } from '@danske/sapphire-react';
|
|
5
|
-
import { useProgressBar } from '
|
|
6
|
-
import { filterDOMProps } from '
|
|
5
|
+
import { useProgressBar } from 'react-aria/useProgressBar';
|
|
6
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
7
7
|
|
|
8
|
-
var __defProp = Object.defineProperty;
|
|
9
|
-
var __defProps = Object.defineProperties;
|
|
10
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
11
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
12
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
13
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
14
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
15
|
-
var __spreadValues = (a, b) => {
|
|
16
|
-
for (var prop in b || (b = {}))
|
|
17
|
-
if (__hasOwnProp.call(b, prop))
|
|
18
|
-
__defNormalProp(a, prop, b[prop]);
|
|
19
|
-
if (__getOwnPropSymbols)
|
|
20
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
21
|
-
if (__propIsEnum.call(b, prop))
|
|
22
|
-
__defNormalProp(a, prop, b[prop]);
|
|
23
|
-
}
|
|
24
|
-
return a;
|
|
25
|
-
};
|
|
26
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
27
8
|
const ProgressIndicator = (props) => {
|
|
28
9
|
const {
|
|
29
10
|
maxValue = 100,
|
|
@@ -33,25 +14,32 @@ const ProgressIndicator = (props) => {
|
|
|
33
14
|
} = props;
|
|
34
15
|
useThemeCheck();
|
|
35
16
|
const { styleProps } = useSapphireStyleProps(props);
|
|
36
|
-
const { progressBarProps } = useProgressBar(
|
|
17
|
+
const { progressBarProps } = useProgressBar({
|
|
18
|
+
...props,
|
|
37
19
|
minValue: 0,
|
|
38
20
|
valueLabel: ariaValueText
|
|
39
|
-
})
|
|
21
|
+
});
|
|
40
22
|
const minValue = 0;
|
|
41
23
|
const value = Math.min(Math.max(realValue, minValue), maxValue);
|
|
42
24
|
const widthPercentage = value / maxValue * 100;
|
|
43
|
-
return /* @__PURE__ */ React.createElement(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
25
|
+
return /* @__PURE__ */ React.createElement(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
...filterDOMProps(props, { global: true }),
|
|
29
|
+
className: clsx(styles["sapphire-progress"])
|
|
30
|
+
},
|
|
31
|
+
/* @__PURE__ */ React.createElement(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
...progressBarProps,
|
|
35
|
+
className: styles["sapphire-progress--indicator"],
|
|
36
|
+
style: { ...styleProps, width: `${widthPercentage}%` },
|
|
37
|
+
"aria-label": "aria-label" in props ? props["aria-label"] : void 0,
|
|
38
|
+
"aria-labelledby": "aria-labelledby" in props ? props["aria-labelledby"] : void 0
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
segments > 1 && /* @__PURE__ */ React.createElement("div", { className: styles["sapphire-progress--segments"] }, Array.from({ length: segments }, (_, index) => /* @__PURE__ */ React.createElement("span", { key: index })))
|
|
42
|
+
);
|
|
55
43
|
};
|
|
56
44
|
|
|
57
45
|
export { ProgressIndicator };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressIndicator.js","sources":["../../../../src/ProgressIndicator/src/ProgressIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';\nimport {\n SapphireStyleProps,\n useThemeCheck,\n useSapphireStyleProps,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { useProgressBar } from '
|
|
1
|
+
{"version":3,"file":"ProgressIndicator.js","sources":["../../../../src/ProgressIndicator/src/ProgressIndicator.tsx"],"sourcesContent":["import React from 'react';\nimport clsx from 'clsx';\nimport styles from '@danske/sapphire-css/components/progressIndicator/progressIndicator.module.css';\nimport {\n SapphireStyleProps,\n useThemeCheck,\n useSapphireStyleProps,\n GlobalDomAttributes,\n} from '@danske/sapphire-react';\nimport { useProgressBar } from 'react-aria/useProgressBar';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\n\nexport type ProgressIndicatorProps = {\n /**\n * The maximum value for the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuemax\n *\n * @default 100\n */\n maxValue?: number;\n\n /**\n * The current value of the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuenow\n */\n value: number;\n\n /**\n * Defines how many segments the progress bar will have.\n *\n * @default 1\n */\n segments?: number;\n\n /**\n * Human-readable text alternative for the current value of the progress bar. Will be used as:\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-valuetext\n */\n 'aria-valuetext'?: string;\n} & SapphireStyleProps &\n GlobalDomAttributes &\n ({ 'aria-labelledby': string } | { 'aria-label': string });\n\nexport const ProgressIndicator = (\n props: ProgressIndicatorProps\n): JSX.Element => {\n const {\n maxValue = 100,\n value: realValue,\n segments = 1,\n 'aria-valuetext': ariaValueText,\n } = props;\n\n useThemeCheck();\n const { styleProps } = useSapphireStyleProps(props);\n const { progressBarProps } = useProgressBar({\n ...props,\n minValue: 0,\n valueLabel: ariaValueText,\n });\n\n const minValue = 0;\n\n const value = Math.min(Math.max(realValue, minValue), maxValue);\n const widthPercentage = (value / maxValue) * 100;\n\n return (\n <div\n {...filterDOMProps(props, { global: true })}\n className={clsx(styles['sapphire-progress'])}\n >\n <div\n {...progressBarProps}\n className={styles['sapphire-progress--indicator']}\n style={{ ...styleProps, width: `${widthPercentage}%` }}\n aria-label={'aria-label' in props ? props['aria-label'] : undefined}\n aria-labelledby={\n 'aria-labelledby' in props ? props['aria-labelledby'] : undefined\n }\n />\n {segments > 1 && (\n <div className={styles['sapphire-progress--segments']}>\n {Array.from({ length: segments }, (_, index) => (\n <span key={index}></span>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA2CO,MAAM,iBAAA,GAAoB,CAC/B,KAAA,KACgB;AAChB,EAAA,MAAM;AAAA,IACJ,QAAA,GAAW,GAAA;AAAA,IACX,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,GAAW,CAAA;AAAA,IACX,gBAAA,EAAkB;AAAA,GACpB,GAAI,KAAA;AAEJ,EAAA,aAAA,EAAc;AACd,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,qBAAA,CAAsB,KAAK,CAAA;AAClD,EAAA,MAAM,EAAE,gBAAA,EAAiB,GAAI,cAAA,CAAe;AAAA,IAC1C,GAAG,KAAA;AAAA,IACH,QAAA,EAAU,CAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,CAAA;AAEjB,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,SAAA,EAAW,QAAQ,GAAG,QAAQ,CAAA;AAC9D,EAAA,MAAM,eAAA,GAAmB,QAAQ,QAAA,GAAY,GAAA;AAE7C,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC1C,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,mBAAmB,CAAC;AAAA,KAAA;AAAA,oBAE3C,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACE,GAAG,gBAAA;AAAA,QACJ,SAAA,EAAW,OAAO,8BAA8B,CAAA;AAAA,QAChD,OAAO,EAAE,GAAG,YAAY,KAAA,EAAO,CAAA,EAAG,eAAe,CAAA,CAAA,CAAA,EAAI;AAAA,QACrD,YAAA,EAAY,YAAA,IAAgB,KAAA,GAAQ,KAAA,CAAM,YAAY,CAAA,GAAI,MAAA;AAAA,QAC1D,iBAAA,EACE,iBAAA,IAAqB,KAAA,GAAQ,KAAA,CAAM,iBAAiB,CAAA,GAAI;AAAA;AAAA,KAE5D;AAAA,IACC,QAAA,GAAW,qBACV,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,WAAW,MAAA,CAAO,6BAA6B,CAAA,EAAA,EACjD,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAS,EAAG,CAAC,CAAA,EAAG,KAAA,yCACnC,MAAA,EAAA,EAAK,GAAA,EAAK,KAAA,EAAO,CACnB,CACH;AAAA,GAEJ;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/Sidebar/index.ts"],"sourcesContent":["import { Sidebar } from './src/Sidebar';\nimport { SidebarHeader } from './src/Header';\nimport { SidebarItem } from './src/Item';\nimport { SidebarExpandableItem } from './src/ExpandableItem';\nimport { SidebarSection } from './src/Section';\nimport { SidebarBody } from './src/Body';\nimport { SidebarList } from './src/List';\nimport { ResponsiveSidebarProvider } from './src/ResponsiveSidebarContext';\nimport { SidebarPanelTrigger } from './src/Panel';\n\nconst _Sidebar = Object.assign(Sidebar, {\n ResponsiveProvider: ResponsiveSidebarProvider,\n Header: SidebarHeader,\n Body: SidebarBody,\n List: SidebarList,\n Item: SidebarItem,\n ExpandableItem: SidebarExpandableItem,\n Section: SidebarSection,\n PanelTrigger: SidebarPanelTrigger,\n});\n\nexport { _Sidebar as Sidebar };\nexport { type SidebarProps } from './src/Sidebar';\nexport { type SidebarItemProps } from './src/Item';\nexport { type SidebarExpandableItemProps } from './src/ExpandableItem';\nexport { type SidebarSectionProps } from './src/Section';\nexport { type SidebarBodyProps } from './src/Body';\nexport { type SidebarListProps } from './src/List';\nexport { type SidebarHeaderProps } from './src/Header';\n"],"names":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/Sidebar/index.ts"],"sourcesContent":["import { Sidebar } from './src/Sidebar';\nimport { SidebarHeader } from './src/Header';\nimport { SidebarItem } from './src/Item';\nimport { SidebarExpandableItem } from './src/ExpandableItem';\nimport { SidebarSection } from './src/Section';\nimport { SidebarBody } from './src/Body';\nimport { SidebarList } from './src/List';\nimport { ResponsiveSidebarProvider } from './src/ResponsiveSidebarContext';\nimport { SidebarPanelTrigger } from './src/Panel';\n\nconst _Sidebar = Object.assign(Sidebar, {\n ResponsiveProvider: ResponsiveSidebarProvider,\n Header: SidebarHeader,\n Body: SidebarBody,\n List: SidebarList,\n Item: SidebarItem,\n ExpandableItem: SidebarExpandableItem,\n Section: SidebarSection,\n PanelTrigger: SidebarPanelTrigger,\n});\n\nexport { _Sidebar as Sidebar };\nexport { type SidebarProps } from './src/Sidebar';\nexport { type SidebarItemProps } from './src/Item';\nexport { type SidebarExpandableItemProps } from './src/ExpandableItem';\nexport { type SidebarSectionProps } from './src/Section';\nexport { type SidebarBodyProps } from './src/Body';\nexport { type SidebarListProps } from './src/List';\nexport { type SidebarHeaderProps } from './src/Header';\n"],"names":[],"mappings":";;;;;;;;;;AAUA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,OAAA,EAAS;AAAA,EACtC,kBAAA,EAAoB,yBAAA;AAAA,EACpB,MAAA,EAAQ,aAAA;AAAA,EACR,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,WAAA;AAAA,EACN,cAAA,EAAgB,qBAAA;AAAA,EAChB,OAAA,EAAS,cAAA;AAAA,EACT,YAAA,EAAc;AAChB,CAAC;;;;"}
|
|
@@ -1,55 +1,30 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import { filterDOMProps } from '
|
|
3
|
+
import { filterDOMProps } from 'react-aria/filterDOMProps';
|
|
4
4
|
import styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';
|
|
5
5
|
import { useScrollCheck } from '@danske/sapphire-react';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var __spreadValues = (a, b) => {
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
22
|
-
};
|
|
23
|
-
var __objRest = (source, exclude) => {
|
|
24
|
-
var target = {};
|
|
25
|
-
for (var prop in source)
|
|
26
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
27
|
-
target[prop] = source[prop];
|
|
28
|
-
if (source != null && __getOwnPropSymbols)
|
|
29
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
30
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
31
|
-
target[prop] = source[prop];
|
|
32
|
-
}
|
|
33
|
-
return target;
|
|
34
|
-
};
|
|
35
|
-
const SidebarBody = (_a) => {
|
|
36
|
-
var _b = _a, {
|
|
37
|
-
elementType = "nav",
|
|
38
|
-
children
|
|
39
|
-
} = _b, props = __objRest(_b, [
|
|
40
|
-
"elementType",
|
|
41
|
-
"children"
|
|
42
|
-
]);
|
|
7
|
+
const SidebarBody = ({
|
|
8
|
+
elementType = "nav",
|
|
9
|
+
children,
|
|
10
|
+
...props
|
|
11
|
+
}) => {
|
|
43
12
|
const RootNode = elementType;
|
|
44
13
|
const sidebarBody = useRef(null);
|
|
45
14
|
const { isScrolled, scrollCheckProps } = useScrollCheck(sidebarBody);
|
|
46
|
-
return /* @__PURE__ */ React.createElement(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
15
|
+
return /* @__PURE__ */ React.createElement(
|
|
16
|
+
RootNode,
|
|
17
|
+
{
|
|
18
|
+
ref: sidebarBody,
|
|
19
|
+
tabIndex: -1,
|
|
20
|
+
className: clsx(styles["sapphire-sidebar__body"], {
|
|
21
|
+
[styles["sapphire-sidebar__body--scrolled"]]: isScrolled
|
|
22
|
+
}),
|
|
23
|
+
...filterDOMProps(props, { global: true }),
|
|
24
|
+
...scrollCheckProps
|
|
25
|
+
},
|
|
26
|
+
children
|
|
27
|
+
);
|
|
53
28
|
};
|
|
54
29
|
|
|
55
30
|
export { SidebarBody };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Body.js","sources":["../../../../src/Sidebar/src/Body.tsx"],"sourcesContent":["import React, { ReactNode, useRef } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from '
|
|
1
|
+
{"version":3,"file":"Body.js","sources":["../../../../src/Sidebar/src/Body.tsx"],"sourcesContent":["import React, { ReactNode, useRef } from 'react';\nimport clsx from 'clsx';\nimport { filterDOMProps } from 'react-aria/filterDOMProps';\nimport { DOMProps } from '@react-types/shared';\nimport styles from '@danske/sapphire-css/components/sidebar/sidebar.module.css';\nimport { useScrollCheck } from '@danske/sapphire-react';\n\nexport interface SidebarBodyProps extends DOMProps {\n /**\n * Wrapping element type.\n * @default 'nav'\n */\n elementType?: string;\n children?: ReactNode;\n}\n\nexport const SidebarBody = ({\n elementType = 'nav',\n children,\n ...props\n}: SidebarBodyProps): React.JSX.Element => {\n const RootNode = elementType as any;\n const sidebarBody = useRef<HTMLElement>(null);\n const { isScrolled, scrollCheckProps } = useScrollCheck(sidebarBody);\n\n return (\n <RootNode\n ref={sidebarBody}\n tabIndex={\n -1 /* Some browsers will make this focusable because it overflows */\n }\n className={clsx(styles['sapphire-sidebar__body'], {\n [styles['sapphire-sidebar__body--scrolled']]: isScrolled,\n })}\n {...filterDOMProps(props, { global: true })}\n {...scrollCheckProps}\n >\n {children}\n </RootNode>\n );\n};\n"],"names":[],"mappings":";;;;;;AAgBO,MAAM,cAAc,CAAC;AAAA,EAC1B,WAAA,GAAc,KAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,KAA2C;AACzC,EAAA,MAAM,QAAA,GAAW,WAAA;AACjB,EAAA,MAAM,WAAA,GAAc,OAAoB,IAAI,CAAA;AAC5C,EAAA,MAAM,EAAE,UAAA,EAAY,gBAAA,EAAiB,GAAI,eAAe,WAAW,CAAA;AAEnE,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,WAAA;AAAA,MACL,QAAA,EACE,EAAA;AAAA,MAEF,SAAA,EAAW,IAAA,CAAK,MAAA,CAAO,wBAAwB,CAAA,EAAG;AAAA,QAChD,CAAC,MAAA,CAAO,kCAAkC,CAAC,GAAG;AAAA,OAC/C,CAAA;AAAA,MACA,GAAG,cAAA,CAAe,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAAA,MACzC,GAAG;AAAA,KAAA;AAAA,IAEH;AAAA,GACH;AAEJ;;;;"}
|