reshaped 3.8.0-canary.6 → 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 (223) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.js +10 -10
  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/DropdownMenu.js +4 -4
  32. package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +2 -2
  33. package/dist/components/DropdownMenu/tests/DropdownMenu.stories.d.ts +35 -6
  34. package/dist/components/DropdownMenu/tests/DropdownMenu.stories.js +222 -115
  35. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.d.ts +0 -15
  36. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.js +0 -106
  37. package/dist/components/FileUpload/FileUpload.module.css +1 -1
  38. package/dist/components/Flyout/Flyout.module.css +1 -1
  39. package/dist/components/Flyout/utilities/flyout.js +0 -1
  40. package/dist/components/Flyout/utilities/getPositionFallbacks.js +3 -3
  41. package/dist/components/Flyout/utilities/isFullyVisible.d.ts +0 -2
  42. package/dist/components/Flyout/utilities/isFullyVisible.js +5 -7
  43. package/dist/components/FormControl/tests/FormControl.stories.d.ts +2 -0
  44. package/dist/components/FormControl/tests/FormControl.stories.js +35 -0
  45. package/dist/components/Hidden/Hidden.js +2 -1
  46. package/dist/components/Hidden/tests/Hidden.stories.d.ts +2 -0
  47. package/dist/components/Hidden/tests/Hidden.stories.js +9 -0
  48. package/dist/components/HiddenVisually/tests/HiddenVisually.stories.d.ts +2 -0
  49. package/dist/components/HiddenVisually/tests/HiddenVisually.stories.js +9 -0
  50. package/dist/components/Hotkey/tests/Hotkey.stories.d.ts +2 -0
  51. package/dist/components/Hotkey/tests/Hotkey.stories.js +15 -0
  52. package/dist/components/Icon/tests/Icon.stories.d.ts +3 -0
  53. package/dist/components/Icon/tests/Icon.stories.js +23 -0
  54. package/dist/components/Link/tests/Link.stories.d.ts +28 -5
  55. package/dist/components/Link/tests/Link.stories.js +141 -58
  56. package/dist/components/Link/tests/Link.test.stories.d.ts +0 -13
  57. package/dist/components/Link/tests/Link.test.stories.js +0 -85
  58. package/dist/components/Loader/tests/Loader.stories.d.ts +11 -2
  59. package/dist/components/Loader/tests/Loader.stories.js +52 -25
  60. package/dist/components/Loader/tests/Loader.test.stories.d.ts +0 -3
  61. package/dist/components/Loader/tests/Loader.test.stories.js +0 -21
  62. package/dist/components/MenuItem/MenuItem.module.css +1 -1
  63. package/dist/components/MenuItem/tests/MenuItem.stories.d.ts +37 -7
  64. package/dist/components/MenuItem/tests/MenuItem.stories.js +218 -112
  65. package/dist/components/Modal/Modal.js +1 -1
  66. package/dist/components/Modal/Modal.module.css +1 -1
  67. package/dist/components/Modal/tests/Modal.stories.d.ts +53 -10
  68. package/dist/components/Modal/tests/Modal.stories.js +366 -214
  69. package/dist/components/Overlay/tests/Overlay.stories.d.ts +15 -1
  70. package/dist/components/Overlay/tests/Overlay.stories.js +135 -1
  71. package/dist/components/Pagination/tests/Pagination.stories.d.ts +14 -1
  72. package/dist/components/Pagination/tests/Pagination.stories.js +93 -15
  73. package/dist/components/PinField/tests/PinField.stories.d.ts +1 -1
  74. package/dist/components/PinField/tests/PinField.stories.js +1 -1
  75. package/dist/components/Popover/Popover.js +2 -2
  76. package/dist/components/Popover/Popover.module.css +1 -1
  77. package/dist/components/Popover/Popover.types.d.ts +2 -0
  78. package/dist/components/Progress/tests/Progress.stories.d.ts +19 -4
  79. package/dist/components/Progress/tests/Progress.stories.js +85 -49
  80. package/dist/components/Radio/Radio.module.css +1 -1
  81. package/dist/components/Radio/tests/Radio.stories.d.ts +25 -4
  82. package/dist/components/Radio/tests/Radio.stories.js +147 -65
  83. package/dist/components/RadioGroup/tests/RadioGroup.stories.d.ts +9 -2
  84. package/dist/components/RadioGroup/tests/RadioGroup.stories.js +64 -38
  85. package/dist/components/Reshaped/Reshaped.css +1 -1
  86. package/dist/components/Resizable/Resizable.js +4 -3
  87. package/dist/components/Scrim/tests/Scrim.stories.d.ts +10 -2
  88. package/dist/components/Scrim/tests/Scrim.stories.js +51 -31
  89. package/dist/components/ScrollArea/ScrollArea.module.css +1 -1
  90. package/dist/components/Select/Select.d.ts +8 -1
  91. package/dist/components/Select/Select.js +22 -48
  92. package/dist/components/Select/Select.module.css +1 -1
  93. package/dist/components/Select/Select.types.d.ts +83 -38
  94. package/dist/components/Select/SelectCustom.d.ts +3 -0
  95. package/dist/components/Select/SelectCustom.js +12 -0
  96. package/dist/components/Select/SelectCustomControlled.d.ts +4 -0
  97. package/dist/components/Select/SelectCustomControlled.js +102 -0
  98. package/dist/components/Select/SelectCustomUncontrolled.d.ts +4 -0
  99. package/dist/components/Select/SelectCustomUncontrolled.js +18 -0
  100. package/dist/components/Select/SelectEndContent.d.ts +3 -0
  101. package/dist/components/Select/SelectEndContent.js +12 -0
  102. package/dist/components/Select/SelectNative.d.ts +4 -0
  103. package/dist/components/Select/SelectNative.js +29 -0
  104. package/dist/components/Select/SelectOption.d.ts +4 -0
  105. package/dist/components/Select/SelectOption.js +15 -0
  106. package/dist/components/Select/SelectOptionGroup.d.ts +4 -0
  107. package/dist/components/Select/SelectOptionGroup.js +11 -0
  108. package/dist/components/Select/SelectRoot.d.ts +4 -0
  109. package/dist/components/Select/SelectRoot.js +21 -0
  110. package/dist/components/Select/SelectStartContent.d.ts +3 -0
  111. package/dist/components/Select/SelectStartContent.js +20 -0
  112. package/dist/components/Select/SelectTrigger.d.ts +4 -0
  113. package/dist/components/Select/SelectTrigger.js +16 -0
  114. package/dist/components/Select/tests/Select.stories.d.ts +38 -10
  115. package/dist/components/Select/tests/Select.stories.js +504 -175
  116. package/dist/components/Skeleton/tests/Skeleton.stories.d.ts +10 -2
  117. package/dist/components/Skeleton/tests/Skeleton.stories.js +46 -28
  118. package/dist/components/Slider/Slider.module.css +1 -1
  119. package/dist/components/Stepper/Stepper.js +2 -2
  120. package/dist/components/Stepper/Stepper.types.d.ts +2 -0
  121. package/dist/components/Stepper/tests/Stepper.stories.d.ts +18 -3
  122. package/dist/components/Stepper/tests/Stepper.stories.js +99 -47
  123. package/dist/components/Switch/Switch.module.css +1 -1
  124. package/dist/components/Switch/tests/Switch.stories.d.ts +10 -2
  125. package/dist/components/Switch/tests/Switch.stories.js +77 -23
  126. package/dist/components/Switch/tests/Switch.test.stories.d.ts +0 -10
  127. package/dist/components/Switch/tests/Switch.test.stories.js +0 -68
  128. package/dist/components/Table/Table.js +6 -3
  129. package/dist/components/Table/Table.module.css +1 -1
  130. package/dist/components/Table/tests/Table.stories.d.ts +25 -5
  131. package/dist/components/Table/tests/Table.stories.js +274 -177
  132. package/dist/components/Table/tests/Table.test.stories.d.ts +0 -5
  133. package/dist/components/Table/tests/Table.test.stories.js +0 -82
  134. package/dist/components/Tabs/Tabs.module.css +1 -1
  135. package/dist/components/TextArea/TextArea.module.css +1 -1
  136. package/dist/components/TextArea/tests/TextArea.stories.d.ts +41 -9
  137. package/dist/components/TextArea/tests/TextArea.stories.js +179 -93
  138. package/dist/components/TextField/TextField.js +1 -1
  139. package/dist/components/TextField/TextField.module.css +1 -1
  140. package/dist/components/TextField/tests/TextField.stories.d.ts +41 -11
  141. package/dist/components/TextField/tests/TextField.stories.js +206 -132
  142. package/dist/components/TextField/tests/TextField.test.stories.d.ts +0 -13
  143. package/dist/components/TextField/tests/TextField.test.stories.js +0 -88
  144. package/dist/components/Theme/Theme.module.css +1 -1
  145. package/dist/components/Timeline/Timeline.js +3 -2
  146. package/dist/components/Timeline/tests/Timeline.stories.d.ts +10 -2
  147. package/dist/components/Timeline/tests/Timeline.stories.js +69 -45
  148. package/dist/components/Timeline/tests/Timeline.test.stories.d.ts +0 -2
  149. package/dist/components/Timeline/tests/Timeline.test.stories.js +0 -21
  150. package/dist/components/Toast/tests/Toast.stories.d.ts +32 -8
  151. package/dist/components/Toast/tests/Toast.stories.js +109 -37
  152. package/dist/components/Tooltip/tests/Tooltip.stories.d.ts +18 -4
  153. package/dist/components/Tooltip/tests/Tooltip.stories.js +139 -107
  154. package/dist/components/Tooltip/tests/Tooltip.test.stories.d.ts +0 -6
  155. package/dist/components/Tooltip/tests/Tooltip.test.stories.js +0 -29
  156. package/dist/components/View/View.js +6 -4
  157. package/dist/components/View/tests/View.stories.d.ts +4 -0
  158. package/dist/components/View/tests/View.stories.js +39 -0
  159. package/dist/hooks/tests/useDrag.stories.js +1 -1
  160. package/dist/utilities/props.d.ts +3 -0
  161. package/dist/utilities/props.js +19 -0
  162. package/dist/utilities/scroll/disable.js +2 -2
  163. package/package.json +1 -1
  164. package/dist/components/Alert/tests/Alert.test.stories.d.ts +0 -15
  165. package/dist/components/Alert/tests/Alert.test.stories.js +0 -26
  166. package/dist/components/Badge/tests/Badge.test.stories.d.ts +0 -20
  167. package/dist/components/Badge/tests/Badge.test.stories.js +0 -46
  168. package/dist/components/Breadcrumbs/tests/Breadcrumbs.test.stories.d.ts +0 -23
  169. package/dist/components/Breadcrumbs/tests/Breadcrumbs.test.stories.js +0 -76
  170. package/dist/components/Button/tests/Button.test.stories.d.ts +0 -28
  171. package/dist/components/Button/tests/Button.test.stories.js +0 -135
  172. package/dist/components/Card/tests/Card.test.stories.d.ts +0 -35
  173. package/dist/components/Card/tests/Card.test.stories.js +0 -54
  174. package/dist/components/Checkbox/tests/Checkbox.test.stories.d.ts +0 -25
  175. package/dist/components/Checkbox/tests/Checkbox.test.stories.js +0 -104
  176. package/dist/components/CheckboxGroup/tests/CheckboxGroup.test.stories.d.ts +0 -22
  177. package/dist/components/CheckboxGroup/tests/CheckboxGroup.test.stories.js +0 -78
  178. package/dist/components/Container/tests/Container.test.stories.d.ts +0 -15
  179. package/dist/components/Container/tests/Container.test.stories.js +0 -26
  180. package/dist/components/ContextMenu/tests/ContextMenu.test.stories.d.ts +0 -25
  181. package/dist/components/ContextMenu/tests/ContextMenu.test.stories.js +0 -53
  182. package/dist/components/Dismissible/tests/Dismissible.test.stories.d.ts +0 -19
  183. package/dist/components/Dismissible/tests/Dismissible.test.stories.js +0 -42
  184. package/dist/components/Divider/tests/Divider.test.stories.d.ts +0 -18
  185. package/dist/components/Divider/tests/Divider.test.stories.js +0 -47
  186. package/dist/components/FormControl/tests/FormControl.test.stories.d.ts +0 -20
  187. package/dist/components/FormControl/tests/FormControl.test.stories.js +0 -49
  188. package/dist/components/Hidden/tests/Hidden.test.stories.d.ts +0 -15
  189. package/dist/components/Hidden/tests/Hidden.test.stories.js +0 -20
  190. package/dist/components/HiddenVisually/tests/HiddenVisually.test.stories.d.ts +0 -15
  191. package/dist/components/HiddenVisually/tests/HiddenVisually.test.stories.js +0 -20
  192. package/dist/components/Hotkey/tests/Hotkey.test.stories.d.ts +0 -15
  193. package/dist/components/Hotkey/tests/Hotkey.test.stories.js +0 -26
  194. package/dist/components/Icon/tests/Icon.test.stories.d.ts +0 -16
  195. package/dist/components/Icon/tests/Icon.test.stories.js +0 -35
  196. package/dist/components/MenuItem/tests/MenuItem.test.stories.d.ts +0 -27
  197. package/dist/components/MenuItem/tests/MenuItem.test.stories.js +0 -116
  198. package/dist/components/Modal/tests/Modal.test.stories.d.ts +0 -31
  199. package/dist/components/Modal/tests/Modal.test.stories.js +0 -149
  200. package/dist/components/Overlay/tests/Overlay.test.stories.d.ts +0 -28
  201. package/dist/components/Overlay/tests/Overlay.test.stories.js +0 -148
  202. package/dist/components/Pagination/tests/Pagination.test.stories.d.ts +0 -23
  203. package/dist/components/Pagination/tests/Pagination.test.stories.js +0 -86
  204. package/dist/components/Progress/tests/Progress.test.stories.d.ts +0 -16
  205. package/dist/components/Progress/tests/Progress.test.stories.js +0 -35
  206. package/dist/components/Radio/tests/Radio.test.stories.d.ts +0 -30
  207. package/dist/components/Radio/tests/Radio.test.stories.js +0 -118
  208. package/dist/components/RadioGroup/tests/RadioGroup.test.stories.d.ts +0 -22
  209. package/dist/components/RadioGroup/tests/RadioGroup.test.stories.js +0 -78
  210. package/dist/components/Scrim/tests/Scrim.test.stories.d.ts +0 -15
  211. package/dist/components/Scrim/tests/Scrim.test.stories.js +0 -25
  212. package/dist/components/Select/tests/Select.test.stories.d.ts +0 -27
  213. package/dist/components/Select/tests/Select.test.stories.js +0 -132
  214. package/dist/components/Skeleton/tests/Skeleton.test.stories.d.ts +0 -15
  215. package/dist/components/Skeleton/tests/Skeleton.test.stories.js +0 -23
  216. package/dist/components/Stepper/tests/Stepper.test.stories.d.ts +0 -20
  217. package/dist/components/Stepper/tests/Stepper.test.stories.js +0 -28
  218. package/dist/components/TextArea/tests/TextArea.test.stories.d.ts +0 -28
  219. package/dist/components/TextArea/tests/TextArea.test.stories.js +0 -99
  220. package/dist/components/Toast/tests/Toast.test.stories.d.ts +0 -16
  221. package/dist/components/Toast/tests/Toast.test.stories.js +0 -101
  222. package/dist/components/View/tests/View.test.stories.d.ts +0 -24
  223. package/dist/components/View/tests/View.test.stories.js +0 -50
@@ -4,6 +4,8 @@ import DropdownMenu from "../index.js";
4
4
  import View from "../../View/index.js";
5
5
  import { useTheme } from "../../Theme/useTheme.js";
6
6
  import IconCheckmark from "../../../icons/Checkmark.js";
7
+ import { expect, fn, userEvent, waitFor, within } from "storybook/test";
8
+ import { sleep } from "../../../utilities/helpers.js";
7
9
  export default {
8
10
  title: "Components/DropdownMenu",
9
11
  component: DropdownMenu,
@@ -13,125 +15,227 @@ export default {
13
15
  },
14
16
  },
15
17
  };
16
- export const position = () => (<Example>
17
- <Example.Item title="position: default">
18
- <DropdownMenu>
19
- <DropdownMenu.Trigger>
20
- {(attributes) => <Button attributes={attributes}>Open</Button>}
21
- </DropdownMenu.Trigger>
22
- <DropdownMenu.Content>
23
- <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
24
- <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
25
- </DropdownMenu.Content>
26
- </DropdownMenu>
27
- </Example.Item>
18
+ export const position = {
19
+ name: "position",
20
+ render: () => (<Example>
21
+ <Example.Item title="position: default">
22
+ <DropdownMenu>
23
+ <DropdownMenu.Trigger>
24
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
25
+ </DropdownMenu.Trigger>
26
+ <DropdownMenu.Content>
27
+ <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
28
+ <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
29
+ </DropdownMenu.Content>
30
+ </DropdownMenu>
31
+ </Example.Item>
28
32
 
29
- <Example.Item title="position: end">
30
- <DropdownMenu position="end">
31
- <DropdownMenu.Trigger>
32
- {(attributes) => <Button attributes={attributes}>Open</Button>}
33
- </DropdownMenu.Trigger>
34
- <DropdownMenu.Content>
35
- <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
36
- <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
37
- </DropdownMenu.Content>
38
- </DropdownMenu>
39
- </Example.Item>
33
+ <Example.Item title="position: end">
34
+ <DropdownMenu position="end">
35
+ <DropdownMenu.Trigger>
36
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
37
+ </DropdownMenu.Trigger>
38
+ <DropdownMenu.Content>
39
+ <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
40
+ <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
41
+ </DropdownMenu.Content>
42
+ </DropdownMenu>
43
+ </Example.Item>
40
44
 
41
- <Example.Item title={["position: top-start", "should change to top-start to fit viewport"]}>
42
- <DropdownMenu position="top-end">
43
- <DropdownMenu.Trigger>
44
- {(attributes) => <Button attributes={attributes}>Open</Button>}
45
- </DropdownMenu.Trigger>
46
- <DropdownMenu.Content>
47
- <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
48
- <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
49
- </DropdownMenu.Content>
50
- </DropdownMenu>
51
- </Example.Item>
52
- <div style={{ height: 2000 }}/>
53
- </Example>);
54
- export const sections = () => (<Example>
55
- <Example.Item title="2 sections">
56
- <DropdownMenu>
57
- <DropdownMenu.Trigger>
58
- {(attributes) => <Button attributes={attributes}>Open</Button>}
59
- </DropdownMenu.Trigger>
60
- <DropdownMenu.Content>
61
- <DropdownMenu.Section>
62
- <DropdownMenu.Item>Item 1</DropdownMenu.Item>
63
- <DropdownMenu.Item>Item 2</DropdownMenu.Item>
64
- </DropdownMenu.Section>
45
+ <Example.Item title={["position: top-start", "should change to top-start to fit viewport"]}>
46
+ <DropdownMenu position="top-end">
47
+ <DropdownMenu.Trigger>
48
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
49
+ </DropdownMenu.Trigger>
50
+ <DropdownMenu.Content>
51
+ <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
52
+ <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
53
+ </DropdownMenu.Content>
54
+ </DropdownMenu>
55
+ </Example.Item>
56
+ <div style={{ height: 2000 }}/>
57
+ </Example>),
58
+ };
59
+ export const sections = {
60
+ name: "sections",
61
+ render: () => (<Example>
62
+ <Example.Item title="2 sections">
63
+ <DropdownMenu>
64
+ <DropdownMenu.Trigger>
65
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
66
+ </DropdownMenu.Trigger>
67
+ <DropdownMenu.Content>
68
+ <DropdownMenu.Section>
69
+ <DropdownMenu.Item>Item 1</DropdownMenu.Item>
70
+ <DropdownMenu.Item>Item 2</DropdownMenu.Item>
71
+ </DropdownMenu.Section>
65
72
 
66
- <DropdownMenu.Section>
67
- <DropdownMenu.Item>Item 3</DropdownMenu.Item>
68
- <DropdownMenu.Item>Item 4</DropdownMenu.Item>
69
- </DropdownMenu.Section>
70
- </DropdownMenu.Content>
71
- </DropdownMenu>
72
- </Example.Item>
73
- </Example>);
74
- export const submenu = () => (<Example>
75
- <Example.Item title="submenu">
76
- <DropdownMenu>
77
- <DropdownMenu.Trigger>
78
- {(attributes) => <Button attributes={attributes}>Open</Button>}
79
- </DropdownMenu.Trigger>
80
- <DropdownMenu.Content>
81
- <DropdownMenu.Item onClick={() => { }}>Item 1</DropdownMenu.Item>
82
- <DropdownMenu.SubMenu>
83
- <DropdownMenu.SubTrigger>Item 2</DropdownMenu.SubTrigger>
84
- <DropdownMenu.Content>
85
- <DropdownMenu.Item onClick={() => { }}>SubItem 1</DropdownMenu.Item>
86
- <DropdownMenu.Item onClick={() => { }}>SubItem 2</DropdownMenu.Item>
87
- </DropdownMenu.Content>
88
- </DropdownMenu.SubMenu>
89
- <DropdownMenu.SubMenu>
90
- <DropdownMenu.SubTrigger>Item 3</DropdownMenu.SubTrigger>
91
- <DropdownMenu.Content>
92
- <DropdownMenu.Item onClick={() => { }}>SubItem 2-1</DropdownMenu.Item>
93
- <DropdownMenu.Item onClick={() => { }}>SubItem 2-2</DropdownMenu.Item>
94
- </DropdownMenu.Content>
95
- </DropdownMenu.SubMenu>
73
+ <DropdownMenu.Section>
74
+ <DropdownMenu.Item>Item 3</DropdownMenu.Item>
75
+ <DropdownMenu.Item>Item 4</DropdownMenu.Item>
76
+ </DropdownMenu.Section>
77
+ </DropdownMenu.Content>
78
+ </DropdownMenu>
79
+ </Example.Item>
80
+ </Example>),
81
+ };
82
+ export const submenu = {
83
+ name: "submenu",
84
+ render: () => (<Example>
85
+ <Example.Item title="submenu">
86
+ <DropdownMenu>
87
+ <DropdownMenu.Trigger>
88
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
89
+ </DropdownMenu.Trigger>
90
+ <DropdownMenu.Content>
91
+ <DropdownMenu.Item onClick={() => { }}>Item 1</DropdownMenu.Item>
92
+ <DropdownMenu.SubMenu>
93
+ <DropdownMenu.SubTrigger>Item 2</DropdownMenu.SubTrigger>
94
+ <DropdownMenu.Content>
95
+ <DropdownMenu.Item onClick={() => { }}>SubItem 1</DropdownMenu.Item>
96
+ <DropdownMenu.Item onClick={() => { }}>SubItem 2</DropdownMenu.Item>
97
+ </DropdownMenu.Content>
98
+ </DropdownMenu.SubMenu>
99
+ <DropdownMenu.SubMenu>
100
+ <DropdownMenu.SubTrigger>Item 3</DropdownMenu.SubTrigger>
101
+ <DropdownMenu.Content>
102
+ <DropdownMenu.Item onClick={() => { }}>SubItem 2-1</DropdownMenu.Item>
103
+ <DropdownMenu.Item onClick={() => { }}>SubItem 2-2</DropdownMenu.Item>
104
+ </DropdownMenu.Content>
105
+ </DropdownMenu.SubMenu>
96
106
 
97
- <DropdownMenu.SubMenu>
98
- <DropdownMenu.SubTrigger disabled>Item 4, disabled</DropdownMenu.SubTrigger>
99
- <DropdownMenu.Content>
100
- <DropdownMenu.Item onClick={() => { }}>SubItem 3-1</DropdownMenu.Item>
101
- <DropdownMenu.Item onClick={() => { }}>SubItem 3-2</DropdownMenu.Item>
102
- </DropdownMenu.Content>
103
- </DropdownMenu.SubMenu>
104
- </DropdownMenu.Content>
105
- </DropdownMenu>
106
- </Example.Item>
107
- </Example>);
108
- export const state = () => (<Example>
109
- <Example.Item title="defaultActive">
110
- <DropdownMenu defaultActive>
111
- <DropdownMenu.Trigger>
112
- {(attributes) => <Button attributes={attributes}>Open</Button>}
113
- </DropdownMenu.Trigger>
114
- <DropdownMenu.Content>
115
- <DropdownMenu.Item icon={IconCheckmark}>Item 1</DropdownMenu.Item>
116
- <DropdownMenu.Item icon={IconCheckmark}>Item 2</DropdownMenu.Item>
117
- </DropdownMenu.Content>
118
- </DropdownMenu>
119
- </Example.Item>
120
- </Example>);
121
- export const testScroll = () => (<Example>
122
- <Example.Item title="Scrolls on page mount to the dropdown">
123
- <div style={{ height: 1000 }}/>
124
- <DropdownMenu position="end" key="scroll" defaultActive>
107
+ <DropdownMenu.SubMenu>
108
+ <DropdownMenu.SubTrigger disabled>Item 4, disabled</DropdownMenu.SubTrigger>
109
+ <DropdownMenu.Content>
110
+ <DropdownMenu.Item onClick={() => { }}>SubItem 3-1</DropdownMenu.Item>
111
+ <DropdownMenu.Item onClick={() => { }}>SubItem 3-2</DropdownMenu.Item>
112
+ </DropdownMenu.Content>
113
+ </DropdownMenu.SubMenu>
114
+ </DropdownMenu.Content>
115
+ </DropdownMenu>
116
+ </Example.Item>
117
+ </Example>),
118
+ };
119
+ export const defaultActive = {
120
+ name: "defaultActive, uncontrolled",
121
+ args: {
122
+ handleOpen: fn(),
123
+ handleClose: fn(),
124
+ },
125
+ render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} defaultActive>
126
+ <DropdownMenu.Trigger>
127
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
128
+ </DropdownMenu.Trigger>
129
+ <DropdownMenu.Content>
130
+ <DropdownMenu.Item>Item</DropdownMenu.Item>
131
+ </DropdownMenu.Content>
132
+ </DropdownMenu>),
133
+ play: async ({ canvasElement, args }) => {
134
+ const canvas = within(canvasElement.ownerDocument.body);
135
+ const trigger = canvas.getAllByRole("button")[0];
136
+ let item = canvas.getByText("Item");
137
+ await sleep(500);
138
+ await userEvent.click(document.body);
139
+ await waitFor(() => {
140
+ expect(args.handleClose).toHaveBeenCalledTimes(1);
141
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
142
+ expect(item).not.toBeInTheDocument();
143
+ });
144
+ await userEvent.click(trigger);
145
+ item = canvas.getByText("Item");
146
+ await waitFor(() => {
147
+ expect(args.handleOpen).toHaveBeenCalledTimes(1);
148
+ expect(args.handleOpen).toHaveBeenCalledWith();
149
+ expect(item).toBeInTheDocument();
150
+ });
151
+ },
152
+ };
153
+ export const active = {
154
+ name: "active, controlled",
155
+ args: {
156
+ handleOpen: fn(),
157
+ handleClose: fn(),
158
+ },
159
+ render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} active>
160
+ <DropdownMenu.Trigger>
161
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
162
+ </DropdownMenu.Trigger>
163
+ <DropdownMenu.Content>
164
+ <DropdownMenu.Item>Item</DropdownMenu.Item>
165
+ </DropdownMenu.Content>
166
+ </DropdownMenu>),
167
+ play: async ({ canvasElement, args }) => {
168
+ const canvas = within(canvasElement.ownerDocument.body);
169
+ const item = canvas.getByText("Item");
170
+ await userEvent.click(document.body);
171
+ await waitFor(() => {
172
+ expect(args.handleClose).toHaveBeenCalledTimes(1);
173
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
174
+ });
175
+ expect(item).toBeInTheDocument();
176
+ },
177
+ };
178
+ export const activeFalse = {
179
+ name: "active false, controlled",
180
+ args: {
181
+ handleOpen: fn(),
182
+ handleClose: fn(),
183
+ },
184
+ render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} active={false}>
185
+ <DropdownMenu.Trigger>
186
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
187
+ </DropdownMenu.Trigger>
188
+ <DropdownMenu.Content>
189
+ <DropdownMenu.Item>Item</DropdownMenu.Item>
190
+ </DropdownMenu.Content>
191
+ </DropdownMenu>),
192
+ play: async ({ canvasElement, args }) => {
193
+ const canvas = within(canvasElement.ownerDocument.body);
194
+ const trigger = canvas.getAllByRole("button")[0];
195
+ await userEvent.click(trigger);
196
+ await waitFor(() => {
197
+ expect(args.handleOpen).toHaveBeenCalledTimes(1);
198
+ expect(args.handleOpen).toHaveBeenCalledWith();
199
+ });
200
+ const item = canvas.queryByText("Item");
201
+ expect(item).not.toBeInTheDocument();
202
+ },
203
+ };
204
+ export const className = {
205
+ name: "className, attributes",
206
+ render: () => (<div data-testid="root">
207
+ <DropdownMenu active>
125
208
  <DropdownMenu.Trigger>
126
209
  {(attributes) => <Button attributes={attributes}>Open</Button>}
127
210
  </DropdownMenu.Trigger>
128
- <DropdownMenu.Content>
129
- <DropdownMenu.Item>Item 1</DropdownMenu.Item>
130
- <DropdownMenu.Item>Item 2</DropdownMenu.Item>
211
+ <DropdownMenu.Content className="test-classname" attributes={{ "data-testid": "test-id" }}>
212
+ <DropdownMenu.Item>Item</DropdownMenu.Item>
131
213
  </DropdownMenu.Content>
132
214
  </DropdownMenu>
133
- </Example.Item>
134
- </Example>);
215
+ </div>),
216
+ play: async ({ canvasElement }) => {
217
+ const canvas = within(canvasElement.ownerDocument.body);
218
+ const menu = await canvas.findByTestId("test-id");
219
+ expect(menu).toHaveClass("test-classname");
220
+ },
221
+ };
222
+ export const testScroll = {
223
+ name: "test: scroll",
224
+ render: () => (<Example>
225
+ <Example.Item title="Scrolls on page mount to the dropdown">
226
+ <div style={{ height: 1000 }}/>
227
+ <DropdownMenu position="end" key="scroll" defaultActive>
228
+ <DropdownMenu.Trigger>
229
+ {(attributes) => <Button attributes={attributes}>Open</Button>}
230
+ </DropdownMenu.Trigger>
231
+ <DropdownMenu.Content>
232
+ <DropdownMenu.Item>Item 1</DropdownMenu.Item>
233
+ <DropdownMenu.Item>Item 2</DropdownMenu.Item>
234
+ </DropdownMenu.Content>
235
+ </DropdownMenu>
236
+ </Example.Item>
237
+ </Example>),
238
+ };
135
239
  const ThemeSwitching = () => {
136
240
  const { invertColorMode } = useTheme();
137
241
  return (<View gap={3} direction="row">
@@ -147,8 +251,11 @@ const ThemeSwitching = () => {
147
251
  <Button onClick={() => invertColorMode()}>Switch color mode</Button>
148
252
  </View>);
149
253
  };
150
- export const testThemeSwitching = () => (<Example>
151
- <Example.Item title="Switch color mode while dropdown is active and check that it still works">
152
- <ThemeSwitching />
153
- </Example.Item>
154
- </Example>);
254
+ export const testThemeSwitching = {
255
+ name: "test: theme switching",
256
+ render: () => (<Example>
257
+ <Example.Item title="Switch color mode while dropdown is active and check that it still works">
258
+ <ThemeSwitching />
259
+ </Example.Item>
260
+ </Example>),
261
+ };
@@ -1,5 +1,3 @@
1
- import { StoryObj } from "@storybook/react-vite";
2
- import { fn } from "storybook/test";
3
1
  declare const _default: {
4
2
  title: string;
5
3
  component: import("react").FC<import("./..").DropdownMenuProps> & {
@@ -21,16 +19,3 @@ declare const _default: {
21
19
  };
22
20
  };
23
21
  export default _default;
24
- export declare const defaultActive: StoryObj<{
25
- handleOpen: ReturnType<typeof fn>;
26
- handleClose: ReturnType<typeof fn>;
27
- }>;
28
- export declare const active: StoryObj<{
29
- handleOpen: ReturnType<typeof fn>;
30
- handleClose: ReturnType<typeof fn>;
31
- }>;
32
- export declare const activeFalse: StoryObj<{
33
- handleOpen: ReturnType<typeof fn>;
34
- handleClose: ReturnType<typeof fn>;
35
- }>;
36
- export declare const className: StoryObj;
@@ -1,7 +1,4 @@
1
- import { expect, fn, userEvent, waitFor, within } from "storybook/test";
2
- import Button from "../../Button/index.js";
3
1
  import DropdownMenu from "../index.js";
4
- import { sleep } from "../../../utilities/helpers.js";
5
2
  export default {
6
3
  title: "Components/DropdownMenu/tests",
7
4
  component: DropdownMenu,
@@ -12,106 +9,3 @@ export default {
12
9
  chromatic: { disableSnapshot: true },
13
10
  },
14
11
  };
15
- export const defaultActive = {
16
- name: "defaultActive, uncontrolled",
17
- args: {
18
- handleOpen: fn(),
19
- handleClose: fn(),
20
- },
21
- render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} defaultActive>
22
- <DropdownMenu.Trigger>
23
- {(attributes) => <Button attributes={attributes}>Open</Button>}
24
- </DropdownMenu.Trigger>
25
- <DropdownMenu.Content>
26
- <DropdownMenu.Item>Item</DropdownMenu.Item>
27
- </DropdownMenu.Content>
28
- </DropdownMenu>),
29
- play: async ({ canvasElement, args }) => {
30
- const canvas = within(canvasElement.ownerDocument.body);
31
- const trigger = canvas.getAllByRole("button")[0];
32
- let item = canvas.getByText("Item");
33
- await sleep(500);
34
- await userEvent.click(document.body);
35
- await waitFor(() => {
36
- expect(args.handleClose).toHaveBeenCalledTimes(1);
37
- expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
38
- expect(item).not.toBeInTheDocument();
39
- });
40
- await userEvent.click(trigger);
41
- item = canvas.getByText("Item");
42
- await waitFor(() => {
43
- expect(args.handleOpen).toHaveBeenCalledTimes(1);
44
- expect(args.handleOpen).toHaveBeenCalledWith();
45
- expect(item).toBeInTheDocument();
46
- });
47
- },
48
- };
49
- export const active = {
50
- name: "active, controlled",
51
- args: {
52
- handleOpen: fn(),
53
- handleClose: fn(),
54
- },
55
- render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} active>
56
- <DropdownMenu.Trigger>
57
- {(attributes) => <Button attributes={attributes}>Open</Button>}
58
- </DropdownMenu.Trigger>
59
- <DropdownMenu.Content>
60
- <DropdownMenu.Item>Item</DropdownMenu.Item>
61
- </DropdownMenu.Content>
62
- </DropdownMenu>),
63
- play: async ({ canvasElement, args }) => {
64
- const canvas = within(canvasElement.ownerDocument.body);
65
- const item = canvas.getByText("Item");
66
- await userEvent.click(document.body);
67
- await waitFor(() => {
68
- expect(args.handleClose).toHaveBeenCalledTimes(1);
69
- expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
70
- });
71
- expect(item).toBeInTheDocument();
72
- },
73
- };
74
- export const activeFalse = {
75
- name: "active false, controlled",
76
- args: {
77
- handleOpen: fn(),
78
- handleClose: fn(),
79
- },
80
- render: (args) => (<DropdownMenu onOpen={args.handleOpen} onClose={args.handleClose} active={false}>
81
- <DropdownMenu.Trigger>
82
- {(attributes) => <Button attributes={attributes}>Open</Button>}
83
- </DropdownMenu.Trigger>
84
- <DropdownMenu.Content>
85
- <DropdownMenu.Item>Item</DropdownMenu.Item>
86
- </DropdownMenu.Content>
87
- </DropdownMenu>),
88
- play: async ({ canvasElement, args }) => {
89
- const canvas = within(canvasElement.ownerDocument.body);
90
- const trigger = canvas.getAllByRole("button")[0];
91
- await userEvent.click(trigger);
92
- await waitFor(() => {
93
- expect(args.handleOpen).toHaveBeenCalledTimes(1);
94
- expect(args.handleOpen).toHaveBeenCalledWith();
95
- });
96
- const item = canvas.queryByText("Item");
97
- expect(item).not.toBeInTheDocument();
98
- },
99
- };
100
- export const className = {
101
- name: "className, attributes",
102
- render: () => (<div data-testid="root">
103
- <DropdownMenu active>
104
- <DropdownMenu.Trigger>
105
- {(attributes) => <Button attributes={attributes}>Open</Button>}
106
- </DropdownMenu.Trigger>
107
- <DropdownMenu.Content className="test-classname" attributes={{ "data-testid": "test-id" }}>
108
- <DropdownMenu.Item>Item</DropdownMenu.Item>
109
- </DropdownMenu.Content>
110
- </DropdownMenu>
111
- </div>),
112
- play: async ({ canvasElement }) => {
113
- const canvas = within(canvasElement.ownerDocument.body);
114
- const menu = await canvas.findByTestId("test-id");
115
- expect(menu).toHaveClass("test-classname");
116
- },
117
- };
@@ -1 +1 @@
1
- .root{--rs-file-upload-radius:var(--rs-radius-medium);display:block}[data-rs-keyboard] .root:focus-within{box-shadow:var(--rs-focus-shadow)}.--inline{--rs-file-upload-radius:var(--rs-radius-small)}.--inline,.--inline .triggerLayer{display:inline-block;vertical-align:top}[data-rs-keyboard] .--inline:focus-within{box-shadow:none}[data-rs-keyboard] .--inline:focus-within .triggerLayer>*{box-shadow:var(--rs-focus-shadow)}.--variant-outline .triggerLayer{border:1px dashed var(--rs-color-border-neutral);border-radius:var(--rs-file-upload-radius)}.--highlighted.--variant-outline .triggerLayer{background:rgba(var(--rs-color-rgb-background-primary),.08);border-color:var(--rs-color-border-primary)}@media (hover:hover) and (pointer:fine){.--variant-outline .triggerLayer:hover:not(:has(.trigger)){background:rgba(var(--rs-color-rgb-background-neutral),.16)}}.triggerLayer:has(.trigger){pointer-events:none}.triggerLayer:has(.trigger) .trigger{pointer-events:all}.trigger{display:contents}
1
+ .root{--rs-file-upload-radius:var(--rs-radius-medium);display:block}[data-rs-keyboard] .root:focus-within{box-shadow:var(--rs-shadow-focus)}.--inline{--rs-file-upload-radius:var(--rs-radius-small)}.--inline,.--inline .triggerLayer{display:inline-block;vertical-align:top}[data-rs-keyboard] .--inline:focus-within{box-shadow:none}[data-rs-keyboard] .--inline:focus-within .triggerLayer>*{box-shadow:var(--rs-shadow-focus)}.--variant-outline .triggerLayer{border:1px dashed var(--rs-color-border-neutral);border-radius:var(--rs-file-upload-radius)}.--highlighted.--variant-outline .triggerLayer{background:rgba(var(--rs-color-rgb-background-primary),.08);border-color:var(--rs-color-border-primary)}@media (hover:hover) and (pointer:fine){.--variant-outline .triggerLayer:hover:not(:has(.trigger)){background:rgba(var(--rs-color-rgb-background-neutral),.16)}}.triggerLayer:has(.trigger){pointer-events:none}.triggerLayer:has(.trigger) .trigger{pointer-events:all}.trigger{display:contents}
@@ -1 +1 @@
1
- .content{--rs-flyout-gap:0;--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;isolation:isolate;pointer-events:none;position:absolute}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{backface-visibility:hidden;height:100%;max-height:100%;max-width:100%;opacity:0;outline:none;overflow:auto;pointer-events:all;transform:scale(.92) translateY(0);transform-origin:var(--rs-flyout-origin-x) var(--rs-flyout-origin-y);transition:1ms var(--rs-easing-accelerate)}[data-rs-keyboard] .inner:focus{box-shadow:var(--rs-focus-shadow)}.content.--width-trigger .inner{transform:scale(1) translateY(var(--rs-unit-x2))}.content.--position-top,.content.--position-top-end,.content.--position-top-start{--rs-flyout-origin-y:100%;padding-bottom:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom,.content.--position-bottom-end,.content.--position-bottom-start{--rs-flyout-origin-y:0%;padding-top:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom-start,.content.--position-top-start{--rs-flyout-origin-x:0%}.content.--position-bottom-end,.content.--position-top-end{--rs-flyout-origin-x:100%}.content.--position-start,.content.--position-start-bottom,.content.--position-start-top{--rs-flyout-origin-x:100%;padding-right:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end,.content.--position-end-bottom,.content.--position-end-top{--rs-flyout-origin-x:0%;padding-left:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end-top,.content.--position-start-top{--rs-flyout-origin-y:0%}.content.--position-end-bottom,.content.--position-start-bottom{--rs-flyout-origin-y:100%}.content.--visible .inner{opacity:1;transform:scale(1) translateY(0)}.content.--animated .inner{transition-duration:var(--rs-duration-rapid);transition-property:opacity,transform}.content.--animated.--visible .inner{transition-duration:var(--rs-duration-fast);transition-timing-function:var(--rs-easing-decelerate)}
1
+ .content{--rs-flyout-gap:0;--rs-flyout-origin-x:50%;--rs-flyout-origin-y:50%;isolation:isolate;pointer-events:none;position:absolute}.content.--hover{pointer-events:all}.content.--hover-disabled,.content.--hover-disabled .inner{pointer-events:none}.inner{backface-visibility:hidden;height:100%;max-height:100%;max-width:100%;opacity:0;outline:none;overflow:auto;pointer-events:all;transform:scale(.92) translateY(0);transform-origin:var(--rs-flyout-origin-x) var(--rs-flyout-origin-y);transition:1ms var(--rs-easing-accelerate)}[data-rs-keyboard] .inner:focus{box-shadow:var(--rs-shadow-focus)}.content.--width-trigger .inner{transform:scale(1) translateY(var(--rs-unit-x2))}.content.--position-top,.content.--position-top-end,.content.--position-top-start{--rs-flyout-origin-y:100%;padding-bottom:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom,.content.--position-bottom-end,.content.--position-bottom-start{--rs-flyout-origin-y:0%;padding-top:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-bottom-start,.content.--position-top-start{--rs-flyout-origin-x:0%}.content.--position-bottom-end,.content.--position-top-end{--rs-flyout-origin-x:100%}.content.--position-start,.content.--position-start-bottom,.content.--position-start-top{--rs-flyout-origin-x:100%;padding-right:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end,.content.--position-end-bottom,.content.--position-end-top{--rs-flyout-origin-x:0%;padding-left:calc(var(--rs-unit-x1) * var(--rs-flyout-gap))}.content.--position-end-top,.content.--position-start-top{--rs-flyout-origin-y:0%}.content.--position-end-bottom,.content.--position-start-bottom{--rs-flyout-origin-y:100%}.content.--visible .inner{opacity:1;transform:scale(1) translateY(0)}.content.--animated .inner{transition-duration:var(--rs-duration-rapid);transition-property:opacity,transform}.content.--animated.--visible .inner{transition-duration:var(--rs-duration-fast);transition-timing-function:var(--rs-easing-decelerate)}
@@ -64,7 +64,6 @@ const flyout = (args) => {
64
64
  flyoutBounds: calculated.boundaries,
65
65
  visualContainerBounds,
66
66
  renderContainerBounds,
67
- container,
68
67
  });
69
68
  };
70
69
  let calculated = null;
@@ -14,7 +14,7 @@ const fallbackOrder = {
14
14
  };
15
15
  // Get an order of positions to try to fit flyout on the screen based on its starting position
16
16
  const getPositionFallbacks = (position, availableFallbacks) => {
17
- const result = [position];
17
+ const result = new Set([position]);
18
18
  const chunks = position.split("-");
19
19
  const [firstChunk] = chunks;
20
20
  const passedPositionOrder = positions[firstChunk];
@@ -31,9 +31,9 @@ const getPositionFallbacks = (position, availableFallbacks) => {
31
31
  const position = fallbackOrder[index];
32
32
  if (availableFallbacks?.indexOf(position) === -1)
33
33
  return;
34
- result.push(position);
34
+ result.add(position);
35
35
  });
36
36
  });
37
- return result;
37
+ return Array.from(result);
38
38
  };
39
39
  export default getPositionFallbacks;
@@ -8,7 +8,5 @@ declare const isFullyVisible: (args: {
8
8
  visualContainerBounds: DOMRect;
9
9
  /** Bounds of the container where flyout content is rendered */
10
10
  renderContainerBounds: DOMRect;
11
- /** Container where the flyout content is rendered */
12
- container: HTMLElement;
13
11
  }) => boolean;
14
12
  export default isFullyVisible;
@@ -2,20 +2,18 @@
2
2
  * Check if element visually fits within its render container
3
3
  */
4
4
  const isFullyVisible = (args) => {
5
- const { flyoutBounds, visualContainerBounds, renderContainerBounds, container } = args;
6
- const scrollX = container === document.body ? window.scrollX : container.scrollLeft;
7
- const scrollY = container === document.body ? window.scrollY : container.scrollTop;
8
- if (renderContainerBounds.left + flyoutBounds.left - scrollX < visualContainerBounds.left) {
5
+ const { flyoutBounds, visualContainerBounds, renderContainerBounds } = args;
6
+ if (renderContainerBounds.left + flyoutBounds.left < visualContainerBounds.left) {
9
7
  return false;
10
8
  }
11
- if (renderContainerBounds.top + flyoutBounds.top - scrollY < visualContainerBounds.top) {
9
+ if (renderContainerBounds.top + flyoutBounds.top < visualContainerBounds.top) {
12
10
  return false;
13
11
  }
14
- if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width - scrollX >
12
+ if (renderContainerBounds.left + flyoutBounds.left + flyoutBounds.width >
15
13
  visualContainerBounds.right) {
16
14
  return false;
17
15
  }
18
- if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height - scrollY >
16
+ if (renderContainerBounds.top + flyoutBounds.top + flyoutBounds.height >
19
17
  visualContainerBounds.bottom) {
20
18
  return false;
21
19
  }
@@ -27,3 +27,5 @@ export declare const composition: {
27
27
  name: string;
28
28
  render: () => import("react").JSX.Element;
29
29
  };
30
+ export declare const className: StoryObj;
31
+ export declare const group: StoryObj;
@@ -3,6 +3,8 @@ import { Example } from "../../../utilities/storybook/index.js";
3
3
  import FormControl from "../index.js";
4
4
  import TextField from "../../TextField/index.js";
5
5
  import View from "../../View/index.js";
6
+ import RadioGroup from "../../RadioGroup/index.js";
7
+ import Radio from "../../Radio/index.js";
6
8
  export default {
7
9
  title: "Utility components/FormControl",
8
10
  component: FormControl,
@@ -106,3 +108,36 @@ export const composition = {
106
108
  </Example.Item>
107
109
  </Example>),
108
110
  };
111
+ export const className = {
112
+ name: "className, attributes",
113
+ render: () => (<FormControl id="test-id" hasError>
114
+ <FormControl.Label>Label</FormControl.Label>
115
+ <TextField name="name"/>
116
+ <FormControl.Helper>Caption</FormControl.Helper>
117
+ <FormControl.Error>Error</FormControl.Error>
118
+ </FormControl>),
119
+ play: async ({ canvas }) => {
120
+ const input = canvas.getByRole("textbox");
121
+ const label = canvas.getByText("Label");
122
+ expect(input).toHaveAttribute("id", "test-id");
123
+ expect(input).toHaveAttribute("aria-describedby", `test-id-caption test-id-error`);
124
+ expect(label).toHaveAttribute("for", "test-id");
125
+ expect(label).toHaveAttribute("id", `test-id-label`);
126
+ },
127
+ };
128
+ export const group = {
129
+ name: "group",
130
+ render: () => (<FormControl group>
131
+ <FormControl.Label>Label</FormControl.Label>
132
+ <RadioGroup name="name">
133
+ <View gap={2}>
134
+ <Radio value="1">One</Radio>
135
+ <Radio value="2">Two</Radio>
136
+ </View>
137
+ </RadioGroup>
138
+ </FormControl>),
139
+ play: async ({ canvas }) => {
140
+ const group = canvas.getByRole("group");
141
+ expect(group).toBeInTheDocument();
142
+ },
143
+ };