@vygruppen/spor-react 12.3.0 → 12.3.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/.turbo/turbo-build.log +11 -11
- package/.turbo/turbo-typegen.log +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/index.d.mts +44 -42
- package/dist/index.d.ts +44 -42
- package/dist/index.js +236 -225
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +241 -230
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/alert/AlertIcon.tsx +17 -11
- package/src/button/Button.tsx +1 -1
- package/src/button/CloseButton.tsx +6 -3
- package/src/button/IconButton.tsx +1 -1
- package/src/datepicker/CalendarTriggerButton.tsx +2 -2
- package/src/datepicker/DatePicker.tsx +5 -1
- package/src/datepicker/DateRangePicker.tsx +4 -1
- package/src/input/Combobox.tsx +149 -157
- package/src/input/ListBox.tsx +27 -34
- package/src/input/NumericStepper.tsx +2 -2
- package/src/input/Switch.tsx +35 -33
- package/src/linjetag/LineIcon.tsx +14 -10
- package/src/loader/ProgressLoader.tsx +12 -8
- package/src/progress-indicator/ProgressIndicator.tsx +2 -1
- package/src/theme/slot-recipes/table.ts +1 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vygruppen/spor-react",
|
3
|
-
"version": "12.3.
|
3
|
+
"version": "12.3.2",
|
4
4
|
"main": "./dist/index.js",
|
5
5
|
"module": "./dist/index.mjs",
|
6
6
|
"types": "./dist/index.d.ts",
|
@@ -35,8 +35,8 @@
|
|
35
35
|
"react-stately": "^3.31.1",
|
36
36
|
"react-swipeable": "^7.0.1",
|
37
37
|
"usehooks-ts": "^3.1.0",
|
38
|
-
"@vygruppen/spor-design-tokens": "4.0.6",
|
39
38
|
"@vygruppen/spor-icon-react": "4.0.4",
|
39
|
+
"@vygruppen/spor-design-tokens": "4.0.6",
|
40
40
|
"@vygruppen/spor-loader": "0.6.0"
|
41
41
|
},
|
42
42
|
"devDependencies": {
|
@@ -56,8 +56,8 @@
|
|
56
56
|
"vitest": "^0.26.3",
|
57
57
|
"vitest-axe": "^0.1.0",
|
58
58
|
"vitest-canvas-mock": "^0.2.2",
|
59
|
-
"@vygruppen/
|
60
|
-
"@vygruppen/
|
59
|
+
"@vygruppen/tsconfig": "0.1.0",
|
60
|
+
"@vygruppen/eslint-config": "1.0.1"
|
61
61
|
},
|
62
62
|
"peerDependencies": {
|
63
63
|
"react": ">=18.0.0 <19.0.0",
|
package/src/alert/AlertIcon.tsx
CHANGED
@@ -12,6 +12,7 @@ import {
|
|
12
12
|
SuccessFill24Icon,
|
13
13
|
WarningFill24Icon,
|
14
14
|
} from "@vygruppen/spor-icon-react";
|
15
|
+
import { forwardRef } from "react";
|
15
16
|
|
16
17
|
import { createTexts, useTranslation } from "../i18n";
|
17
18
|
import { AlertProps } from "./Alert";
|
@@ -24,19 +25,24 @@ type AlertIconProps = {
|
|
24
25
|
/**
|
25
26
|
* Internal component that shows the correct icon for the alert
|
26
27
|
*/
|
27
|
-
export const AlertIcon =
|
28
|
-
|
28
|
+
export const AlertIcon = forwardRef<SVGSVGElement, AlertIconProps>(
|
29
|
+
({ variant, customIcon }, ref) => {
|
30
|
+
const { t } = useTranslation();
|
29
31
|
|
30
|
-
|
32
|
+
const Icon = customIcon ?? getIcon(variant);
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
return (
|
35
|
+
<Box
|
36
|
+
as={Icon}
|
37
|
+
ref={ref}
|
38
|
+
aria-label={t(texts[variant as keyof typeof texts])}
|
39
|
+
color={customIcon ? `alert.${variant}.icon` : undefined}
|
40
|
+
/>
|
41
|
+
);
|
42
|
+
},
|
43
|
+
);
|
44
|
+
|
45
|
+
AlertIcon.displayName = "AlertIcon";
|
40
46
|
|
41
47
|
const getIcon = (variant: AlertProps["variant"]) => {
|
42
48
|
switch (variant) {
|
package/src/button/Button.tsx
CHANGED
@@ -86,7 +86,7 @@ const LoadingContent = ({
|
|
86
86
|
{children}
|
87
87
|
</Flex>
|
88
88
|
<Center position="absolute" inset="1px 0">
|
89
|
-
<ColorInlineLoader
|
89
|
+
<ColorInlineLoader maxWidth="8" marginX={2} marginY={2} />
|
90
90
|
{loadingText && <Box>{loadingText}</Box>}
|
91
91
|
</Center>
|
92
92
|
</>
|
@@ -32,19 +32,19 @@ export const CloseButton = forwardRef<HTMLButtonElement, CloseButtonProps>(
|
|
32
32
|
const { t } = useTranslation();
|
33
33
|
return (
|
34
34
|
<IconButton
|
35
|
-
ref={ref}
|
36
35
|
variant="ghost"
|
37
|
-
icon={
|
36
|
+
icon={<CloseIcon size={size} />}
|
38
37
|
size={size}
|
39
38
|
aria-label={props["aria-label"] || t(texts.close)}
|
40
39
|
{...props}
|
40
|
+
ref={ref}
|
41
41
|
/>
|
42
42
|
);
|
43
43
|
},
|
44
44
|
);
|
45
45
|
CloseButton.displayName = "CloseButton";
|
46
46
|
|
47
|
-
const
|
47
|
+
const CloseIcon = ({ size }: { size: CloseButtonProps["size"] }) => {
|
48
48
|
switch (size) {
|
49
49
|
case "xs":
|
50
50
|
case "sm": {
|
@@ -56,6 +56,9 @@ const getIcon = (size: CloseButtonProps["size"]) => {
|
|
56
56
|
case "lg": {
|
57
57
|
return <CloseFill30Icon />;
|
58
58
|
}
|
59
|
+
default: {
|
60
|
+
return <CloseFill18Icon />;
|
61
|
+
}
|
59
62
|
}
|
60
63
|
};
|
61
64
|
|
@@ -63,9 +63,9 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
|
|
63
63
|
<ChakraIconButton
|
64
64
|
aria-label={props["aria-label"]}
|
65
65
|
size={size}
|
66
|
-
ref={ref}
|
67
66
|
position={"relative"}
|
68
67
|
{...rest}
|
68
|
+
ref={ref}
|
69
69
|
>
|
70
70
|
{loading ? <ColorSpinner width="2em" height="2em" margin={1} /> : icon}
|
71
71
|
</ChakraIconButton>
|
@@ -24,7 +24,7 @@ type CalendarTriggerButtonProps = AriaButtonProps<"button"> &
|
|
24
24
|
export const CalendarTriggerButton = forwardRef<
|
25
25
|
HTMLDivElement,
|
26
26
|
CalendarTriggerButtonProps
|
27
|
-
>(({ variant, disabled, ariaLabelledby, ...buttonProps }) => {
|
27
|
+
>(({ variant, disabled, ariaLabelledby, ...buttonProps }, ref) => {
|
28
28
|
const { t } = useTranslation();
|
29
29
|
const recipe = useSlotRecipe({
|
30
30
|
key: "datePicker",
|
@@ -33,7 +33,7 @@ export const CalendarTriggerButton = forwardRef<
|
|
33
33
|
const styles = recipe({ variant });
|
34
34
|
|
35
35
|
return (
|
36
|
-
<PopoverAnchor {...buttonProps}>
|
36
|
+
<PopoverAnchor {...buttonProps} ref={ref}>
|
37
37
|
<IconButton
|
38
38
|
icon={<CalendarOutline24Icon />}
|
39
39
|
aria-label={t(texts.openCalendar)}
|
@@ -4,6 +4,7 @@ import {
|
|
4
4
|
BoxProps,
|
5
5
|
Popover as ChakraPopover,
|
6
6
|
PopoverAnchor,
|
7
|
+
PopoverRootProps,
|
7
8
|
Portal,
|
8
9
|
RecipeVariantProps,
|
9
10
|
useFieldContext,
|
@@ -40,6 +41,7 @@ type DatePickerProps = Omit<AriaDatePickerProps<DateValue>, "onChange"> &
|
|
40
41
|
showYearNavigation?: boolean;
|
41
42
|
withPortal?: boolean;
|
42
43
|
onChange?: (value: DateValue | null) => void;
|
44
|
+
positioning?: PopoverRootProps["positioning"];
|
43
45
|
} & FieldBaseProps;
|
44
46
|
|
45
47
|
/**
|
@@ -63,6 +65,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
63
65
|
width = "auto",
|
64
66
|
invalid = false,
|
65
67
|
helperText,
|
68
|
+
positioning,
|
66
69
|
...props
|
67
70
|
},
|
68
71
|
externalRef,
|
@@ -75,6 +78,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
75
78
|
isRequired: props.isRequired ?? chakraFieldProps?.required,
|
76
79
|
validationState: chakraFieldProps?.invalid ? "invalid" : "valid",
|
77
80
|
});
|
81
|
+
|
78
82
|
const internalRef = useRef<HTMLDivElement>(null);
|
79
83
|
const ref = externalRef ?? internalRef;
|
80
84
|
const { labelProps, fieldProps, buttonProps, dialogProps, calendarProps } =
|
@@ -120,7 +124,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
120
124
|
flexDirection="column"
|
121
125
|
width={width}
|
122
126
|
>
|
123
|
-
<ChakraPopover.Root {...dialogProps}>
|
127
|
+
<ChakraPopover.Root {...dialogProps} positioning={positioning}>
|
124
128
|
<Field
|
125
129
|
display="inline-flex"
|
126
130
|
id={inputGroupId}
|
@@ -4,6 +4,7 @@ import {
|
|
4
4
|
BoxProps,
|
5
5
|
Popover as ChakraPopover,
|
6
6
|
PopoverAnchor,
|
7
|
+
PopoverRootProps,
|
7
8
|
Portal,
|
8
9
|
useFieldContext,
|
9
10
|
useSlotRecipe,
|
@@ -46,6 +47,7 @@ type DateRangePickerProps = Omit<
|
|
46
47
|
end: DateValue | null;
|
47
48
|
} | null,
|
48
49
|
) => void;
|
50
|
+
positioning?: PopoverRootProps["positioning"];
|
49
51
|
} & FieldBaseProps;
|
50
52
|
/**
|
51
53
|
* A date range picker component.
|
@@ -64,6 +66,7 @@ type DateRangePickerProps = Omit<
|
|
64
66
|
errorText,
|
65
67
|
helperText,
|
66
68
|
invalid,
|
69
|
+
positioning,
|
67
70
|
...props
|
68
71
|
}: DateRangePickerProps) {
|
69
72
|
const fieldContextPRops = useFieldContext();
|
@@ -118,7 +121,7 @@ type DateRangePickerProps = Omit<
|
|
118
121
|
{props.label}
|
119
122
|
</label>
|
120
123
|
)}
|
121
|
-
<ChakraPopover.Root {...dialogProps}>
|
124
|
+
<ChakraPopover.Root {...dialogProps} positioning={positioning}>
|
122
125
|
<Field
|
123
126
|
width="auto"
|
124
127
|
display="inline-flex"
|
package/src/input/Combobox.tsx
CHANGED
@@ -1,12 +1,5 @@
|
|
1
1
|
"use client";
|
2
|
-
import React, {
|
3
|
-
forwardRef,
|
4
|
-
ReactNode,
|
5
|
-
useEffect,
|
6
|
-
useId,
|
7
|
-
useRef,
|
8
|
-
useState,
|
9
|
-
} from "react";
|
2
|
+
import React, { ReactNode, useEffect, useId, useRef, useState } from "react";
|
10
3
|
import { AriaComboBoxProps, useComboBox, useFilter } from "react-aria";
|
11
4
|
import { useComboBoxState } from "react-stately";
|
12
5
|
|
@@ -57,163 +50,162 @@ export type ComboboxProps<T> = Exclude<
|
|
57
50
|
* ```
|
58
51
|
*/
|
59
52
|
|
60
|
-
export const Combobox =
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
const { contains } = useFilter({ sensitivity: "base" });
|
53
|
+
export const Combobox = (props: ComboboxProps<object>) => {
|
54
|
+
const {
|
55
|
+
label,
|
56
|
+
loading,
|
57
|
+
lefticon,
|
58
|
+
righticon,
|
59
|
+
borderBottomLeftRadius = "sm",
|
60
|
+
borderBottomRightRadius = "sm",
|
61
|
+
borderTopLeftRadius = "sm",
|
62
|
+
borderTopRightRadius = "sm",
|
63
|
+
marginBottom,
|
64
|
+
marginTop,
|
65
|
+
marginX,
|
66
|
+
marginY,
|
67
|
+
marginRight,
|
68
|
+
marginLeft,
|
69
|
+
paddingBottom,
|
70
|
+
paddingRight,
|
71
|
+
paddingTop,
|
72
|
+
paddingLeft,
|
73
|
+
paddingX,
|
74
|
+
paddingY,
|
75
|
+
emptyContent,
|
76
|
+
inputRef: externalInputRef,
|
77
|
+
children,
|
78
|
+
variant,
|
79
|
+
} = props;
|
80
|
+
const { contains } = useFilter({ sensitivity: "base" });
|
89
81
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
82
|
+
const fallbackInputRef = useRef<HTMLInputElement>(null);
|
83
|
+
const inputRef = externalInputRef ?? fallbackInputRef;
|
84
|
+
const listBoxRef = useRef<HTMLUListElement>(null);
|
85
|
+
const popoverRef = useRef(null);
|
94
86
|
|
95
|
-
|
87
|
+
const listboxId = `${useId()}-listbox`;
|
96
88
|
|
97
|
-
|
89
|
+
const inputWidth = useInputWidth(inputRef);
|
98
90
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
91
|
+
const state = useComboBoxState({
|
92
|
+
defaultFilter: contains,
|
93
|
+
shouldCloseOnBlur: true,
|
94
|
+
...props,
|
95
|
+
});
|
104
96
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
97
|
+
const comboBoxProps = {
|
98
|
+
borderTopLeftRadius,
|
99
|
+
borderTopRightRadius,
|
100
|
+
marginBottom,
|
101
|
+
marginTop,
|
102
|
+
marginRight,
|
103
|
+
marginLeft,
|
104
|
+
marginX,
|
105
|
+
marginY,
|
106
|
+
paddingBottom,
|
107
|
+
paddingRight,
|
108
|
+
paddingTop,
|
109
|
+
paddingLeft,
|
110
|
+
paddingX,
|
111
|
+
paddingY,
|
112
|
+
lefticon,
|
113
|
+
};
|
122
114
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
115
|
+
const {
|
116
|
+
inputProps: { ...inputProps },
|
117
|
+
listBoxProps,
|
118
|
+
} = useComboBox(
|
119
|
+
{
|
120
|
+
...props,
|
121
|
+
inputRef,
|
122
|
+
listBoxRef,
|
123
|
+
popoverRef,
|
124
|
+
label,
|
125
|
+
},
|
126
|
+
state,
|
127
|
+
);
|
128
|
+
return (
|
129
|
+
<>
|
130
|
+
<Input
|
131
|
+
{...styleProps(comboBoxProps)}
|
132
|
+
aria-haspopup="listbox"
|
133
|
+
ref={inputRef}
|
134
|
+
role="combobox"
|
135
|
+
errorText={props.errorText}
|
136
|
+
helperText={props.helperText}
|
137
|
+
required={props.required}
|
138
|
+
disabled={props.disabled}
|
139
|
+
invalid={props.invalid}
|
140
|
+
label={label}
|
141
|
+
variant={variant}
|
142
|
+
aria-expanded={state.isOpen}
|
143
|
+
aria-autocomplete="list"
|
144
|
+
aria-controls={listboxId}
|
145
|
+
borderBottomLeftRadius={
|
146
|
+
state.isOpen && !loading ? 0 : borderBottomLeftRadius
|
147
|
+
}
|
148
|
+
borderBottomRightRadius={
|
149
|
+
state.isOpen && !loading ? 0 : borderBottomRightRadius
|
150
|
+
}
|
151
|
+
_active={{ backgroundColor: "core.surface.active" }}
|
152
|
+
{...inputProps}
|
153
|
+
endElement={
|
154
|
+
loading ? (
|
155
|
+
<ColorSpinner
|
156
|
+
width="1.5rem"
|
157
|
+
alignSelf="center"
|
158
|
+
paddingRight={paddingRight}
|
159
|
+
css={{
|
160
|
+
div: {
|
161
|
+
display: "flex",
|
162
|
+
alignItems: "center",
|
163
|
+
},
|
164
|
+
}}
|
165
|
+
/>
|
166
|
+
) : (
|
167
|
+
righticon
|
168
|
+
)
|
169
|
+
}
|
170
|
+
placeholder=""
|
171
|
+
/>
|
172
|
+
<span aria-hidden="true" data-trigger="multiselect"></span>
|
173
|
+
{state.isOpen && !loading && (
|
174
|
+
<Popover
|
175
|
+
state={state}
|
176
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
177
|
+
triggerRef={inputRef as any} /* Find a way to not use type any */
|
178
|
+
ref={popoverRef}
|
179
|
+
isNonModal
|
180
|
+
placement="bottom start"
|
181
|
+
shouldFlip={false}
|
182
|
+
hasBackdrop={false}
|
183
|
+
// The minimum padding should be 0, because the popover always should be
|
184
|
+
// aligned with the input field regardless of the left padding in the container.
|
185
|
+
containerPadding={0}
|
186
|
+
>
|
187
|
+
<ListBox
|
188
|
+
{...{
|
189
|
+
autoFocus:
|
190
|
+
typeof listBoxProps.autoFocus === "boolean"
|
191
|
+
? listBoxProps.autoFocus
|
192
|
+
: undefined,
|
193
|
+
}}
|
183
194
|
state={state}
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
shouldFlip={false}
|
190
|
-
hasBackdrop={false}
|
191
|
-
// The minimum padding should be 0, because the popover always should be
|
192
|
-
// aligned with the input field regardless of the left padding in the container.
|
193
|
-
containerPadding={0}
|
195
|
+
id={listboxId}
|
196
|
+
listBoxRef={listBoxRef}
|
197
|
+
emptyContent={emptyContent}
|
198
|
+
maxWidth={inputWidth}
|
199
|
+
variant={variant}
|
194
200
|
>
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
id={listboxId}
|
204
|
-
listBoxRef={listBoxRef}
|
205
|
-
emptyContent={emptyContent}
|
206
|
-
maxWidth={inputWidth}
|
207
|
-
variant={variant}
|
208
|
-
>
|
209
|
-
{children}
|
210
|
-
</ListBox>
|
211
|
-
</Popover>
|
212
|
-
)}
|
213
|
-
</>
|
214
|
-
);
|
215
|
-
},
|
216
|
-
);
|
201
|
+
{children}
|
202
|
+
</ListBox>
|
203
|
+
</Popover>
|
204
|
+
)}
|
205
|
+
</>
|
206
|
+
);
|
207
|
+
};
|
208
|
+
|
217
209
|
Combobox.displayName = "Combobox";
|
218
210
|
|
219
211
|
const useInputWidth = (inputRef: React.RefObject<HTMLInputElement>) => {
|
package/src/input/ListBox.tsx
CHANGED
@@ -8,13 +8,7 @@ import {
|
|
8
8
|
useSlotRecipe,
|
9
9
|
} from "@chakra-ui/react";
|
10
10
|
import type { Node } from "@react-types/shared";
|
11
|
-
import React, {
|
12
|
-
forwardRef,
|
13
|
-
PropsWithChildren,
|
14
|
-
useContext,
|
15
|
-
useEffect,
|
16
|
-
useRef,
|
17
|
-
} from "react";
|
11
|
+
import React, { PropsWithChildren, useContext, useEffect, useRef } from "react";
|
18
12
|
import {
|
19
13
|
AriaListBoxProps,
|
20
14
|
useListBox,
|
@@ -84,33 +78,32 @@ type ListBoxProps<T> = AriaListBoxProps<T> &
|
|
84
78
|
* ```
|
85
79
|
*/
|
86
80
|
|
87
|
-
export const ListBox =
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
item.
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
);
|
81
|
+
export const ListBox = (props: ListBoxProps<object>) => {
|
82
|
+
const { loading, listBoxRef, state, maxWidth, variant, children } = props;
|
83
|
+
const { listBoxProps } = useListBox(props, state, listBoxRef);
|
84
|
+
const recipe = useSlotRecipe({ key: "listBox" });
|
85
|
+
const styles = recipe({ variant });
|
86
|
+
return (
|
87
|
+
<List
|
88
|
+
{...listBoxProps}
|
89
|
+
ref={listBoxRef}
|
90
|
+
css={styles.root}
|
91
|
+
aria-busy={loading}
|
92
|
+
maxWidth={maxWidth}
|
93
|
+
>
|
94
|
+
{state.collection.size === 0 && props.emptyContent}
|
95
|
+
{[...state.collection].map((item) =>
|
96
|
+
item.type === "section" ? (
|
97
|
+
<ListBoxSection key={item.key} section={item} state={state} />
|
98
|
+
) : (
|
99
|
+
<Option key={item.key} item={item} state={state} />
|
100
|
+
),
|
101
|
+
)}
|
102
|
+
{children}
|
103
|
+
</List>
|
104
|
+
);
|
105
|
+
};
|
106
|
+
|
114
107
|
ListBox.displayName = "ListBox";
|
115
108
|
|
116
109
|
/**
|
@@ -69,7 +69,7 @@ export type NumericStepperProps = BoxProps &
|
|
69
69
|
export const NumericStepper = React.forwardRef<
|
70
70
|
HTMLDivElement,
|
71
71
|
NumericStepperProps
|
72
|
-
>((props: NumericStepperProps) => {
|
72
|
+
>((props: NumericStepperProps, ref) => {
|
73
73
|
const {
|
74
74
|
name: nameProp,
|
75
75
|
id: idProp,
|
@@ -102,7 +102,7 @@ export const NumericStepper = React.forwardRef<
|
|
102
102
|
};
|
103
103
|
|
104
104
|
return (
|
105
|
-
<Field css={styles.root} width="auto" {...rest}>
|
105
|
+
<Field css={styles.root} width="auto" {...rest} ref={ref}>
|
106
106
|
<VerySmallButton
|
107
107
|
icon={<SubtractIcon stepLabel={clampedStepSize} />}
|
108
108
|
aria-label={t(
|