@tendaui/components 1.2.4 → 1.3.1

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 (309) hide show
  1. package/_util/scroll.ts +9 -0
  2. package/alert/_example/base.tsx +13 -0
  3. package/alert/_example/collapse.tsx +15 -0
  4. package/badge/_example/base.tsx +10 -0
  5. package/badge/_example/count.tsx +29 -0
  6. package/badge/_example/custom-color.tsx +32 -0
  7. package/badge/_example/dot.tsx +26 -0
  8. package/badge/_example/max-count.tsx +26 -0
  9. package/badge/_example/offset.tsx +29 -0
  10. package/badge/_example/shape.tsx +32 -0
  11. package/badge/_example/show-zero.tsx +23 -0
  12. package/badge/_example/size.tsx +35 -0
  13. package/badge/_example/standalone.tsx +14 -0
  14. package/badge/_example/text-count.tsx +26 -0
  15. package/badge/_example/with-button.tsx +23 -0
  16. package/button/_example/block.tsx +18 -0
  17. package/button/_example/disabled.tsx +22 -0
  18. package/button/_example/ghost.tsx +21 -0
  19. package/button/_example/link.tsx +15 -0
  20. package/button/_example/loading.tsx +19 -0
  21. package/button/_example/shape.tsx +18 -0
  22. package/button/_example/size.tsx +18 -0
  23. package/button/_example/suffix.tsx +16 -0
  24. package/button/_example/theme.tsx +14 -0
  25. package/button/_example/variant-base.tsx +24 -0
  26. package/button/_example/variant-dashed.tsx +24 -0
  27. package/button/_example/variant-outline.tsx +24 -0
  28. package/button/_example/variant-text.tsx +24 -0
  29. package/checkbox/_example/base.tsx +8 -0
  30. package/checkbox/_example/controlled.tsx +11 -0
  31. package/checkbox/_example/group-disabled.tsx +13 -0
  32. package/checkbox/_example/group-with-check-all.tsx +22 -0
  33. package/checkbox/_example/group-with-max.tsx +17 -0
  34. package/checkbox/_example/group-with-options.tsx +18 -0
  35. package/checkbox/_example/group.tsx +17 -0
  36. package/checkbox/_example/states.tsx +19 -0
  37. package/color-picker/ColorPicker.tsx +16 -2
  38. package/color-picker/_example/base.tsx +12 -0
  39. package/color-picker/_example/borderless.tsx +17 -0
  40. package/color-picker/_example/clearable.tsx +12 -0
  41. package/color-picker/_example/disabled.tsx +17 -0
  42. package/color-picker/_example/formats.tsx +30 -0
  43. package/color-picker/_example/manual-input.tsx +39 -0
  44. package/color-picker/_example/recent-colors.tsx +19 -0
  45. package/color-picker/_example/swatch-colors.tsx +28 -0
  46. package/color-picker/_example/with-alpha.tsx +21 -0
  47. package/color-picker/components/panel/format/inputs.tsx +1 -1
  48. package/color-picker/components/panel/index.tsx +13 -0
  49. package/color-picker/components/trigger.tsx +64 -13
  50. package/color-picker/defaultProps.ts +4 -1
  51. package/color-picker/utils/color-picker/cmyk.ts +5 -5
  52. package/color-picker/utils/color-picker/draggable.ts +14 -15
  53. package/color-picker/utils/color-picker/format.ts +21 -26
  54. package/color-picker/utils/color-picker/gradient.ts +35 -41
  55. package/color-picker/utils/color-picker/types.ts +4 -4
  56. package/config-provider/ConfigContext.tsx +1 -0
  57. package/config-provider/ConfigProvider.tsx +18 -1
  58. package/config-provider/type.ts +5 -0
  59. package/dialog/_example/base.tsx +27 -0
  60. package/dialog/_example/confirm-loading.tsx +32 -0
  61. package/dialog/_example/custom-buttons.tsx +24 -0
  62. package/dialog/_example/full-screen.tsx +26 -0
  63. package/dialog/_example/hide-buttons.tsx +39 -0
  64. package/dialog/_example/modeless.tsx +25 -0
  65. package/dialog/_example/placement.tsx +40 -0
  66. package/dialog/_example/plugin-example.tsx +69 -0
  67. package/dialog/_example/themes.tsx +41 -0
  68. package/drawer/Drawer.tsx +17 -9
  69. package/drawer/_example/custom-header-footer.tsx +29 -0
  70. package/drawer/_example/default.tsx +20 -0
  71. package/drawer/_example/events.tsx +53 -0
  72. package/drawer/_example/no-footer.tsx +20 -0
  73. package/drawer/_example/no-overlay.tsx +20 -0
  74. package/drawer/_example/placement.tsx +43 -0
  75. package/drawer/_example/size-draggable.tsx +26 -0
  76. package/drawer/_example/size.tsx +40 -0
  77. package/drawer/defaultProps.ts +1 -1
  78. package/fireworks/Fireworks.tsx +1 -10
  79. package/fireworks/index.ts +0 -1
  80. package/fireworks/type.ts +0 -1
  81. package/form/_example/complex.tsx +76 -0
  82. package/form/_example/default.tsx +58 -0
  83. package/form/_example/disabled.tsx +26 -0
  84. package/form/_example/form-list.tsx +74 -0
  85. package/form/_example/inline-layout.tsx +20 -0
  86. package/form/_example/label-align.tsx +46 -0
  87. package/form/_example/methods.tsx +66 -0
  88. package/form/_example/validation.tsx +71 -0
  89. package/form/hooks/useFormItemStyle.tsx +19 -7
  90. package/form/index.ts +20 -2
  91. package/global-config/default-config.ts +28 -28
  92. package/global-config/locale/ar_KW.ts +176 -187
  93. package/global-config/locale/en_US.ts +180 -195
  94. package/global-config/locale/it_IT.ts +174 -197
  95. package/global-config/locale/ja_JP.ts +178 -193
  96. package/global-config/locale/ko_KR.ts +178 -193
  97. package/global-config/locale/ru_RU.ts +189 -200
  98. package/global-config/locale/zh_CN.ts +179 -193
  99. package/global-config/locale/zh_TW.ts +178 -192
  100. package/global-config/mobile/default-config.ts +3 -3
  101. package/global-config/mobile/locale/ar_KW.ts +76 -77
  102. package/global-config/mobile/locale/en_US.ts +76 -77
  103. package/global-config/mobile/locale/it_IT.ts +76 -77
  104. package/global-config/mobile/locale/ja_JP.ts +64 -65
  105. package/global-config/mobile/locale/ko_KR.ts +64 -65
  106. package/global-config/mobile/locale/ru_RU.ts +76 -77
  107. package/global-config/mobile/locale/zh_CN.ts +64 -65
  108. package/global-config/mobile/locale/zh_TW.ts +64 -65
  109. package/global-config/t.ts +12 -12
  110. package/hooks/useDebounce.ts +27 -0
  111. package/hooks/useLastest.ts +6 -2
  112. package/hooks/useResizeObserve.ts +0 -1
  113. package/index.ts +1 -1
  114. package/input/Input.tsx +53 -10
  115. package/input/_example/auto-width.tsx +14 -0
  116. package/input/_example/borderless.tsx +17 -0
  117. package/input/_example/clearable.tsx +14 -0
  118. package/input/_example/default.tsx +10 -0
  119. package/input/_example/disabled-readonly.tsx +12 -0
  120. package/input/_example/events.tsx +42 -0
  121. package/input/_example/group.tsx +14 -0
  122. package/input/_example/label-suffix.tsx +12 -0
  123. package/input/_example/max-length.tsx +11 -0
  124. package/input/_example/password.tsx +14 -0
  125. package/input/_example/sizes.tsx +12 -0
  126. package/input/_example/status.tsx +13 -0
  127. package/input/_example/text-align.tsx +12 -0
  128. package/input/_example/with-icon.tsx +13 -0
  129. package/input/type.ts +3 -0
  130. package/input/useLengthLimit.ts +122 -0
  131. package/input-number/_example/align.tsx +23 -0
  132. package/input-number/_example/auto-width.tsx +8 -0
  133. package/input-number/_example/default.tsx +8 -0
  134. package/input-number/_example/events.tsx +45 -0
  135. package/input-number/_example/format.tsx +27 -0
  136. package/input-number/_example/large-number.tsx +17 -0
  137. package/input-number/_example/min-max.tsx +14 -0
  138. package/input-number/_example/sizes.tsx +35 -0
  139. package/input-number/_example/status.tsx +65 -0
  140. package/input-number/_example/step-and-decimal.tsx +14 -0
  141. package/input-number/_example/themes.tsx +21 -0
  142. package/input-number/_example/with-suffix.tsx +12 -0
  143. package/ip-input/_example/controlled.tsx +26 -0
  144. package/ip-input/_example/default.tsx +12 -0
  145. package/ip-input/_example/full-featured.tsx +32 -0
  146. package/ip-input/_example/ipv6.tsx +23 -0
  147. package/ip-input/_example/keyboard-navigation.tsx +19 -0
  148. package/ip-input/_example/paste-demo.tsx +23 -0
  149. package/ip-input/_example/states.tsx +21 -0
  150. package/ip-input/_example/with-cidr.tsx +23 -0
  151. package/layout/_example/combine-left.tsx +54 -0
  152. package/layout/_example/combine-right.tsx +54 -0
  153. package/layout/_example/custom-aside-width.tsx +56 -0
  154. package/layout/_example/custom-height.tsx +45 -0
  155. package/layout/_example/double-sidebar.tsx +57 -0
  156. package/layout/_example/side-navigation-right.tsx +51 -0
  157. package/layout/_example/side-navigation.tsx +51 -0
  158. package/layout/_example/top-navigation.tsx +41 -0
  159. package/list/_example/async-loading.tsx +46 -0
  160. package/list/_example/default.tsx +23 -0
  161. package/list/_example/header-footer.tsx +40 -0
  162. package/list/_example/multiline.tsx +24 -0
  163. package/list/_example/scroll-loading.tsx +69 -0
  164. package/list/_example/sizes.tsx +45 -0
  165. package/list/_example/split.tsx +36 -0
  166. package/list/_example/stripe.tsx +24 -0
  167. package/list/_example/virtual-scroll.tsx +51 -0
  168. package/list/_example/with-image.tsx +26 -0
  169. package/loading/_example/default.tsx +6 -0
  170. package/loading/_example/delay.tsx +53 -0
  171. package/loading/_example/fullscreen.tsx +29 -0
  172. package/loading/_example/inherit-color.tsx +24 -0
  173. package/loading/_example/no-overlay.tsx +15 -0
  174. package/loading/_example/sizes.tsx +25 -0
  175. package/loading/_example/with-text.tsx +12 -0
  176. package/loading/_example/wrapper.tsx +30 -0
  177. package/notification/_example/default.tsx +31 -0
  178. package/notification/_example/long-content.tsx +37 -0
  179. package/notification/_example/stacking.tsx +40 -0
  180. package/notification/_example/types.tsx +78 -0
  181. package/notification/_example/usage-example.tsx +62 -0
  182. package/package.json +4 -3
  183. package/popup/Popup.tsx +17 -5
  184. package/popup/_example/controlled.tsx +32 -0
  185. package/popup/_example/custom-content.tsx +64 -0
  186. package/popup/_example/default.tsx +19 -0
  187. package/popup/_example/delay.tsx +35 -0
  188. package/popup/_example/disabled.tsx +17 -0
  189. package/popup/_example/no-arrow.tsx +17 -0
  190. package/popup/_example/placements.tsx +61 -0
  191. package/popup/_example/triggers.tsx +26 -0
  192. package/radio/_example/allow-uncheck.tsx +19 -0
  193. package/radio/_example/button-style.tsx +40 -0
  194. package/radio/_example/controlled.tsx +13 -0
  195. package/radio/_example/default.tsx +13 -0
  196. package/radio/_example/group-disabled.tsx +22 -0
  197. package/radio/_example/group-with-options.tsx +20 -0
  198. package/radio/_example/group.tsx +19 -0
  199. package/radio/_example/sizes.tsx +37 -0
  200. package/radio/_example/states.tsx +20 -0
  201. package/select/_example/collapsed.tsx +30 -0
  202. package/select/_example/creatable.tsx +36 -0
  203. package/select/_example/custom-content.tsx +26 -0
  204. package/select/_example/default.tsx +29 -0
  205. package/select/_example/disabled.tsx +20 -0
  206. package/select/_example/filterable.tsx +27 -0
  207. package/select/_example/group-options.tsx +44 -0
  208. package/select/_example/label-suffix.tsx +24 -0
  209. package/select/_example/loading.tsx +19 -0
  210. package/select/_example/multiple.tsx +31 -0
  211. package/select/_example/sizes.tsx +20 -0
  212. package/select/_example/status.tsx +27 -0
  213. package/slider/Slider.tsx +13 -5
  214. package/slider/_example/custom-label.tsx +19 -0
  215. package/slider/_example/default.tsx +14 -0
  216. package/slider/_example/disabled.tsx +17 -0
  217. package/slider/_example/marks.tsx +31 -0
  218. package/slider/_example/range.tsx +16 -0
  219. package/slider/_example/step.tsx +14 -0
  220. package/slider/_example/vertical.tsx +26 -0
  221. package/slider/_example/with-input-number.tsx +21 -0
  222. package/slider/type.ts +1 -1
  223. package/styles/_vars.scss +16 -0
  224. package/styles/components/button/_index.scss +3 -3
  225. package/styles/components/dialog/_index.scss +18 -20
  226. package/styles/components/drawer/_index.scss +4 -3
  227. package/styles/components/drawer/_var.scss +1 -1
  228. package/styles/components/form/_index.scss +7 -6
  229. package/styles/components/input/_mixins.scss +7 -5
  230. package/styles/components/input-number/_index.scss +13 -12
  231. package/styles/components/list/_index.scss +5 -5
  232. package/styles/components/notification/_index.scss +4 -4
  233. package/styles/components/slider/_index.scss +8 -8
  234. package/styles/components/switch/_index.scss +98 -15
  235. package/styles/components/table/_index.scss +37 -29
  236. package/styles/components/tabs/_index.scss +8 -9
  237. package/styles/components/tooltip/_index.scss +104 -0
  238. package/styles/components/tooltip/_vars.scss +23 -0
  239. package/switch/_example/async-change.tsx +25 -0
  240. package/switch/_example/before-change.tsx +22 -0
  241. package/switch/_example/controlled.tsx +14 -0
  242. package/switch/_example/custom-value.tsx +21 -0
  243. package/switch/_example/default.tsx +6 -0
  244. package/switch/_example/disabled.tsx +25 -0
  245. package/switch/_example/loading.tsx +17 -0
  246. package/switch/_example/sizes.tsx +21 -0
  247. package/switch/_example/with-label.tsx +21 -0
  248. package/tab/TabPanel.tsx +9 -6
  249. package/tab/_example/addable.tsx +45 -0
  250. package/tab/_example/card-theme.tsx +22 -0
  251. package/tab/_example/default.tsx +22 -0
  252. package/tab/_example/disabled.tsx +38 -0
  253. package/tab/_example/lazy.tsx +25 -0
  254. package/tab/_example/placement.tsx +36 -0
  255. package/tab/_example/removable.tsx +31 -0
  256. package/tab/_example/sizes.tsx +31 -0
  257. package/tab/_example/with-action.tsx +26 -0
  258. package/table/Cell.tsx +3 -6
  259. package/table/Ellipsis.tsx +73 -0
  260. package/table/_example/alignment.tsx +46 -0
  261. package/table/_example/auto-width.tsx +47 -0
  262. package/table/_example/bordered-stripe-hover.tsx +42 -0
  263. package/table/_example/bordered.tsx +42 -0
  264. package/table/_example/cell-click.tsx +52 -0
  265. package/table/_example/complex.tsx +82 -0
  266. package/table/_example/custom-cell.tsx +68 -0
  267. package/table/_example/custom-empty.tsx +37 -0
  268. package/table/_example/custom-row-class-name.tsx +57 -0
  269. package/table/_example/default.tsx +42 -0
  270. package/table/_example/ellipsis.tsx +56 -0
  271. package/table/_example/empty.tsx +28 -0
  272. package/table/_example/fixed-width.tsx +48 -0
  273. package/table/_example/hover.tsx +42 -0
  274. package/table/_example/row-click.tsx +52 -0
  275. package/table/_example/sizes.tsx +57 -0
  276. package/table/_example/stripe.tsx +42 -0
  277. package/table/_example/vertical-align.tsx +110 -0
  278. package/table/hooks/useTableClassName.ts +3 -3
  279. package/table/index.ts +2 -0
  280. package/table/type.ts +1 -0
  281. package/tag/Tag.tsx +1 -1
  282. package/tag/_example/closable.tsx +44 -0
  283. package/tag/_example/default.tsx +17 -0
  284. package/tag/_example/disabled.tsx +19 -0
  285. package/tag/_example/sizes.tsx +18 -0
  286. package/tag/_example/variants.tsx +37 -0
  287. package/tag-input/_example/collapsed.tsx +27 -0
  288. package/tag-input/_example/controlled-uncontrolled.tsx +26 -0
  289. package/tag-input/_example/default.tsx +15 -0
  290. package/tag-input/_example/disabled-readonly.tsx +21 -0
  291. package/tag-input/_example/events.tsx +64 -0
  292. package/tag-input/_example/excess-display.tsx +27 -0
  293. package/tag-input/_example/max-tags.tsx +22 -0
  294. package/tag-input/_example/sizes.tsx +21 -0
  295. package/tag-input/_example/status.tsx +37 -0
  296. package/tag-input/_example/with-label.tsx +23 -0
  297. package/tag-input/hooks/useTagList.tsx +1 -1
  298. package/tooltip/Tooltip.tsx +76 -0
  299. package/tooltip/_example/base.tsx +26 -0
  300. package/tooltip/_example/custom-content.tsx +47 -0
  301. package/tooltip/_example/placement.tsx +33 -0
  302. package/tooltip/_example/theme.tsx +34 -0
  303. package/tooltip/defaultProps.ts +14 -0
  304. package/tooltip/index.ts +7 -0
  305. package/tooltip/style/index.js +1 -0
  306. package/tooltip/type.ts +99 -0
  307. package/utils/log/index.ts +1 -1
  308. package/utils/log/log.ts +2 -3
  309. package/utils/log/types.ts +1 -4
@@ -1,101 +1,100 @@
1
- /* eslint-disable no-template-curly-in-string */
2
1
  // 文件有效,为国际化做准备
3
- import 'dayjs/locale/zh-cn';
2
+ import "dayjs/locale/zh-cn";
4
3
 
5
4
  export default {
6
5
  actionSheet: {
7
- cancel: '取消',
6
+ cancel: "取消"
8
7
  },
9
8
  calendar: {
10
- title: '请选择日期',
11
- confirm: '确认',
12
- weekdays: ['', '', '', '', '', '', ''],
13
- monthTitle: '{year} 年 {month}',
14
- months: ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月', '7 月', '8 月', '9 月', '10 月', '11 月', '12 月'],
9
+ title: "请选择日期",
10
+ confirm: "确认",
11
+ weekdays: ["", "", "", "", "", "", ""],
12
+ monthTitle: "{year} 年 {month}",
13
+ months: ["1 月", "2 月", "3 月", "4 月", "5 月", "6 月", "7 月", "8 月", "9 月", "10 月", "11 月", "12 月"]
15
14
  },
16
15
  cascader: {
17
- title: '标题',
18
- placeholder: '选择选项',
16
+ title: "标题",
17
+ placeholder: "选择选项"
19
18
  },
20
19
  dropdownMenu: {
21
- reset: '重置',
22
- confirm: '确定',
20
+ reset: "重置",
21
+ confirm: "确定"
23
22
  },
24
23
  dateTimePicker: {
25
- title: '选择时间',
26
- cancel: '取消',
27
- confirm: '确定',
28
- format: 'YYYY-MM-DD',
29
- yearLabel: '',
30
- monthLabel: '',
31
- dateLabel: '',
32
- hourLabel: '',
33
- minuteLabel: '',
34
- secondLabel: '',
24
+ title: "选择时间",
25
+ cancel: "取消",
26
+ confirm: "确定",
27
+ format: "YYYY-MM-DD",
28
+ yearLabel: "",
29
+ monthLabel: "",
30
+ dateLabel: "",
31
+ hourLabel: "",
32
+ minuteLabel: "",
33
+ secondLabel: ""
35
34
  },
36
35
  form: {
37
36
  errorMessage: {
38
- date: '请输入正确的${name}',
39
- url: '请输入正确的${name}',
40
- required: '${name}必填',
41
- whitespace: '${name}不能为空',
42
- max: '${name}字符长度不能超过 ${validate} 个字符,一个中文等于两个字符',
43
- min: '${name}字符长度不能少于 ${validate} 个字符,一个中文等于两个字符',
44
- len: '${name}字符长度必须是 ${validate}',
45
- enum: '${name}只能是${validate}等',
46
- idcard: '请输入正确的${name}',
47
- telnumber: '请输入正确的${name}',
48
- pattern: '请输入正确的${name}',
49
- validator: '${name}不符合要求',
50
- boolean: '${name}数据类型必须是布尔类型',
51
- number: '${name}必须是数字',
37
+ date: "请输入正确的${name}",
38
+ url: "请输入正确的${name}",
39
+ required: "${name}必填",
40
+ whitespace: "${name}不能为空",
41
+ max: "${name}字符长度不能超过 ${validate} 个字符,一个中文等于两个字符",
42
+ min: "${name}字符长度不能少于 ${validate} 个字符,一个中文等于两个字符",
43
+ len: "${name}字符长度必须是 ${validate}",
44
+ enum: "${name}只能是${validate}等",
45
+ idcard: "请输入正确的${name}",
46
+ telnumber: "请输入正确的${name}",
47
+ pattern: "请输入正确的${name}",
48
+ validator: "${name}不符合要求",
49
+ boolean: "${name}数据类型必须是布尔类型",
50
+ number: "${name}必须是数字"
52
51
  },
53
- colonText: '',
52
+ colonText: ""
54
53
  },
55
54
  picker: {
56
- cancel: '取消',
57
- confirm: '确认',
55
+ cancel: "取消",
56
+ confirm: "确认"
58
57
  },
59
58
  pullDownRefresh: {
60
- loadingTexts: ['下拉刷新', '松手刷新', '正在刷新', '刷新完成'],
59
+ loadingTexts: ["下拉刷新", "松手刷新", "正在刷新", "刷新完成"]
61
60
  },
62
61
  rate: {
63
- valueText: '{value} 分',
64
- noValueText: '未评分',
62
+ valueText: "{value} 分",
63
+ noValueText: "未评分"
65
64
  },
66
65
  tabBar: {
67
- newsAriaLabel: '有新的消息',
68
- moreNewsAriaLabel: '有很多消息',
69
- haveMoreNewsAriaLabel: '有 {value}+ 条消息',
70
- haveNewsAriaLabel: '有 {value} 条消息',
66
+ newsAriaLabel: "有新的消息",
67
+ moreNewsAriaLabel: "有很多消息",
68
+ haveMoreNewsAriaLabel: "有 {value}+ 条消息",
69
+ haveNewsAriaLabel: "有 {value} 条消息"
71
70
  },
72
71
  table: {
73
- empty: '暂无数据',
72
+ empty: "暂无数据"
74
73
  },
75
74
  list: {
76
- loading: '加载中...',
77
- loadingMoreText: '点击加载更多',
78
- pulling: '下拉即可刷新...',
79
- loosing: '释放即可刷新...',
80
- success: '刷新成功',
75
+ loading: "加载中...",
76
+ loadingMoreText: "点击加载更多",
77
+ pulling: "下拉即可刷新...",
78
+ loosing: "释放即可刷新...",
79
+ success: "刷新成功"
81
80
  },
82
81
  upload: {
83
82
  progress: {
84
- uploadingText: '上传中...',
85
- waitingText: '待上传',
86
- failText: '上传失败',
87
- successText: '上传成功',
88
- },
83
+ uploadingText: "上传中...",
84
+ waitingText: "待上传",
85
+ failText: "上传失败",
86
+ successText: "上传成功"
87
+ }
89
88
  },
90
89
  guide: {
91
- next: '下一步',
92
- skip: '跳过',
93
- finish: '完成',
94
- back: '返回',
90
+ next: "下一步",
91
+ skip: "跳过",
92
+ finish: "完成",
93
+ back: "返回"
95
94
  },
96
95
  qrcode: {
97
- expiredText: '二维码过期',
98
- refreshText: '点击刷新',
99
- scannedText: '已扫描',
100
- },
96
+ expiredText: "二维码过期",
97
+ refreshText: "点击刷新",
98
+ scannedText: "已扫描"
99
+ }
101
100
  };
@@ -1,101 +1,100 @@
1
- /* eslint-disable no-template-curly-in-string */
2
1
  // 文件有效,为国际化做准备
3
- import 'dayjs/locale/zh-tw';
2
+ import "dayjs/locale/zh-tw";
4
3
 
5
4
  export default {
6
5
  actionSheet: {
7
- cancel: '取消',
6
+ cancel: "取消"
8
7
  },
9
8
  calendar: {
10
- title: '請選擇日期',
11
- confirm: '確認',
12
- weekdays: ['', '', '', '', '', '', ''],
13
- monthTitle: '{year} 年 {month}',
14
- months: ['1 月', '2 月', '3 月', '4 月', '5 月', '6 月', '7 月', '8 月', '9 月', '10 月', '11 月', '12 月'],
9
+ title: "請選擇日期",
10
+ confirm: "確認",
11
+ weekdays: ["", "", "", "", "", "", ""],
12
+ monthTitle: "{year} 年 {month}",
13
+ months: ["1 月", "2 月", "3 月", "4 月", "5 月", "6 月", "7 月", "8 月", "9 月", "10 月", "11 月", "12 月"]
15
14
  },
16
15
  cascader: {
17
- title: '標題',
18
- placeholder: '選擇選項',
16
+ title: "標題",
17
+ placeholder: "選擇選項"
19
18
  },
20
19
  dropdownMenu: {
21
- reset: '重置',
22
- confirm: '確定',
20
+ reset: "重置",
21
+ confirm: "確定"
23
22
  },
24
23
  dateTimePicker: {
25
- title: '選擇時間',
26
- cancel: '取消',
27
- confirm: '確定',
28
- format: 'YYYY-MM-DD',
29
- yearLabel: '',
30
- monthLabel: '',
31
- dateLabel: '',
32
- hourLabel: '',
33
- minuteLabel: '',
34
- secondLabel: '',
24
+ title: "選擇時間",
25
+ cancel: "取消",
26
+ confirm: "確定",
27
+ format: "YYYY-MM-DD",
28
+ yearLabel: "",
29
+ monthLabel: "",
30
+ dateLabel: "",
31
+ hourLabel: "",
32
+ minuteLabel: "",
33
+ secondLabel: ""
35
34
  },
36
35
  form: {
37
36
  errorMessage: {
38
- date: '請輸入正確的${name}',
39
- url: '請輸入正確的${name}',
40
- whitespace: '${name}不能為空',
41
- required: '${name}必填',
42
- max: '${name}字符長度不能超過 ${validate} 個字符,一個中文等於兩個字符',
43
- min: '${name}字符長度不能少於 ${validate} 個字符,一個中文等於兩個字符',
44
- len: '${name}字符長度必須是 ${validate}',
45
- enum: '${name}只能是${validate}等',
46
- idcard: '請輸入正確的${name}',
47
- telnumber: '請輸入正確的${name}',
48
- pattern: '請輸入正確的${name}',
49
- validator: '${name}不符合要求',
50
- boolean: '${name}數據類型必須是布林類型',
51
- number: '${name}必須是數字',
37
+ date: "請輸入正確的${name}",
38
+ url: "請輸入正確的${name}",
39
+ whitespace: "${name}不能為空",
40
+ required: "${name}必填",
41
+ max: "${name}字符長度不能超過 ${validate} 個字符,一個中文等於兩個字符",
42
+ min: "${name}字符長度不能少於 ${validate} 個字符,一個中文等於兩個字符",
43
+ len: "${name}字符長度必須是 ${validate}",
44
+ enum: "${name}只能是${validate}等",
45
+ idcard: "請輸入正確的${name}",
46
+ telnumber: "請輸入正確的${name}",
47
+ pattern: "請輸入正確的${name}",
48
+ validator: "${name}不符合要求",
49
+ boolean: "${name}數據類型必須是布林類型",
50
+ number: "${name}必須是數字"
52
51
  },
53
- colonText: '',
52
+ colonText: ""
54
53
  },
55
54
  picker: {
56
- cancel: '取消',
57
- confirm: '確認',
55
+ cancel: "取消",
56
+ confirm: "確認"
58
57
  },
59
58
  pullDownRefresh: {
60
- loadingTexts: ['下拉刷新', '鬆手刷新', '正在刷新', '刷新完成'],
59
+ loadingTexts: ["下拉刷新", "鬆手刷新", "正在刷新", "刷新完成"]
61
60
  },
62
61
  rate: {
63
- valueText: '{value} 分',
64
- noValueText: '未評分',
62
+ valueText: "{value} 分",
63
+ noValueText: "未評分"
65
64
  },
66
65
  tabBar: {
67
- newsAriaLabel: '有新消息',
68
- moreNewsAriaLabel: '有很多消息',
69
- haveMoreNewsAriaLabel: '有 {value}+ 條消息',
70
- haveNewsAriaLabel: '有 {value} 條消息',
66
+ newsAriaLabel: "有新消息",
67
+ moreNewsAriaLabel: "有很多消息",
68
+ haveMoreNewsAriaLabel: "有 {value}+ 條消息",
69
+ haveNewsAriaLabel: "有 {value} 條消息"
71
70
  },
72
71
  table: {
73
- empty: '暫無數據',
72
+ empty: "暫無數據"
74
73
  },
75
74
  list: {
76
- loading: '加載中...',
77
- loadingMoreText: '點擊加載更多',
78
- pulling: '下拉即可刷新...',
79
- loosing: '釋放即可刷新...',
80
- success: '刷新成功',
75
+ loading: "加載中...",
76
+ loadingMoreText: "點擊加載更多",
77
+ pulling: "下拉即可刷新...",
78
+ loosing: "釋放即可刷新...",
79
+ success: "刷新成功"
81
80
  },
82
81
  upload: {
83
82
  progress: {
84
- uploadingText: '上傳中...',
85
- waitingText: '待上傳',
86
- failText: '上傳失敗',
87
- successText: '上傳成功',
88
- },
83
+ uploadingText: "上傳中...",
84
+ waitingText: "待上傳",
85
+ failText: "上傳失敗",
86
+ successText: "上傳成功"
87
+ }
89
88
  },
90
89
  guide: {
91
- next: '下一步',
92
- skip: '跳過',
93
- finish: '完成',
94
- back: '返回',
90
+ next: "下一步",
91
+ skip: "跳過",
92
+ finish: "完成",
93
+ back: "返回"
95
94
  },
96
95
  qrcode: {
97
- expiredText: '二維碼過期',
98
- refreshText: '點擊刷新',
99
- scannedText: '已掃描',
100
- },
96
+ expiredText: "二維碼過期",
97
+ refreshText: "點擊刷新",
98
+ scannedText: "已掃描"
99
+ }
101
100
  };
@@ -1,4 +1,4 @@
1
- import { isString } from 'lodash-es';
1
+ import { isString } from "lodash-es";
2
2
 
3
3
  /**
4
4
  * 复数规则判断函数
@@ -55,26 +55,26 @@ export function t<T>(pattern: T, ...args: any[]): string {
55
55
  if (args.length > 0) {
56
56
  const [firstArg, secondArg] = args;
57
57
 
58
- if (typeof firstArg === 'number') {
59
- // 第一个参数是数字,表示 count
58
+ if (typeof firstArg === "number") {
59
+ // 第一个参数是数字,表示 count
60
60
  count = firstArg;
61
- if (secondArg && typeof secondArg === 'object') {
62
- // 第二个参数是对象,表示额外的数据
61
+ if (secondArg && typeof secondArg === "object") {
62
+ // 第二个参数是对象,表示额外的数据
63
63
  data = secondArg;
64
64
  } else {
65
65
  data.count = count; // 若没有提供第二个参数,则将 count 添加到数据中
66
66
  }
67
- } else if (typeof firstArg === 'object' && firstArg !== null) {
68
- // 第一个参数是对象,表示数据
67
+ } else if (typeof firstArg === "object" && firstArg !== null) {
68
+ // 第一个参数是对象,表示数据
69
69
  data = firstArg;
70
70
  }
71
71
  }
72
72
 
73
73
  // 处理复数形式:支持 "no items | one item | {count} items" 格式
74
- if (text.includes('|')) {
75
- const pluralParts = text.split('|').map((part) => part.trim());
74
+ if (text.includes("|")) {
75
+ const pluralParts = text.split("|").map((part) => part.trim());
76
76
 
77
- if (typeof count === 'number') {
77
+ if (typeof count === "number") {
78
78
  // 使用 count 进行复数处理
79
79
  const pluralIndex = getPluralIndex(count);
80
80
 
@@ -82,7 +82,7 @@ export function t<T>(pattern: T, ...args: any[]): string {
82
82
  if (pluralIndex < pluralParts.length) {
83
83
  text = pluralParts[pluralIndex];
84
84
  } else {
85
- // 如果索引超出范围,使用最后一个选项
85
+ // 如果索引超出范围,使用最后一个选项
86
86
  text = pluralParts[pluralParts.length - 1];
87
87
  }
88
88
  } else {
@@ -107,5 +107,5 @@ export function t<T>(pattern: T, ...args: any[]): string {
107
107
  }
108
108
 
109
109
  // 如果不是字符串或函数,返回空字符串
110
- return '';
110
+ return "";
111
111
  }
@@ -0,0 +1,27 @@
1
+ import { useCallback, useRef } from 'react';
2
+
3
+ /**
4
+ * 防抖钩子
5
+ * @param fn 要执行的函数
6
+ * @param delay 延迟时间(毫秒)
7
+ * @returns 防抖后的函数
8
+ */
9
+ export default function useDebounce<T extends (...args: any[]) => any>(
10
+ fn: T,
11
+ delay: number
12
+ ): (...args: Parameters<T>) => void {
13
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null);
14
+
15
+ return useCallback(
16
+ (...args: Parameters<T>) => {
17
+ if (timeoutRef.current) {
18
+ clearTimeout(timeoutRef.current);
19
+ }
20
+
21
+ timeoutRef.current = setTimeout(() => {
22
+ fn(...args);
23
+ }, delay);
24
+ },
25
+ [fn, delay]
26
+ );
27
+ }
@@ -1,8 +1,12 @@
1
- import { useRef } from "react";
1
+ import { useRef, useEffect } from "react";
2
2
 
3
3
  const useLatest = <T>(value: T) => {
4
4
  const ref = useRef(value);
5
- ref.current = value;
5
+
6
+ useEffect(() => {
7
+ ref.current = value;
8
+ }, [value]);
9
+
6
10
  return ref;
7
11
  };
8
12
 
@@ -31,6 +31,5 @@ export default function useResizeObserver(
31
31
  observer = null;
32
32
  }
33
33
  };
34
- // eslint-disable-next-line
35
34
  }, [container, enabled]);
36
35
  }
package/index.ts CHANGED
@@ -34,7 +34,7 @@ export * from "./switch";
34
34
  export * from "./form";
35
35
  export * from "./ip-input";
36
36
  export * from "./fireworks";
37
- // export * from './tooltip';
37
+ export * from "./tooltip";
38
38
  export * from "./drawer";
39
39
  // export * from './progress';
40
40
  // export * from './popconfirm';
package/input/Input.tsx CHANGED
@@ -11,6 +11,8 @@ import { StyledProps, TNode, TElement } from "../common";
11
11
  import { isFunction } from "lodash-es";
12
12
  import useConfig from "../hooks/useConfig";
13
13
  import { useLocaleReceiver } from "../locale/LocalReceiver";
14
+ import useLengthLimit from "./useLengthLimit";
15
+
14
16
  export interface InputProps extends TdInputProps, StyledProps {
15
17
  showInput?: boolean; // 控制透传readonly同时是否展示input 默认保留 因为正常Input需要撑开宽度
16
18
  keepWrapperWidth?: boolean; // 控制透传autoWidth之后是否容器宽度也自适应 多选等组件需要用到自适应但也需要保留宽度
@@ -81,6 +83,12 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
81
83
  onCompositionstart,
82
84
  onCompositionend,
83
85
  onChange: onChangeFromProps,
86
+ maxlength,
87
+ maxcharacter,
88
+ allowInputOverMax = false,
89
+ status,
90
+ onValidate,
91
+ showLimitNumber = true,
84
92
  ...restProps
85
93
  } = props;
86
94
  const composingRef = useRef(false);
@@ -97,6 +105,16 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
97
105
  const isInnerInputReadonly = readonly || !allowInput;
98
106
  const isValueEnabled = value && !disabled;
99
107
  const isShowClearIcon = ((clearable && isValueEnabled) || showClearIconOnEmpty) && isHover;
108
+
109
+ // 使用长度限制 hook
110
+ const { limitNumber, getValueByLimitNumber, tStatus } = useLengthLimit({
111
+ value: value === undefined ? undefined : String(value),
112
+ status,
113
+ maxlength,
114
+ maxcharacter,
115
+ allowInputOverMax,
116
+ onValidate
117
+ });
100
118
  let suffixIconNew = suffixIcon;
101
119
  if (isShowClearIcon)
102
120
  suffixIconNew = (
@@ -128,6 +146,8 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
128
146
  const suffixIconContent = renderIcon("t", "suffix", parseTNode(suffixIconNew));
129
147
  const labelContent = isFunction(label) ? label() : label;
130
148
  const suffixContent = isFunction(suffix) ? suffix() : suffix;
149
+ const limitNumberNode =
150
+ limitNumber && showLimitNumber ? <div className={`${classPrefix}-input__limit-number`}>{limitNumber}</div> : null;
131
151
 
132
152
  const updateInputWidth = () => {
133
153
  if (!autoWidth || !inputRef.current) return;
@@ -167,6 +187,17 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
167
187
  setRenderType(type);
168
188
  }, [type]);
169
189
 
190
+ // 初始判断长度,如超限自动截断并触发onchange
191
+ useEffect(() => {
192
+ if (value) {
193
+ const limitedValue = getValueByLimitNumber(value);
194
+ if (limitedValue.length !== value.length && !allowInputOverMax) {
195
+ onChange?.(limitedValue, { trigger: "initial" });
196
+ }
197
+ }
198
+ // eslint-disable-next-line react-hooks/exhaustive-deps
199
+ }, []);
200
+
170
201
  const innerValue = composingRef.current ? composingValue : value ?? "";
171
202
  const formatDisplayValue = format && !isFocused ? format(innerValue) : innerValue;
172
203
 
@@ -204,9 +235,10 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
204
235
  [`${classPrefix}-size-s`]: size === "small",
205
236
  [`${classPrefix}-size-l`]: size === "large",
206
237
  [`${classPrefix}-align-${align}`]: align,
207
- [`${classPrefix}-inpu${classPrefix}--prefix`]: prefixIcon || labelContent,
208
- [`${classPrefix}-inpu${classPrefix}--suffix`]: suffixIconContent || suffixContent,
209
- [`${classPrefix}-inpu${classPrefix}--borderless`]: borderless,
238
+ [`${classPrefix}-is-${tStatus}`]: tStatus && tStatus !== "default",
239
+ [`${classPrefix}-input--prefix`]: prefixIcon || labelContent,
240
+ [`${classPrefix}-input--suffix`]: suffixIconContent || suffixContent || limitNumberNode,
241
+ [`${classPrefix}-input--borderless`]: borderless,
210
242
  [`${classPrefix}-input--focused`]: isFocused
211
243
  })}
212
244
  onMouseEnter={handleMouseEnter}
@@ -225,7 +257,12 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
225
257
  {innerValue || placeholder}
226
258
  </span>
227
259
  )}
228
- {suffixContent ? <div className={`${classPrefix}-input__suffix`}>{suffixContent}</div> : null}
260
+ {suffixContent || limitNumberNode ? (
261
+ <div className={`${classPrefix}-input__suffix`}>
262
+ {suffixContent}
263
+ {limitNumberNode}
264
+ </div>
265
+ ) : null}
229
266
  {suffixIconContent}
230
267
  </div>
231
268
  );
@@ -256,17 +293,17 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
256
293
  trigger: InputContextTrigger = "input"
257
294
  ) {
258
295
  let { value: newStr } = e.currentTarget;
296
+ // 应用长度限制
297
+ const limitedValue = getValueByLimitNumber(newStr);
259
298
  if (composingRef.current) {
260
- setComposingValue(newStr);
299
+ setComposingValue(limitedValue);
261
300
  } else {
262
301
  // 完成中文输入时同步一次 composingValue
263
- setComposingValue(newStr);
264
- onChange(newStr, { e, trigger });
302
+ setComposingValue(limitedValue);
303
+ onChange(limitedValue, { e, trigger });
265
304
  }
266
305
  }
267
306
 
268
- // 添加MouseDown阻止冒泡,防止點擊Clear value會導致彈窗閃爍一下
269
- // https://github.com/Tencent/tdesign-react/issues/2320
270
307
  function handleMouseDown(e: React.MouseEvent<HTMLSpanElement, globalThis.MouseEvent>) {
271
308
  e.stopPropagation();
272
309
  // 兼容React16
@@ -378,7 +415,13 @@ const Input = forwardRef<HTMLInputElement, InputProps>((originalProps, ref) => {
378
415
  {...restProps}
379
416
  >
380
417
  {renderInputNode}
381
- {tips && <div className={classNames(`${classPrefix}-input__tips`)}>{tips}</div>}
418
+ {tips && (
419
+ <div
420
+ className={classNames(`${classPrefix}-input__tips`, `${classPrefix}-input__tips--${tStatus || "default"}`)}
421
+ >
422
+ {tips}
423
+ </div>
424
+ )}
382
425
  </div>
383
426
  );
384
427
  });
@@ -0,0 +1,14 @@
1
+ import React, { useState } from "react";
2
+ import { Input } from "../index";
3
+
4
+ const AutoWidthInput = () => {
5
+ const [value, setValue] = useState("自适应宽度");
6
+ return (
7
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
8
+ <Input autoWidth value={value} onChange={(val) => setValue(val)} placeholder="宽度随内容变化" />
9
+ <div style={{ color: "#666", fontSize: "12px" }}>输入更多内容,输入框会自动变宽</div>
10
+ </div>
11
+ );
12
+ };
13
+
14
+ export default AutoWidthInput;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { Input } from "../index";
3
+
4
+ const BorderlessInput = () => (
5
+ <div style={{ display: "flex", gap: "24px", width: "500px" }}>
6
+ <div>
7
+ <div style={{ marginBottom: "8px", color: "#666" }}>有边框</div>
8
+ <Input placeholder="有边框" />
9
+ </div>
10
+ <div>
11
+ <div style={{ marginBottom: "8px", color: "#666" }}>无边框</div>
12
+ <Input borderless placeholder="无边框" />
13
+ </div>
14
+ </div>
15
+ );
16
+
17
+ export default BorderlessInput;
@@ -0,0 +1,14 @@
1
+ import React, { useState } from "react";
2
+ import { Input } from "../index";
3
+
4
+ const ClearableInput = () => {
5
+ const [value, setValue] = useState("可清空的内容");
6
+ return (
7
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px", width: "500px" }}>
8
+ <Input clearable value={value} onChange={(val) => setValue(val)} placeholder="输入内容后显示清除按钮" />
9
+ <div style={{ color: "#666", fontSize: "12px" }}>当前值:{value || "(空)"}</div>
10
+ </div>
11
+ );
12
+ };
13
+
14
+ export default ClearableInput;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { Input } from "../index";
3
+
4
+ const DefaultInput = () => (
5
+ <div style={{ width: "500px" }}>
6
+ <Input placeholder="请输入内容" />
7
+ </div>
8
+ );
9
+
10
+ export default DefaultInput;