@aloudata/aloudata-design 0.1.0-beta1

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 (293) hide show
  1. package/.editorconfig +16 -0
  2. package/.eslintrc.js +43 -0
  3. package/.fatherrc.ts +16 -0
  4. package/.prettierignore +7 -0
  5. package/.prettierrc.js +1 -0
  6. package/.stylelintrc.json +36 -0
  7. package/.umirc.ts +15 -0
  8. package/README.md +82 -0
  9. package/commitlint.config.js +21 -0
  10. package/docs/index.md +21 -0
  11. package/jest/setupTests.js +1 -0
  12. package/lib/Button/demo/Icon/index.d.ts +3 -0
  13. package/lib/Button/demo/Icon/index.js +82 -0
  14. package/lib/Button/demo/Icon/index.less +6 -0
  15. package/lib/Button/demo/basic/index.d.ts +4 -0
  16. package/lib/Button/demo/basic/index.js +73 -0
  17. package/lib/Button/demo/basic/index.less +7 -0
  18. package/lib/Button/demo/disable/index.d.ts +3 -0
  19. package/lib/Button/demo/disable/index.js +37 -0
  20. package/lib/Button/demo/disable/index.less +0 -0
  21. package/lib/Button/demo/href/index.d.ts +2 -0
  22. package/lib/Button/demo/href/index.js +30 -0
  23. package/lib/Button/demo/loading/index.d.ts +3 -0
  24. package/lib/Button/demo/loading/index.js +51 -0
  25. package/lib/Button/demo/loading/index.less +6 -0
  26. package/lib/Button/index.d.ts +50 -0
  27. package/lib/Button/index.js +124 -0
  28. package/lib/Button/style/index.d.ts +2 -0
  29. package/lib/Button/style/index.js +5 -0
  30. package/lib/Button/style/index.less +255 -0
  31. package/lib/Dropdown/Button.d.ts +69 -0
  32. package/lib/Dropdown/Button.js +52 -0
  33. package/lib/Dropdown/demo/basic/index.d.ts +4 -0
  34. package/lib/Dropdown/demo/basic/index.js +35 -0
  35. package/lib/Dropdown/demo/button/index.d.ts +3 -0
  36. package/lib/Dropdown/demo/button/index.js +182 -0
  37. package/lib/Dropdown/demo/button/index.less +9 -0
  38. package/lib/Dropdown/demo/placement/index.d.ts +2 -0
  39. package/lib/Dropdown/demo/placement/index.js +56 -0
  40. package/lib/Dropdown/demo/subMenu/index.d.ts +2 -0
  41. package/lib/Dropdown/demo/subMenu/index.js +59 -0
  42. package/lib/Dropdown/demo/trigger/index.d.ts +2 -0
  43. package/lib/Dropdown/demo/trigger/index.js +32 -0
  44. package/lib/Dropdown/index.d.ts +59 -0
  45. package/lib/Dropdown/index.js +47 -0
  46. package/lib/Dropdown/style/index.d.ts +2 -0
  47. package/lib/Dropdown/style/index.js +5 -0
  48. package/lib/Dropdown/style/index.less +40 -0
  49. package/lib/Icon/iconfont/demo.css +539 -0
  50. package/lib/Icon/iconfont/demo_index.html +628 -0
  51. package/lib/Icon/iconfont/iconfont.css +93 -0
  52. package/lib/Icon/iconfont/iconfont.js +48 -0
  53. package/lib/Icon/iconfont/iconfont.json +142 -0
  54. package/lib/Icon/iconfont/iconfont.ttf +0 -0
  55. package/lib/Icon/iconfont/iconfont.woff +0 -0
  56. package/lib/Icon/iconfont/iconfont.woff2 +0 -0
  57. package/lib/Icon/index.d.ts +11 -0
  58. package/lib/Icon/index.js +54 -0
  59. package/lib/Icon/index.less +32 -0
  60. package/lib/Input/components/Group/index.d.ts +15 -0
  61. package/lib/Input/components/Group/index.js +24 -0
  62. package/lib/Input/components/Password/index.d.ts +10 -0
  63. package/lib/Input/components/Password/index.js +33 -0
  64. package/lib/Input/components/TextArea/index.d.ts +52 -0
  65. package/lib/Input/components/TextArea/index.js +26 -0
  66. package/lib/Input/demo/allowClear/index.d.ts +3 -0
  67. package/lib/Input/demo/allowClear/index.js +25 -0
  68. package/lib/Input/demo/allowClear/index.less +0 -0
  69. package/lib/Input/demo/basic/index.d.ts +4 -0
  70. package/lib/Input/demo/basic/index.js +80 -0
  71. package/lib/Input/demo/basic/index.less +6 -0
  72. package/lib/Input/demo/gourp/index.d.ts +2 -0
  73. package/lib/Input/demo/gourp/index.js +81 -0
  74. package/lib/Input/demo/password/index.d.ts +3 -0
  75. package/lib/Input/demo/password/index.js +35 -0
  76. package/lib/Input/demo/password/index.less +0 -0
  77. package/lib/Input/demo/prefix/index.d.ts +3 -0
  78. package/lib/Input/demo/prefix/index.js +32 -0
  79. package/lib/Input/demo/prefix/index.less +0 -0
  80. package/lib/Input/demo/showCount/index.d.ts +3 -0
  81. package/lib/Input/demo/showCount/index.js +31 -0
  82. package/lib/Input/demo/showCount/index.less +0 -0
  83. package/lib/Input/demo/textArea/autoSize.d.ts +2 -0
  84. package/lib/Input/demo/textArea/autoSize.js +63 -0
  85. package/lib/Input/index.d.ts +65 -0
  86. package/lib/Input/index.js +63 -0
  87. package/lib/Input/style/index.d.ts +2 -0
  88. package/lib/Input/style/index.js +5 -0
  89. package/lib/Input/style/index.less +62 -0
  90. package/lib/Menu/Divider.d.ts +5 -0
  91. package/lib/Menu/Divider.js +28 -0
  92. package/lib/Menu/MenuItem.d.ts +17 -0
  93. package/lib/Menu/MenuItem.js +28 -0
  94. package/lib/Menu/SubMenu.d.ts +26 -0
  95. package/lib/Menu/SubMenu.js +44 -0
  96. package/lib/Menu/index.d.ts +20 -0
  97. package/lib/Menu/index.js +49 -0
  98. package/lib/Menu/style/index.d.ts +2 -0
  99. package/lib/Menu/style/index.js +5 -0
  100. package/lib/Menu/style/index.less +33 -0
  101. package/lib/Select/BaseSelect.d.ts +5 -0
  102. package/lib/Select/BaseSelect.js +433 -0
  103. package/lib/Select/OptionsList/OptGroup.d.ts +7 -0
  104. package/lib/Select/OptionsList/OptGroup.js +14 -0
  105. package/lib/Select/OptionsList/OptionItem.d.ts +35 -0
  106. package/lib/Select/OptionsList/OptionItem.js +185 -0
  107. package/lib/Select/OptionsList/Options.d.ts +7 -0
  108. package/lib/Select/OptionsList/Options.js +14 -0
  109. package/lib/Select/OptionsList/index.d.ts +4 -0
  110. package/lib/Select/OptionsList/index.js +207 -0
  111. package/lib/Select/Selector/index.d.ts +4 -0
  112. package/lib/Select/Selector/index.js +273 -0
  113. package/lib/Select/VirtualList.d.ts +5 -0
  114. package/lib/Select/VirtualList.js +42 -0
  115. package/lib/Select/demo/disabled/index.d.ts +2 -0
  116. package/lib/Select/demo/disabled/index.js +64 -0
  117. package/lib/Select/demo/multiple/index.d.ts +2 -0
  118. package/lib/Select/demo/multiple/index.js +154 -0
  119. package/lib/Select/demo/options/index.d.ts +2 -0
  120. package/lib/Select/demo/options/index.js +69 -0
  121. package/lib/Select/demo/single/index.d.ts +2 -0
  122. package/lib/Select/demo/single/index.js +99 -0
  123. package/lib/Select/hooks/useCacheOption.d.ts +9 -0
  124. package/lib/Select/hooks/useCacheOption.js +113 -0
  125. package/lib/Select/index.d.ts +12 -0
  126. package/lib/Select/index.js +34 -0
  127. package/lib/Select/interface.d.ts +221 -0
  128. package/lib/Select/interface.js +5 -0
  129. package/lib/Select/style/index.d.ts +2 -0
  130. package/lib/Select/style/index.js +5 -0
  131. package/lib/Select/style/index.less +539 -0
  132. package/lib/Select/utils.d.ts +21 -0
  133. package/lib/Select/utils.js +233 -0
  134. package/lib/Tabs/TabPane.d.ts +21 -0
  135. package/lib/Tabs/TabPane.js +24 -0
  136. package/lib/Tabs/demo/adaptHeight/index.d.ts +3 -0
  137. package/lib/Tabs/demo/adaptHeight/index.js +34 -0
  138. package/lib/Tabs/demo/adaptHeight/index.less +3 -0
  139. package/lib/Tabs/demo/basic/index.d.ts +4 -0
  140. package/lib/Tabs/demo/basic/index.js +67 -0
  141. package/lib/Tabs/demo/basic/index.less +5 -0
  142. package/lib/Tabs/demo/horizontalScroll/index.d.ts +3 -0
  143. package/lib/Tabs/demo/horizontalScroll/index.js +45 -0
  144. package/lib/Tabs/demo/horizontalScroll/index.less +3 -0
  145. package/lib/Tabs/index.d.ts +41 -0
  146. package/lib/Tabs/index.js +58 -0
  147. package/lib/Tabs/style/index.d.ts +2 -0
  148. package/lib/Tabs/style/index.js +5 -0
  149. package/lib/Tabs/style/index.less +61 -0
  150. package/lib/Tooltip/demo/basic/index.d.ts +2 -0
  151. package/lib/Tooltip/demo/basic/index.js +20 -0
  152. package/lib/Tooltip/demo/overflow/index.d.ts +2 -0
  153. package/lib/Tooltip/demo/overflow/index.js +20 -0
  154. package/lib/Tooltip/demo/placement/index.d.ts +6 -0
  155. package/lib/Tooltip/demo/placement/index.js +86 -0
  156. package/lib/Tooltip/demo/placement/index.less +7 -0
  157. package/lib/Tooltip/demo/trigger/index.d.ts +3 -0
  158. package/lib/Tooltip/demo/trigger/index.js +34 -0
  159. package/lib/Tooltip/demo/trigger/index.less +5 -0
  160. package/lib/Tooltip/index.d.ts +63 -0
  161. package/lib/Tooltip/index.js +44 -0
  162. package/lib/Tooltip/style/index.d.ts +2 -0
  163. package/lib/Tooltip/style/index.js +5 -0
  164. package/lib/Tooltip/style/index.less +14 -0
  165. package/lib/_utils/hooks/useControlledState.d.ts +2 -0
  166. package/lib/_utils/hooks/useControlledState.js +63 -0
  167. package/lib/_utils/hooks/usePrefixCls.d.ts +2 -0
  168. package/lib/_utils/hooks/usePrefixCls.js +27 -0
  169. package/lib/index.d.ts +8 -0
  170. package/lib/index.js +63 -0
  171. package/lib/style/index.d.ts +2 -0
  172. package/lib/style/index.js +5 -0
  173. package/lib/style/index.less +3 -0
  174. package/lib/style/mixins/index.less +0 -0
  175. package/lib/style/themes/default/index.less +36 -0
  176. package/lib/style/themes/default/themeColor.less +259 -0
  177. package/package.json +83 -0
  178. package/public/favicon.ico +0 -0
  179. package/src/Button/demo/Icon/index.less +6 -0
  180. package/src/Button/demo/Icon/index.tsx +41 -0
  181. package/src/Button/demo/basic/index.less +7 -0
  182. package/src/Button/demo/basic/index.tsx +26 -0
  183. package/src/Button/demo/disable/index.less +0 -0
  184. package/src/Button/demo/disable/index.tsx +16 -0
  185. package/src/Button/demo/href/index.tsx +14 -0
  186. package/src/Button/demo/loading/index.less +6 -0
  187. package/src/Button/demo/loading/index.tsx +21 -0
  188. package/src/Button/index.md +25 -0
  189. package/src/Button/index.test.tsx +58 -0
  190. package/src/Button/index.tsx +136 -0
  191. package/src/Button/style/index.less +255 -0
  192. package/src/Button/style/index.ts +2 -0
  193. package/src/Dropdown/Button.tsx +93 -0
  194. package/src/Dropdown/demo/basic/index.tsx +20 -0
  195. package/src/Dropdown/demo/button/index.less +9 -0
  196. package/src/Dropdown/demo/button/index.tsx +98 -0
  197. package/src/Dropdown/demo/placement/index.tsx +47 -0
  198. package/src/Dropdown/demo/subMenu/index.tsx +35 -0
  199. package/src/Dropdown/demo/trigger/index.tsx +19 -0
  200. package/src/Dropdown/index.md +35 -0
  201. package/src/Dropdown/index.test.tsx +185 -0
  202. package/src/Dropdown/index.tsx +71 -0
  203. package/src/Dropdown/style/index.less +40 -0
  204. package/src/Dropdown/style/index.ts +2 -0
  205. package/src/Icon/iconfont/demo.css +539 -0
  206. package/src/Icon/iconfont/demo_index.html +628 -0
  207. package/src/Icon/iconfont/iconfont.css +93 -0
  208. package/src/Icon/iconfont/iconfont.js +1 -0
  209. package/src/Icon/iconfont/iconfont.json +142 -0
  210. package/src/Icon/iconfont/iconfont.ttf +0 -0
  211. package/src/Icon/iconfont/iconfont.woff +0 -0
  212. package/src/Icon/iconfont/iconfont.woff2 +0 -0
  213. package/src/Icon/index.less +32 -0
  214. package/src/Icon/index.tsx +38 -0
  215. package/src/Input/components/Group/index.tsx +21 -0
  216. package/src/Input/components/Password/index.tsx +23 -0
  217. package/src/Input/components/TextArea/index.tsx +57 -0
  218. package/src/Input/demo/allowClear/index.less +0 -0
  219. package/src/Input/demo/allowClear/index.tsx +10 -0
  220. package/src/Input/demo/basic/index.less +6 -0
  221. package/src/Input/demo/basic/index.tsx +25 -0
  222. package/src/Input/demo/gourp/index.tsx +30 -0
  223. package/src/Input/demo/password/index.less +0 -0
  224. package/src/Input/demo/password/index.tsx +11 -0
  225. package/src/Input/demo/prefix/index.less +0 -0
  226. package/src/Input/demo/prefix/index.tsx +13 -0
  227. package/src/Input/demo/showCount/index.less +0 -0
  228. package/src/Input/demo/showCount/index.tsx +16 -0
  229. package/src/Input/demo/textArea/autoSize.tsx +21 -0
  230. package/src/Input/index.md +37 -0
  231. package/src/Input/index.test.tsx +78 -0
  232. package/src/Input/index.tsx +91 -0
  233. package/src/Input/style/index.less +62 -0
  234. package/src/Input/style/index.ts +2 -0
  235. package/src/Menu/Divider.tsx +12 -0
  236. package/src/Menu/MenuItem.tsx +24 -0
  237. package/src/Menu/SubMenu.tsx +37 -0
  238. package/src/Menu/index.md +36 -0
  239. package/src/Menu/index.test.tsx +144 -0
  240. package/src/Menu/index.tsx +27 -0
  241. package/src/Menu/style/index.less +33 -0
  242. package/src/Menu/style/index.ts +2 -0
  243. package/src/Select/BaseSelect.tsx +321 -0
  244. package/src/Select/OptionsList/OptGroup.tsx +9 -0
  245. package/src/Select/OptionsList/OptionItem.tsx +151 -0
  246. package/src/Select/OptionsList/Options.tsx +11 -0
  247. package/src/Select/OptionsList/index.tsx +169 -0
  248. package/src/Select/Selector/index.tsx +211 -0
  249. package/src/Select/VirtualList.tsx +36 -0
  250. package/src/Select/demo/disabled/index.tsx +44 -0
  251. package/src/Select/demo/multiple/index.tsx +77 -0
  252. package/src/Select/demo/options/index.tsx +63 -0
  253. package/src/Select/demo/single/index.tsx +50 -0
  254. package/src/Select/hooks/useCacheOption.ts +67 -0
  255. package/src/Select/index.md +72 -0
  256. package/src/Select/index.tsx +23 -0
  257. package/src/Select/interface.ts +231 -0
  258. package/src/Select/style/index.less +539 -0
  259. package/src/Select/style/index.ts +2 -0
  260. package/src/Select/utils.tsx +133 -0
  261. package/src/Tabs/TabPane.tsx +28 -0
  262. package/src/Tabs/demo/adaptHeight/index.less +3 -0
  263. package/src/Tabs/demo/adaptHeight/index.tsx +33 -0
  264. package/src/Tabs/demo/basic/index.less +5 -0
  265. package/src/Tabs/demo/basic/index.tsx +30 -0
  266. package/src/Tabs/demo/horizontalScroll/index.less +3 -0
  267. package/src/Tabs/demo/horizontalScroll/index.tsx +36 -0
  268. package/src/Tabs/index.md +30 -0
  269. package/src/Tabs/index.test.tsx +100 -0
  270. package/src/Tabs/index.tsx +64 -0
  271. package/src/Tabs/style/index.less +61 -0
  272. package/src/Tabs/style/index.ts +2 -0
  273. package/src/Tooltip/demo/basic/index.tsx +10 -0
  274. package/src/Tooltip/demo/overflow/index.tsx +10 -0
  275. package/src/Tooltip/demo/placement/index.less +7 -0
  276. package/src/Tooltip/demo/placement/index.tsx +60 -0
  277. package/src/Tooltip/demo/trigger/index.less +5 -0
  278. package/src/Tooltip/demo/trigger/index.tsx +22 -0
  279. package/src/Tooltip/index.md +28 -0
  280. package/src/Tooltip/index.test.tsx +152 -0
  281. package/src/Tooltip/index.tsx +113 -0
  282. package/src/Tooltip/style/index.less +14 -0
  283. package/src/Tooltip/style/index.ts +2 -0
  284. package/src/_utils/hooks/useControlledState.ts +39 -0
  285. package/src/_utils/hooks/usePrefixCls.ts +11 -0
  286. package/src/index.ts +8 -0
  287. package/src/style/index.less +3 -0
  288. package/src/style/index.ts +2 -0
  289. package/src/style/mixins/index.less +0 -0
  290. package/src/style/themes/default/index.less +36 -0
  291. package/src/style/themes/default/themeColor.less +259 -0
  292. package/tsconfig.json +13 -0
  293. package/typings.d.ts +3 -0
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { Dropdown, Menu } from '@aloudata/aloudata-design';
3
+
4
+ const MenuItem = Menu.Item;
5
+
6
+ export default () => {
7
+ const menu = (
8
+ <Menu>
9
+ <MenuItem key={1}>1st menu item</MenuItem>
10
+ <MenuItem key={2} disabled>2nd menu item</MenuItem>
11
+ <MenuItem key={3}>3nd menu item</MenuItem>
12
+ </Menu>
13
+ );
14
+ return (
15
+ <Dropdown overlay={menu} trigger={['click']}>
16
+ <span>Click me</span>
17
+ </Dropdown>
18
+ );
19
+ }
@@ -0,0 +1,35 @@
1
+ ---
2
+ # nav:
3
+ # title: 组件
4
+ # path: /components
5
+ title: Dropdown 下拉菜单
6
+ group:
7
+ title: 组件
8
+ ---
9
+
10
+ # Dropdown 下拉菜单
11
+
12
+ 向下弹出的列表
13
+
14
+ ## 代码演示
15
+
16
+ <code src="./demo/basic" title="基本" description="最简单的用法">
17
+
18
+ <code src="./demo/placement" title="弹出位置" description="支持6个弹出位置">
19
+
20
+ <code src="./demo/trigger" title="触发方式" description="点击触发下拉菜单">
21
+
22
+ <code src="./demo/subMenu" title="多级菜单" description="传入的菜单有多个层级">
23
+
24
+ <code src="./demo/button" title="带下拉框的按钮" description="按钮和下拉框结合">
25
+
26
+
27
+ ## API
28
+
29
+ ### Dropdown
30
+
31
+ <API exports='["default"]' hideTitle />
32
+
33
+ ### Dropdown.Button
34
+
35
+ <API exports='["default.Button"]' hideTitle />
@@ -0,0 +1,185 @@
1
+ import '@testing-library/jest-dom';
2
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
+ import Menu from '../Menu';
4
+ import React from 'react';
5
+ import { act } from 'react-dom/test-utils';
6
+ import Dropdown from './index';
7
+
8
+ const menu = (
9
+ <Menu>
10
+ <Menu.Item key="1">1st menu item</Menu.Item>
11
+ <Menu.Item key="2">2nd menu item</Menu.Item>
12
+ </Menu>
13
+ );
14
+
15
+ describe('Dropdown', () => {
16
+ it('destroyPopupOnHide', () => {
17
+ const msg = 'trigger';
18
+ const { rerender } = render(<Dropdown visible overlay={menu} destroyPopupOnHide><span>{msg}</span></Dropdown>);
19
+ rerender(<Dropdown visible={false} overlay={menu} destroyPopupOnHide><span>{msg}</span></Dropdown>);
20
+
21
+ expect(screen.queryByText('1st menu item')).toBeNull();
22
+ });
23
+
24
+ it('getPopupContainer', async () => {
25
+ const container = document.createElement('div');
26
+ container.classList.add('container');
27
+ document.body.appendChild(container);
28
+
29
+ await act(async () => {
30
+ render(<Dropdown visible overlay={menu} getPopupContainer={() => container}><span>trigger</span></Dropdown>);
31
+ // 加下面这行的原因是,不加时会报menu的state在act外部变化的异常
32
+ await waitFor(() => {
33
+ return document.querySelector('.container .ant-dropdown');
34
+ });
35
+ });
36
+
37
+ expect(document.querySelector('.container .ant-dropdown')).not.toBeNull();
38
+
39
+ document.body.removeChild(container);
40
+ });
41
+
42
+ it('overlay callback menu', async () => {
43
+ await act(async () => {
44
+ render(<Dropdown visible overlay={() => menu}><span>trigger</span></Dropdown>);
45
+ // 加下面这行的原因是,不加时会报menu的state在act外部变化的异常
46
+ await waitFor(() => {
47
+ return screen.queryByText('1st menu item');
48
+ });
49
+ });
50
+
51
+ expect(screen.queryByText('1st menu item')).not.toBeNull();
52
+ });
53
+
54
+ it('overlayClassName', async () => {
55
+ const overlayClassName = 'overlayClassName';
56
+ await act(async () => {
57
+ render(<Dropdown visible overlay={menu} overlayClassName={overlayClassName}><span>trigger</span></Dropdown>);
58
+ // 加下面这行的原因是,不加时会报menu的state在act外部变化的异常
59
+ await waitFor(() => {
60
+ return screen.queryByText('1st menu item');
61
+ });
62
+ });
63
+ expect(document.querySelector(`.${overlayClassName}.ant-dropdown`)).not.toBeNull();
64
+ });
65
+
66
+ it('visible', async () => {
67
+ const msg = 'visible';
68
+
69
+ await act(async () => {
70
+ const { rerender } = render(<Dropdown visible overlay={menu}><span>{msg}</span></Dropdown>);
71
+ rerender(<Dropdown visible={false} overlay={menu}><span>{msg}</span></Dropdown>);
72
+ await waitFor(() => {
73
+ return document.querySelector('.ant-dropdown');
74
+ });
75
+ });
76
+
77
+ expect(
78
+ document.querySelector('.ant-dropdown.ant-dropdown-hidden'),
79
+ ).not.toBeNull();
80
+ });
81
+
82
+ it('onVisibleChange', async () => {
83
+ jest.useFakeTimers();
84
+
85
+ const className = 'onVisibleChangeClassName';
86
+
87
+ let visible = false;
88
+ const onVisibleChange = (newVisible: boolean) => {
89
+ visible = newVisible;
90
+ };
91
+
92
+ await act(async () => {
93
+ render(<Dropdown overlay={menu} onVisibleChange={onVisibleChange}><span className={className}>trigger</span></Dropdown>);
94
+ });
95
+
96
+ const innerDom = document.querySelector(`.${className}`);
97
+ fireEvent.mouseEnter(innerDom!);
98
+
99
+ await act(async () => {
100
+ // menu内容出现后,依然没有触发onVisibleChange,测试了延时超过150ms,能触发onVisibleChange,没有搞清原理
101
+ const DELAY_TIME = 150;
102
+ jest.advanceTimersByTime(DELAY_TIME);
103
+ await waitFor(() => {
104
+ return document.querySelector('.ant-dropdown');
105
+ });
106
+ });
107
+ expect(visible).toBeTruthy();
108
+
109
+ jest.runOnlyPendingTimers();
110
+ jest.useRealTimers();
111
+ });
112
+ });
113
+
114
+ describe('Dropdown.Button', () => {
115
+ it('overlay callback menu', async () => {
116
+ await act(async () => {
117
+ render(<Dropdown.Button visible overlay={() => menu}><span>trigger</span></Dropdown.Button>);
118
+ // 加下面这行的原因是,不加时会报menu的state在act外部变化的异常
119
+ await waitFor(() => {
120
+ return screen.queryByText('1st menu item');
121
+ });
122
+ });
123
+
124
+ expect(screen.queryByText('1st menu item')).not.toBeNull();
125
+ });
126
+
127
+ it('visible', async () => {
128
+ const msg = 'visible';
129
+
130
+ await act(async () => {
131
+ const { rerender } = render(<Dropdown.Button visible overlay={menu}><span>{msg}</span></Dropdown.Button>);
132
+ rerender(<Dropdown.Button visible={false} overlay={menu}><span>{msg}</span></Dropdown.Button>);
133
+ await waitFor(() => {
134
+ return document.querySelector('.ant-dropdown');
135
+ });
136
+ });
137
+
138
+ expect(
139
+ document.querySelector('.ant-dropdown.ant-dropdown-hidden'),
140
+ ).not.toBeNull();
141
+ });
142
+
143
+ it('onVisibleChange', async () => {
144
+ jest.useFakeTimers();
145
+
146
+ const className = 'onVisibleChangeClassName';
147
+
148
+ let visible = false;
149
+ const onVisibleChange = (newVisible: boolean) => {
150
+ visible = newVisible;
151
+ };
152
+
153
+ await act(async () => {
154
+ render(<Dropdown.Button overlay={menu} onVisibleChange={onVisibleChange}><span className={className}>trigger</span></Dropdown.Button>);
155
+ });
156
+
157
+ const innerDom = document.querySelector(`.${className}`);
158
+ fireEvent.mouseEnter(innerDom!);
159
+
160
+ await act(async () => {
161
+ // menu内容出现后,依然没有触发onVisibleChange,测试了延时超过150ms,能触发onVisibleChange,没有搞清原理
162
+ const DELAY_TIME = 150;
163
+ jest.advanceTimersByTime(DELAY_TIME);
164
+ await waitFor(() => {
165
+ return document.querySelector('.ant-dropdown');
166
+ });
167
+ });
168
+ expect(visible).toBeTruthy();
169
+
170
+ jest.runOnlyPendingTimers();
171
+ jest.useRealTimers();
172
+ });
173
+
174
+ it('onClick', async () => {
175
+ const fn = jest.fn();
176
+ await act(async () => {
177
+ render(<Dropdown.Button visible overlay={menu} onClick={fn}><span>trigger</span></Dropdown.Button>);
178
+ await waitFor(() => {
179
+ return document.querySelector('.ant-dropdown');
180
+ });
181
+ });
182
+ screen.queryByText('trigger')?.closest('span')?.click();
183
+ expect(fn).toHaveBeenCalled();
184
+ });
185
+ });
@@ -0,0 +1,71 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { Dropdown as AntdDropdown } from 'antd';
3
+ // eslint-disable-next-line import/no-cycle
4
+ import DropdownButton from './Button';
5
+ import './style';
6
+
7
+ export type ActionType = 'hover' | 'click' | 'contextMenu';
8
+
9
+ export interface IDropdownProps {
10
+ /**
11
+ * @description 关闭后是否销毁Dropdown
12
+ * @default false
13
+ */
14
+ destroyPopupOnHide?: boolean;
15
+ /**
16
+ * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位
17
+ * @default () => document.body
18
+ */
19
+ getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
20
+ /**
21
+ * @description 菜单
22
+ * @type Menu | () => Menu
23
+ * @default -
24
+ */
25
+ overlay: ReactElement | (() => ReactElement);
26
+ /**
27
+ * @description 下拉根元素的类名称
28
+ * @default -
29
+ */
30
+ overlayClassName?: string;
31
+ /**
32
+ * @description 菜单弹出位置
33
+ * @default bottomLeft
34
+ */
35
+ placement?: 'bottomLeft' | 'bottomCenter' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight';
36
+ /**
37
+ * @description 触发下拉的行为
38
+ * @type ActionType[], 其中 ActionType 为 'hover' | 'click' | 'contextMenu';
39
+ * @default [hover]
40
+ */
41
+ trigger?: ActionType[];
42
+ /**
43
+ * @description 菜单是否显示
44
+ * @default -
45
+ */
46
+ visible?: boolean;
47
+ /**
48
+ * @description 菜单显示状态改变时调用,参数为 visible,点击菜单按钮导致的消失不会触发
49
+ * @default -
50
+ */
51
+ onVisibleChange?: (visible: boolean) => void;
52
+ children?: React.ReactNode;
53
+ /**
54
+ * @description 是否禁用
55
+ * @default false
56
+ */
57
+ // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性
58
+ disabled?: boolean;
59
+ }
60
+
61
+ export default function Dropdown(props: IDropdownProps) {
62
+ const { children, visible, ...otherProps } = props;
63
+ // antd根据visible字段是否存在来判断visible是否是可控模式
64
+ const antdDropdownProps: Omit<IDropdownProps, 'children'> = otherProps;
65
+ if (visible !== undefined) {
66
+ antdDropdownProps.visible = visible;
67
+ }
68
+ return <AntdDropdown {...antdDropdownProps}>{children}</AntdDropdown>;
69
+ }
70
+
71
+ Dropdown.Button = DropdownButton;
@@ -0,0 +1,40 @@
1
+ @import '../../style/index.less';
2
+
3
+ .ant-dropdown-menu > .ant-dropdown-menu {
4
+ padding: 0;
5
+ box-shadow: none;
6
+ }
7
+
8
+ .ald-menu,
9
+ .ald-submenu {
10
+ .ant-dropdown-menu-item-active {
11
+ background-color: @NL97;
12
+ }
13
+
14
+ .ant-dropdown-menu-item-disabled {
15
+ color: @NL80;
16
+ }
17
+
18
+ .ant-dropdown-menu-submenu-title {
19
+ padding: 5px 24px 5px 12px;
20
+
21
+ .ant-dropdown-menu-submenu-expand-icon {
22
+ right: 12px;
23
+ }
24
+ }
25
+
26
+ .ant-dropdown-menu-item {
27
+ padding: 5px 12px;
28
+ }
29
+
30
+ .ant-dropdown-menu-item,
31
+ .ant-dropdown-menu-submenu-title {
32
+ &:hover {
33
+ background-color: @NL97;
34
+ }
35
+ }
36
+ }
37
+
38
+ .ald-submenu.ant-dropdown-menu-submenu-popup ul {
39
+ margin: 0;
40
+ }
@@ -0,0 +1,2 @@
1
+ import '../../style'
2
+ import './index.less';