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
@@ -3,7 +3,7 @@ import type * as G from "../../types/global";
|
|
3
3
|
import type { FormControlProps } from "../FormControl";
|
4
4
|
import type { ActionableProps } from "../Actionable";
|
5
5
|
import type { IconProps } from "../Icon";
|
6
|
-
type Size = G.Responsive<"medium" | "large" | "xlarge">;
|
6
|
+
type Size = G.Responsive<"small" | "medium" | "large" | "xlarge">;
|
7
7
|
type Option = {
|
8
8
|
label: string;
|
9
9
|
value: string;
|
@@ -44,46 +44,72 @@ export const variants = () => (<Example>
|
|
44
44
|
</Example.Item>
|
45
45
|
</Example>);
|
46
46
|
export const size = () => (<Example>
|
47
|
-
<Example.Item title="size:
|
48
|
-
<
|
47
|
+
<Example.Item title="size: small">
|
48
|
+
<View direction="row" gap={4}>
|
49
|
+
<View.Item grow>
|
50
|
+
<Select size="small" name="animal" icon={IconZap} options={[
|
49
51
|
{ label: "Dog", value: "dog" },
|
50
52
|
{ label: "Turtle", value: "turtle" },
|
51
53
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
<Select size="medium" name="animal" icon={IconZap} options={[
|
54
|
+
</View.Item>
|
55
|
+
<View.Item grow>
|
56
|
+
<Select size="small" name="animal" startSlot={<Placeholder h={16}/>} options={[
|
56
57
|
{ label: "Dog", value: "dog" },
|
57
58
|
{ label: "Turtle", value: "turtle" },
|
58
59
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
60
|
+
</View.Item>
|
61
|
+
</View>
|
59
62
|
</Example.Item>
|
60
63
|
|
61
|
-
<Example.Item title="size:
|
62
|
-
<
|
64
|
+
<Example.Item title="size: medium">
|
65
|
+
<View direction="row" gap={4}>
|
66
|
+
<View.Item grow>
|
67
|
+
<Select size="medium" name="animal" icon={IconZap} options={[
|
63
68
|
{ label: "Dog", value: "dog" },
|
64
69
|
{ label: "Turtle", value: "turtle" },
|
65
70
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
<Select size="large" name="animal" icon={IconZap} options={[
|
71
|
+
</View.Item>
|
72
|
+
<View.Item grow>
|
73
|
+
<Select size="medium" name="animal" startSlot={<Placeholder h={24}/>} options={[
|
70
74
|
{ label: "Dog", value: "dog" },
|
71
75
|
{ label: "Turtle", value: "turtle" },
|
72
76
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
77
|
+
</View.Item>
|
78
|
+
</View>
|
73
79
|
</Example.Item>
|
74
80
|
|
75
|
-
<Example.Item title="size:
|
76
|
-
<
|
81
|
+
<Example.Item title="size: large">
|
82
|
+
<View direction="row" gap={4}>
|
83
|
+
<View.Item grow>
|
84
|
+
<Select size="large" name="animal" icon={IconZap} options={[
|
85
|
+
{ label: "Dog", value: "dog" },
|
86
|
+
{ label: "Turtle", value: "turtle" },
|
87
|
+
]} inputAttributes={{ "aria-label": "test select" }}/>
|
88
|
+
</View.Item>
|
89
|
+
<View.Item grow>
|
90
|
+
<Select size="large" name="animal" startSlot={<Placeholder h={24}/>} options={[
|
77
91
|
{ label: "Dog", value: "dog" },
|
78
92
|
{ label: "Turtle", value: "turtle" },
|
79
93
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
94
|
+
</View.Item>
|
95
|
+
</View>
|
80
96
|
</Example.Item>
|
81
97
|
|
82
|
-
<Example.Item title="size: xlarge
|
83
|
-
<
|
98
|
+
<Example.Item title="size: xlarge">
|
99
|
+
<View direction="row" gap={4}>
|
100
|
+
<View.Item grow>
|
101
|
+
<Select size="xlarge" name="animal" icon={IconZap} options={[
|
102
|
+
{ label: "Dog", value: "dog" },
|
103
|
+
{ label: "Turtle", value: "turtle" },
|
104
|
+
]} inputAttributes={{ "aria-label": "test select" }}/>
|
105
|
+
</View.Item>
|
106
|
+
<View.Item grow>
|
107
|
+
<Select size="xlarge" name="animal" startSlot={<Placeholder h={24}/>} options={[
|
84
108
|
{ label: "Dog", value: "dog" },
|
85
109
|
{ label: "Turtle", value: "turtle" },
|
86
110
|
]} inputAttributes={{ "aria-label": "test select" }}/>
|
111
|
+
</View.Item>
|
112
|
+
</View>
|
87
113
|
</Example.Item>
|
88
114
|
|
89
115
|
<Example.Item title={["responsive size", "[s] xlarge", "[m+] medium"]}>
|
@@ -1,13 +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 { useFormControl } from "../FormControl/index.js";
|
5
5
|
import Text from "../Text/index.js";
|
6
6
|
import useElementId from "../../hooks/useElementId.js";
|
7
7
|
import s from "./Switch.module.css";
|
8
8
|
const Switch = (props) => {
|
9
|
-
const { children, name, checked, size, reversed, defaultChecked, onChange, onFocus, onBlur, className, attributes, } = props;
|
10
|
-
const rootClassNames = classNames(s.root, size && s
|
9
|
+
const { children, name, checked, size = "medium", reversed, defaultChecked, onChange, onFocus, onBlur, className, attributes, } = props;
|
10
|
+
const rootClassNames = classNames(s.root, size && responsiveClassNames(s, "--size", size), reversed && s["--reversed"], className);
|
11
11
|
const formControl = useFormControl();
|
12
12
|
const id = useElementId(formControl?.attributes.id || props.id || props.inputAttributes?.id);
|
13
13
|
const inputAttributes = { ...props.inputAttributes, ...formControl?.attributes };
|
@@ -21,7 +21,13 @@ const Switch = (props) => {
|
|
21
21
|
checked: event.target.checked,
|
22
22
|
});
|
23
23
|
};
|
24
|
-
return (_jsxs("label", { ...attributes, className: rootClassNames, children: [_jsx("input", { type: "checkbox", ...inputAttributes, className: s.input, name: name, checked: checked, defaultChecked: defaultChecked, disabled: disabled, onChange: handleChange, onFocus: onFocus || inputAttributes?.onFocus, onBlur: onBlur || inputAttributes?.onBlur, id: id }), _jsx("span", { className: s.area, "aria-hidden": "true", children: _jsx("span", { className: s.thumb }) }), children && (_jsx(Text, { variant: size
|
24
|
+
return (_jsxs("label", { ...attributes, className: rootClassNames, children: [_jsx("input", { type: "checkbox", ...inputAttributes, className: s.input, name: name, checked: checked, defaultChecked: defaultChecked, disabled: disabled, onChange: handleChange, onFocus: onFocus || inputAttributes?.onFocus, onBlur: onBlur || inputAttributes?.onBlur, id: id }), _jsx("span", { className: s.area, "aria-hidden": "true", children: _jsx("span", { className: s.thumb }) }), children && (_jsx(Text, { variant: responsivePropDependency(size, (value) => {
|
25
|
+
if (value === "large")
|
26
|
+
return "body-2";
|
27
|
+
if (value === "medium")
|
28
|
+
return "body-3";
|
29
|
+
return "caption-1";
|
30
|
+
}), weight: "medium", color: disabled ? "disabled" : undefined, children: children }))] }));
|
25
31
|
};
|
26
32
|
Switch.displayName = "Switch";
|
27
33
|
export default Switch;
|
@@ -1 +1 @@
|
|
1
|
-
.root{align-items:center;display:inline-flex;gap:var(--rs-
|
1
|
+
.root{align-items:center;display:inline-flex;gap:var(--rs-switch-gap);position:relative;vertical-align:top;-webkit-tap-highlight-color:transparent}.root.--reversed{flex-direction:row-reverse}.input{border:0;height:1px;left:0;opacity:0;outline:none;position:absolute;top:0;width:1px}.input:checked+.area{background:var(--rs-color-background-primary);border-color:transparent}.input:checked+.area .thumb{transform:translateX(calc(var(--rs-switch-width) - var(--rs-switch-height)))}[dir=rtl] .input:checked+.area .thumb{transform:translateX(calc(var(--rs-switch-height) - var(--rs-switch-width)))}[data-rs-keyboard] .input:focus+.area{box-shadow:var(--rs-focus-shadow)}.input[disabled]+.area{background:var(--rs-color-background-disabled);cursor:not-allowed}.input[disabled]+.area .thumb{opacity:.8}.input[disabled]:checked+.area{background:var(--rs-color-background-primary);opacity:.4}.input[disabled]:checked+.area .thumb{opacity:1}.area{align-items:center;background:var(--rs-color-background-neutral);border:2px solid transparent;box-sizing:border-box;cursor:pointer;display:flex;height:var(--rs-switch-height);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:background,border;width:var(--rs-switch-width)}.area,.thumb{border-radius:999px}.thumb{background:var(--rs-color-white);box-shadow:var(--rs-shadow-raised);height:calc(var(--rs-switch-height) - var(--rs-unit-x1));transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:transform;width:calc(var(--rs-switch-height) - var(--rs-unit-x1))}.--size-small{--rs-switch-height:var(--rs-unit-x4);--rs-switch-width:var(--rs-unit-x6);--rs-switch-gap:var(--rs-unit-x1);--rs-switch-line-height:var(--rs-line-height-caption-1);--rs-switch-font-size:var(--rs-font-size-caption-1)}.--size-medium{--rs-switch-height:var(--rs-unit-x5);--rs-switch-width:var(--rs-unit-x8);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-3);--rs-switch-font-size:var(--rs-font-size-body-3)}.--size-large{--rs-switch-height:var(--rs-unit-x6);--rs-switch-width:var(--rs-unit-x10);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-2);--rs-switch-font-size:var(--rs-font-size-body-2)}@media (--rs-viewport-m ){.--size-small--m{--rs-switch-height:var(--rs-unit-x4);--rs-switch-width:var(--rs-unit-x6);--rs-switch-gap:var(--rs-unit-x1);--rs-switch-line-height:var(--rs-line-height-caption-1);--rs-switch-font-size:var(--rs-font-size-caption-1)}.--size-medium--m{--rs-switch-height:var(--rs-unit-x5);--rs-switch-width:var(--rs-unit-x8);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-3);--rs-switch-font-size:var(--rs-font-size-body-3)}.--size-large--m{--rs-switch-height:var(--rs-unit-x6);--rs-switch-width:var(--rs-unit-x10);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-2);--rs-switch-font-size:var(--rs-font-size-body-2)}}@media (--rs-viewport-l ){.--size-small--l{--rs-switch-height:var(--rs-unit-x4);--rs-switch-width:var(--rs-unit-x6);--rs-switch-gap:var(--rs-unit-x1);--rs-switch-line-height:var(--rs-line-height-caption-1);--rs-switch-font-size:var(--rs-font-size-caption-1)}.--size-medium--l{--rs-switch-height:var(--rs-unit-x5);--rs-switch-width:var(--rs-unit-x8);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-3);--rs-switch-font-size:var(--rs-font-size-body-3)}.--size-large--l{--rs-switch-height:var(--rs-unit-x6);--rs-switch-width:var(--rs-unit-x10);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-2);--rs-switch-font-size:var(--rs-font-size-body-2)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-switch-height:var(--rs-unit-x4);--rs-switch-width:var(--rs-unit-x6);--rs-switch-gap:var(--rs-unit-x1);--rs-switch-line-height:var(--rs-line-height-caption-1);--rs-switch-font-size:var(--rs-font-size-caption-1)}.--size-medium--xl{--rs-switch-height:var(--rs-unit-x5);--rs-switch-width:var(--rs-unit-x8);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-3);--rs-switch-font-size:var(--rs-font-size-body-3)}.--size-large--xl{--rs-switch-height:var(--rs-unit-x6);--rs-switch-width:var(--rs-unit-x10);--rs-switch-gap:var(--rs-unit-x2);--rs-switch-line-height:var(--rs-line-height-body-2);--rs-switch-font-size:var(--rs-font-size-body-2)}}
|
@@ -6,7 +6,7 @@ type BaseProps = {
|
|
6
6
|
name: string;
|
7
7
|
disabled?: boolean;
|
8
8
|
reversed?: boolean;
|
9
|
-
size?: "medium" | "small" | "large"
|
9
|
+
size?: G.Responsive<"medium" | "small" | "large">;
|
10
10
|
onChange?: G.ChangeHandler<boolean>;
|
11
11
|
onFocus?: (e: React.FocusEvent) => void;
|
12
12
|
onBlur?: (e: React.FocusEvent) => void;
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Example } from "../../../utilities/storybook/index.js";
|
2
2
|
import Switch from "../index.js";
|
3
|
+
import View from "../../View/index.js";
|
3
4
|
export default {
|
4
5
|
title: "Components/Switch",
|
5
6
|
component: Switch,
|
@@ -30,27 +31,41 @@ export const size = () => (<Example>
|
|
30
31
|
<Example.Item title="size: large">
|
31
32
|
<Switch name="active" size="large" inputAttributes={{ "aria-label": "test switch" }}/>
|
32
33
|
</Example.Item>
|
34
|
+
<Example.Item title="size: responsive, s: small, m: large">
|
35
|
+
<Switch name="active" size={{ s: "small", m: "large" }} inputAttributes={{ "aria-label": "test switch" }}/>
|
36
|
+
</Example.Item>
|
33
37
|
</Example>);
|
34
38
|
export const label = () => (<Example>
|
35
39
|
<Example.Item title="size: medium">
|
36
|
-
<
|
37
|
-
|
38
|
-
|
40
|
+
<View direction="row" gap={8}>
|
41
|
+
<Switch name="active" inputAttributes={{ "aria-label": "test switch" }}>
|
42
|
+
Wi-fi
|
43
|
+
</Switch>
|
44
|
+
<Switch reversed name="active" inputAttributes={{ "aria-label": "test switch" }}>
|
45
|
+
Wi-fi
|
46
|
+
</Switch>
|
47
|
+
</View>
|
39
48
|
</Example.Item>
|
40
49
|
<Example.Item title="size: small">
|
41
|
-
<
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
</
|
50
|
+
<View direction="row" gap={8}>
|
51
|
+
<Switch name="active" size="small" inputAttributes={{ "aria-label": "test switch" }}>
|
52
|
+
Wi-fi
|
53
|
+
</Switch>
|
54
|
+
<Switch reversed name="active" size="small" inputAttributes={{ "aria-label": "test switch" }}>
|
55
|
+
Wi-fi
|
56
|
+
</Switch>
|
57
|
+
</View>
|
49
58
|
</Example.Item>
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
59
|
+
|
60
|
+
<Example.Item title="size: large">
|
61
|
+
<View direction="row" gap={8}>
|
62
|
+
<Switch name="active" size="large" inputAttributes={{ "aria-label": "test switch" }}>
|
63
|
+
Wi-fi
|
64
|
+
</Switch>
|
65
|
+
<Switch reversed name="active" size="large" inputAttributes={{ "aria-label": "test switch" }}>
|
66
|
+
Wi-fi
|
67
|
+
</Switch>
|
68
|
+
</View>
|
54
69
|
</Example.Item>
|
55
70
|
</Example>);
|
56
71
|
export const disabled = () => (<Example>
|
@@ -50,7 +50,7 @@ const TextField = (props) => {
|
|
50
50
|
return;
|
51
51
|
onChange({ name, value: event.target.value, event });
|
52
52
|
};
|
53
|
-
return (_jsxs("div", { ...attributes, "data-rs-aligner-target": true, className: rootClassName, children: [_jsx(TextFieldSlot, { position: "start", icon: icon, slot: startSlot, size: size, affix: prefix, id: id }), _jsx("input", { ...inputAttributes, className: s.input, disabled: disabled, name: name, placeholder: placeholder, value: value, defaultValue: defaultValue, onChange: handleChange, onFocus: onFocus || inputAttributes?.onFocus, onBlur: onBlur || inputAttributes?.onBlur, id: inputId }), _jsx(TextFieldSlot, { position: "end", icon: endIcon, slot: endSlot, size: size, affix: suffix, id: id })] }));
|
53
|
+
return (_jsxs("div", { ...attributes, "data-rs-aligner-target": true, className: rootClassName, children: [_jsx(TextFieldSlot, { position: "start", icon: icon, slot: startSlot, size: size, affix: prefix, id: id }), _jsx("input", { type: "text", ...inputAttributes, className: classNames(s.input, inputAttributes.className), disabled: disabled, name: name, placeholder: placeholder, value: value, defaultValue: defaultValue, onChange: handleChange, onFocus: onFocus || inputAttributes?.onFocus, onBlur: onBlur || inputAttributes?.onBlur, id: inputId }), _jsx(TextFieldSlot, { position: "end", icon: endIcon, slot: endSlot, size: size, affix: suffix, id: id })] }));
|
54
54
|
};
|
55
55
|
TextField.Aligner = Aligner;
|
56
56
|
TextField.displayName = "TextField";
|
@@ -1 +1 @@
|
|
1
|
-
.root{--rs-p-h:var(--rs-text-field-gap);align-items:center;background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);
|
1
|
+
.root{--rs-p-h:var(--rs-text-field-gap);align-items:center;background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);border-radius:var(--rs-text-field-radius);display:flex;gap:var(--rs-text-field-gap);padding:0 calc(var(--rs-text-field-gap) - 1px);position:relative;row-gap:var(--rs-unit-x1);z-index:0}.root.--focused,.root:has(label:active),.root:not(:has(button:focus,a:focus,[tabindex="0"]:focus,[role=button]:focus)):focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.root.--multiline{flex-wrap:wrap}.root.--multiline .input{width:auto}.root.--rounded{border-radius:999px}.root.--rounded .affix:first-child,.root.--rounded .icon:first-child{padding-inline-start:var(--rs-unit-x1)}.root.--rounded .input:first-child{padding-inline-start:calc(var(--rs-text-field-gap) + var(--rs-unit-x1))}.input{background:none;border:none;box-sizing:border-box;color:var(--rs-color-foreground-neutral);flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);margin:0 calc(var(--rs-text-field-gap) * -1);outline:none;padding-block:calc(var(--rs-text-field-p-v) - 1px);padding-inline:var(--rs-text-field-gap);position:relative;width:100%;z-index:1}.input:-webkit-autofill{-webkit-background-clip:text;-webkit-text-fill-color:var(--rs-color-foreground-neutral)}.affix,.input{font-size:var(--rs-text-field-font-size);letter-spacing:var(--rs-text-field-letter-spacing);line-height:var(--rs-text-field-line-height)}.affix,.icon{cursor:text}.affix,.icon,.slot{align-items:center;display:flex;flex-shrink:0;max-width:100%;min-height:calc(var(--rs-text-field-line-height) + var(--rs-unit-x2) - 2px);position:relative;z-index:5}.slot--position-end:last-child{margin-inline-end:calc(var(--rs-text-field-gap) * -1);padding-inline-end:var(--rs-text-field-action-inset)}.affix{color:var(--rs-color-foreground-neutral-faded)}.affix.affix--position-start{padding-inline-end:var(--rs-text-field-gap)}.affix.affix--position-start:after{border-inline-end:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-end:0;position:absolute}.affix.affix--position-end{padding-inline-start:var(--rs-text-field-gap)}.affix.affix--position-end:after{border-inline-start:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-start:0;position:absolute}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.--size-small{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x1);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-medium{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x2);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-large{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x3);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x2)}.--size-xlarge{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x4);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x1)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded.--focused,.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.--focused,.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.--focused,.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}@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-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x1);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-medium--m{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x2);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-large--m{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x3);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x2)}.--size-xlarge--m{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x4);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x1)}}@media (--rs-viewport-l ){.--size-small--l{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x1);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-medium--l{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x2);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-large--l{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x3);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x2)}.--size-xlarge--l{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x4);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x1)}}@media (--rs-viewport-xl ){.--size-small--xl{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x1);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-medium--xl{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x2);--rs-text-field-font-size:var(--rs-font-size-body-3);--rs-text-field-line-height:var(--rs-line-height-body-3);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-3);--rs-text-field-action-inset:var(--rs-unit-x1)}.--size-large--xl{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x3);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x2)}.--size-xlarge--xl{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-radius:var(--rs-radius-small);--rs-text-field-p-v:var(--rs-unit-x4);--rs-text-field-font-size:var(--rs-font-size-body-2);--rs-text-field-line-height:var(--rs-line-height-body-2);--rs-text-field-letter-spacing:var(--rs-letter-spacing-body-2);--rs-text-field-action-inset:var(--rs-unit-x1)}}
|
@@ -2,8 +2,8 @@ import type React from "react";
|
|
2
2
|
import type * as G from "../../types/global";
|
3
3
|
import type { FormControlProps } from "../FormControl";
|
4
4
|
import type { IconProps } from "../Icon";
|
5
|
-
type Size = G.Responsive<"medium" | "large" | "xlarge">;
|
6
|
-
type BaseProps = {
|
5
|
+
type Size = G.Responsive<"small" | "medium" | "large" | "xlarge">;
|
6
|
+
export type BaseProps = {
|
7
7
|
id?: string;
|
8
8
|
name: string;
|
9
9
|
size?: Size;
|
@@ -1,2 +1,2 @@
|
|
1
1
|
export { default } from "./TextField";
|
2
|
-
export type { Props as TextFieldProps } from "./TextField.types";
|
2
|
+
export type { Props as TextFieldProps, BaseProps as TextFieldBaseProps } from "./TextField.types";
|
@@ -83,6 +83,10 @@ export const attachments = () => (<Example>
|
|
83
83
|
</Example.Item>
|
84
84
|
</Example>);
|
85
85
|
export const size = () => (<Example>
|
86
|
+
<Example.Item title="size: small">
|
87
|
+
<TextField name="Name" placeholder="Enter your name" size="small" icon={IconZap}/>
|
88
|
+
</Example.Item>
|
89
|
+
|
86
90
|
<Example.Item title="size: medium">
|
87
91
|
<TextField name="Name" placeholder="Enter your name" size="medium" icon={IconZap}/>
|
88
92
|
</Example.Item>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import { expect, userEvent } from "@storybook/test";
|
3
|
+
import { Example } from "../../utilities/storybook/index.js";
|
3
4
|
import Button from "../../components/Button/index.js";
|
4
5
|
import useScrollLock from "../useScrollLock.js";
|
5
6
|
import View from "../../components/View/index.js";
|
@@ -66,3 +67,31 @@ export const container = {
|
|
66
67
|
expect(root).not.toHaveStyle("overflow: hidden");
|
67
68
|
},
|
68
69
|
};
|
70
|
+
export const testContainerAsync = {
|
71
|
+
name: "test: containerRef locked count",
|
72
|
+
render: () => {
|
73
|
+
const containerRef = React.useRef(null);
|
74
|
+
const globalLock = useScrollLock();
|
75
|
+
const scopedLock = useScrollLock({ containerRef });
|
76
|
+
return (<Example>
|
77
|
+
<Example.Item title="calling regular lock and lock with a container only requires a single unlock to remove overflow">
|
78
|
+
<View attributes={{ ref: containerRef }} gap={4} direction="row">
|
79
|
+
<Button onClick={globalLock.scrollLocked ? globalLock.unlockScroll : globalLock.lockScroll}>
|
80
|
+
Toggle
|
81
|
+
</Button>
|
82
|
+
<Button onClick={scopedLock.scrollLocked ? scopedLock.unlockScroll : scopedLock.lockScroll}>
|
83
|
+
Toggle
|
84
|
+
</Button>
|
85
|
+
</View>
|
86
|
+
</Example.Item>
|
87
|
+
</Example>);
|
88
|
+
},
|
89
|
+
play: async ({ canvas }) => {
|
90
|
+
const [buttonGlobal, buttonScoped] = canvas.getAllByRole("button");
|
91
|
+
await userEvent.click(buttonGlobal);
|
92
|
+
expect(document.body).toHaveStyle("overflow: hidden");
|
93
|
+
await userEvent.click(buttonScoped);
|
94
|
+
await userEvent.click(buttonGlobal);
|
95
|
+
expect(document.body).not.toHaveStyle("overflow: hidden");
|
96
|
+
},
|
97
|
+
};
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
const IconChevronUp = () => {
|
3
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "18 15 12 9 6 15" }) }));
|
4
|
+
};
|
5
|
+
export default IconChevronUp;
|
@@ -0,0 +1,3 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
const IconMinus = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) }));
|
3
|
+
export default IconMinus;
|
package/dist/icons/Plus.d.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
declare const
|
2
|
-
export default
|
1
|
+
declare const IconPlus: () => import("react/jsx-runtime").JSX.Element;
|
2
|
+
export default IconPlus;
|
package/dist/icons/Plus.js
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
const
|
3
|
-
export default
|
2
|
+
const IconPlus = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), _jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
|
3
|
+
export default IconPlus;
|
package/dist/index.d.ts
CHANGED
@@ -63,6 +63,8 @@ export { default as MenuItem } from "./components/MenuItem";
|
|
63
63
|
export type { MenuItemProps } from "./components/MenuItem";
|
64
64
|
export { default as Modal } from "./components/Modal";
|
65
65
|
export type { ModalProps } from "./components/Modal";
|
66
|
+
export { default as NumberField } from "./components/NumberField";
|
67
|
+
export type { NumberFieldProps } from "./components/NumberField";
|
66
68
|
export { default as Overlay } from "./components/Overlay";
|
67
69
|
export type { OverlayProps } from "./components/Overlay";
|
68
70
|
export { default as Pagination } from "./components/Pagination";
|
package/dist/index.js
CHANGED
@@ -32,6 +32,7 @@ export { default as Link } from "./components/Link/index.js";
|
|
32
32
|
export { default as Loader } from "./components/Loader/index.js";
|
33
33
|
export { default as MenuItem } from "./components/MenuItem/index.js";
|
34
34
|
export { default as Modal } from "./components/Modal/index.js";
|
35
|
+
export { default as NumberField } from "./components/NumberField/index.js";
|
35
36
|
export { default as Overlay } from "./components/Overlay/index.js";
|
36
37
|
export { default as Pagination } from "./components/Pagination/index.js";
|
37
38
|
export { default as PinField } from "./components/PinField/index.js";
|
@@ -1,23 +1,31 @@
|
|
1
1
|
import { isIOS } from "../platform.js";
|
2
|
+
import { findClosestRenderContainer } from "../dom/index.js";
|
2
3
|
import lockSafariScroll from "./lockSafari.js";
|
3
4
|
import lockStandardScroll from "./lockStandard.js";
|
4
|
-
let
|
5
|
+
let bodyLockedCount = 0;
|
5
6
|
let reset = () => { };
|
6
7
|
export const lockScroll = (args) => {
|
7
|
-
|
8
|
-
|
8
|
+
const isIOSLock = isIOS() && !args.containerEl && !args.originEl;
|
9
|
+
let container = document.body;
|
10
|
+
if (args.originEl && !isIOSLock)
|
11
|
+
container = findClosestRenderContainer({ el: args.originEl }).el;
|
12
|
+
if (args.containerEl && !isIOSLock)
|
13
|
+
container = args.containerEl;
|
14
|
+
if (container === document.body)
|
15
|
+
bodyLockedCount += 1;
|
16
|
+
if (bodyLockedCount > 1)
|
9
17
|
return;
|
10
|
-
if (
|
18
|
+
if (isIOSLock) {
|
11
19
|
reset = lockSafariScroll();
|
12
20
|
}
|
13
21
|
else {
|
14
|
-
reset = lockStandardScroll({
|
22
|
+
reset = lockStandardScroll({ container });
|
15
23
|
}
|
16
24
|
args.cb?.();
|
17
25
|
};
|
18
26
|
export const unlockScroll = (cb) => {
|
19
|
-
|
20
|
-
if (
|
27
|
+
bodyLockedCount -= 1;
|
28
|
+
if (bodyLockedCount > 0)
|
21
29
|
return;
|
22
30
|
reset();
|
23
31
|
cb?.();
|
@@ -1,13 +1,8 @@
|
|
1
|
-
import { findClosestRenderContainer } from "../dom/index.js";
|
2
1
|
import { getScrollbarWidth } from "./helpers.js";
|
3
2
|
import { StyleCache } from "../css.js";
|
4
3
|
const styleCache = new StyleCache();
|
5
4
|
const lockStandardScroll = (args) => {
|
6
|
-
|
7
|
-
if (args.originEl)
|
8
|
-
container = findClosestRenderContainer({ el: args.originEl }).el;
|
9
|
-
if (args.containerEl)
|
10
|
-
container = args.containerEl;
|
5
|
+
const { container } = args;
|
11
6
|
const rect = container.getBoundingClientRect();
|
12
7
|
const isOverflowing = rect.left + rect.right < window.innerWidth;
|
13
8
|
styleCache.set(container, { overflow: "hidden" });
|
@@ -15,8 +10,6 @@ const lockStandardScroll = (args) => {
|
|
15
10
|
const scrollBarWidth = getScrollbarWidth();
|
16
11
|
styleCache.set(container, { paddingRight: `${scrollBarWidth}px` });
|
17
12
|
}
|
18
|
-
return () =>
|
19
|
-
styleCache.reset();
|
20
|
-
};
|
13
|
+
return () => styleCache.reset();
|
21
14
|
};
|
22
15
|
export default lockStandardScroll;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "reshaped",
|
3
3
|
"description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
|
4
|
-
"version": "3.4.
|
4
|
+
"version": "3.4.7",
|
5
5
|
"license": "MIT",
|
6
6
|
"email": "hello@reshaped.so",
|
7
7
|
"homepage": "https://reshaped.so",
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import { StoryObj } from "@storybook/react";
|
3
|
-
import { fn } from "@storybook/test";
|
4
|
-
declare const _default: {
|
5
|
-
title: string;
|
6
|
-
component: {
|
7
|
-
(props: import("./..").AutocompleteProps): React.JSX.Element;
|
8
|
-
Item: {
|
9
|
-
(props: import("../Autocomplete.types").ItemProps): React.JSX.Element;
|
10
|
-
displayName: string;
|
11
|
-
};
|
12
|
-
displayName: string;
|
13
|
-
};
|
14
|
-
parameters: {
|
15
|
-
iframe: {
|
16
|
-
url: string;
|
17
|
-
};
|
18
|
-
chromatic: {
|
19
|
-
disableSnapshot: boolean;
|
20
|
-
};
|
21
|
-
};
|
22
|
-
};
|
23
|
-
export default _default;
|
24
|
-
export declare const base: StoryObj<{
|
25
|
-
handleItemSelect: ReturnType<typeof fn>;
|
26
|
-
handleBackspace: ReturnType<typeof fn>;
|
27
|
-
}>;
|
@@ -1,86 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import { expect, waitFor, within, fn } from "@storybook/test";
|
3
|
-
import { Example } from "../../../utilities/storybook/index.js";
|
4
|
-
import Autocomplete from "../index.js";
|
5
|
-
import FormControl from "../../FormControl/index.js";
|
6
|
-
import { sleep } from "../../../utilities/helpers.js";
|
7
|
-
import userEvent from "@testing-library/user-event";
|
8
|
-
export default {
|
9
|
-
title: "Components/Autocomplete/tests",
|
10
|
-
component: Autocomplete,
|
11
|
-
parameters: {
|
12
|
-
iframe: {
|
13
|
-
url: "https://reshaped.so/docs/components/autocomplete",
|
14
|
-
},
|
15
|
-
chromatic: { disableSnapshot: true },
|
16
|
-
},
|
17
|
-
};
|
18
|
-
export const base = {
|
19
|
-
name: "base",
|
20
|
-
args: {
|
21
|
-
handleBackspace: fn(),
|
22
|
-
handleItemSelect: fn(),
|
23
|
-
},
|
24
|
-
render: (args) => {
|
25
|
-
const [value, setValue] = React.useState("");
|
26
|
-
return (<Example>
|
27
|
-
<Example.Item title="Base">
|
28
|
-
<FormControl>
|
29
|
-
<FormControl.Label>Food</FormControl.Label>
|
30
|
-
<Autocomplete name="fruit" placeholder="Pick your food" value={value} onChange={(args) => setValue(args.value)} onBackspace={args.handleBackspace} onItemSelect={args.handleItemSelect}>
|
31
|
-
{["Pizza", "Pie", "Ice-cream"].map((v, i) => {
|
32
|
-
return (<Autocomplete.Item key={v} value={v} data={i === 0 ? { foo: "bar" } : undefined}>
|
33
|
-
{v}
|
34
|
-
</Autocomplete.Item>);
|
35
|
-
})}
|
36
|
-
</Autocomplete>
|
37
|
-
</FormControl>
|
38
|
-
</Example.Item>
|
39
|
-
</Example>);
|
40
|
-
},
|
41
|
-
play: async ({ canvasElement, args }) => {
|
42
|
-
const canvas = within(canvasElement.ownerDocument.body);
|
43
|
-
const input = canvas.getByRole("combobox");
|
44
|
-
// Reset the focus
|
45
|
-
document.body.focus();
|
46
|
-
// Test keyboard selection after focusing the input
|
47
|
-
input.focus();
|
48
|
-
let options = [];
|
49
|
-
await waitFor(() => {
|
50
|
-
options = canvas.getAllByRole("option");
|
51
|
-
});
|
52
|
-
expect(options).toHaveLength(3);
|
53
|
-
await waitFor(() => {
|
54
|
-
expect(options[0]).toHaveAttribute("data-rs-focus");
|
55
|
-
});
|
56
|
-
expect(options[1]).not.toHaveAttribute("data-rs-focus");
|
57
|
-
await userEvent.keyboard("{ArrowDown/}");
|
58
|
-
await userEvent.keyboard("{Enter/}");
|
59
|
-
expect(input).toHaveValue("Pie");
|
60
|
-
expect(args.handleItemSelect).toHaveBeenCalledTimes(1);
|
61
|
-
expect(args.handleItemSelect).toHaveBeenCalledWith({
|
62
|
-
value: "Pie",
|
63
|
-
data: undefined,
|
64
|
-
});
|
65
|
-
// Give browser time to focus on the input
|
66
|
-
await sleep(100);
|
67
|
-
// Test click selection after opening with down arrow
|
68
|
-
await userEvent.keyboard("{ArrowDown/}");
|
69
|
-
await waitFor(() => {
|
70
|
-
options = canvas.getAllByRole("option");
|
71
|
-
});
|
72
|
-
await userEvent.click(options[0]);
|
73
|
-
expect(input).toHaveValue("Pizza");
|
74
|
-
expect(args.handleItemSelect).toHaveBeenCalledTimes(2);
|
75
|
-
expect(args.handleItemSelect).toHaveBeenCalledWith({
|
76
|
-
value: "Pizza",
|
77
|
-
data: { foo: "bar" },
|
78
|
-
});
|
79
|
-
input.focus();
|
80
|
-
await userEvent.keyboard("{Backspace/}");
|
81
|
-
await waitFor(() => {
|
82
|
-
expect(args.handleBackspace).toHaveBeenCalledTimes(1);
|
83
|
-
expect(args.handleBackspace).toHaveBeenCalledWith();
|
84
|
-
});
|
85
|
-
},
|
86
|
-
};
|