reshaped 3.8.0-canary.7 → 3.8.0-canary.8

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.
Files changed (186) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.js +9 -9
  4. package/dist/components/Actionable/Actionable.module.css +1 -1
  5. package/dist/components/Alert/tests/Alert.stories.d.ts +6 -5
  6. package/dist/components/Alert/tests/Alert.stories.js +15 -2
  7. package/dist/components/Badge/Badge.module.css +1 -1
  8. package/dist/components/Badge/tests/Badge.stories.d.ts +5 -0
  9. package/dist/components/Badge/tests/Badge.stories.js +34 -0
  10. package/dist/components/Breadcrumbs/tests/Breadcrumbs.stories.d.ts +8 -4
  11. package/dist/components/Breadcrumbs/tests/Breadcrumbs.stories.js +57 -1
  12. package/dist/components/Button/tests/Button.stories.d.ts +54 -12
  13. package/dist/components/Button/tests/Button.stories.js +725 -588
  14. package/dist/components/Card/Card.module.css +1 -1
  15. package/dist/components/Card/tests/Card.stories.d.ts +28 -6
  16. package/dist/components/Card/tests/Card.stories.js +110 -65
  17. package/dist/components/Carousel/Carousel.module.css +1 -1
  18. package/dist/components/Checkbox/Checkbox.module.css +1 -1
  19. package/dist/components/Checkbox/tests/Checkbox.stories.d.ts +20 -4
  20. package/dist/components/Checkbox/tests/Checkbox.stories.js +150 -79
  21. package/dist/components/CheckboxGroup/tests/CheckboxGroup.stories.d.ts +9 -2
  22. package/dist/components/CheckboxGroup/tests/CheckboxGroup.stories.js +67 -35
  23. package/dist/components/Container/tests/Container.stories.d.ts +2 -0
  24. package/dist/components/Container/tests/Container.stories.js +14 -0
  25. package/dist/components/ContextMenu/tests/ContextMenu.stories.d.ts +10 -1
  26. package/dist/components/ContextMenu/tests/ContextMenu.stories.js +57 -13
  27. package/dist/components/Dismissible/tests/Dismissible.stories.d.ts +5 -0
  28. package/dist/components/Dismissible/tests/Dismissible.stories.js +30 -1
  29. package/dist/components/Divider/tests/Divider.stories.d.ts +8 -3
  30. package/dist/components/Divider/tests/Divider.stories.js +71 -41
  31. package/dist/components/DropdownMenu/tests/DropdownMenu.stories.d.ts +35 -6
  32. package/dist/components/DropdownMenu/tests/DropdownMenu.stories.js +222 -115
  33. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.d.ts +0 -15
  34. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.js +0 -106
  35. package/dist/components/FileUpload/FileUpload.module.css +1 -1
  36. package/dist/components/Flyout/Flyout.module.css +1 -1
  37. package/dist/components/Flyout/utilities/flyout.js +0 -1
  38. package/dist/components/FormControl/tests/FormControl.stories.d.ts +2 -0
  39. package/dist/components/FormControl/tests/FormControl.stories.js +35 -0
  40. package/dist/components/Hidden/tests/Hidden.stories.d.ts +2 -0
  41. package/dist/components/Hidden/tests/Hidden.stories.js +9 -0
  42. package/dist/components/HiddenVisually/tests/HiddenVisually.stories.d.ts +2 -0
  43. package/dist/components/HiddenVisually/tests/HiddenVisually.stories.js +9 -0
  44. package/dist/components/Hotkey/tests/Hotkey.stories.d.ts +2 -0
  45. package/dist/components/Hotkey/tests/Hotkey.stories.js +15 -0
  46. package/dist/components/Icon/tests/Icon.stories.d.ts +3 -0
  47. package/dist/components/Icon/tests/Icon.stories.js +23 -0
  48. package/dist/components/Link/tests/Link.stories.d.ts +28 -5
  49. package/dist/components/Link/tests/Link.stories.js +141 -58
  50. package/dist/components/Link/tests/Link.test.stories.d.ts +0 -13
  51. package/dist/components/Link/tests/Link.test.stories.js +0 -85
  52. package/dist/components/Loader/tests/Loader.stories.d.ts +11 -2
  53. package/dist/components/Loader/tests/Loader.stories.js +52 -25
  54. package/dist/components/Loader/tests/Loader.test.stories.d.ts +0 -3
  55. package/dist/components/Loader/tests/Loader.test.stories.js +0 -21
  56. package/dist/components/MenuItem/tests/MenuItem.stories.d.ts +37 -7
  57. package/dist/components/MenuItem/tests/MenuItem.stories.js +218 -112
  58. package/dist/components/Modal/Modal.js +1 -1
  59. package/dist/components/Modal/Modal.module.css +1 -1
  60. package/dist/components/Modal/tests/Modal.stories.d.ts +53 -10
  61. package/dist/components/Modal/tests/Modal.stories.js +366 -214
  62. package/dist/components/Overlay/tests/Overlay.stories.d.ts +15 -1
  63. package/dist/components/Overlay/tests/Overlay.stories.js +135 -1
  64. package/dist/components/Pagination/tests/Pagination.stories.d.ts +14 -1
  65. package/dist/components/Pagination/tests/Pagination.stories.js +93 -15
  66. package/dist/components/PinField/tests/PinField.stories.d.ts +1 -1
  67. package/dist/components/PinField/tests/PinField.stories.js +1 -1
  68. package/dist/components/Popover/Popover.module.css +1 -1
  69. package/dist/components/Progress/tests/Progress.stories.d.ts +19 -4
  70. package/dist/components/Progress/tests/Progress.stories.js +85 -49
  71. package/dist/components/Radio/Radio.module.css +1 -1
  72. package/dist/components/Radio/tests/Radio.stories.d.ts +25 -4
  73. package/dist/components/Radio/tests/Radio.stories.js +147 -65
  74. package/dist/components/RadioGroup/tests/RadioGroup.stories.d.ts +9 -2
  75. package/dist/components/RadioGroup/tests/RadioGroup.stories.js +64 -38
  76. package/dist/components/Reshaped/Reshaped.css +1 -1
  77. package/dist/components/Scrim/tests/Scrim.stories.d.ts +10 -2
  78. package/dist/components/Scrim/tests/Scrim.stories.js +51 -31
  79. package/dist/components/ScrollArea/ScrollArea.module.css +1 -1
  80. package/dist/components/Select/Select.module.css +1 -1
  81. package/dist/components/Select/Select.types.d.ts +38 -11
  82. package/dist/components/Select/SelectCustom.js +2 -1
  83. package/dist/components/Select/SelectCustomControlled.js +23 -9
  84. package/dist/components/Select/SelectCustomUncontrolled.js +10 -7
  85. package/dist/components/Select/SelectTrigger.js +1 -1
  86. package/dist/components/Select/tests/Select.stories.d.ts +3 -0
  87. package/dist/components/Select/tests/Select.stories.js +91 -34
  88. package/dist/components/Skeleton/tests/Skeleton.stories.d.ts +10 -2
  89. package/dist/components/Skeleton/tests/Skeleton.stories.js +46 -28
  90. package/dist/components/Slider/Slider.module.css +1 -1
  91. package/dist/components/Stepper/tests/Stepper.stories.d.ts +18 -4
  92. package/dist/components/Stepper/tests/Stepper.stories.js +99 -70
  93. package/dist/components/Switch/Switch.module.css +1 -1
  94. package/dist/components/Switch/tests/Switch.stories.d.ts +10 -2
  95. package/dist/components/Switch/tests/Switch.stories.js +77 -23
  96. package/dist/components/Switch/tests/Switch.test.stories.d.ts +0 -10
  97. package/dist/components/Switch/tests/Switch.test.stories.js +0 -68
  98. package/dist/components/Table/Table.module.css +1 -1
  99. package/dist/components/Table/tests/Table.stories.d.ts +25 -5
  100. package/dist/components/Table/tests/Table.stories.js +274 -177
  101. package/dist/components/Table/tests/Table.test.stories.d.ts +0 -5
  102. package/dist/components/Table/tests/Table.test.stories.js +0 -82
  103. package/dist/components/Tabs/Tabs.module.css +1 -1
  104. package/dist/components/TextArea/TextArea.module.css +1 -1
  105. package/dist/components/TextArea/tests/TextArea.stories.d.ts +41 -9
  106. package/dist/components/TextArea/tests/TextArea.stories.js +179 -93
  107. package/dist/components/TextField/TextField.js +1 -1
  108. package/dist/components/TextField/TextField.module.css +1 -1
  109. package/dist/components/TextField/tests/TextField.stories.d.ts +41 -11
  110. package/dist/components/TextField/tests/TextField.stories.js +206 -132
  111. package/dist/components/TextField/tests/TextField.test.stories.d.ts +0 -13
  112. package/dist/components/TextField/tests/TextField.test.stories.js +0 -88
  113. package/dist/components/Theme/Theme.module.css +1 -1
  114. package/dist/components/Timeline/tests/Timeline.stories.d.ts +10 -2
  115. package/dist/components/Timeline/tests/Timeline.stories.js +69 -42
  116. package/dist/components/Timeline/tests/Timeline.test.stories.d.ts +0 -2
  117. package/dist/components/Timeline/tests/Timeline.test.stories.js +0 -21
  118. package/dist/components/Toast/tests/Toast.stories.d.ts +32 -8
  119. package/dist/components/Toast/tests/Toast.stories.js +109 -37
  120. package/dist/components/Tooltip/tests/Tooltip.stories.d.ts +18 -4
  121. package/dist/components/Tooltip/tests/Tooltip.stories.js +139 -107
  122. package/dist/components/Tooltip/tests/Tooltip.test.stories.d.ts +0 -6
  123. package/dist/components/Tooltip/tests/Tooltip.test.stories.js +0 -29
  124. package/dist/components/View/tests/View.stories.d.ts +4 -0
  125. package/dist/components/View/tests/View.stories.js +39 -0
  126. package/dist/hooks/tests/useDrag.stories.js +1 -1
  127. package/dist/utilities/scroll/disable.js +2 -2
  128. package/package.json +1 -1
  129. package/dist/components/Alert/tests/Alert.test.stories.d.ts +0 -15
  130. package/dist/components/Alert/tests/Alert.test.stories.js +0 -26
  131. package/dist/components/Badge/tests/Badge.test.stories.d.ts +0 -20
  132. package/dist/components/Badge/tests/Badge.test.stories.js +0 -46
  133. package/dist/components/Breadcrumbs/tests/Breadcrumbs.test.stories.d.ts +0 -23
  134. package/dist/components/Breadcrumbs/tests/Breadcrumbs.test.stories.js +0 -76
  135. package/dist/components/Button/tests/Button.test.stories.d.ts +0 -28
  136. package/dist/components/Button/tests/Button.test.stories.js +0 -135
  137. package/dist/components/Card/tests/Card.test.stories.d.ts +0 -35
  138. package/dist/components/Card/tests/Card.test.stories.js +0 -54
  139. package/dist/components/Checkbox/tests/Checkbox.test.stories.d.ts +0 -25
  140. package/dist/components/Checkbox/tests/Checkbox.test.stories.js +0 -104
  141. package/dist/components/CheckboxGroup/tests/CheckboxGroup.test.stories.d.ts +0 -22
  142. package/dist/components/CheckboxGroup/tests/CheckboxGroup.test.stories.js +0 -78
  143. package/dist/components/Container/tests/Container.test.stories.d.ts +0 -15
  144. package/dist/components/Container/tests/Container.test.stories.js +0 -26
  145. package/dist/components/ContextMenu/tests/ContextMenu.test.stories.d.ts +0 -25
  146. package/dist/components/ContextMenu/tests/ContextMenu.test.stories.js +0 -53
  147. package/dist/components/Dismissible/tests/Dismissible.test.stories.d.ts +0 -19
  148. package/dist/components/Dismissible/tests/Dismissible.test.stories.js +0 -42
  149. package/dist/components/Divider/tests/Divider.test.stories.d.ts +0 -18
  150. package/dist/components/Divider/tests/Divider.test.stories.js +0 -47
  151. package/dist/components/FormControl/tests/FormControl.test.stories.d.ts +0 -20
  152. package/dist/components/FormControl/tests/FormControl.test.stories.js +0 -49
  153. package/dist/components/Hidden/tests/Hidden.test.stories.d.ts +0 -15
  154. package/dist/components/Hidden/tests/Hidden.test.stories.js +0 -20
  155. package/dist/components/HiddenVisually/tests/HiddenVisually.test.stories.d.ts +0 -15
  156. package/dist/components/HiddenVisually/tests/HiddenVisually.test.stories.js +0 -20
  157. package/dist/components/Hotkey/tests/Hotkey.test.stories.d.ts +0 -15
  158. package/dist/components/Hotkey/tests/Hotkey.test.stories.js +0 -26
  159. package/dist/components/Icon/tests/Icon.test.stories.d.ts +0 -16
  160. package/dist/components/Icon/tests/Icon.test.stories.js +0 -35
  161. package/dist/components/MenuItem/tests/MenuItem.test.stories.d.ts +0 -27
  162. package/dist/components/MenuItem/tests/MenuItem.test.stories.js +0 -116
  163. package/dist/components/Modal/tests/Modal.test.stories.d.ts +0 -31
  164. package/dist/components/Modal/tests/Modal.test.stories.js +0 -149
  165. package/dist/components/Overlay/tests/Overlay.test.stories.d.ts +0 -28
  166. package/dist/components/Overlay/tests/Overlay.test.stories.js +0 -148
  167. package/dist/components/Pagination/tests/Pagination.test.stories.d.ts +0 -23
  168. package/dist/components/Pagination/tests/Pagination.test.stories.js +0 -86
  169. package/dist/components/Progress/tests/Progress.test.stories.d.ts +0 -16
  170. package/dist/components/Progress/tests/Progress.test.stories.js +0 -35
  171. package/dist/components/Radio/tests/Radio.test.stories.d.ts +0 -30
  172. package/dist/components/Radio/tests/Radio.test.stories.js +0 -118
  173. package/dist/components/RadioGroup/tests/RadioGroup.test.stories.d.ts +0 -22
  174. package/dist/components/RadioGroup/tests/RadioGroup.test.stories.js +0 -78
  175. package/dist/components/Scrim/tests/Scrim.test.stories.d.ts +0 -15
  176. package/dist/components/Scrim/tests/Scrim.test.stories.js +0 -25
  177. package/dist/components/Skeleton/tests/Skeleton.test.stories.d.ts +0 -15
  178. package/dist/components/Skeleton/tests/Skeleton.test.stories.js +0 -23
  179. package/dist/components/Stepper/tests/Stepper.test.stories.d.ts +0 -20
  180. package/dist/components/Stepper/tests/Stepper.test.stories.js +0 -28
  181. package/dist/components/TextArea/tests/TextArea.test.stories.d.ts +0 -28
  182. package/dist/components/TextArea/tests/TextArea.test.stories.js +0 -99
  183. package/dist/components/Toast/tests/Toast.test.stories.d.ts +0 -16
  184. package/dist/components/Toast/tests/Toast.test.stories.js +0 -101
  185. package/dist/components/View/tests/View.test.stories.d.ts +0 -24
  186. package/dist/components/View/tests/View.test.stories.js +0 -50
@@ -9,6 +9,8 @@ import Switch from "../../Switch/index.js";
9
9
  import TextField from "../../TextField/index.js";
10
10
  import useToggle from "../../../hooks/useToggle.js";
11
11
  import Radio from "../../Radio/index.js";
12
+ import { expect, fn, userEvent, waitFor, within } from "storybook/test";
13
+ import { sleep } from "../../../utilities/helpers.js";
12
14
  export default {
13
15
  title: "Components/Modal",
14
16
  component: Modal,
@@ -37,239 +39,389 @@ const Demo = (props) => {
37
39
  </Modal>
38
40
  </>);
39
41
  };
40
- export const position = () => (<Example>
41
- <Example.Item title={["responsive position", "[s] full-screen", "[m] center", "[l] end"]}>
42
- <Demo position={{ s: "full-screen", m: "center", l: "end" }}/>
43
- </Example.Item>
44
- <Example.Item title="position: center">
45
- <Demo position="center"/>
46
- </Example.Item>
47
- <Example.Item title="position: bottom">
48
- <Demo position="bottom"/>
49
- </Example.Item>
50
- <Example.Item title="position: start">
51
- <Demo position="start"/>
52
- </Example.Item>
53
- <Example.Item title="position: end">
54
- <Demo position="end"/>
55
- </Example.Item>
56
- <Example.Item title="position: full-screen">
57
- <Demo position="full-screen"/>
58
- </Example.Item>
59
- </Example>);
60
- export const size = () => {
61
- return (<Example>
62
- <Example.Item title="size: default">
63
- <Demo />
42
+ export const position = {
43
+ name: "position",
44
+ render: () => (<Example>
45
+ <Example.Item title={["responsive position", "[s] full-screen", "[m] center", "[l] end"]}>
46
+ <Demo position={{ s: "full-screen", m: "center", l: "end" }}/>
64
47
  </Example.Item>
65
- <Example.Item title="size: 300px">
66
- <Demo size="300px"/>
48
+ <Example.Item title="position: center">
49
+ <Demo position="center"/>
67
50
  </Example.Item>
68
- <Example.Item title={["size: 800px", "should have max width of 100% minus gaps on the sides"]}>
69
- <Demo size="800px"/>
51
+ <Example.Item title="position: bottom">
52
+ <Demo position="bottom"/>
70
53
  </Example.Item>
71
- <Example.Item title={[
72
- "responsive size, responsive position",
73
- "[s] auto",
74
- "[m+] 600px",
75
- "bottom position changes height instead of width",
76
- ]}>
77
- <Demo position={{ s: "bottom", m: "center", l: "end" }} size={{ s: "auto", m: "600px" }}/>
54
+ <Example.Item title="position: start">
55
+ <Demo position="start"/>
78
56
  </Example.Item>
79
- </Example>);
80
- };
81
- export const padding = () => (<Example>
82
- <Example.Item title="padding: 0">
83
- <Demo padding={0}/>
84
- </Example.Item>
85
- <Example.Item title="padding: 6">
86
- <Demo padding={6}/>
87
- </Example.Item>
88
- <Example.Item title={["responsive padding", "[s] 2", "[m+]: 6"]}>
89
- <Demo padding={{ s: 2, m: 6 }}/>
90
- </Example.Item>
91
- </Example>);
92
- export const overflow = () => (<Example>
93
- <Example.Item title="default overflow">
94
- <Demo>
95
- <div style={{
96
- position: "absolute",
97
- top: -32,
98
- left: -32,
99
- height: 100,
100
- width: 100,
101
- background: "tomato",
102
- }}/>
103
- </Demo>
104
- </Example.Item>
105
-
106
- <Example.Item title="overflow: visible">
107
- <Demo overflow="visible">
108
- <div style={{
109
- position: "absolute",
110
- top: -32,
111
- left: -32,
112
- height: 100,
113
- width: 100,
114
- background: "tomato",
115
- }}/>
116
- </Demo>
117
- </Example.Item>
118
- </Example>);
119
- export const composition = () => (<Example>
120
- <Example.Item title="title, subtitle, dismissible">
121
- <Demo title="Modal title" subtitle="Modal subtitle"/>
122
- </Example.Item>
123
- </Example>);
124
- export const overlay = () => (<Example>
125
- <Example.Item title="transparentOverlay, doesn't lock scroll">
126
- <Demo transparentOverlay/>
127
- </Example.Item>
128
- <Example.Item title="blurredOverlay">
129
- <Demo blurredOverlay/>
130
- </Example.Item>
131
- <View height="1000px"/>
132
- </Example>);
133
- export const flags = () => {
134
- return (<Example>
135
- <Example.Item title="disableCloseOnOutsideClick">
136
- <Demo disableCloseOnOutsideClick/>
57
+ <Example.Item title="position: end">
58
+ <Demo position="end"/>
59
+ </Example.Item>
60
+ <Example.Item title="position: full-screen">
61
+ <Demo position="full-screen"/>
137
62
  </Example.Item>
138
- </Example>);
63
+ </Example>),
139
64
  };
140
- export const containerRef = () => {
141
- const containerRef = React.useRef(null);
142
- const containerRef2 = React.useRef(null);
143
- const toggle = useToggle();
144
- const toggle2 = useToggle();
145
- return (<Example>
146
- <Example.Item title={["in scrollable container", "scroll and then open"]}>
147
- <View attributes={{ ref: containerRef2 }} borderRadius="medium" height="400px" overflow="auto" backgroundColor="neutral-faded" padding={4}>
148
- <View gap={4} align="start">
149
- <Button onClick={toggle2.activate}>Open modal</Button>
150
- <View height="500px" backgroundColor="primary" width="500px" borderRadius="medium"/>
151
- </View>
152
- <Modal containerRef={containerRef2} active={toggle2.active} onClose={toggle2.deactivate} position="end">
153
- <Placeholder />
154
- </Modal>
155
- </View>
65
+ export const size = {
66
+ name: "size",
67
+ render: () => {
68
+ return (<Example>
69
+ <Example.Item title="size: default">
70
+ <Demo />
71
+ </Example.Item>
72
+ <Example.Item title="size: 300px">
73
+ <Demo size="300px"/>
74
+ </Example.Item>
75
+ <Example.Item title={["size: 800px", "should have max width of 100% minus gaps on the sides"]}>
76
+ <Demo size="800px"/>
77
+ </Example.Item>
78
+ <Example.Item title={[
79
+ "responsive size, responsive position",
80
+ "[s] auto",
81
+ "[m+] 600px",
82
+ "bottom position changes height instead of width",
83
+ ]}>
84
+ <Demo position={{ s: "bottom", m: "center", l: "end" }} size={{ s: "auto", m: "600px" }}/>
85
+ </Example.Item>
86
+ </Example>);
87
+ },
88
+ };
89
+ export const padding = {
90
+ name: "padding",
91
+ render: () => (<Example>
92
+ <Example.Item title="padding: 0">
93
+ <Demo padding={0}/>
156
94
  </Example.Item>
157
- <Example.Item title="in static container">
158
- <View attributes={{ ref: containerRef }} borderRadius="medium" height="400px" overflow="hidden" backgroundColor="neutral-faded" padding={4}>
159
- <Button onClick={toggle.activate}>Open modal</Button>
160
- <Modal containerRef={containerRef} active={toggle.active} onClose={toggle.deactivate} position="end">
161
- <Placeholder />
162
- </Modal>
163
- </View>
95
+ <Example.Item title="padding: 6">
96
+ <Demo padding={6}/>
164
97
  </Example.Item>
165
- </Example>);
166
- };
167
- export const edgeCases = () => {
168
- const menuModalToggle = useToggle();
169
- const menuModalToggleInner = useToggle();
170
- const scrollModalToggle = useToggle();
171
- const inputRef = React.useRef(null);
172
- return (<Example>
173
- <Example.Item title="keyboard focus stays on the modal first">
174
- <Demo title="Modal title" autoFocus={false}/>
98
+ <Example.Item title={["responsive padding", "[s] 2", "[m+]: 6"]}>
99
+ <Demo padding={{ s: 2, m: 6 }}/>
175
100
  </Example.Item>
176
- <Example.Item title="trap focus works with custom children components">
177
- <Demo title="Modal title">
178
- <View gap={3} direction="row">
179
- <Button onClick={() => { }}>Button</Button>
180
- <Switch name="switch"/>
181
- </View>
101
+ </Example>),
102
+ };
103
+ export const overflow = {
104
+ name: "overflow",
105
+ render: () => (<Example>
106
+ <Example.Item title="default overflow">
107
+ <Demo>
108
+ <div style={{
109
+ position: "absolute",
110
+ top: -32,
111
+ left: -32,
112
+ height: 100,
113
+ width: 100,
114
+ background: "tomato",
115
+ }}/>
182
116
  </Demo>
183
117
  </Example.Item>
184
- <Example.Item title="focus moves to the input">
185
- <Demo title="Modal title" onOpen={() => {
186
- inputRef.current?.focus();
187
- }}>
188
- <View gap={3} direction="row">
189
- <Button onClick={() => { }}>Button</Button>
190
- <TextField name="name" inputAttributes={{ ref: inputRef }}/>
191
- </View>
118
+
119
+ <Example.Item title="overflow: visible">
120
+ <Demo overflow="visible">
121
+ <div style={{
122
+ position: "absolute",
123
+ top: -32,
124
+ left: -32,
125
+ height: 100,
126
+ width: 100,
127
+ background: "tomato",
128
+ }}/>
192
129
  </Demo>
193
130
  </Example.Item>
194
- <Example.Item title="Focus moves to the input with autoFocus">
195
- <Demo title="Modal title">
196
- <View gap={3} direction="row">
197
- <Button onClick={() => { }}>Button</Button>
198
- <TextField name="name" placeholder="autofocus" inputAttributes={{ autoFocus: true }}/>
199
- </View>
200
- </Demo>
131
+ </Example>),
132
+ };
133
+ export const composition = {
134
+ name: "composition",
135
+ render: () => (<Example>
136
+ <Example.Item title="title, subtitle, dismissible">
137
+ <Demo title="Modal title" subtitle="Modal subtitle"/>
201
138
  </Example.Item>
202
- <Example.Item title="scrollable area in modal ignores swipe-to-close">
203
- <View gap={3} direction="row">
204
- <Button onClick={scrollModalToggle.activate}>Open</Button>
205
- <Modal active={scrollModalToggle.active} onClose={scrollModalToggle.deactivate} size="300px" position="bottom">
206
- <View height="1000px" backgroundColor="neutral-faded" borderRadius="medium" padding={4}>
207
- Content
208
- </View>
209
- </Modal>
210
- </View>
139
+ </Example>),
140
+ };
141
+ export const overlay = {
142
+ name: "overlay",
143
+ render: () => (<Example>
144
+ <Example.Item title="transparentOverlay, doesn't lock scroll">
145
+ <Demo transparentOverlay/>
146
+ </Example.Item>
147
+ <Example.Item title="blurredOverlay">
148
+ <Demo blurredOverlay/>
211
149
  </Example.Item>
212
- <Example.Item title={[
213
- "trap focus works correctly when it was already trapped",
214
- "focus return back to the dropdown trigger on modal close",
215
- "closing dropdown inside the modal doesn't close the modal",
216
- ]}>
217
- <DropdownMenu>
218
- <DropdownMenu.Trigger>
219
- {(attributes) => <Button attributes={attributes}>Open menu</Button>}
220
- </DropdownMenu.Trigger>
221
- <DropdownMenu.Content>
222
- <DropdownMenu.Item onClick={menuModalToggle.activate}>Open dialog</DropdownMenu.Item>
223
- <DropdownMenu.Item>Item 2</DropdownMenu.Item>
224
- </DropdownMenu.Content>
225
- </DropdownMenu>
226
- <Modal active={menuModalToggle.active} onClose={menuModalToggle.deactivate}>
227
- <View gap={3}>
228
- <DropdownMenu>
229
- <DropdownMenu.Trigger>
230
- {(attributes) => <Button attributes={attributes}>Open menu</Button>}
231
- </DropdownMenu.Trigger>
232
- <DropdownMenu.Content>
233
- <DropdownMenu.Item>Item 1</DropdownMenu.Item>
234
- <DropdownMenu.Item>Item 2</DropdownMenu.Item>
235
- </DropdownMenu.Content>
236
- </DropdownMenu>
237
- <Button onClick={menuModalToggleInner.activate}>Open dialog</Button>
238
- <Button onClick={menuModalToggle.deactivate}>Close</Button>
239
- <Modal active={menuModalToggleInner.active} onClose={menuModalToggleInner.deactivate}>
240
- <Button onClick={menuModalToggleInner.deactivate}>Close</Button>
150
+ <View height="1000px"/>
151
+ </Example>),
152
+ };
153
+ export const flags = {
154
+ name: "disableCloseOnOutsideClick",
155
+ render: () => {
156
+ return (<Example>
157
+ <Example.Item title="disableCloseOnOutsideClick">
158
+ <Demo disableCloseOnOutsideClick/>
159
+ </Example.Item>
160
+ </Example>);
161
+ },
162
+ };
163
+ export const containerRef = {
164
+ name: "containerRef",
165
+ render: () => {
166
+ const containerRef = React.useRef(null);
167
+ const containerRef2 = React.useRef(null);
168
+ const toggle = useToggle();
169
+ const toggle2 = useToggle();
170
+ return (<Example>
171
+ <Example.Item title={["in scrollable container", "scroll and then open"]}>
172
+ <View attributes={{ ref: containerRef2 }} borderRadius="medium" height="400px" overflow="auto" backgroundColor="neutral-faded" padding={4}>
173
+ <View gap={4} align="start">
174
+ <Button onClick={toggle2.activate}>Open modal</Button>
175
+ <View height="500px" backgroundColor="primary" width="500px" borderRadius="medium"/>
176
+ </View>
177
+ <Modal containerRef={containerRef2} active={toggle2.active} onClose={toggle2.deactivate} position="end">
178
+ <Placeholder />
179
+ </Modal>
180
+ </View>
181
+ </Example.Item>
182
+ <Example.Item title="in static container">
183
+ <View attributes={{ ref: containerRef }} borderRadius="medium" height="400px" overflow="hidden" backgroundColor="neutral-faded" padding={4}>
184
+ <Button onClick={toggle.activate}>Open modal</Button>
185
+ <Modal containerRef={containerRef} active={toggle.active} onClose={toggle.deactivate} position="end">
186
+ <Placeholder />
241
187
  </Modal>
242
188
  </View>
189
+ </Example.Item>
190
+ </Example>);
191
+ },
192
+ };
193
+ export const renderProps = {
194
+ name: "children, render props",
195
+ render: () => (<Modal active className="test-classname" attributes={{ "data-testid": "test-id" }}>
196
+ <Modal.Title>Title</Modal.Title>
197
+ Content
198
+ </Modal>),
199
+ play: async ({ canvasElement }) => {
200
+ const canvas = within(canvasElement.ownerDocument.body);
201
+ const root = canvas.getByText("Content");
202
+ expect(root).toBeInTheDocument();
203
+ },
204
+ };
205
+ export const handlers = {
206
+ name: "onOpen, onClose, onAfterOpen, onAfterClose",
207
+ args: {
208
+ handleOpen: fn(),
209
+ handleClose: fn(),
210
+ handleAfterClose: fn(),
211
+ handleAfterOpen: fn(),
212
+ },
213
+ render: (args) => {
214
+ const overlayToggle = useToggle();
215
+ return (<>
216
+ <Button onClick={() => overlayToggle.toggle()}>Open overlay</Button>
217
+ <Modal active={overlayToggle.active} onClose={(closeArgs) => {
218
+ overlayToggle.deactivate();
219
+ args.handleClose(closeArgs);
220
+ }} onOpen={args.handleOpen} onAfterOpen={args.handleAfterOpen} onAfterClose={args.handleAfterClose}>
221
+ <Modal.Title>Title</Modal.Title>
222
+ Content
243
223
  </Modal>
244
- </Example.Item>
224
+ </>);
225
+ },
226
+ play: async ({ canvasElement, args }) => {
227
+ const canvas = within(canvasElement.ownerDocument.body);
228
+ const trigger = canvas.getAllByRole("button")[0];
229
+ let overlay;
230
+ await userEvent.click(trigger);
231
+ overlay = canvas.getByText("Content");
232
+ await waitFor(() => {
233
+ expect(args.handleOpen).toHaveBeenCalledTimes(1);
234
+ expect(args.handleOpen).toHaveBeenCalledWith();
235
+ });
236
+ // Wait for transition
237
+ await waitFor(() => {
238
+ expect(args.handleAfterOpen).toHaveBeenCalledTimes(1);
239
+ expect(args.handleAfterOpen).toHaveBeenCalledWith();
240
+ });
241
+ // Close by changing the state after the trigger click
242
+ await userEvent.click(trigger);
243
+ // Wait for transition
244
+ await waitFor(() => {
245
+ // Changing state doesn't trigger onClose
246
+ expect(args.handleClose).toHaveBeenCalledTimes(0);
247
+ expect(args.handleAfterClose).toHaveBeenCalledTimes(1);
248
+ expect(args.handleAfterClose).toHaveBeenCalledWith();
249
+ });
250
+ // Open
251
+ await userEvent.click(trigger);
252
+ await sleep(100);
253
+ overlay = canvas.getAllByRole("button", { hidden: true }).at(-1);
254
+ // Close by clicking on the overlay
255
+ await userEvent.click(overlay);
256
+ await waitFor(() => {
257
+ expect(args.handleClose).toHaveBeenCalledTimes(1);
258
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "overlay-click" });
259
+ expect(args.handleAfterClose).toHaveBeenCalledTimes(2);
260
+ expect(args.handleAfterClose).toHaveBeenCalledWith();
261
+ });
262
+ // Open
263
+ await userEvent.click(trigger);
264
+ await sleep(100);
265
+ // Close by pressing Escape
266
+ await userEvent.keyboard("{Escape}");
267
+ await waitFor(() => {
268
+ expect(args.handleClose).toHaveBeenCalledTimes(2);
269
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "escape-key" });
270
+ expect(args.handleAfterClose).toHaveBeenCalledTimes(3);
271
+ expect(args.handleAfterClose).toHaveBeenCalledWith();
272
+ });
273
+ },
274
+ };
275
+ export const disableCloseOnClick = {
276
+ name: "disableCloseOnOutsideClick",
277
+ args: {
278
+ handleClose: fn(),
279
+ },
280
+ render: (args) => (<Modal active disableCloseOnOutsideClick onClose={(closeArgs) => {
281
+ args.handleClose(closeArgs);
282
+ }}>
283
+ <Modal.Title>Title</Modal.Title>
284
+ Content
285
+ </Modal>),
286
+ play: async ({ canvasElement, args }) => {
287
+ const canvas = within(canvasElement.ownerDocument.body);
288
+ const overlay = canvas.getByText("Content");
289
+ await userEvent.click(overlay);
290
+ expect(args.handleClose).toHaveBeenCalledTimes(0);
291
+ await userEvent.keyboard("{Escape}");
292
+ expect(args.handleClose).toHaveBeenCalledTimes(1);
293
+ },
294
+ };
295
+ export const className = {
296
+ name: "className, attributes",
297
+ render: () => (<Modal active className="test-classname" attributes={{ "data-testid": "test-id" }}>
298
+ <Modal.Title>Title</Modal.Title>
299
+ Content
300
+ </Modal>),
301
+ play: async ({ canvasElement }) => {
302
+ const canvas = within(canvasElement.ownerDocument.body);
303
+ const root = canvas.getByTestId("test-id");
304
+ expect(root).toHaveClass("test-classname");
305
+ },
306
+ };
307
+ export const edgeCases = {
308
+ name: "test: edge cases",
309
+ render: () => {
310
+ const menuModalToggle = useToggle();
311
+ const menuModalToggleInner = useToggle();
312
+ const scrollModalToggle = useToggle();
313
+ const inputRef = React.useRef(null);
314
+ return (<Example>
315
+ <Example.Item title="Scrolls with long content on touch devices">
316
+ <Demo position="center">
317
+ <Button onClick={() => { }}>Action</Button>
318
+ <View height="2000px" backgroundColor="primary-faded"/>
319
+ </Demo>
320
+ </Example.Item>
321
+ <Example.Item title="keyboard focus stays on the modal first">
322
+ <Demo title="Modal title" autoFocus={false}/>
323
+ </Example.Item>
324
+ <Example.Item title="trap focus works with custom children components">
325
+ <Demo title="Modal title">
326
+ <View gap={3} direction="row">
327
+ <Button onClick={() => { }}>Button</Button>
328
+ <Switch name="switch"/>
329
+ </View>
330
+ </Demo>
331
+ </Example.Item>
332
+ <Example.Item title="focus moves to the input">
333
+ <Demo title="Modal title" onOpen={() => {
334
+ inputRef.current?.focus();
335
+ }}>
336
+ <View gap={3} direction="row">
337
+ <Button onClick={() => { }}>Button</Button>
338
+ <TextField name="name" inputAttributes={{ ref: inputRef }}/>
339
+ </View>
340
+ </Demo>
341
+ </Example.Item>
342
+ <Example.Item title="Focus moves to the input with autoFocus">
343
+ <Demo title="Modal title">
344
+ <View gap={3} direction="row">
345
+ <Button onClick={() => { }}>Button</Button>
346
+ <TextField name="name" placeholder="autofocus" inputAttributes={{ autoFocus: true }}/>
347
+ </View>
348
+ </Demo>
349
+ </Example.Item>
350
+ <Example.Item title="scrollable area in modal ignores swipe-to-close">
351
+ <View gap={3} direction="row">
352
+ <Button onClick={scrollModalToggle.activate}>Open</Button>
353
+ <Modal active={scrollModalToggle.active} onClose={scrollModalToggle.deactivate} size="300px" position="bottom">
354
+ <View height="1000px" backgroundColor="neutral-faded" borderRadius="medium" padding={4}>
355
+ Content
356
+ </View>
357
+ </Modal>
358
+ </View>
359
+ </Example.Item>
360
+ <Example.Item title={[
361
+ "trap focus works correctly when it was already trapped",
362
+ "focus return back to the dropdown trigger on modal close",
363
+ "closing dropdown inside the modal doesn't close the modal",
364
+ ]}>
365
+ <DropdownMenu>
366
+ <DropdownMenu.Trigger>
367
+ {(attributes) => <Button attributes={attributes}>Open menu</Button>}
368
+ </DropdownMenu.Trigger>
369
+ <DropdownMenu.Content>
370
+ <DropdownMenu.Item onClick={menuModalToggle.activate}>Open dialog</DropdownMenu.Item>
371
+ <DropdownMenu.Item>Item 2</DropdownMenu.Item>
372
+ </DropdownMenu.Content>
373
+ </DropdownMenu>
374
+ <Modal active={menuModalToggle.active} onClose={menuModalToggle.deactivate}>
375
+ <View gap={3}>
376
+ <DropdownMenu>
377
+ <DropdownMenu.Trigger>
378
+ {(attributes) => <Button attributes={attributes}>Open menu</Button>}
379
+ </DropdownMenu.Trigger>
380
+ <DropdownMenu.Content>
381
+ <DropdownMenu.Item>Item 1</DropdownMenu.Item>
382
+ <DropdownMenu.Item>Item 2</DropdownMenu.Item>
383
+ </DropdownMenu.Content>
384
+ </DropdownMenu>
385
+ <Button onClick={menuModalToggleInner.activate}>Open dialog</Button>
386
+ <Button onClick={menuModalToggle.deactivate}>Close</Button>
387
+ <Modal active={menuModalToggleInner.active} onClose={menuModalToggleInner.deactivate}>
388
+ <Button onClick={menuModalToggleInner.deactivate}>Close</Button>
389
+ </Modal>
390
+ </View>
391
+ </Modal>
392
+ </Example.Item>
245
393
 
246
- <Example.Item title="disableSwipeGesture">
247
- <Demo disableSwipeGesture position="start"/>
248
- </Example.Item>
394
+ <Example.Item title="disableSwipeGesture">
395
+ <Demo disableSwipeGesture position="start"/>
396
+ </Example.Item>
249
397
 
250
- <Example.Item title="scroll locks on open">
251
- <Demo />
252
- <View height="1000px"/>
253
- </Example.Item>
254
- </Example>);
398
+ <Example.Item title="scroll locks on open">
399
+ <Demo />
400
+ <View height="1000px"/>
401
+ </Example.Item>
402
+ </Example>);
403
+ },
255
404
  };
256
- export const trapFocusEdgeCases = () => {
257
- const toggle = useToggle();
258
- return (<Example>
259
- <Example.Item title="Radio should be navigatable with arrow keys">
260
- <Button onClick={toggle.activate}>Open modal</Button>
261
- <Modal active={toggle.active} onClose={toggle.deactivate}>
262
- <View gap={2}>
263
- <Button onClick={() => { }}>Action 1</Button>
264
- <Radio name="radio" value="1">
265
- Option 1
266
- </Radio>
267
- <Radio name="radio" value="2">
268
- Option 2
269
- </Radio>
270
- <Button onClick={() => { }}>Action 2</Button>
271
- </View>
272
- </Modal>
273
- </Example.Item>
274
- </Example>);
405
+ export const trapFocusEdgeCases = {
406
+ name: "test: trap focus edge cases",
407
+ render: () => {
408
+ const toggle = useToggle();
409
+ return (<Example>
410
+ <Example.Item title="Radio should be navigatable with arrow keys">
411
+ <Button onClick={toggle.activate}>Open modal</Button>
412
+ <Modal active={toggle.active} onClose={toggle.deactivate}>
413
+ <View gap={2}>
414
+ <Button onClick={() => { }}>Action 1</Button>
415
+ <Radio name="radio" value="1">
416
+ Option 1
417
+ </Radio>
418
+ <Radio name="radio" value="2">
419
+ Option 2
420
+ </Radio>
421
+ <Button onClick={() => { }}>Action 2</Button>
422
+ </View>
423
+ </Modal>
424
+ </Example.Item>
425
+ </Example>);
426
+ },
275
427
  };
@@ -1,7 +1,9 @@
1
1
  import { StoryObj } from "@storybook/react-vite";
2
+ import { fn } from "storybook/test";
3
+ import React from "react";
2
4
  declare const _default: {
3
5
  title: string;
4
- component: import("react").FC<import("./..").OverlayProps>;
6
+ component: React.FC<import("./..").OverlayProps>;
5
7
  parameters: {
6
8
  iframe: {
7
9
  url: string;
@@ -12,3 +14,15 @@ export default _default;
12
14
  export declare const base: StoryObj;
13
15
  export declare const transparent: StoryObj;
14
16
  export declare const blurred: StoryObj;
17
+ export declare const renderProps: StoryObj;
18
+ export declare const handlers: StoryObj<{
19
+ handleOpen: ReturnType<typeof fn>;
20
+ handleAfterOpen: ReturnType<typeof fn>;
21
+ handleClose: ReturnType<typeof fn>;
22
+ handleAfterClose: ReturnType<typeof fn>;
23
+ }>;
24
+ export declare const disableCloseOnClick: StoryObj<{
25
+ handleClose: ReturnType<typeof fn>;
26
+ }>;
27
+ export declare const containerRef: StoryObj;
28
+ export declare const className: StoryObj;