@tendaui/components 1.2.4 → 1.3.0

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 (406) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +176 -176
  3. package/_util/scroll.ts +9 -0
  4. package/alert/_example/base.tsx +13 -0
  5. package/alert/_example/collapse.tsx +15 -0
  6. package/badge/_example/base.tsx +10 -0
  7. package/badge/_example/count.tsx +29 -0
  8. package/badge/_example/custom-color.tsx +32 -0
  9. package/badge/_example/dot.tsx +26 -0
  10. package/badge/_example/max-count.tsx +26 -0
  11. package/badge/_example/offset.tsx +29 -0
  12. package/badge/_example/shape.tsx +32 -0
  13. package/badge/_example/show-zero.tsx +23 -0
  14. package/badge/_example/size.tsx +35 -0
  15. package/badge/_example/standalone.tsx +14 -0
  16. package/badge/_example/text-count.tsx +26 -0
  17. package/badge/_example/with-button.tsx +23 -0
  18. package/button/_example/block.tsx +18 -0
  19. package/button/_example/disabled.tsx +22 -0
  20. package/button/_example/ghost.tsx +24 -0
  21. package/button/_example/link.tsx +15 -0
  22. package/button/_example/loading.tsx +19 -0
  23. package/button/_example/shape.tsx +18 -0
  24. package/button/_example/size.tsx +18 -0
  25. package/button/_example/suffix.tsx +16 -0
  26. package/button/_example/theme.tsx +14 -0
  27. package/button/_example/variant-base.tsx +24 -0
  28. package/button/_example/variant-dashed.tsx +24 -0
  29. package/button/_example/variant-outline.tsx +24 -0
  30. package/button/_example/variant-text.tsx +24 -0
  31. package/checkbox/_example/base.tsx +8 -0
  32. package/checkbox/_example/controlled.tsx +11 -0
  33. package/checkbox/_example/group-disabled.tsx +13 -0
  34. package/checkbox/_example/group-with-check-all.tsx +22 -0
  35. package/checkbox/_example/group-with-max.tsx +17 -0
  36. package/checkbox/_example/group-with-options.tsx +18 -0
  37. package/checkbox/_example/group.tsx +17 -0
  38. package/checkbox/_example/states.tsx +19 -0
  39. package/color-picker/ColorPicker.tsx +16 -2
  40. package/color-picker/_example/base.tsx +12 -0
  41. package/color-picker/_example/borderless.tsx +17 -0
  42. package/color-picker/_example/clearable.tsx +12 -0
  43. package/color-picker/_example/disabled.tsx +17 -0
  44. package/color-picker/_example/formats.tsx +30 -0
  45. package/color-picker/_example/manual-input.tsx +39 -0
  46. package/color-picker/_example/recent-colors.tsx +19 -0
  47. package/color-picker/_example/swatch-colors.tsx +28 -0
  48. package/color-picker/_example/with-alpha.tsx +21 -0
  49. package/color-picker/components/panel/format/inputs.tsx +1 -1
  50. package/color-picker/components/panel/index.tsx +13 -0
  51. package/color-picker/components/trigger.tsx +64 -13
  52. package/color-picker/defaultProps.ts +4 -1
  53. package/color-picker/utils/color-picker/cmyk.ts +89 -89
  54. package/color-picker/utils/color-picker/color.ts +467 -467
  55. package/color-picker/utils/color-picker/constants.ts +187 -187
  56. package/color-picker/utils/color-picker/draggable.ts +99 -100
  57. package/color-picker/utils/color-picker/format.ts +90 -95
  58. package/color-picker/utils/color-picker/gradient.ts +237 -243
  59. package/color-picker/utils/color-picker/index.ts +7 -7
  60. package/color-picker/utils/color-picker/types.ts +33 -33
  61. package/config-provider/ConfigContext.tsx +1 -0
  62. package/config-provider/ConfigProvider.tsx +18 -1
  63. package/config-provider/type.ts +5 -0
  64. package/dialog/_example/base.tsx +27 -0
  65. package/dialog/_example/confirm-loading.tsx +32 -0
  66. package/dialog/_example/custom-buttons.tsx +24 -0
  67. package/dialog/_example/full-screen.tsx +26 -0
  68. package/dialog/_example/hide-buttons.tsx +39 -0
  69. package/dialog/_example/modeless.tsx +25 -0
  70. package/dialog/_example/placement.tsx +40 -0
  71. package/dialog/_example/plugin-example.tsx +69 -0
  72. package/dialog/_example/themes.tsx +41 -0
  73. package/dialog/hooks/useDialogPosition.ts +35 -35
  74. package/drawer/Drawer.tsx +17 -9
  75. package/drawer/_example/custom-header-footer.tsx +29 -0
  76. package/drawer/_example/default.tsx +20 -0
  77. package/drawer/_example/events.tsx +53 -0
  78. package/drawer/_example/no-footer.tsx +20 -0
  79. package/drawer/_example/no-overlay.tsx +20 -0
  80. package/drawer/_example/placement.tsx +43 -0
  81. package/drawer/_example/size-draggable.tsx +26 -0
  82. package/drawer/_example/size.tsx +40 -0
  83. package/drawer/defaultProps.ts +1 -1
  84. package/fireworks/Fireworks.tsx +1 -10
  85. package/fireworks/index.ts +0 -1
  86. package/fireworks/type.ts +0 -1
  87. package/form/_example/complex.tsx +76 -0
  88. package/form/_example/default.tsx +58 -0
  89. package/form/_example/disabled.tsx +26 -0
  90. package/form/_example/form-list.tsx +74 -0
  91. package/form/_example/inline-layout.tsx +20 -0
  92. package/form/_example/label-align.tsx +46 -0
  93. package/form/_example/methods.tsx +66 -0
  94. package/form/_example/validation.tsx +71 -0
  95. package/form/hooks/useFormItemStyle.tsx +19 -7
  96. package/form/index.ts +20 -2
  97. package/form/type.ts +519 -519
  98. package/global-config/default-config.ts +95 -95
  99. package/global-config/locale/ar_KW.ts +259 -270
  100. package/global-config/locale/en_US.ts +265 -280
  101. package/global-config/locale/it_IT.ts +264 -287
  102. package/global-config/locale/ja_JP.ts +264 -279
  103. package/global-config/locale/ko_KR.ts +264 -279
  104. package/global-config/locale/ru_RU.ts +277 -288
  105. package/global-config/locale/zh_CN.ts +265 -279
  106. package/global-config/locale/zh_TW.ts +265 -279
  107. package/global-config/mobile/default-config.ts +6 -6
  108. package/global-config/mobile/locale/ar_KW.ts +112 -113
  109. package/global-config/mobile/locale/en_US.ts +113 -114
  110. package/global-config/mobile/locale/it_IT.ts +113 -114
  111. package/global-config/mobile/locale/ja_JP.ts +100 -101
  112. package/global-config/mobile/locale/ko_KR.ts +100 -101
  113. package/global-config/mobile/locale/ru_RU.ts +112 -113
  114. package/global-config/mobile/locale/zh_CN.ts +100 -101
  115. package/global-config/mobile/locale/zh_TW.ts +100 -101
  116. package/global-config/t.ts +111 -111
  117. package/hooks/useDebounce.ts +27 -0
  118. package/hooks/useLastest.ts +6 -2
  119. package/hooks/useResizeObserve.ts +0 -1
  120. package/index.ts +1 -1
  121. package/input/Input.tsx +53 -10
  122. package/input/_example/auto-width.tsx +14 -0
  123. package/input/_example/borderless.tsx +17 -0
  124. package/input/_example/clearable.tsx +14 -0
  125. package/input/_example/default.tsx +10 -0
  126. package/input/_example/disabled-readonly.tsx +12 -0
  127. package/input/_example/events.tsx +42 -0
  128. package/input/_example/group.tsx +14 -0
  129. package/input/_example/label-suffix.tsx +12 -0
  130. package/input/_example/max-length.tsx +11 -0
  131. package/input/_example/password.tsx +14 -0
  132. package/input/_example/sizes.tsx +12 -0
  133. package/input/_example/status.tsx +13 -0
  134. package/input/_example/text-align.tsx +12 -0
  135. package/input/_example/with-icon.tsx +13 -0
  136. package/input/type.ts +3 -0
  137. package/input/useLengthLimit.ts +122 -0
  138. package/input-number/InputNumber.tsx +124 -124
  139. package/input-number/_example/align.tsx +23 -0
  140. package/input-number/_example/auto-width.tsx +8 -0
  141. package/input-number/_example/default.tsx +8 -0
  142. package/input-number/_example/events.tsx +45 -0
  143. package/input-number/_example/format.tsx +27 -0
  144. package/input-number/_example/large-number.tsx +17 -0
  145. package/input-number/_example/min-max.tsx +14 -0
  146. package/input-number/_example/sizes.tsx +35 -0
  147. package/input-number/_example/status.tsx +65 -0
  148. package/input-number/_example/step-and-decimal.tsx +14 -0
  149. package/input-number/_example/themes.tsx +21 -0
  150. package/input-number/_example/with-suffix.tsx +12 -0
  151. package/input-number/defaultProps.ts +17 -17
  152. package/input-number/index.ts +9 -9
  153. package/input-number/style/css.js +1 -1
  154. package/input-number/style/index.js +1 -1
  155. package/input-number/useInputNumber.tsx +270 -270
  156. package/ip-input/_example/controlled.tsx +26 -0
  157. package/ip-input/_example/default.tsx +12 -0
  158. package/ip-input/_example/full-featured.tsx +32 -0
  159. package/ip-input/_example/ipv6.tsx +23 -0
  160. package/ip-input/_example/keyboard-navigation.tsx +19 -0
  161. package/ip-input/_example/paste-demo.tsx +23 -0
  162. package/ip-input/_example/states.tsx +21 -0
  163. package/ip-input/_example/with-cidr.tsx +23 -0
  164. package/layout/_example/combine-left.tsx +54 -0
  165. package/layout/_example/combine-right.tsx +54 -0
  166. package/layout/_example/custom-aside-width.tsx +56 -0
  167. package/layout/_example/custom-height.tsx +45 -0
  168. package/layout/_example/double-sidebar.tsx +57 -0
  169. package/layout/_example/side-navigation-right.tsx +51 -0
  170. package/layout/_example/side-navigation.tsx +51 -0
  171. package/layout/_example/top-navigation.tsx +41 -0
  172. package/list/ListItem.tsx +36 -36
  173. package/list/ListItemMeta.tsx +40 -40
  174. package/list/_example/async-loading.tsx +46 -0
  175. package/list/_example/default.tsx +23 -0
  176. package/list/_example/header-footer.tsx +40 -0
  177. package/list/_example/multiline.tsx +24 -0
  178. package/list/_example/scroll-loading.tsx +69 -0
  179. package/list/_example/sizes.tsx +45 -0
  180. package/list/_example/split.tsx +36 -0
  181. package/list/_example/stripe.tsx +24 -0
  182. package/list/_example/virtual-scroll.tsx +51 -0
  183. package/list/_example/with-image.tsx +26 -0
  184. package/list/defaultProps.ts +11 -11
  185. package/list/hooks/useListVirtualScroll.ts +82 -82
  186. package/list/style/css.js +1 -1
  187. package/list/style/index.js +1 -1
  188. package/loading/_example/default.tsx +6 -0
  189. package/loading/_example/delay.tsx +53 -0
  190. package/loading/_example/fullscreen.tsx +29 -0
  191. package/loading/_example/inherit-color.tsx +24 -0
  192. package/loading/_example/no-overlay.tsx +15 -0
  193. package/loading/_example/sizes.tsx +25 -0
  194. package/loading/_example/with-text.tsx +12 -0
  195. package/loading/_example/wrapper.tsx +30 -0
  196. package/locale/LocalReceiver.ts +55 -55
  197. package/locale/ar_KW.ts +7 -7
  198. package/locale/en_US.ts +7 -7
  199. package/locale/it_IT.ts +6 -6
  200. package/locale/ja_JP.ts +6 -6
  201. package/locale/ko_KR.ts +6 -6
  202. package/locale/ru_RU.ts +6 -6
  203. package/locale/zh_CN.ts +5 -5
  204. package/locale/zh_TW.ts +7 -7
  205. package/notification/_example/default.tsx +31 -0
  206. package/notification/_example/long-content.tsx +37 -0
  207. package/notification/_example/stacking.tsx +40 -0
  208. package/notification/_example/types.tsx +78 -0
  209. package/notification/_example/usage-example.tsx +62 -0
  210. package/package.json +4 -3
  211. package/popup/Popup.tsx +17 -5
  212. package/popup/_example/controlled.tsx +32 -0
  213. package/popup/_example/custom-content.tsx +64 -0
  214. package/popup/_example/default.tsx +19 -0
  215. package/popup/_example/delay.tsx +35 -0
  216. package/popup/_example/disabled.tsx +17 -0
  217. package/popup/_example/no-arrow.tsx +17 -0
  218. package/popup/_example/placements.tsx +61 -0
  219. package/popup/_example/triggers.tsx +26 -0
  220. package/radio/_example/allow-uncheck.tsx +19 -0
  221. package/radio/_example/button-style.tsx +40 -0
  222. package/radio/_example/controlled.tsx +13 -0
  223. package/radio/_example/default.tsx +13 -0
  224. package/radio/_example/group-disabled.tsx +22 -0
  225. package/radio/_example/group-with-options.tsx +20 -0
  226. package/radio/_example/group.tsx +19 -0
  227. package/radio/_example/sizes.tsx +37 -0
  228. package/radio/_example/states.tsx +20 -0
  229. package/select/_example/collapsed.tsx +30 -0
  230. package/select/_example/creatable.tsx +36 -0
  231. package/select/_example/custom-content.tsx +26 -0
  232. package/select/_example/default.tsx +29 -0
  233. package/select/_example/disabled.tsx +20 -0
  234. package/select/_example/filterable.tsx +27 -0
  235. package/select/_example/group-options.tsx +44 -0
  236. package/select/_example/label-suffix.tsx +24 -0
  237. package/select/_example/loading.tsx +19 -0
  238. package/select/_example/multiple.tsx +31 -0
  239. package/select/_example/sizes.tsx +20 -0
  240. package/select/_example/status.tsx +27 -0
  241. package/select/type.ts +382 -382
  242. package/select-input/type.ts +280 -280
  243. package/slider/Slider.tsx +13 -5
  244. package/slider/SliderHandleButton.tsx +50 -50
  245. package/slider/_example/custom-label.tsx +19 -0
  246. package/slider/_example/default.tsx +14 -0
  247. package/slider/_example/disabled.tsx +17 -0
  248. package/slider/_example/marks.tsx +31 -0
  249. package/slider/_example/range.tsx +16 -0
  250. package/slider/_example/step.tsx +14 -0
  251. package/slider/_example/vertical.tsx +26 -0
  252. package/slider/_example/with-input-number.tsx +21 -0
  253. package/slider/defaultProps.ts +15 -15
  254. package/slider/style/css.js +1 -1
  255. package/slider/style/index.js +1 -1
  256. package/slider/type.ts +1 -1
  257. package/styles/_global.scss +40 -40
  258. package/styles/_vars.scss +374 -358
  259. package/styles/components/alert/_index.scss +175 -175
  260. package/styles/components/alert/_vars.scss +41 -41
  261. package/styles/components/badge/_index.scss +71 -71
  262. package/styles/components/badge/_vars.scss +26 -26
  263. package/styles/components/button/_index.scss +499 -499
  264. package/styles/components/button/_mixins.scss +40 -40
  265. package/styles/components/button/_vars.scss +121 -121
  266. package/styles/components/checkbox/_index.scss +158 -158
  267. package/styles/components/checkbox/_var.scss +59 -59
  268. package/styles/components/color-picker/_index.scss +586 -586
  269. package/styles/components/color-picker/_vars.scss +79 -79
  270. package/styles/components/dialog/_animate.scss +133 -133
  271. package/styles/components/dialog/_index.scss +310 -312
  272. package/styles/components/dialog/_vars.scss +60 -60
  273. package/styles/components/drawer/_index.scss +206 -205
  274. package/styles/components/drawer/_var.scss +55 -55
  275. package/styles/components/fireworks/_index.scss +86 -86
  276. package/styles/components/fireworks/_vars.scss +5 -5
  277. package/styles/components/form/_index.scss +175 -174
  278. package/styles/components/form/_mixins.scss +74 -74
  279. package/styles/components/form/_vars.scss +101 -101
  280. package/styles/components/input/_index.scss +350 -350
  281. package/styles/components/input/_mixins.scss +120 -118
  282. package/styles/components/input/_vars.scss +130 -130
  283. package/styles/components/input-number/_index.scss +340 -339
  284. package/styles/components/input-number/_vars.scss +56 -56
  285. package/styles/components/ip-input/_index.scss +277 -277
  286. package/styles/components/layout/_index.scss +47 -47
  287. package/styles/components/layout/_vars.scss +19 -19
  288. package/styles/components/layout/doc.scss +74 -74
  289. package/styles/components/list/_index.scss +172 -172
  290. package/styles/components/list/_vars.scss +42 -42
  291. package/styles/components/loading/_index.scss +113 -113
  292. package/styles/components/loading/_vars.scss +40 -40
  293. package/styles/components/notification/_index.scss +144 -144
  294. package/styles/components/notification/_mixins.scss +13 -13
  295. package/styles/components/notification/_vars.scss +60 -60
  296. package/styles/components/popup/_index.scss +78 -78
  297. package/styles/components/popup/_mixin.scss +149 -149
  298. package/styles/components/popup/_vars.scss +33 -33
  299. package/styles/components/radio/_index.scss +376 -376
  300. package/styles/components/radio/_vars.scss +89 -89
  301. package/styles/components/select/_index.scss +291 -291
  302. package/styles/components/select/_var.scss +64 -64
  303. package/styles/components/select-input/_index.scss +5 -5
  304. package/styles/components/select-input/_var.scss +4 -4
  305. package/styles/components/slider/_index.scss +241 -241
  306. package/styles/components/slider/_vars.scss +51 -51
  307. package/styles/components/switch/_index.scss +248 -165
  308. package/styles/components/switch/_vars.scss +63 -63
  309. package/styles/components/table/_index.scss +194 -186
  310. package/styles/components/table/_var.scss +52 -52
  311. package/styles/components/tabs/_index.scss +165 -166
  312. package/styles/components/tabs/_mixins.scss +11 -11
  313. package/styles/components/tabs/_vars.scss +72 -72
  314. package/styles/components/tag/_index.scss +317 -317
  315. package/styles/components/tag/_var.scss +86 -86
  316. package/styles/components/tag-input/_index.scss +164 -164
  317. package/styles/components/tag-input/_vars.scss +17 -17
  318. package/styles/components/tooltip/_index.scss +104 -0
  319. package/styles/components/tooltip/_vars.scss +23 -0
  320. package/styles/mixins/_focus.scss +8 -8
  321. package/styles/mixins/_layout.scss +32 -32
  322. package/styles/mixins/_reset.scss +11 -11
  323. package/styles/mixins/_scrollbar.scss +32 -32
  324. package/styles/mixins/_text.scss +50 -50
  325. package/styles/themes/_dark.scss +169 -169
  326. package/styles/themes/_font.scss +69 -69
  327. package/styles/themes/_index.scss +5 -5
  328. package/styles/themes/_light.scss +170 -170
  329. package/styles/themes/_radius.scss +9 -9
  330. package/styles/themes/_size.scss +68 -68
  331. package/styles/utilities/_animation.scss +58 -58
  332. package/styles/utilities/_tips.scss +10 -10
  333. package/switch/_example/async-change.tsx +25 -0
  334. package/switch/_example/before-change.tsx +22 -0
  335. package/switch/_example/controlled.tsx +14 -0
  336. package/switch/_example/custom-value.tsx +21 -0
  337. package/switch/_example/default.tsx +6 -0
  338. package/switch/_example/disabled.tsx +25 -0
  339. package/switch/_example/loading.tsx +17 -0
  340. package/switch/_example/sizes.tsx +21 -0
  341. package/switch/_example/with-label.tsx +21 -0
  342. package/tab/TabPanel.tsx +9 -6
  343. package/tab/_example/addable.tsx +45 -0
  344. package/tab/_example/card-theme.tsx +22 -0
  345. package/tab/_example/default.tsx +22 -0
  346. package/tab/_example/disabled.tsx +38 -0
  347. package/tab/_example/lazy.tsx +25 -0
  348. package/tab/_example/placement.tsx +36 -0
  349. package/tab/_example/removable.tsx +31 -0
  350. package/tab/_example/sizes.tsx +31 -0
  351. package/tab/_example/with-action.tsx +26 -0
  352. package/table/Cell.tsx +3 -6
  353. package/table/Ellipsis.tsx +73 -0
  354. package/table/_example/alignment.tsx +46 -0
  355. package/table/_example/auto-width.tsx +47 -0
  356. package/table/_example/bordered-stripe-hover.tsx +42 -0
  357. package/table/_example/bordered.tsx +42 -0
  358. package/table/_example/cell-click.tsx +52 -0
  359. package/table/_example/complex.tsx +82 -0
  360. package/table/_example/custom-cell.tsx +68 -0
  361. package/table/_example/custom-empty.tsx +37 -0
  362. package/table/_example/custom-row-class-name.tsx +57 -0
  363. package/table/_example/default.tsx +42 -0
  364. package/table/_example/ellipsis.tsx +56 -0
  365. package/table/_example/empty.tsx +28 -0
  366. package/table/_example/fixed-width.tsx +48 -0
  367. package/table/_example/hover.tsx +42 -0
  368. package/table/_example/row-click.tsx +52 -0
  369. package/table/_example/sizes.tsx +57 -0
  370. package/table/_example/stripe.tsx +42 -0
  371. package/table/_example/vertical-align.tsx +110 -0
  372. package/table/hooks/useTableClassName.ts +3 -3
  373. package/table/index.ts +2 -0
  374. package/table/type.ts +1 -0
  375. package/tag/Tag.tsx +1 -1
  376. package/tag/_example/closable.tsx +44 -0
  377. package/tag/_example/default.tsx +17 -0
  378. package/tag/_example/disabled.tsx +19 -0
  379. package/tag/_example/sizes.tsx +18 -0
  380. package/tag/_example/variants.tsx +37 -0
  381. package/tag-input/_example/collapsed.tsx +27 -0
  382. package/tag-input/_example/controlled-uncontrolled.tsx +26 -0
  383. package/tag-input/_example/default.tsx +15 -0
  384. package/tag-input/_example/disabled-readonly.tsx +21 -0
  385. package/tag-input/_example/events.tsx +64 -0
  386. package/tag-input/_example/excess-display.tsx +27 -0
  387. package/tag-input/_example/max-tags.tsx +22 -0
  388. package/tag-input/_example/sizes.tsx +21 -0
  389. package/tag-input/_example/status.tsx +37 -0
  390. package/tag-input/_example/with-label.tsx +23 -0
  391. package/tag-input/hooks/useTagList.tsx +1 -1
  392. package/tooltip/Tooltip.tsx +76 -0
  393. package/tooltip/_example/base.tsx +26 -0
  394. package/tooltip/_example/custom-content.tsx +47 -0
  395. package/tooltip/_example/placement.tsx +33 -0
  396. package/tooltip/_example/theme.tsx +34 -0
  397. package/tooltip/defaultProps.ts +14 -0
  398. package/tooltip/index.ts +7 -0
  399. package/tooltip/style/index.js +1 -0
  400. package/tooltip/type.ts +99 -0
  401. package/utils/input-number/large-number.ts +423 -423
  402. package/utils/input-number/number.ts +257 -257
  403. package/utils/log/index.ts +3 -3
  404. package/utils/log/log.ts +29 -30
  405. package/utils/log/types.ts +9 -12
  406. package/utils/style.ts +58 -58
@@ -0,0 +1,62 @@
1
+ import React from "react";
2
+ import { NotificationProvider, useNotification, Button } from "@tendaui/react";
3
+
4
+ const UsageExampleDemo = () => {
5
+ const UsageNotificationDemo = () => {
6
+ const { success, error } = useNotification();
7
+
8
+ const handleSubmit = () => {
9
+ // 模拟异步操作
10
+ setTimeout(() => {
11
+ const isSuccess = Math.random() > 0.5;
12
+ if (isSuccess) {
13
+ success({
14
+ title: "提交成功",
15
+ message: "您的表单已成功提交"
16
+ });
17
+ } else {
18
+ error({
19
+ title: "提交失败",
20
+ message: "网络异常,请稍后重试"
21
+ });
22
+ }
23
+ }, 500);
24
+ };
25
+
26
+ const handleDelete = () => {
27
+ success({
28
+ title: "删除成功",
29
+ message: "数据已成功删除"
30
+ });
31
+ };
32
+
33
+ const handleSave = () => {
34
+ success({
35
+ title: "保存成功",
36
+ message: "您的更改已保存"
37
+ });
38
+ };
39
+
40
+ return (
41
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
42
+ <div style={{ color: "#666", fontSize: "12px" }}>模拟真实业务场景中的通知使用</div>
43
+ <div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
44
+ <Button theme="primary" onClick={handleSubmit}>
45
+ 提交表单(随机结果)
46
+ </Button>
47
+ <Button theme="danger" onClick={handleDelete}>
48
+ 删除数据
49
+ </Button>
50
+ <Button onClick={handleSave}>保存更改</Button>
51
+ </div>
52
+ </div>
53
+ );
54
+ };
55
+ return (
56
+ <NotificationProvider>
57
+ <UsageNotificationDemo />
58
+ </NotificationProvider>
59
+ );
60
+ };
61
+
62
+ export default UsageExampleDemo;
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@tendaui/components",
3
- "version": "1.2.4",
3
+ "version": "1.3.0",
4
4
  "description": "TendaUI React Components - Source code",
5
5
  "main": "index.ts",
6
6
  "module": "index.ts",
7
7
  "types": "index.ts",
8
8
  "scripts": {
9
- "test": "echo \"Error: no test specified\" && exit 1"
9
+ "test": "vitest run --config ../../vitest.config.ts",
10
+ "test:watch": "vitest --config ../../vitest.config.ts"
10
11
  },
11
12
  "peerDependencies": {
12
13
  "react": ">=16.13.1",
@@ -51,5 +52,5 @@
51
52
  "**/style/css.js",
52
53
  "**/style/all.js"
53
54
  ],
54
- "gitHead": "bdc34c68fc499513c8403e5645531f277d1c0dda"
55
+ "gitHead": "3c98b020d36c078d64e7fc4f418874e8ab567cb2"
55
56
  }
package/popup/Popup.tsx CHANGED
@@ -38,7 +38,7 @@ export interface PopupRef {
38
38
 
39
39
  const Popup = forwardRef<PopupRef, PopupProps>((originalProps, ref) => {
40
40
  const props = useDefaultProps<PopupProps>(originalProps, popupDefaultProps);
41
- const { classPrefix } = useConfig();
41
+ const { classPrefix, direction } = useConfig();
42
42
  const {
43
43
  trigger,
44
44
  content,
@@ -110,10 +110,22 @@ const Popup = forwardRef<PopupRef, PopupProps>((originalProps, ref) => {
110
110
  }, [hideEmptyPopup, content, visible, popupElement]);
111
111
 
112
112
  // 转化 placement
113
- const popperPlacement = useMemo(
114
- () => placement && (placement.replace(/-(left|top)$/, "-start").replace(/-(right|bottom)$/, "-end") as Placement),
115
- [placement]
116
- );
113
+ const popperPlacement = useMemo(() => {
114
+ if (!placement) return placement;
115
+ const normalized = placement.replace(/-(left|top)$/, "-start").replace(/-(right|bottom)$/, "-end");
116
+ if (direction !== "rtl") return normalized as Placement;
117
+ const parts = normalized.split("-");
118
+ const mirrored = parts
119
+ .map((part) => {
120
+ if (part === "left") return "right";
121
+ if (part === "right") return "left";
122
+ if (part === "start") return "end";
123
+ if (part === "end") return "start";
124
+ return part;
125
+ })
126
+ .join("-");
127
+ return mirrored as Placement;
128
+ }, [placement, direction]);
117
129
  // 获取 triggerNode
118
130
  const { getTriggerNode, getPopupProps, getTriggerDom } = useTrigger({
119
131
  triggerRef,
@@ -0,0 +1,32 @@
1
+ import React, { useState } from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const ControlledDemo = () => {
5
+ const [visible, setVisible] = useState(false);
6
+ return (
7
+ <div style={{ padding: "40px", display: "flex", flexDirection: "column", gap: "16px", alignItems: "center" }}>
8
+ <div style={{ display: "flex", gap: "8px" }}>
9
+ <Button onClick={() => setVisible(true)}>打开</Button>
10
+ <Button onClick={() => setVisible(false)}>关闭</Button>
11
+ <Button onClick={() => setVisible(!visible)}>切换</Button>
12
+ </div>
13
+ <Popup
14
+ visible={visible}
15
+ onVisibleChange={(v) => setVisible(v)}
16
+ content={
17
+ <div style={{ padding: "12px" }}>
18
+ <p>这是受控的弹出层</p>
19
+ <Button size="small" onClick={() => setVisible(false)}>
20
+ 关闭
21
+ </Button>
22
+ </div>
23
+ }
24
+ showArrow
25
+ >
26
+ <Button>触发元素</Button>
27
+ </Popup>
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export default ControlledDemo;
@@ -0,0 +1,64 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const CustomContentDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", gap: "16px", justifyContent: "center" }}>
7
+ <Popup
8
+ trigger="click"
9
+ content={
10
+ <div style={{ padding: "16px", width: "200px" }}>
11
+ <h4 style={{ margin: "0 0 8px 0" }}>标题</h4>
12
+ <p style={{ margin: "0 0 12px 0", color: "#666", fontSize: "12px" }}>
13
+ 这是一段描述文字,可以放置更多内容。
14
+ </p>
15
+ <div style={{ display: "flex", gap: "8px", justifyContent: "flex-end" }}>
16
+ <Button size="small" variant="outline">
17
+ 取消
18
+ </Button>
19
+ <Button size="small" theme="primary">
20
+ 确定
21
+ </Button>
22
+ </div>
23
+ </div>
24
+ }
25
+ showArrow
26
+ >
27
+ <Button>自定义内容</Button>
28
+ </Popup>
29
+
30
+ <Popup
31
+ trigger="hover"
32
+ content={
33
+ <div style={{ padding: "12px" }}>
34
+ <div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
35
+ <div
36
+ style={{
37
+ width: "40px",
38
+ height: "40px",
39
+ borderRadius: "50%",
40
+ background: "var(--td-brand-color)",
41
+ display: "flex",
42
+ alignItems: "center",
43
+ justifyContent: "center",
44
+ color: "#fff"
45
+ }}
46
+ >
47
+ A
48
+ </div>
49
+ <div>
50
+ <div style={{ fontWeight: "bold" }}>用户名</div>
51
+ <div style={{ fontSize: "12px", color: "#999" }}>user@example.com</div>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ }
56
+ showArrow
57
+ >
58
+ <Button>用户卡片</Button>
59
+ </Popup>
60
+ </div>
61
+ );
62
+ };
63
+
64
+ export default CustomContentDemo;
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const DefaultDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", justifyContent: "center" }}>
7
+ <Popup
8
+ trigger="click"
9
+ placement="top"
10
+ content={<div style={{ padding: "12px" }}>这是弹出层内容</div>}
11
+ showArrow
12
+ >
13
+ <Button>点击显示 Popup</Button>
14
+ </Popup>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default DefaultDemo;
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const DelayDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", gap: "16px", justifyContent: "center" }}>
7
+ <Popup
8
+ trigger="hover"
9
+ content={<div style={{ padding: "12px" }}>延迟 500ms 显示</div>}
10
+ delay={[500, 0]}
11
+ showArrow
12
+ >
13
+ <Button>延迟显示</Button>
14
+ </Popup>
15
+ <Popup
16
+ trigger="hover"
17
+ content={<div style={{ padding: "12px" }}>延迟 500ms 隐藏</div>}
18
+ delay={[0, 500]}
19
+ showArrow
20
+ >
21
+ <Button>延迟隐藏</Button>
22
+ </Popup>
23
+ <Popup
24
+ trigger="hover"
25
+ content={<div style={{ padding: "12px" }}>延迟 300ms 显示和隐藏</div>}
26
+ delay={300}
27
+ showArrow
28
+ >
29
+ <Button>统一延迟</Button>
30
+ </Popup>
31
+ </div>
32
+ );
33
+ };
34
+
35
+ export default DelayDemo;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const DisabledDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", gap: "16px", justifyContent: "center" }}>
7
+ <Popup trigger="click" content={<div style={{ padding: "12px" }}>正常状态</div>} showArrow>
8
+ <Button>正常</Button>
9
+ </Popup>
10
+ <Popup trigger="click" content={<div style={{ padding: "12px" }}>禁用状态</div>} showArrow disabled>
11
+ <Button disabled>禁用</Button>
12
+ </Popup>
13
+ </div>
14
+ );
15
+ };
16
+
17
+ export default DisabledDemo;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const NoArrowDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", gap: "16px", justifyContent: "center" }}>
7
+ <Popup trigger="hover" content={<div style={{ padding: "12px" }}>有箭头</div>} showArrow>
8
+ <Button>有箭头</Button>
9
+ </Popup>
10
+ <Popup trigger="hover" content={<div style={{ padding: "12px" }}>无箭头</div>} showArrow={false}>
11
+ <Button>无箭头</Button>
12
+ </Popup>
13
+ </div>
14
+ );
15
+ };
16
+
17
+ export default NoArrowDemo;
@@ -0,0 +1,61 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const PlacementsDemo = () => {
5
+ const popupContent = (text: string) => <div style={{ padding: "8px 12px", fontSize: "12px" }}>{text}</div>;
6
+
7
+ return (
8
+ <div style={{ padding: "80px 120px" }}>
9
+ <div style={{ display: "flex", justifyContent: "center", gap: "8px", marginBottom: "8px" }}>
10
+ <Popup placement="top-left" content={popupContent("top-left")} showArrow trigger="hover">
11
+ <Button size="small">TL</Button>
12
+ </Popup>
13
+ <Popup placement="top" content={popupContent("top")} showArrow trigger="hover">
14
+ <Button size="small">Top</Button>
15
+ </Popup>
16
+ <Popup placement="top-right" content={popupContent("top-right")} showArrow trigger="hover">
17
+ <Button size="small">TR</Button>
18
+ </Popup>
19
+ </div>
20
+
21
+ <div style={{ display: "flex", justifyContent: "space-between", width: "280px", margin: "0 auto" }}>
22
+ <div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
23
+ <Popup placement="left-top" content={popupContent("left-top")} showArrow trigger="hover">
24
+ <Button size="small">LT</Button>
25
+ </Popup>
26
+ <Popup placement="left" content={popupContent("left")} showArrow trigger="hover">
27
+ <Button size="small">Left</Button>
28
+ </Popup>
29
+ <Popup placement="left-bottom" content={popupContent("left-bottom")} showArrow trigger="hover">
30
+ <Button size="small">LB</Button>
31
+ </Popup>
32
+ </div>
33
+ <div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
34
+ <Popup placement="right-top" content={popupContent("right-top")} showArrow trigger="hover">
35
+ <Button size="small">RT</Button>
36
+ </Popup>
37
+ <Popup placement="right" content={popupContent("right")} showArrow trigger="hover">
38
+ <Button size="small">Right</Button>
39
+ </Popup>
40
+ <Popup placement="right-bottom" content={popupContent("right-bottom")} showArrow trigger="hover">
41
+ <Button size="small">RB</Button>
42
+ </Popup>
43
+ </div>
44
+ </div>
45
+
46
+ <div style={{ display: "flex", justifyContent: "center", gap: "8px", marginTop: "8px" }}>
47
+ <Popup placement="bottom-left" content={popupContent("bottom-left")} showArrow trigger="hover">
48
+ <Button size="small">BL</Button>
49
+ </Popup>
50
+ <Popup placement="bottom" content={popupContent("bottom")} showArrow trigger="hover">
51
+ <Button size="small">Bottom</Button>
52
+ </Popup>
53
+ <Popup placement="bottom-right" content={popupContent("bottom-right")} showArrow trigger="hover">
54
+ <Button size="small">BR</Button>
55
+ </Popup>
56
+ </div>
57
+ </div>
58
+ );
59
+ };
60
+
61
+ export default PlacementsDemo;
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { Popup, Button } from "@tendaui/react";
3
+
4
+ const TriggersDemo = () => {
5
+ return (
6
+ <div style={{ padding: "40px", display: "flex", gap: "16px", flexWrap: "wrap", justifyContent: "center" }}>
7
+ <Popup trigger="click" content={<div style={{ padding: "12px" }}>点击触发</div>} showArrow>
8
+ <Button>Click 触发</Button>
9
+ </Popup>
10
+
11
+ <Popup trigger="hover" content={<div style={{ padding: "12px" }}>悬停触发</div>} showArrow>
12
+ <Button>Hover 触发</Button>
13
+ </Popup>
14
+
15
+ <Popup trigger="focus" content={<div style={{ padding: "12px" }}>聚焦触发</div>} showArrow>
16
+ <Button>Focus 触发</Button>
17
+ </Popup>
18
+
19
+ <Popup trigger="context-menu" content={<div style={{ padding: "12px" }}>右键触发</div>} showArrow>
20
+ <Button>右键触发</Button>
21
+ </Popup>
22
+ </div>
23
+ );
24
+ };
25
+
26
+ export default TriggersDemo;
@@ -0,0 +1,19 @@
1
+ import React, { useState } from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const AllowUncheckDemo = () => {
5
+ const [value, setValue] = useState<string | undefined>("a");
6
+ return (
7
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
8
+ <div>当前选中:{value || "(无)"}</div>
9
+ <Radio.Group allowUncheck value={value} onChange={(val) => setValue(val as string)}>
10
+ <Radio value="a">选项 A</Radio>
11
+ <Radio value="b">选项 B</Radio>
12
+ <Radio value="c">选项 C</Radio>
13
+ </Radio.Group>
14
+ <div style={{ color: "#666", fontSize: "12px" }}>提示:再次点击已选中的选项可以取消选中</div>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default AllowUncheckDemo;
@@ -0,0 +1,40 @@
1
+ import React, { useState } from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const ButtonStyleDemo = () => {
5
+ const [value1, setValue1] = useState("a");
6
+ const [value2, setValue2] = useState("a");
7
+ const [value3, setValue3] = useState("a");
8
+ return (
9
+ <div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
10
+ <div>
11
+ <div style={{ marginBottom: "8px", color: "#666" }}>outline 样式(默认)</div>
12
+ <Radio.Group value={value1} onChange={(val) => setValue1(val as string)} variant="outline">
13
+ <Radio.Button value="a">选项 A</Radio.Button>
14
+ <Radio.Button value="b">选项 B</Radio.Button>
15
+ <Radio.Button value="c">选项 C</Radio.Button>
16
+ </Radio.Group>
17
+ </div>
18
+
19
+ <div>
20
+ <div style={{ marginBottom: "8px", color: "#666" }}>primary-filled 样式</div>
21
+ <Radio.Group value={value2} onChange={(val) => setValue2(val as string)} variant="primary-filled">
22
+ <Radio.Button value="a">选项 A</Radio.Button>
23
+ <Radio.Button value="b">选项 B</Radio.Button>
24
+ <Radio.Button value="c">选项 C</Radio.Button>
25
+ </Radio.Group>
26
+ </div>
27
+
28
+ <div>
29
+ <div style={{ marginBottom: "8px", color: "#666" }}>default-filled 样式</div>
30
+ <Radio.Group value={value3} onChange={(val) => setValue3(val as string)} variant="default-filled">
31
+ <Radio.Button value="a">选项 A</Radio.Button>
32
+ <Radio.Button value="b">选项 B</Radio.Button>
33
+ <Radio.Button value="c">选项 C</Radio.Button>
34
+ </Radio.Group>
35
+ </div>
36
+ </div>
37
+ );
38
+ };
39
+
40
+ export default ButtonStyleDemo;
@@ -0,0 +1,13 @@
1
+ import React, { useState } from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const ControlledDemo = () => {
5
+ const [checked, setChecked] = useState(true);
6
+ return (
7
+ <Radio checked={checked} onChange={(val) => setChecked(val)}>
8
+ 受控单选框(点击切换)
9
+ </Radio>
10
+ );
11
+ };
12
+
13
+ export default ControlledDemo;
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const DefaultDemo = () => {
5
+ return (
6
+ <div>
7
+ <Radio>未选中</Radio>
8
+ <Radio defaultChecked>选中</Radio>
9
+ </div>
10
+ );
11
+ };
12
+
13
+ export default DefaultDemo;
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const GroupDisabledDemo = () => {
5
+ return (
6
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
7
+ <Radio.Group disabled defaultValue="b">
8
+ <Radio value="a">选项 A</Radio>
9
+ <Radio value="b">选项 B</Radio>
10
+ <Radio value="c">选项 C</Radio>
11
+ </Radio.Group>
12
+
13
+ <Radio.Group disabled defaultValue="b" variant="primary-filled">
14
+ <Radio.Button value="a">选项 A</Radio.Button>
15
+ <Radio.Button value="b">选项 B</Radio.Button>
16
+ <Radio.Button value="c">选项 C</Radio.Button>
17
+ </Radio.Group>
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export default GroupDisabledDemo;
@@ -0,0 +1,20 @@
1
+ import React, { useState } from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const GroupWithOptionsDemo = () => {
5
+ const [value, setValue] = useState("2");
6
+ const options = [
7
+ { label: "选项一", value: "1" },
8
+ { label: "选项二", value: "2" },
9
+ { label: "选项三", value: "3", disabled: true },
10
+ { label: "选项四", value: "4" }
11
+ ];
12
+ return (
13
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
14
+ <div>当前选中值:{value}</div>
15
+ <Radio.Group options={options} value={value} onChange={(val) => setValue(val as string)} />
16
+ </div>
17
+ );
18
+ };
19
+
20
+ export default GroupWithOptionsDemo;
@@ -0,0 +1,19 @@
1
+ import React, { useState } from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const GroupDemo = () => {
5
+ const [value, setValue] = useState("beijing");
6
+ return (
7
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
8
+ <div>当前选中:{value}</div>
9
+ <Radio.Group value={value} onChange={(val) => setValue(val as string)}>
10
+ <Radio value="beijing">北京</Radio>
11
+ <Radio value="shanghai">上海</Radio>
12
+ <Radio value="guangzhou">广州</Radio>
13
+ <Radio value="shenzhen">深圳</Radio>
14
+ </Radio.Group>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default GroupDemo;
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const SizesDemo = () => {
5
+ return (
6
+ <div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
7
+ <div>
8
+ <div style={{ marginBottom: "8px", color: "#666" }}>小尺寸</div>
9
+ <Radio.Group size="small" defaultValue="a">
10
+ <Radio.Button value="a">选项 A</Radio.Button>
11
+ <Radio.Button value="b">选项 B</Radio.Button>
12
+ <Radio.Button value="c">选项 C</Radio.Button>
13
+ </Radio.Group>
14
+ </div>
15
+
16
+ <div>
17
+ <div style={{ marginBottom: "8px", color: "#666" }}>中尺寸(默认)</div>
18
+ <Radio.Group size="medium" defaultValue="a">
19
+ <Radio.Button value="a">选项 A</Radio.Button>
20
+ <Radio.Button value="b">选项 B</Radio.Button>
21
+ <Radio.Button value="c">选项 C</Radio.Button>
22
+ </Radio.Group>
23
+ </div>
24
+
25
+ <div>
26
+ <div style={{ marginBottom: "8px", color: "#666" }}>大尺寸</div>
27
+ <Radio.Group size="large" defaultValue="a">
28
+ <Radio.Button value="a">选项 A</Radio.Button>
29
+ <Radio.Button value="b">选项 B</Radio.Button>
30
+ <Radio.Button value="c">选项 C</Radio.Button>
31
+ </Radio.Group>
32
+ </div>
33
+ </div>
34
+ );
35
+ };
36
+
37
+ export default SizesDemo;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Radio } from "@tendaui/react";
3
+
4
+ const StatesDemo = () => {
5
+ return (
6
+ <div style={{ display: "flex", gap: "16px", flexWrap: "wrap" }}>
7
+ <Radio>未选中</Radio>
8
+ <Radio defaultChecked>选中</Radio>
9
+ <Radio disabled>禁用未选中</Radio>
10
+ <Radio disabled defaultChecked>
11
+ 禁用选中
12
+ </Radio>
13
+ <Radio readonly defaultChecked>
14
+ 只读选中
15
+ </Radio>
16
+ </div>
17
+ );
18
+ };
19
+
20
+ export default StatesDemo;
@@ -0,0 +1,30 @@
1
+ import React, { useState } from "react";
2
+ import { Select } from "@tendaui/react";
3
+
4
+ const basicOptions = [
5
+ { label: "架构云", value: "1", title: "架构云选项" },
6
+ { label: "大数据", value: "2" },
7
+ { label: "区块链", value: "3" },
8
+ { label: "物联网", value: "4", disabled: true },
9
+ { label: "人工智能", value: "5" }
10
+ ];
11
+
12
+ const CollapsedExample = () => {
13
+ const [value, setValue] = useState<string[]>(["1", "2", "3", "5"]);
14
+ return (
15
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
16
+ <Select
17
+ value={value}
18
+ onChange={(val) => setValue(val as string[])}
19
+ options={basicOptions}
20
+ placeholder="请选择"
21
+ multiple
22
+ minCollapsedNum={2}
23
+ style={{ width: "400px" }}
24
+ />
25
+ <div style={{ color: "#666", fontSize: "12px" }}>超过 2 个选项时会折叠显示</div>
26
+ </div>
27
+ );
28
+ };
29
+
30
+ export default CollapsedExample;