reshaped 3.4.6 → 3.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -2
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.js +11 -11
- package/dist/components/Autocomplete/Autocomplete.js +25 -8
- package/dist/components/Autocomplete/Autocomplete.module.css +1 -0
- package/dist/components/Autocomplete/tests/Autocomplete.stories.d.ts +15 -1
- package/dist/components/Autocomplete/tests/Autocomplete.stories.js +193 -64
- package/dist/components/Calendar/Calendar.module.css +1 -1
- package/dist/components/Checkbox/Checkbox.js +17 -4
- package/dist/components/Checkbox/Checkbox.module.css +1 -1
- package/dist/components/Checkbox/Checkbox.types.d.ts +1 -0
- package/dist/components/Checkbox/tests/Checkbox.stories.d.ts +1 -0
- package/dist/components/Checkbox/tests/Checkbox.stories.js +40 -0
- package/dist/components/Dismissible/Dismissible.js +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js +1 -1
- package/dist/components/FormControl/FormControlLabel.js +2 -7
- package/dist/components/NumberField/NumberField.d.ts +6 -0
- package/dist/components/NumberField/NumberField.js +11 -0
- package/dist/components/NumberField/NumberField.module.css +1 -0
- package/dist/components/NumberField/NumberField.types.d.ts +19 -0
- package/dist/components/NumberField/NumberField.types.js +1 -0
- package/dist/components/NumberField/NumberFieldControlled.d.ts +6 -0
- package/dist/components/NumberField/NumberFieldControlled.js +146 -0
- package/dist/components/NumberField/NumberFieldUncontrolled.d.ts +6 -0
- package/dist/components/NumberField/NumberFieldUncontrolled.js +16 -0
- package/dist/components/NumberField/index.d.ts +2 -0
- package/dist/components/NumberField/index.js +1 -0
- package/dist/components/NumberField/tests/NumberField.stories.d.ts +29 -0
- package/dist/components/NumberField/tests/NumberField.stories.js +215 -0
- package/dist/components/PinField/PinField.module.css +1 -1
- package/dist/components/PinField/PinField.types.d.ts +1 -1
- package/dist/components/PinField/PinFieldControlled.js +1 -0
- package/dist/components/PinField/tests/PinField.stories.js +8 -0
- package/dist/components/Radio/Radio.js +11 -4
- package/dist/components/Radio/Radio.module.css +1 -1
- package/dist/components/Radio/Radio.types.d.ts +1 -0
- package/dist/components/Radio/tests/Radio.stories.d.ts +1 -0
- package/dist/components/Radio/tests/Radio.stories.js +31 -0
- package/dist/components/Select/Select.module.css +1 -1
- package/dist/components/Select/Select.types.d.ts +1 -1
- package/dist/components/Select/tests/Select.stories.js +42 -16
- package/dist/components/Switch/Switch.js +10 -4
- package/dist/components/Switch/Switch.module.css +1 -1
- package/dist/components/Switch/Switch.types.d.ts +1 -1
- package/dist/components/Switch/tests/Switch.stories.js +30 -15
- package/dist/components/TextField/TextField.js +1 -1
- package/dist/components/TextField/TextField.module.css +1 -1
- package/dist/components/TextField/TextField.types.d.ts +2 -2
- package/dist/components/TextField/index.d.ts +1 -1
- package/dist/components/TextField/tests/TextField.stories.js +4 -0
- package/dist/hooks/tests/useScrollLock.stories.d.ts +1 -0
- package/dist/hooks/tests/useScrollLock.stories.js +29 -0
- package/dist/icons/ChevronUp.d.ts +2 -0
- package/dist/icons/ChevronUp.js +5 -0
- package/dist/icons/Minus.d.ts +2 -0
- package/dist/icons/Minus.js +3 -0
- package/dist/icons/Plus.d.ts +2 -2
- package/dist/icons/Plus.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/utilities/scroll/lock.js +15 -7
- package/dist/utilities/scroll/lockStandard.d.ts +1 -2
- package/dist/utilities/scroll/lockStandard.js +2 -9
- package/package.json +1 -1
- package/dist/components/Autocomplete/tests/Autocomplete.test.stories.d.ts +0 -27
- package/dist/components/Autocomplete/tests/Autocomplete.test.stories.js +0 -86
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TextFieldBaseProps } from "../TextField";
|
|
2
|
+
import type * as G from "../../types/global";
|
|
3
|
+
export type BaseProps = Omit<TextFieldBaseProps, "endSlot" | "onChange"> & {
|
|
4
|
+
onChange?: G.ChangeHandler<number>;
|
|
5
|
+
increaseAriaLabel: string;
|
|
6
|
+
decreaseAriaLabel: string;
|
|
7
|
+
min?: number;
|
|
8
|
+
max?: number;
|
|
9
|
+
step?: number;
|
|
10
|
+
};
|
|
11
|
+
export type ControlledProps = BaseProps & {
|
|
12
|
+
value: number | null;
|
|
13
|
+
defaultValue?: never;
|
|
14
|
+
};
|
|
15
|
+
export type UncontrolledProps = BaseProps & {
|
|
16
|
+
value?: never;
|
|
17
|
+
defaultValue?: number;
|
|
18
|
+
};
|
|
19
|
+
export type Props = ControlledProps | UncontrolledProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import Actionable from "../Actionable/index.js";
|
|
5
|
+
import Icon from "../Icon/index.js";
|
|
6
|
+
import TextField from "../TextField/index.js";
|
|
7
|
+
import IconChevronUp from "../../icons/ChevronUp.js";
|
|
8
|
+
import IconChevronDown from "../../icons/ChevronDown.js";
|
|
9
|
+
import IconPlus from "../../icons/Plus.js";
|
|
10
|
+
import IconMinus from "../../icons/Minus.js";
|
|
11
|
+
import useElementId from "../../hooks/useElementId.js";
|
|
12
|
+
import useHotkeys from "../../hooks/useHotkeys.js";
|
|
13
|
+
import * as keys from "../../constants/keys.js";
|
|
14
|
+
import s from "./NumberField.module.css";
|
|
15
|
+
import useHandlerRef from "../../hooks/useHandlerRef.js";
|
|
16
|
+
import { useFormControl } from "../FormControl/index.js";
|
|
17
|
+
const NumberFieldControlled = (props) => {
|
|
18
|
+
const { increaseAriaLabel, decreaseAriaLabel, min, max, step = 1, name, value, onChange, ...textFieldProps } = props;
|
|
19
|
+
const formControl = useFormControl();
|
|
20
|
+
const id = useElementId(textFieldProps.id);
|
|
21
|
+
const inputId = formControl?.attributes.id || props.inputAttributes?.id || id;
|
|
22
|
+
const disabled = formControl?.disabled || props.disabled;
|
|
23
|
+
const hasError = formControl?.hasError || props.hasError;
|
|
24
|
+
const increaseDisabled = disabled || (value && max ? value >= max : false);
|
|
25
|
+
const decreaseDisabled = disabled || (value && min ? value <= min : false);
|
|
26
|
+
const inputRef = React.useRef(null);
|
|
27
|
+
const rootRef = React.useRef(null);
|
|
28
|
+
const [textValue, setTextValue] = React.useState(value?.toString() || "");
|
|
29
|
+
// Sync value to a ref to handle holding controlss pressed
|
|
30
|
+
// And changing it without waiting for a rerender
|
|
31
|
+
const valueRef = React.useRef(value);
|
|
32
|
+
const onChangeRef = useHandlerRef(onChange);
|
|
33
|
+
const pressedTimeoutRef = React.useRef(null);
|
|
34
|
+
const changeIntervalRef = React.useRef(null);
|
|
35
|
+
const calculateDirectionalChange = React.useCallback((direction) => {
|
|
36
|
+
const delta = step * direction;
|
|
37
|
+
const value = valueRef.current;
|
|
38
|
+
let nextValue = value === null ? delta : value + delta;
|
|
39
|
+
if (max !== undefined && nextValue > max)
|
|
40
|
+
nextValue = max;
|
|
41
|
+
if (min !== undefined && nextValue < min)
|
|
42
|
+
nextValue = min;
|
|
43
|
+
// Keep the right precision and avoid JS rounding errors
|
|
44
|
+
const floatPartLength = value?.toString().split(".")[1]?.length || 0;
|
|
45
|
+
return Number(nextValue.toFixed(floatPartLength));
|
|
46
|
+
}, [step, min, max]);
|
|
47
|
+
const commitValue = React.useCallback((value, options) => {
|
|
48
|
+
onChangeRef.current?.({ value, name });
|
|
49
|
+
// Only update the ref here when typing in the input
|
|
50
|
+
// Otherwise it will be updated when value changes
|
|
51
|
+
if (!options?.programmatic)
|
|
52
|
+
valueRef.current = value;
|
|
53
|
+
}, [name, onChangeRef]);
|
|
54
|
+
const handleIncrease = React.useCallback(() => {
|
|
55
|
+
const nextValue = calculateDirectionalChange(1);
|
|
56
|
+
commitValue(nextValue, { programmatic: true });
|
|
57
|
+
}, [calculateDirectionalChange, commitValue]);
|
|
58
|
+
const handleDecrease = React.useCallback(() => {
|
|
59
|
+
const nextValue = calculateDirectionalChange(-1);
|
|
60
|
+
commitValue(nextValue, { programmatic: true });
|
|
61
|
+
}, [calculateDirectionalChange, commitValue]);
|
|
62
|
+
const handleChange = (args) => {
|
|
63
|
+
if (!args.value.match(/^(-?)[0-9]*(\.?)[0-9]*$/))
|
|
64
|
+
return;
|
|
65
|
+
setTextValue(args.value);
|
|
66
|
+
const numberValue = parseFloat(args.value);
|
|
67
|
+
if (isNaN(numberValue))
|
|
68
|
+
return;
|
|
69
|
+
commitValue(numberValue);
|
|
70
|
+
};
|
|
71
|
+
const handleControlPointerDown = (e, callback) => {
|
|
72
|
+
if (disabled)
|
|
73
|
+
return;
|
|
74
|
+
callback();
|
|
75
|
+
if (e.pointerType !== "touch") {
|
|
76
|
+
inputRef.current?.focus();
|
|
77
|
+
}
|
|
78
|
+
pressedTimeoutRef.current = setTimeout(() => {
|
|
79
|
+
changeIntervalRef.current = setInterval(() => {
|
|
80
|
+
callback();
|
|
81
|
+
}, 50);
|
|
82
|
+
}, 500);
|
|
83
|
+
};
|
|
84
|
+
const handleControlPointerUp = () => {
|
|
85
|
+
if (disabled)
|
|
86
|
+
return;
|
|
87
|
+
if (pressedTimeoutRef.current) {
|
|
88
|
+
clearTimeout(pressedTimeoutRef.current);
|
|
89
|
+
pressedTimeoutRef.current = null;
|
|
90
|
+
}
|
|
91
|
+
if (changeIntervalRef.current) {
|
|
92
|
+
clearTimeout(changeIntervalRef.current);
|
|
93
|
+
changeIntervalRef.current = null;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
useHotkeys({
|
|
97
|
+
[keys.UP]: handleIncrease,
|
|
98
|
+
[keys.DOWN]: handleDecrease,
|
|
99
|
+
}, [handleIncrease, handleDecrease], {
|
|
100
|
+
preventDefault: true,
|
|
101
|
+
ref: rootRef,
|
|
102
|
+
});
|
|
103
|
+
React.useEffect(() => {
|
|
104
|
+
valueRef.current = value;
|
|
105
|
+
setTextValue(value?.toString() ?? "");
|
|
106
|
+
}, [value]);
|
|
107
|
+
const controlsNode = (_jsxs("span", { className: s.controls, children: [_jsxs(Actionable, { className: s.control, disabled: increaseDisabled, disableFocusRing: true, as: "span", attributes: {
|
|
108
|
+
"aria-label": increaseAriaLabel,
|
|
109
|
+
"aria-controls": id,
|
|
110
|
+
role: "button",
|
|
111
|
+
tabIndex: increaseDisabled ? undefined : -1,
|
|
112
|
+
onPointerDown: (e) => handleControlPointerDown(e, handleIncrease),
|
|
113
|
+
onPointerUp: handleControlPointerUp,
|
|
114
|
+
onPointerLeave: handleControlPointerUp,
|
|
115
|
+
// Prevent menu from opening on long press
|
|
116
|
+
onContextMenu: (e) => e.preventDefault(),
|
|
117
|
+
}, children: [_jsx(Icon, { svg: IconChevronUp, size: 3, className: s["icon--mouse"] }), _jsx(Icon, { svg: IconPlus, size: 4, className: s["icon--touch"] })] }), _jsxs(Actionable, { className: s.control, disabled: decreaseDisabled, disableFocusRing: true, as: "span", attributes: {
|
|
118
|
+
"aria-label": decreaseAriaLabel,
|
|
119
|
+
"aria-controls": id,
|
|
120
|
+
role: "button",
|
|
121
|
+
tabIndex: decreaseDisabled ? undefined : -1,
|
|
122
|
+
onPointerDown: (e) => handleControlPointerDown(e, handleDecrease),
|
|
123
|
+
onPointerUp: handleControlPointerUp,
|
|
124
|
+
onPointerLeave: handleControlPointerUp,
|
|
125
|
+
// Prevent menu from opening on long press
|
|
126
|
+
onContextMenu: (e) => e.preventDefault(),
|
|
127
|
+
}, children: [_jsx(Icon, { svg: IconChevronDown, size: 3, className: s["icon--mouse"] }), _jsx(Icon, { svg: IconMinus, size: 4, className: s["icon--touch"] })] })] }));
|
|
128
|
+
return (_jsx(TextField, { attributes: {
|
|
129
|
+
...textFieldProps.attributes,
|
|
130
|
+
role: "group",
|
|
131
|
+
ref: rootRef,
|
|
132
|
+
}, id: inputId, hasError: hasError, inputAttributes: {
|
|
133
|
+
...textFieldProps.inputAttributes,
|
|
134
|
+
ref: inputRef,
|
|
135
|
+
inputMode: "numeric",
|
|
136
|
+
autoComplete: "off",
|
|
137
|
+
autoCorrect: "off",
|
|
138
|
+
spellCheck: "false",
|
|
139
|
+
min,
|
|
140
|
+
max,
|
|
141
|
+
step,
|
|
142
|
+
className: s.field,
|
|
143
|
+
}, ...textFieldProps, disabled: disabled, value: textValue, onChange: handleChange, name: name, endSlot: controlsNode }));
|
|
144
|
+
};
|
|
145
|
+
NumberFieldControlled.displayName = "NumberFieldControlled";
|
|
146
|
+
export default NumberFieldControlled;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import NumberFieldControlled from "./NumberFieldControlled.js";
|
|
5
|
+
const NumberFieldUncontrolled = (props) => {
|
|
6
|
+
const { defaultValue, onChange } = props;
|
|
7
|
+
const [value, setValue] = React.useState(defaultValue ?? null);
|
|
8
|
+
const handleChange = (args) => {
|
|
9
|
+
setValue(args.value);
|
|
10
|
+
if (onChange)
|
|
11
|
+
onChange(args);
|
|
12
|
+
};
|
|
13
|
+
return (_jsx(NumberFieldControlled, { ...props, value: value, defaultValue: undefined, onChange: handleChange }));
|
|
14
|
+
};
|
|
15
|
+
NumberFieldUncontrolled.displayName = "NumberFieldUncontrolled";
|
|
16
|
+
export default NumberFieldUncontrolled;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./NumberField.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StoryObj } from "@storybook/react";
|
|
2
|
+
import { Mock } from "@storybook/test";
|
|
3
|
+
declare const _default: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: {
|
|
6
|
+
(props: import("./..").NumberFieldProps): import("react").JSX.Element;
|
|
7
|
+
displayName: string;
|
|
8
|
+
};
|
|
9
|
+
parameters: {
|
|
10
|
+
iframe: {
|
|
11
|
+
url: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|
|
16
|
+
export declare const base: StoryObj;
|
|
17
|
+
export declare const disabled: StoryObj<{
|
|
18
|
+
handleChange: Mock;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const defaultValue: StoryObj<{
|
|
21
|
+
handleChange: Mock;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const value: StoryObj<{
|
|
24
|
+
handleChange: Mock;
|
|
25
|
+
}>;
|
|
26
|
+
export declare const minMax: StoryObj;
|
|
27
|
+
export declare const className: StoryObj;
|
|
28
|
+
export declare const formControl: StoryObj;
|
|
29
|
+
export declare const valueChanges: StoryObj;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { expect, fn, userEvent } from "@storybook/test";
|
|
2
|
+
import FormControl from "../../FormControl/index.js";
|
|
3
|
+
import NumberField from "../index.js";
|
|
4
|
+
import { Example } from "../../../utilities/storybook/index.js";
|
|
5
|
+
export default {
|
|
6
|
+
title: "Components/NumberField",
|
|
7
|
+
component: NumberField,
|
|
8
|
+
parameters: {
|
|
9
|
+
iframe: {
|
|
10
|
+
url: "https://reshaped.so/docs/components/number-field",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const base = {
|
|
15
|
+
name: "base",
|
|
16
|
+
render: () => {
|
|
17
|
+
return (<Example>
|
|
18
|
+
<Example.Item title="base">
|
|
19
|
+
<NumberField name="test-name" increaseAriaLabel="Increase" decreaseAriaLabel="Decrease" inputAttributes={{ "aria-label": "Label" }}/>
|
|
20
|
+
</Example.Item>
|
|
21
|
+
</Example>);
|
|
22
|
+
},
|
|
23
|
+
play: async ({ canvas }) => {
|
|
24
|
+
const input = canvas.getByRole("textbox");
|
|
25
|
+
const [increaseButton, decreaseButton] = canvas.getAllByRole("button");
|
|
26
|
+
expect(input).toHaveAttribute("name", "test-name");
|
|
27
|
+
expect(increaseButton).toHaveAccessibleName("Increase");
|
|
28
|
+
expect(decreaseButton).toHaveAccessibleName("Decrease");
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const disabled = {
|
|
32
|
+
name: "disabled",
|
|
33
|
+
args: {
|
|
34
|
+
handleChange: fn(),
|
|
35
|
+
},
|
|
36
|
+
render: (args) => (<NumberField name="test-name" onChange={args.handleChange} increaseAriaLabel="Increase" decreaseAriaLabel="Decrease" disabled inputAttributes={{ "aria-label": "Label" }}/>),
|
|
37
|
+
play: async ({ canvas, args }) => {
|
|
38
|
+
const input = canvas.getByRole("textbox");
|
|
39
|
+
const increaseButton = document.querySelector('[aria-label="Increase"]');
|
|
40
|
+
const decreaseButton = document.querySelector('[aria-label="Decrease"]');
|
|
41
|
+
expect(input).toBeDisabled();
|
|
42
|
+
await userEvent.click(increaseButton);
|
|
43
|
+
expect(args.handleChange).not.toHaveBeenCalled();
|
|
44
|
+
await userEvent.click(decreaseButton);
|
|
45
|
+
expect(args.handleChange).not.toHaveBeenCalled();
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const defaultValue = {
|
|
49
|
+
name: "defaultValue, uncontrolled",
|
|
50
|
+
args: {
|
|
51
|
+
handleChange: fn(),
|
|
52
|
+
},
|
|
53
|
+
render: (args) => (<NumberField name="test-name" defaultValue={2} onChange={args.handleChange} increaseAriaLabel="Increase" decreaseAriaLabel="Decrease" inputAttributes={{ "aria-label": "Label" }}/>),
|
|
54
|
+
play: async ({ canvas, args }) => {
|
|
55
|
+
const input = canvas.getByRole("textbox");
|
|
56
|
+
const [increaseButton, decreaseButton] = canvas.getAllByRole("button");
|
|
57
|
+
expect(input).toHaveValue("2");
|
|
58
|
+
input.focus();
|
|
59
|
+
await userEvent.keyboard("3");
|
|
60
|
+
expect(args.handleChange).toBeCalledTimes(1);
|
|
61
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
62
|
+
name: "test-name",
|
|
63
|
+
value: 23,
|
|
64
|
+
});
|
|
65
|
+
expect(input).toHaveValue("23");
|
|
66
|
+
await userEvent.click(increaseButton);
|
|
67
|
+
expect(args.handleChange).toBeCalledTimes(2);
|
|
68
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
69
|
+
name: "test-name",
|
|
70
|
+
value: 24,
|
|
71
|
+
});
|
|
72
|
+
expect(input).toHaveValue("24");
|
|
73
|
+
await userEvent.click(decreaseButton);
|
|
74
|
+
expect(args.handleChange).toBeCalledTimes(3);
|
|
75
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
76
|
+
name: "test-name",
|
|
77
|
+
value: 23,
|
|
78
|
+
});
|
|
79
|
+
expect(input).toHaveValue("23");
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
export const value = {
|
|
83
|
+
name: "value, controlled",
|
|
84
|
+
args: {
|
|
85
|
+
handleChange: fn(),
|
|
86
|
+
},
|
|
87
|
+
render: (args) => (<NumberField name="test-name" value={2} onChange={args.handleChange} increaseAriaLabel="Increase" decreaseAriaLabel="Decrease" inputAttributes={{ "aria-label": "Label" }}/>),
|
|
88
|
+
play: async ({ canvas, args }) => {
|
|
89
|
+
const input = canvas.getByRole("textbox");
|
|
90
|
+
const [increaseButton, decreaseButton] = canvas.getAllByRole("button");
|
|
91
|
+
expect(input).toHaveValue("2");
|
|
92
|
+
input.focus();
|
|
93
|
+
await userEvent.keyboard("3");
|
|
94
|
+
expect(args.handleChange).toBeCalledTimes(1);
|
|
95
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
96
|
+
name: "test-name",
|
|
97
|
+
value: 23,
|
|
98
|
+
});
|
|
99
|
+
expect(input).toHaveValue("23");
|
|
100
|
+
await userEvent.click(increaseButton);
|
|
101
|
+
expect(args.handleChange).toBeCalledTimes(2);
|
|
102
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
103
|
+
name: "test-name",
|
|
104
|
+
value: 24,
|
|
105
|
+
});
|
|
106
|
+
expect(input).toHaveValue("23");
|
|
107
|
+
await userEvent.click(decreaseButton);
|
|
108
|
+
expect(args.handleChange).toBeCalledTimes(3);
|
|
109
|
+
expect(args.handleChange).toHaveBeenLastCalledWith({
|
|
110
|
+
name: "test-name",
|
|
111
|
+
value: 22,
|
|
112
|
+
});
|
|
113
|
+
expect(input).toHaveValue("23");
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
export const minMax = {
|
|
117
|
+
name: "min, max, step",
|
|
118
|
+
render: () => (<NumberField name="test-name" defaultValue={6} min={5} max={15} step={5} increaseAriaLabel="Increase" decreaseAriaLabel="Decrease" inputAttributes={{ "aria-label": "Label" }}/>),
|
|
119
|
+
play: async ({ canvas }) => {
|
|
120
|
+
const input = canvas.getByRole("textbox");
|
|
121
|
+
const [increaseButton, decreaseButton] = canvas.getAllByRole("button");
|
|
122
|
+
expect(input).toHaveValue("6");
|
|
123
|
+
await userEvent.click(increaseButton);
|
|
124
|
+
expect(input).toHaveValue("11");
|
|
125
|
+
await userEvent.click(decreaseButton);
|
|
126
|
+
await userEvent.click(decreaseButton);
|
|
127
|
+
expect(input).toHaveValue("5");
|
|
128
|
+
await userEvent.click(increaseButton);
|
|
129
|
+
await userEvent.click(increaseButton);
|
|
130
|
+
await userEvent.click(increaseButton);
|
|
131
|
+
expect(input).toHaveValue("15");
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
export const className = {
|
|
135
|
+
name: "className, attributes",
|
|
136
|
+
render: () => (<div data-testid="root">
|
|
137
|
+
<NumberField className="test-classname" attributes={{ id: "test-id" }} name="name" inputAttributes={{ id: "test-input-id", "aria-label": "Label" }} increaseAriaLabel="Increase" decreaseAriaLabel="Decrease"/>
|
|
138
|
+
</div>),
|
|
139
|
+
play: async ({ canvas }) => {
|
|
140
|
+
const root = canvas.getByTestId("root").firstChild;
|
|
141
|
+
const input = canvas.getByRole("textbox");
|
|
142
|
+
expect(root).toHaveClass("test-classname");
|
|
143
|
+
expect(root).toHaveAttribute("id", "test-id");
|
|
144
|
+
expect(input).toHaveAttribute("id", "test-input-id");
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
export const formControl = {
|
|
148
|
+
name: "test: FormControl",
|
|
149
|
+
render: () => (<Example>
|
|
150
|
+
<Example.Item title="FormControl">
|
|
151
|
+
<FormControl>
|
|
152
|
+
<FormControl.Label>Label</FormControl.Label>
|
|
153
|
+
<NumberField name="name" increaseAriaLabel="Increase" decreaseAriaLabel="Decrease"/>
|
|
154
|
+
<FormControl.Helper>Helper</FormControl.Helper>
|
|
155
|
+
</FormControl>
|
|
156
|
+
</Example.Item>
|
|
157
|
+
|
|
158
|
+
<Example.Item title="FormControl, disabled">
|
|
159
|
+
<FormControl disabled>
|
|
160
|
+
<FormControl.Label>Label</FormControl.Label>
|
|
161
|
+
<NumberField name="name" increaseAriaLabel="Increase" decreaseAriaLabel="Decrease"/>
|
|
162
|
+
<FormControl.Helper>Helper</FormControl.Helper>
|
|
163
|
+
</FormControl>
|
|
164
|
+
</Example.Item>
|
|
165
|
+
|
|
166
|
+
<Example.Item title="FormControl, error">
|
|
167
|
+
<FormControl hasError>
|
|
168
|
+
<FormControl.Label>Label</FormControl.Label>
|
|
169
|
+
<NumberField name="name" increaseAriaLabel="Increase" decreaseAriaLabel="Decrease"/>
|
|
170
|
+
<FormControl.Error>Error</FormControl.Error>
|
|
171
|
+
</FormControl>
|
|
172
|
+
</Example.Item>
|
|
173
|
+
</Example>),
|
|
174
|
+
};
|
|
175
|
+
export const valueChanges = {
|
|
176
|
+
name: "test: keyboard",
|
|
177
|
+
render: () => (<Example>
|
|
178
|
+
<Example.Item title="keyboard">
|
|
179
|
+
<NumberField name="name" increaseAriaLabel="Increase" decreaseAriaLabel="Decrease"/>
|
|
180
|
+
</Example.Item>
|
|
181
|
+
</Example>),
|
|
182
|
+
play: async ({ canvas }) => {
|
|
183
|
+
const input = canvas.getByRole("textbox");
|
|
184
|
+
input.focus();
|
|
185
|
+
await userEvent.keyboard("-");
|
|
186
|
+
expect(input).toHaveValue("-");
|
|
187
|
+
await userEvent.keyboard("1");
|
|
188
|
+
expect(input).toHaveValue("-1");
|
|
189
|
+
await userEvent.keyboard("-");
|
|
190
|
+
expect(input).toHaveValue("-1");
|
|
191
|
+
await userEvent.keyboard("2");
|
|
192
|
+
expect(input).toHaveValue("-12");
|
|
193
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
194
|
+
expect(input).toHaveValue("-11");
|
|
195
|
+
await userEvent.keyboard("{ArrowDown}");
|
|
196
|
+
expect(input).toHaveValue("-12");
|
|
197
|
+
await userEvent.keyboard(".");
|
|
198
|
+
expect(input).toHaveValue("-12.");
|
|
199
|
+
await userEvent.keyboard("3");
|
|
200
|
+
expect(input).toHaveValue("-12.3");
|
|
201
|
+
await userEvent.keyboard(".");
|
|
202
|
+
expect(input).toHaveValue("-12.3");
|
|
203
|
+
await userEvent.keyboard("-");
|
|
204
|
+
expect(input).toHaveValue("-12.3");
|
|
205
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
206
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
207
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
208
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
209
|
+
await userEvent.keyboard("{ArrowUp}");
|
|
210
|
+
expect(input).toHaveValue("-7.3");
|
|
211
|
+
await userEvent.keyboard("{ArrowDown}");
|
|
212
|
+
expect(input).toHaveValue("-8.3");
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
// Value change edge cases
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.root{display:inline-flex
|
|
1
|
+
.root{display:inline-flex}.input,.root{vertical-align:top}.input{background:transparent;border:transparent;caret-color:transparent;color:transparent;font-size:16px;inset:0;outline:none;padding-left:100%;position:absolute}.item{box-sizing:border-box;cursor:text}.item--focused{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.item--focused:empty:before{animation:rs-pin-field-caret 1s ease-out infinite;background:var(--rs-color-foreground-neutral);border-radius:999px;content:"";height:var(--rs-font-size-body-2);left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:1px}@media (hover:hover){.root:hover .input{pointer-events:none}}@keyframes rs-pin-field-caret{0%,49.9%,to{opacity:1}50%,99.9%{opacity:0}}
|
|
@@ -11,6 +11,7 @@ import * as keys from "../../constants/keys.js";
|
|
|
11
11
|
import { regExpNumericChar, regExpAlphabeticChar, regExpAlphaNumericChar, } from "./PinField.constants.js";
|
|
12
12
|
import s from "./PinField.module.css";
|
|
13
13
|
const sizeMap = {
|
|
14
|
+
small: 7,
|
|
14
15
|
medium: 9,
|
|
15
16
|
large: 12,
|
|
16
17
|
xlarge: 14,
|
|
@@ -40,6 +40,14 @@ export const variant = () => (<Example>
|
|
|
40
40
|
</Example.Item>
|
|
41
41
|
</Example>);
|
|
42
42
|
export const size = () => (<Example>
|
|
43
|
+
<Example.Item title="size: small">
|
|
44
|
+
<PinField name="pin" size="small" inputAttributes={{ "aria-label": "Pin" }}/>
|
|
45
|
+
</Example.Item>
|
|
46
|
+
|
|
47
|
+
<Example.Item title="size: medium">
|
|
48
|
+
<PinField name="pin" size="medium" inputAttributes={{ "aria-label": "Pin" }}/>
|
|
49
|
+
</Example.Item>
|
|
50
|
+
|
|
43
51
|
<Example.Item title="size: large">
|
|
44
52
|
<PinField name="pin" size="large" inputAttributes={{ "aria-label": "Pin" }}/>
|
|
45
53
|
</Example.Item>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { classNames } from "../../utilities/helpers.js";
|
|
3
|
+
import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/helpers.js";
|
|
4
4
|
import HiddenInput from "../_private/HiddenInput/index.js";
|
|
5
|
+
import Text from "../Text/index.js";
|
|
5
6
|
import { useRadioGroup } from "../RadioGroup/index.js";
|
|
6
7
|
import { useFormControl } from "../FormControl/index.js";
|
|
7
8
|
import s from "./Radio.module.css";
|
|
8
9
|
const Radio = (props) => {
|
|
9
|
-
const { children, value, onChange, onFocus, onBlur, className, attributes, inputAttributes } = props;
|
|
10
|
+
const { children, value, onChange, onFocus, onBlur, size = "medium", className, attributes, inputAttributes, } = props;
|
|
10
11
|
const formControl = useFormControl();
|
|
11
12
|
const radioGroup = useRadioGroup();
|
|
12
13
|
const hasError = formControl?.hasError || props.hasError || radioGroup?.hasError;
|
|
@@ -14,7 +15,7 @@ const Radio = (props) => {
|
|
|
14
15
|
const checked = radioGroup ? radioGroup.value === value : props.checked;
|
|
15
16
|
const defaultChecked = radioGroup ? undefined : props.defaultChecked;
|
|
16
17
|
const name = radioGroup ? radioGroup.name : props.name;
|
|
17
|
-
const rootClassName = classNames(s.root, className, hasError && s["--error"], disabled && s["--disabled"]);
|
|
18
|
+
const rootClassName = classNames(s.root, className, hasError && s["--error"], disabled && s["--disabled"], size && responsiveClassNames(s, "--size", size));
|
|
18
19
|
const handleChange = (event) => {
|
|
19
20
|
if (!name)
|
|
20
21
|
return;
|
|
@@ -25,7 +26,13 @@ const Radio = (props) => {
|
|
|
25
26
|
if (radioGroup?.onChange)
|
|
26
27
|
radioGroup.onChange(changeArgs);
|
|
27
28
|
};
|
|
28
|
-
return (_jsxs("label", { ...attributes, className: rootClassName, children: [_jsxs("span", { className: s.field, children: [_jsx(HiddenInput, { className: s.input, type: "radio", checked: checked, defaultChecked: defaultChecked, name: name, disabled: disabled, value: value, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, attributes: inputAttributes }), _jsx("div", { className: s.decorator })] }), children && _jsx(
|
|
29
|
+
return (_jsxs("label", { ...attributes, className: rootClassName, children: [_jsxs("span", { className: s.field, children: [_jsx(HiddenInput, { className: s.input, type: "radio", checked: checked, defaultChecked: defaultChecked, name: name, disabled: disabled, value: value, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, attributes: inputAttributes }), _jsx("div", { className: s.decorator })] }), children && (_jsx(Text, { as: "span", variant: responsivePropDependency(size, (size) => {
|
|
30
|
+
if (size === "large")
|
|
31
|
+
return "body-2";
|
|
32
|
+
if (size === "small")
|
|
33
|
+
return "caption-1";
|
|
34
|
+
return "body-3";
|
|
35
|
+
}), children: children }))] }));
|
|
29
36
|
};
|
|
30
37
|
Radio.displayName = "Radio";
|
|
31
38
|
export default Radio;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.root{align-items:center;cursor:pointer;display:inline-flex;user-select:none;vertical-align:top;-webkit-tap-highlight-color:transparent}.root:hover .
|
|
1
|
+
@layer rs.radio.base;@layer rs.radio.error;@layer rs.radio.checked;@layer rs.radio.disabled;@layer rs.radio.base{.root{align-items:center;cursor:pointer;display:inline-flex;gap:var(--rs-radio-gap);user-select:none;vertical-align:top;-webkit-tap-highlight-color:transparent}.root:hover .decorator{background:var(--rs-color-background-neutral-faded)}.field{position:relative}.decorator{background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);border-radius:50%;height:var(--rs-radio-line-height);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background-color,border-color;width:var(--rs-radio-line-height)}.decorator:after{background:var(--rs-color-on-background-primary);border-radius:50%;content:"";height:calc(var(--rs-radio-line-height) * .4);left:50%;opacity:0;position:absolute;top:50%;transform:translate(-50%,-50%) scale(0);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;width:calc(var(--rs-radio-line-height) * .4)}.--size-small{--rs-radio-line-height:var(--rs-line-height-caption-1);--rs-radio-gap:var(--rs-unit-x1)}.--size-medium{--rs-radio-line-height:var(--rs-line-height-body-3);--rs-radio-gap:var(--rs-unit-x2)}.--size-large{--rs-radio-line-height:var(--rs-line-height-body-2);--rs-radio-gap:var(--rs-unit-x2)}[data-rs-keyboard] .input:focus+.decorator{box-shadow:var(--rs-focus-shadow)}}@layer rs.radio.error{.root.--error .decorator{border-color:var(--rs-color-border-critical)}}@layer rs.radio.checked{.input:checked+.decorator{background:var(--rs-color-background-primary);border-color:var(--rs-color-background-primary)}.input:checked+.decorator:after{opacity:1;transform:translate(-50%,-50%) scale(1)}}@layer rs.radio.disabled{.root.--disabled{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.root.--disabled .decorator{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled .decorator:after{background-color:var(--rs-color-foreground-disabled)}.root.--disabled .input:checked+.decorator{background:var(--rs-color-background-disabled);border-color:transparent}}@media (--rs-viewport-m ){.--size-small--m{--rs-radio-line-height:var(--rs-line-height-caption-1);--rs-radio-gap:var(--rs-unit-x1)}.--size-medium--m{--rs-radio-line-height:var(--rs-line-height-body-3);--rs-radio-gap:var(--rs-unit-x2)}.--size-large--m{--rs-radio-line-height:var(--rs-line-height-body-2);--rs-radio-gap:var(--rs-unit-x2)}}@media (--rs-viewport-l ){.--size-small--l{--rs-radio-line-height:var(--rs-line-height-caption-1);--rs-radio-gap:var(--rs-unit-x1)}.--size-medium--l{--rs-radio-line-height:var(--rs-line-height-body-3);--rs-radio-gap:var(--rs-unit-x2)}.--size-large--l{--rs-radio-line-height:var(--rs-line-height-body-2);--rs-radio-gap:var(--rs-unit-x2)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-radio-line-height:var(--rs-line-height-caption-1);--rs-radio-gap:var(--rs-unit-x1)}.--size-medium--xl{--rs-radio-line-height:var(--rs-line-height-body-3);--rs-radio-gap:var(--rs-unit-x2)}.--size-large--xl{--rs-radio-line-height:var(--rs-line-height-body-2);--rs-radio-gap:var(--rs-unit-x2)}}
|
|
@@ -12,5 +12,6 @@ declare const _default: {
|
|
|
12
12
|
};
|
|
13
13
|
export default _default;
|
|
14
14
|
export declare const selection: () => import("react").JSX.Element;
|
|
15
|
+
export declare const size: () => import("react").JSX.Element;
|
|
15
16
|
export declare const error: () => import("react").JSX.Element;
|
|
16
17
|
export declare const disabled: () => import("react").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Example } from "../../../utilities/storybook/index.js";
|
|
2
2
|
import Radio from "../index.js";
|
|
3
|
+
import View from "../../View/index.js";
|
|
3
4
|
export default {
|
|
4
5
|
title: "Components/Radio",
|
|
5
6
|
component: Radio,
|
|
@@ -28,6 +29,36 @@ export const selection = () => (<Example>
|
|
|
28
29
|
</Radio>
|
|
29
30
|
</Example.Item>
|
|
30
31
|
</Example>);
|
|
32
|
+
export const size = () => (<Example>
|
|
33
|
+
<Example.Item title="size: small">
|
|
34
|
+
<View gap={4} direction="row">
|
|
35
|
+
<Radio name="animal" value="dog" size="small" defaultChecked>
|
|
36
|
+
Radio
|
|
37
|
+
</Radio>
|
|
38
|
+
</View>
|
|
39
|
+
</Example.Item>
|
|
40
|
+
<Example.Item title="size: medium">
|
|
41
|
+
<View gap={4} direction="row">
|
|
42
|
+
<Radio name="animal" value="dog" size="medium">
|
|
43
|
+
Radio
|
|
44
|
+
</Radio>
|
|
45
|
+
</View>
|
|
46
|
+
</Example.Item>
|
|
47
|
+
<Example.Item title="size: large">
|
|
48
|
+
<View gap={4} direction="row">
|
|
49
|
+
<Radio name="animal" value="dog" size="large">
|
|
50
|
+
Radio
|
|
51
|
+
</Radio>
|
|
52
|
+
</View>
|
|
53
|
+
</Example.Item>
|
|
54
|
+
<Example.Item title="size: responsive, s: small, m: large">
|
|
55
|
+
<View gap={4} direction="row">
|
|
56
|
+
<Radio name="animal" value="dog" size={{ s: "small", m: "large" }}>
|
|
57
|
+
Radio
|
|
58
|
+
</Radio>
|
|
59
|
+
</View>
|
|
60
|
+
</Example.Item>
|
|
61
|
+
</Example>);
|
|
31
62
|
export const error = () => (<Example>
|
|
32
63
|
<Example.Item title="error">
|
|
33
64
|
<Radio name="error" value="dog" hasError>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.root{background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;overflow:hidden;padding:calc(var(--rs-unit-x1) - 1px) 0;position:relative;z-index:0}.root:focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.input{align-items:center;-webkit-appearance:none;appearance:none;background:none;border:0;box-sizing:border-box;color:var(--rs-color-foreground-neutral);cursor:pointer;display:flex;flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);outline:none;padding-inline-end:calc(var(--rs-select-chevron-size) + var(--rs-select-gap) * 2 + var(--rs-unit-x1));padding-inline-start:var(--rs-select-gap);position:relative;width:100%;z-index:1}.input::-ms-expand{display:none}.slot{align-items:center;display:flex;flex-shrink:0;padding-inline-start:var(--rs-select-gap);position:relative;z-index:5}.input .slot{padding-inline-end:var(--rs-select-gap);padding-inline-start:0}.arrow{color:var(--rs-color-foreground-neutral-faded);display:flex;inset-block-start:50%;inset-inline-end:var(--rs-select-gap);pointer-events:none;position:absolute;transform:translateY(-50%);z-index:5}.--size-
|
|
1
|
+
.root{background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;overflow:hidden;padding:calc(var(--rs-unit-x1) - 1px) 0;position:relative;z-index:0}.root:focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.input{align-items:center;-webkit-appearance:none;appearance:none;background:none;border:0;box-sizing:border-box;color:var(--rs-color-foreground-neutral);cursor:pointer;display:flex;flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);outline:none;padding-inline-end:calc(var(--rs-select-chevron-size) + var(--rs-select-gap) * 2 + var(--rs-unit-x1));padding-inline-start:var(--rs-select-gap);position:relative;width:100%;z-index:1}.input::-ms-expand{display:none}.slot{align-items:center;display:flex;flex-shrink:0;padding-inline-start:var(--rs-select-gap);position:relative;z-index:5}.input .slot{padding-inline-end:var(--rs-select-gap);padding-inline-start:0}.arrow{color:var(--rs-color-foreground-neutral-faded);display:flex;inset-block-start:50%;inset-inline-end:var(--rs-select-gap);pointer-events:none;position:absolute;transform:translateY(-50%);z-index:5}.--size-small{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent;border-color:transparent}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent;box-shadow:none}.root.--status-error{border-color:var(--rs-color-border-critical)}.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}.root.--placeholder .input{color:var(--rs-color-foreground-neutral-faded)}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled .arrow,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-small--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--m{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--m{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--m{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}@media (--rs-viewport-l ){.--size-small--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--l{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--l{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--l{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-small--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:0}.--size-medium--xl{--rs-select-gap:var(--rs-unit-x2);--rs-select-chevron-size:var(--rs-unit-x4);border-radius:var(--rs-radius-small)}.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3);padding-block:var(--rs-unit-x1)}.--size-large--xl{--rs-select-gap:var(--rs-unit-x3);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x2)}.--size-xlarge--xl{--rs-select-gap:var(--rs-unit-x4);--rs-select-chevron-size:var(--rs-unit-x5);border-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2);padding-block:var(--rs-unit-x3)}}
|