@tendaui/components 1.0.0 → 1.0.2

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 (270) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +176 -176
  3. package/alert/Alert.tsx +3 -2
  4. package/button/_example/base.tsx +10 -0
  5. package/button/_example/icon.tsx +20 -0
  6. package/color-picker/ColorPickPanel.tsx +9 -0
  7. package/color-picker/ColorPicker.tsx +67 -0
  8. package/color-picker/components/panel/alpha.tsx +32 -0
  9. package/color-picker/components/panel/format/index.tsx +47 -0
  10. package/color-picker/components/panel/format/inputs.tsx +119 -0
  11. package/color-picker/components/panel/header.tsx +37 -0
  12. package/color-picker/components/panel/hue.tsx +20 -0
  13. package/color-picker/components/panel/index.tsx +191 -0
  14. package/color-picker/components/panel/saturation.tsx +81 -0
  15. package/color-picker/components/panel/slider.tsx +76 -0
  16. package/color-picker/components/panel/swatches.tsx +84 -0
  17. package/color-picker/components/trigger.tsx +49 -0
  18. package/color-picker/defaultProps.ts +7 -0
  19. package/color-picker/helpers.ts +53 -0
  20. package/color-picker/hooks/useClassNames.ts +9 -0
  21. package/color-picker/hooks/useStyles.ts +39 -0
  22. package/color-picker/index.ts +12 -0
  23. package/color-picker/style/css.js +1 -0
  24. package/color-picker/style/index.js +1 -0
  25. package/color-picker/type.ts +143 -0
  26. package/color-picker/utils/color-picker/cmyk.ts +89 -0
  27. package/color-picker/utils/color-picker/color.ts +467 -0
  28. package/color-picker/utils/color-picker/constants.ts +187 -0
  29. package/color-picker/utils/color-picker/draggable.ts +100 -0
  30. package/color-picker/utils/color-picker/format.ts +95 -0
  31. package/color-picker/utils/color-picker/gradient.ts +243 -0
  32. package/color-picker/utils/color-picker/index.ts +7 -0
  33. package/color-picker/utils/color-picker/types.ts +33 -0
  34. package/common/observe.ts +33 -0
  35. package/common.ts +20 -0
  36. package/config-provider/ConfigContext.tsx +4 -1
  37. package/config-provider/index.ts +1 -1
  38. package/dialog/DialogCard.tsx +4 -6
  39. package/dialog/hooks/useDialogPosition.ts +1 -2
  40. package/dialog/plugin.tsx +3 -2
  41. package/drawer/Drawer.tsx +264 -0
  42. package/drawer/defaultProps.ts +19 -0
  43. package/drawer/hooks/useDrag.ts +98 -0
  44. package/drawer/hooks/useLockStyle.ts +36 -0
  45. package/drawer/index.ts +5 -0
  46. package/drawer/style/css.js +1 -0
  47. package/drawer/style/index.js +1 -0
  48. package/drawer/type.ts +193 -0
  49. package/drawer/utils/index.ts +76 -0
  50. package/fireworks/Fireworks.tsx +138 -0
  51. package/fireworks/index.ts +10 -0
  52. package/fireworks/style/css.js +0 -0
  53. package/fireworks/style/index.js +0 -0
  54. package/fireworks/type.ts +72 -0
  55. package/form/FormItem.tsx +5 -5
  56. package/form/easing.ts +10 -0
  57. package/form/scroll.ts +124 -0
  58. package/form/type.ts +519 -519
  59. package/global-config/default-config.ts +95 -0
  60. package/global-config/locale/ar_KW.ts +270 -0
  61. package/global-config/locale/en_US.ts +280 -0
  62. package/global-config/locale/it_IT.ts +287 -0
  63. package/global-config/locale/ja_JP.ts +279 -0
  64. package/global-config/locale/ko_KR.ts +279 -0
  65. package/global-config/locale/ru_RU.ts +288 -0
  66. package/global-config/locale/zh_CN.ts +279 -0
  67. package/global-config/locale/zh_TW.ts +279 -0
  68. package/global-config/mobile/default-config.ts +6 -0
  69. package/global-config/mobile/locale/ar_KW.ts +113 -0
  70. package/global-config/mobile/locale/en_US.ts +114 -0
  71. package/global-config/mobile/locale/it_IT.ts +114 -0
  72. package/global-config/mobile/locale/ja_JP.ts +101 -0
  73. package/global-config/mobile/locale/ko_KR.ts +101 -0
  74. package/global-config/mobile/locale/ru_RU.ts +113 -0
  75. package/global-config/mobile/locale/zh_CN.ts +101 -0
  76. package/global-config/mobile/locale/zh_TW.ts +101 -0
  77. package/global-config/t.ts +111 -0
  78. package/hooks/useControlled.ts +3 -3
  79. package/hooks/useDeepEffect.ts +32 -0
  80. package/hooks/useGlobalIcon.ts +10 -3
  81. package/hooks/useLastest.ts +2 -6
  82. package/hooks/useResizeObserve.ts +36 -0
  83. package/index.ts +10 -7
  84. package/input/Input.tsx +4 -1
  85. package/input/defaultProps.ts +0 -2
  86. package/input/type.ts +1 -6
  87. package/input-number/InputNumber.tsx +124 -0
  88. package/input-number/defaultProps.ts +17 -0
  89. package/input-number/index.ts +9 -0
  90. package/input-number/style/css.js +1 -0
  91. package/input-number/style/index.js +1 -0
  92. package/input-number/type.ts +147 -0
  93. package/input-number/useInputNumber.tsx +270 -0
  94. package/ip-input/IPInput.tsx +516 -0
  95. package/ip-input/defaultProps.ts +11 -0
  96. package/ip-input/index.ts +3 -0
  97. package/ip-input/style/css.js +1 -0
  98. package/ip-input/style/index.js +1 -0
  99. package/ip-input/type.ts +115 -0
  100. package/ip-input/utils.ts +112 -0
  101. package/layout/Aside.tsx +38 -0
  102. package/layout/Layout.tsx +104 -0
  103. package/layout/defaultProps.ts +9 -0
  104. package/layout/index.ts +9 -0
  105. package/layout/style/css.js +1 -0
  106. package/layout/style/index.js +1 -0
  107. package/layout/type.ts +43 -0
  108. package/list/List.tsx +144 -0
  109. package/list/ListItem.tsx +36 -0
  110. package/list/ListItemMeta.tsx +40 -0
  111. package/list/defaultProps.ts +11 -0
  112. package/list/hooks/useListVirtualScroll.ts +82 -0
  113. package/list/index.ts +11 -0
  114. package/list/style/css.js +1 -0
  115. package/list/style/index.js +1 -0
  116. package/list/type.ts +93 -0
  117. package/locale/LocalReceiver.ts +55 -0
  118. package/locale/ar_KW.ts +7 -0
  119. package/locale/en_US.ts +7 -0
  120. package/locale/it_IT.ts +6 -0
  121. package/locale/ja_JP.ts +6 -0
  122. package/locale/ko_KR.ts +6 -0
  123. package/locale/ru_RU.ts +6 -0
  124. package/locale/zh_CN.ts +5 -0
  125. package/locale/zh_TW.ts +7 -0
  126. package/notification/NotifyContainer.tsx +2 -2
  127. package/notification/NotifyContext.tsx +1 -0
  128. package/package.json +6 -3
  129. package/popup/Popup.tsx +34 -10
  130. package/radio/Radio.tsx +24 -0
  131. package/radio/RadioGroup.tsx +159 -0
  132. package/radio/defaultProps.ts +18 -0
  133. package/radio/index.ts +12 -0
  134. package/radio/style/css.js +0 -0
  135. package/radio/style/index.js +1 -0
  136. package/radio/type.ts +115 -0
  137. package/radio/useKeyboard.ts +36 -0
  138. package/select/hooks/useOptions.ts +10 -7
  139. package/select/hooks/usePanelVirtualScroll.ts +1 -1
  140. package/select/type.ts +382 -382
  141. package/select-input/type.ts +280 -280
  142. package/slider/Slider.tsx +270 -0
  143. package/slider/SliderHandleButton.tsx +50 -0
  144. package/slider/defaultProps.ts +15 -0
  145. package/slider/index.ts +9 -0
  146. package/slider/style/css.js +1 -0
  147. package/slider/style/index.js +1 -0
  148. package/slider/type.ts +77 -0
  149. package/style/all.js +26 -0
  150. package/styles/_global.scss +39 -39
  151. package/styles/_vars.scss +358 -386
  152. package/styles/components/alert/_index.scss +175 -175
  153. package/styles/components/alert/_vars.scss +39 -39
  154. package/styles/components/badge/_index.scss +70 -70
  155. package/styles/components/badge/_vars.scss +25 -25
  156. package/styles/components/button/_index.scss +499 -511
  157. package/styles/components/button/_mixins.scss +39 -39
  158. package/styles/components/button/_vars.scss +120 -122
  159. package/styles/components/checkbox/_index.scss +158 -158
  160. package/styles/components/checkbox/_var.scss +60 -60
  161. package/styles/components/color-picker/_index.scss +586 -0
  162. package/styles/components/color-picker/_mixins.scss +0 -0
  163. package/styles/components/color-picker/_vars.scss +84 -0
  164. package/styles/components/dialog/_animate.scss +135 -135
  165. package/styles/components/dialog/_index.scss +311 -311
  166. package/styles/components/dialog/_vars.scss +59 -59
  167. package/styles/components/drawer/_index.scss +205 -0
  168. package/styles/components/drawer/_mixins.scss +1 -0
  169. package/styles/components/drawer/_var.scss +53 -0
  170. package/styles/components/fireworks/_index.scss +86 -0
  171. package/styles/components/fireworks/_vars.scss +4 -0
  172. package/styles/components/form/_index.scss +174 -174
  173. package/styles/components/form/_mixins.scss +76 -76
  174. package/styles/components/form/_vars.scss +100 -100
  175. package/styles/components/input/_index.scss +349 -349
  176. package/styles/components/input/_mixins.scss +116 -116
  177. package/styles/components/input/_vars.scss +134 -134
  178. package/styles/components/input-number/_index.scss +353 -0
  179. package/styles/components/input-number/_mixins.scss +0 -0
  180. package/styles/components/input-number/_vars.scss +65 -0
  181. package/styles/components/ip-input/_index.scss +280 -0
  182. package/styles/components/layout/_index.scss +47 -0
  183. package/styles/components/layout/_mixin.scss +0 -0
  184. package/styles/components/layout/_vars.scss +18 -0
  185. package/styles/components/layout/doc.scss +74 -0
  186. package/styles/components/list/_index.scss +172 -0
  187. package/styles/components/list/_mixins.scss +0 -0
  188. package/styles/components/list/_vars.scss +41 -0
  189. package/styles/components/loading/_index.scss +112 -112
  190. package/styles/components/loading/_vars.scss +39 -39
  191. package/styles/components/notification/_index.scss +160 -160
  192. package/styles/components/notification/_mixins.scss +12 -12
  193. package/styles/components/notification/_vars.scss +59 -59
  194. package/styles/components/popup/_index.scss +82 -82
  195. package/styles/components/popup/_mixin.scss +149 -149
  196. package/styles/components/popup/_var.scss +31 -31
  197. package/styles/components/radio/_index.scss +376 -0
  198. package/styles/components/radio/_mixins.scss +0 -0
  199. package/styles/components/radio/_var.scss +92 -0
  200. package/styles/components/select/_index.scss +290 -290
  201. package/styles/components/select/_var.scss +65 -65
  202. package/styles/components/select-input/_index.scss +5 -5
  203. package/styles/components/select-input/_var.scss +3 -3
  204. package/styles/components/slider/_index.scss +241 -0
  205. package/styles/components/slider/_mixins.scss +0 -0
  206. package/styles/components/slider/_vars.scss +50 -0
  207. package/styles/components/switch/_index.scss +279 -279
  208. package/styles/components/switch/_vars.scss +61 -61
  209. package/styles/components/table/_index.scss +193 -0
  210. package/styles/components/table/_var.scss +52 -0
  211. package/styles/components/tabs/_index.scss +165 -0
  212. package/styles/components/tabs/_mixins.scss +11 -0
  213. package/styles/components/tabs/_vars.scss +71 -0
  214. package/styles/components/tag/_index.scss +316 -316
  215. package/styles/components/tag/_var.scss +85 -85
  216. package/styles/components/tag-input/_index.scss +163 -163
  217. package/styles/components/tag-input/_vars.scss +16 -16
  218. package/styles/globals.css +250 -250
  219. package/styles/mixins/_focus.scss +7 -7
  220. package/styles/mixins/_layout.scss +32 -32
  221. package/styles/mixins/_reset.scss +10 -10
  222. package/styles/mixins/_scrollbar.scss +31 -31
  223. package/styles/mixins/_text.scss +48 -48
  224. package/styles/rillple.css +16 -16
  225. package/styles/scrollbar.css +41 -41
  226. package/styles/themes/_dark.scss +191 -191
  227. package/styles/themes/_font.scss +69 -79
  228. package/styles/themes/_index.scss +5 -5
  229. package/styles/themes/_light.scss +190 -190
  230. package/styles/themes/_radius.scss +9 -9
  231. package/styles/themes/_size.scss +68 -68
  232. package/styles/themes.css +66 -66
  233. package/styles/utilities/_animation.scss +57 -57
  234. package/styles/utilities/_tips.scss +9 -9
  235. package/tab/TabBar.tsx +85 -0
  236. package/tab/TabNav.tsx +103 -0
  237. package/tab/TabNavItem.tsx +80 -0
  238. package/tab/TabPanel.tsx +42 -0
  239. package/tab/Tabs.tsx +71 -0
  240. package/tab/defaultProps.ts +19 -0
  241. package/tab/index.ts +7 -0
  242. package/tab/style/index.js +1 -0
  243. package/tab/type.ts +125 -0
  244. package/tab/useTabClass.ts +20 -0
  245. package/table/Cell.tsx +109 -0
  246. package/table/TBody.tsx +77 -0
  247. package/table/THead.tsx +63 -0
  248. package/table/TR.tsx +78 -0
  249. package/table/Table.tsx +73 -0
  250. package/table/defaultProps.ts +14 -0
  251. package/table/hooks/index.ts +4 -0
  252. package/table/hooks/useTableClassName.ts +63 -0
  253. package/table/hooks/useTableStyle.ts +93 -0
  254. package/table/index.ts +7 -0
  255. package/table/style/css.js +1 -0
  256. package/table/style/index.js +1 -0
  257. package/table/type.ts +192 -0
  258. package/tag/Tag.tsx +1 -1
  259. package/tag-input/hooks/useTagList.tsx +1 -1
  260. package/utils/dom.ts +4 -0
  261. package/utils/forwardRefWithStatics.ts +1 -4
  262. package/utils/input-number/large-number.ts +423 -0
  263. package/utils/input-number/number.ts +257 -0
  264. package/utils/isFragment.ts +6 -6
  265. package/utils/log/index.ts +3 -0
  266. package/utils/log/log.ts +30 -0
  267. package/utils/log/types.ts +12 -0
  268. package/utils/number.ts +21 -0
  269. package/utils/scroll.ts +26 -0
  270. package/utils/style.ts +2 -4
@@ -0,0 +1,270 @@
1
+ import React, { useMemo, useRef } from "react";
2
+ import classNames from "classnames";
3
+ import { isFunction, isNumber, isString } from "lodash-es";
4
+
5
+ import { largeNumberToFixed } from "@tendaui/utils/js/input-number/large-number";
6
+ import { accAdd, numberToPercent } from "../utils/number";
7
+ import useConfig from "../hooks/useConfig";
8
+ import useControlled from "../hooks/useControlled";
9
+ import useDefaultProps from "../hooks/useDefaultProps";
10
+ import InputNumber from "../input-number/InputNumber";
11
+ import { sliderDefaultProps } from "./defaultProps";
12
+ import SliderHandleButton from "./SliderHandleButton";
13
+
14
+ import type { StyledProps, TNode } from "../common";
15
+ import type { MouseCallback } from "../hooks/useMouseEvent";
16
+ import type { SliderValue, TdSliderProps } from "./type";
17
+
18
+ export interface SliderProps<T extends SliderValue = SliderValue> extends TdSliderProps<T>, StyledProps {}
19
+
20
+ const LEFT_NODE = 0;
21
+ const RIGHT_NODE = 1;
22
+ type SliderHandleNode = typeof LEFT_NODE | typeof RIGHT_NODE;
23
+
24
+ const Slider = React.forwardRef<HTMLDivElement, SliderProps>((originalProps, ref) => {
25
+ const { classPrefix } = useConfig();
26
+ const props = useDefaultProps(originalProps, sliderDefaultProps);
27
+ const {
28
+ disabled,
29
+ inputNumberProps,
30
+ label,
31
+ layout,
32
+ marks,
33
+ max,
34
+ min,
35
+ range,
36
+ step,
37
+ tooltipProps,
38
+ className,
39
+ style,
40
+ onChange
41
+ } = props;
42
+
43
+ const sliderRef = useRef<HTMLDivElement>(null);
44
+ const [value, internalOnChange] = useControlled(props, "value", onChange);
45
+ const isVertical = layout === "vertical";
46
+
47
+ const renderValue = Array.isArray(value) ? value : [min, Math.min(max, value)];
48
+ const start = (renderValue[LEFT_NODE] - min) / (max - min);
49
+ const width = (renderValue[RIGHT_NODE] - renderValue[LEFT_NODE]) / (max - min);
50
+ const end = start + width;
51
+
52
+ const precision = useMemo(() => {
53
+ if (!Number.isInteger(step)) return step.toString().split(".")[1].length;
54
+ return undefined;
55
+ }, [step]);
56
+
57
+ const dots = useMemo<{ value: number; label: TNode; position: number }[]>(() => {
58
+ // 当 marks 为数字数组
59
+ if (Array.isArray(marks)) {
60
+ if (marks.some((mark) => typeof mark !== "number")) {
61
+ console.warn('The props "marks" only support number!');
62
+ return [];
63
+ }
64
+ return marks.map((mark) => ({ value: mark, position: (mark - min) / (max - min), label: mark }));
65
+ }
66
+ // 当 marks 为对象
67
+ if (marks && typeof marks === "object") {
68
+ const result = [];
69
+ Object.keys(marks).forEach((key) => {
70
+ const numberKey = Number(key);
71
+ if (typeof numberKey !== "number") {
72
+ console.warn('The props "marks" key only support number!');
73
+ } else {
74
+ result.push({
75
+ value: numberKey,
76
+ label: marks[numberKey],
77
+ position: (numberKey - min) / (max - min)
78
+ });
79
+ }
80
+ });
81
+ return result;
82
+ }
83
+ return [];
84
+ }, [max, min, marks]);
85
+
86
+ const allDots = useMemo(() => {
87
+ // 默认
88
+ const result = [];
89
+ for (let i = min; i <= max; i = accAdd(i, step)) {
90
+ result.push({
91
+ value: i,
92
+ position: (i - min) / (max - min)
93
+ });
94
+ }
95
+ return result;
96
+ }, [max, min, step]);
97
+
98
+ const startDirection = isVertical ? "bottom" : "left";
99
+ const stepDirection = isVertical ? "top" : "left";
100
+ const sizeKey = isVertical ? "height" : "width";
101
+ const renderDots = isVertical ? dots.map((item) => ({ ...item, position: 1 - item.position })) : dots;
102
+
103
+ const handleInputChange = (newValue: number, nodeIndex: SliderHandleNode) => {
104
+ const safeValue = Number(newValue.toFixed(32));
105
+ let resultValue = Math.max(Math.min(max, safeValue), min);
106
+ if (precision) resultValue = Number(largeNumberToFixed(String(resultValue), precision));
107
+ // 判断是否出现左值大于右值
108
+ if (nodeIndex === LEFT_NODE && value && safeValue > value[RIGHT_NODE]) resultValue = value[RIGHT_NODE];
109
+ // 判断是否出现右值大于左值
110
+ if (nodeIndex === RIGHT_NODE && value && safeValue < value[LEFT_NODE]) resultValue = value[LEFT_NODE];
111
+ if (Array.isArray(value)) {
112
+ const arrValue = value.slice();
113
+ arrValue[nodeIndex] = resultValue;
114
+ internalOnChange(arrValue);
115
+ } else {
116
+ internalOnChange(resultValue);
117
+ }
118
+ };
119
+
120
+ const createInput = (nodeIndex: SliderHandleNode) => {
121
+ const inputProps = typeof inputNumberProps === "object" ? inputNumberProps : {};
122
+ const currentValue = renderValue[nodeIndex];
123
+
124
+ return (
125
+ <InputNumber
126
+ value={currentValue}
127
+ onChange={(v: number) => {
128
+ if (typeof v !== "undefined") {
129
+ handleInputChange(Number(v), nodeIndex);
130
+ }
131
+ }}
132
+ className={classNames(`${classPrefix}-slider-input`, { "is-vertical": isVertical })}
133
+ disabled={disabled}
134
+ theme="column"
135
+ min={min}
136
+ max={max}
137
+ {...inputProps}
138
+ />
139
+ );
140
+ };
141
+
142
+ const nearbyValueChange = (value: number) => {
143
+ const buttonBias =
144
+ Math.abs(value - renderValue[LEFT_NODE]) > Math.abs(value - renderValue[RIGHT_NODE]) ? RIGHT_NODE : LEFT_NODE;
145
+ handleInputChange(value, buttonBias);
146
+ };
147
+
148
+ const setPosition = (position: number, nodeIndex?: SliderHandleNode) => {
149
+ let index = 0;
150
+ let minDistance = 1;
151
+ for (let i = 0; i < allDots.length; i++) {
152
+ const diff = Math.abs(allDots[i].position - position);
153
+ if (minDistance > diff) {
154
+ index = i;
155
+ minDistance = diff;
156
+ }
157
+ }
158
+ const { value } = allDots[index];
159
+ if (nodeIndex === undefined && range) {
160
+ nearbyValueChange(value);
161
+ } else {
162
+ handleInputChange(value, nodeIndex);
163
+ }
164
+ };
165
+
166
+ const onSliderChange = (event: MouseCallback, nodeIndex?: SliderHandleNode) => {
167
+ if (disabled || !sliderRef.current) return;
168
+
169
+ const clientKey = isVertical ? "clientY" : "clientX";
170
+ const sliderPositionInfo = sliderRef.current.getBoundingClientRect();
171
+ const sliderOffset = sliderPositionInfo[startDirection];
172
+ const position = ((event[clientKey] - sliderOffset) / sliderPositionInfo[sizeKey]) * (isVertical ? -1 : 1);
173
+ setPosition(position, nodeIndex);
174
+ };
175
+
176
+ const handleClickMarks = (event: React.MouseEvent, value: number) => {
177
+ event.stopPropagation();
178
+ nearbyValueChange(value);
179
+ };
180
+
181
+ const createHandleButton = (nodeIndex: SliderHandleNode, style: React.CSSProperties) => {
182
+ const currentValue = renderValue[nodeIndex];
183
+ // 模板替换
184
+ let tipLabel: React.ReactNode = currentValue;
185
+
186
+ if (isFunction(label)) {
187
+ tipLabel = label({ value: currentValue, position: nodeIndex === LEFT_NODE ? "start" : "end" });
188
+ }
189
+ if (isString(label)) {
190
+ tipLabel = label.replace(/\$\{value\}/g, currentValue.toString());
191
+ }
192
+ if (isNumber(tipLabel) && precision) tipLabel = largeNumberToFixed(String(tipLabel), precision);
193
+
194
+ return (
195
+ <SliderHandleButton
196
+ toolTipProps={{ content: tipLabel, ...tooltipProps }}
197
+ hideTips={label === false}
198
+ classPrefix={classPrefix}
199
+ style={style}
200
+ onChange={(e) => onSliderChange(e, nodeIndex)}
201
+ />
202
+ );
203
+ };
204
+
205
+ return (
206
+ <div
207
+ style={{ ...style }}
208
+ className={classNames(`${classPrefix}-slider__container`, { "is-vertical": isVertical })}
209
+ ref={ref}
210
+ >
211
+ <div
212
+ ref={sliderRef}
213
+ className={classNames(`${classPrefix}-slider`, className, {
214
+ [`${classPrefix}-is-disabled`]: disabled,
215
+ [`${classPrefix}-slider--vertical`]: isVertical,
216
+ [`${classPrefix}-slider--with-input`]: inputNumberProps
217
+ })}
218
+ onClick={onSliderChange}
219
+ >
220
+ <div className={classNames(`${classPrefix}-slider__rail`)}>
221
+ <div
222
+ style={{ [startDirection]: numberToPercent(start), [sizeKey]: numberToPercent(width) }}
223
+ className={classNames(`${classPrefix}-slider__track`)}
224
+ ></div>
225
+ {range ? createHandleButton(LEFT_NODE, { [startDirection]: numberToPercent(start) }) : null}
226
+ {createHandleButton(RIGHT_NODE, { [startDirection]: numberToPercent(end) })}
227
+ <div className={`${classPrefix}-slider__stops`}>
228
+ {renderDots.map(({ position, value }) => {
229
+ if (position === 0 || position === 1) {
230
+ return null;
231
+ }
232
+ return (
233
+ <div
234
+ key={value}
235
+ style={{ [stepDirection]: numberToPercent(position) }}
236
+ className={classNames(`${classPrefix}-slider__stop`)}
237
+ ></div>
238
+ );
239
+ })}
240
+ </div>
241
+ <div className={classNames(`${classPrefix}-slider__mark`)}>
242
+ {renderDots.map(({ position, value, label }) => (
243
+ <div
244
+ key={value}
245
+ onClick={(event) => handleClickMarks(event, value)}
246
+ style={{ [stepDirection]: numberToPercent(position) }}
247
+ className={classNames(`${classPrefix}-slider__mark-text`)}
248
+ >
249
+ {label}
250
+ </div>
251
+ ))}
252
+ </div>
253
+ </div>
254
+ </div>
255
+ {inputNumberProps ? (
256
+ <div className={classNames(`${classPrefix}-slider__input-container`, { "is-vertical": isVertical })}>
257
+ {range && createInput(LEFT_NODE)}
258
+ {range && <div className={`${classPrefix}-slider__center-line`}></div>}
259
+ {createInput(RIGHT_NODE)}
260
+ </div>
261
+ ) : null}
262
+ </div>
263
+ );
264
+ });
265
+
266
+ Slider.displayName = "Slider";
267
+
268
+ export default Slider as <T extends SliderValue = SliderValue>(
269
+ props: SliderProps<T> & React.RefAttributes<HTMLDivElement>
270
+ ) => React.ReactElement;
@@ -0,0 +1,50 @@
1
+ import React, { useRef, useState } from "react";
2
+ import classNames from "classnames";
3
+ import useMouseEvent, { type MouseCallback } from "../hooks/useMouseEvent";
4
+
5
+ interface SliderHandleButtonProps {
6
+ onChange: (event: MouseCallback) => void;
7
+ classPrefix: string;
8
+ style: React.CSSProperties;
9
+ hideTips: boolean;
10
+ toolTipProps?: any;
11
+ }
12
+
13
+ const SliderHandleButton: React.FC<SliderHandleButtonProps> = ({ onChange, style, classPrefix }) => {
14
+ const sliderNodeRef = useRef<HTMLDivElement>(null);
15
+ const [popupVisible, setPopupVisible] = useState(false);
16
+
17
+ const { isMoving } = useMouseEvent(sliderNodeRef, {
18
+ onEnter() {
19
+ setPopupVisible(true);
20
+ },
21
+ onDown: () => {
22
+ setPopupVisible(true);
23
+ },
24
+ onMove: (e) => {
25
+ setPopupVisible(true);
26
+ onChange(e);
27
+ },
28
+ onLeave: () => {
29
+ setPopupVisible(false);
30
+ },
31
+ onUp: (e) => {
32
+ setPopupVisible(false);
33
+ onChange(e);
34
+ }
35
+ });
36
+
37
+ const handleNode = (
38
+ <div ref={sliderNodeRef} style={style} className={`${classPrefix}-slider__button-wrapper`}>
39
+ <div
40
+ className={classNames(`${classPrefix}-slider__button`, {
41
+ [`${classPrefix}-slider__button--dragging`]: isMoving
42
+ })}
43
+ ></div>
44
+ </div>
45
+ );
46
+
47
+ return handleNode;
48
+ };
49
+
50
+ export default SliderHandleButton;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
3
+ * */
4
+
5
+ import { TdSliderProps } from "./type";
6
+
7
+ export const sliderDefaultProps: TdSliderProps = {
8
+ inputNumberProps: false,
9
+ label: true,
10
+ layout: "horizontal",
11
+ max: 100,
12
+ min: 0,
13
+ range: false,
14
+ step: 1
15
+ };
@@ -0,0 +1,9 @@
1
+ import _Slider from "./Slider";
2
+
3
+ import "./style/index.js";
4
+
5
+ export type { SliderProps } from "./Slider";
6
+ export * from "./type";
7
+
8
+ export const Slider = _Slider;
9
+ export default Slider;
@@ -0,0 +1 @@
1
+ import "./index.css";
@@ -0,0 +1 @@
1
+ import "../../styles/components/slider/_index.scss";
package/slider/type.ts ADDED
@@ -0,0 +1,77 @@
1
+ import { InputNumberProps } from "../input-number";
2
+ import { TNode } from "../common";
3
+ import React from "react";
4
+
5
+ export interface TooltipProps {
6
+ content?: string | React.ReactNode;
7
+ [key: string]: any;
8
+ }
9
+
10
+ export interface TdSliderProps<T = SliderValue> {
11
+ /**
12
+ * 是否禁用组件
13
+ * @default false
14
+ */
15
+ disabled?: boolean;
16
+ /**
17
+ * 用于控制数字输入框组件,值为 false 表示不显示数字输入框;值为 true 表示呈现默认数字输入框;值类型为 Object 表示透传属性到数字输入框组件
18
+ * @default false
19
+ */
20
+ inputNumberProps?: boolean | InputNumberProps<number>;
21
+ /**
22
+ * 滑块当前值文本。<br />值为 true 显示默认文案;值为 false 不显示滑块当前值文本;<br />值为 `${value}%` 则表示组件会根据占位符渲染文案;<br />值类型为函数时,参数 `value` 标识滑块值,参数 `position=start` 表示范围滑块的起始值,参数 `position=end` 表示范围滑块的终点值
23
+ * @default true
24
+ */
25
+ label?: string | boolean | TNode<{ value: SliderValue; position?: "start" | "end" }>;
26
+ /**
27
+ * 滑块布局方向
28
+ * @default horizontal
29
+ */
30
+ layout?: "vertical" | "horizontal";
31
+ /**
32
+ * 刻度标记,示例:[0, 10, 40, 200] 或者 `{ 10: (val) => val + '%', 50: (h) => <button>50</button> }`
33
+ */
34
+ marks?: Array<number> | SliderMarks;
35
+ /**
36
+ * 滑块范围最大值
37
+ * @default 100
38
+ */
39
+ max?: number;
40
+ /**
41
+ * 滑块范围最小值
42
+ * @default 0
43
+ */
44
+ min?: number;
45
+ /**
46
+ * 双游标滑块
47
+ * @default false
48
+ */
49
+ range?: boolean;
50
+ /**
51
+ * 步长
52
+ * @default 1
53
+ */
54
+ step?: number;
55
+ /**
56
+ * 透传提示组件属性
57
+ */
58
+ tooltipProps?: TooltipProps;
59
+ /**
60
+ * 滑块值
61
+ */
62
+ value?: SliderValue;
63
+ /**
64
+ * 滑块值,非受控属性
65
+ */
66
+ defaultValue?: SliderValue;
67
+ /**
68
+ * 滑块值变化时触发
69
+ */
70
+ onChange?: (value: T) => void;
71
+ }
72
+
73
+ export interface SliderMarks {
74
+ [mark: number]: string | TNode<{ value: number }>;
75
+ }
76
+
77
+ export type SliderValue = number | Array<number>;
package/style/all.js ADDED
@@ -0,0 +1,26 @@
1
+ import "../alert/style/index.js";
2
+ import "../badge/style/index.js";
3
+ import "../button/style/index.js";
4
+ import "../checkbox/style/index.js";
5
+ import "../color-picker/style/index.js";
6
+ import "../dialog/style/index.js";
7
+ import "../drawer/style/index.js";
8
+ import "../fireworks/style/index.js";
9
+ import "../form/style/index.js";
10
+ import "../input/style/index.js";
11
+ import "../input-number/style/index.js";
12
+ import "../ip-input/style/index.js";
13
+ import "../layout/style/index.js";
14
+ import "../list/style/index.js";
15
+ import "../loading/style/index.js";
16
+ import "../notification/style/index.js";
17
+ import "../popup/style/index.js";
18
+ import "../radio/style/index.js";
19
+ import "../select/style/index.js";
20
+ import "../select-input/style/index.js";
21
+ import "../slider/style/index.js";
22
+ import "../switch/style/index.js";
23
+ import "../tab/style/index.js";
24
+ import "../table/style/index.js";
25
+ import "../tag/style/index.js";
26
+ import "../tag-input/style/index.js";
@@ -1,39 +1,39 @@
1
- @import './_vars.scss';
2
-
3
- @import './mixins/_scrollbar.scss';
4
-
5
- // 响应式断点 后面支持紧凑模式可以迁移过去
6
- :root {
7
- --td-screen-xs: #{$screen-xs};
8
- --td-screen-sm: #{$screen-sm};
9
- --td-screen-md: #{$screen-md};
10
- --td-screen-lg: #{$screen-lg};
11
- --td-screen-xl: #{$screen-xl};
12
- --td-screen-xxl: #{$screen-xxl};
13
- }
14
-
15
- // 统一的scrollbar
16
- .narrow-scrollbar {
17
- @include scrollbar(8px, 2px);
18
- }
19
-
20
- // 统一的可旋转箭头
21
- .#{$prefix}-fake-arrow {
22
- path {
23
- transition: d $anim-duration-base;
24
- stroke: currentcolor;
25
- }
26
-
27
- &--active {
28
- path {
29
- d: path('M3.75 10.2002L7.99274 5.7998L12.2361 10.0425');
30
- }
31
- }
32
- }
33
-
34
- .#{$prefix}-slide-down-enter-active,
35
- .#{$prefix}-slide-down-leave-active {
36
- transition:
37
- height $anim-duration-base $anim-time-fn-easing,
38
- max-height $anim-duration-base $anim-time-fn-easing;
39
- }
1
+ @import './_vars.scss';
2
+
3
+ @import './mixins/_scrollbar.scss';
4
+
5
+ // 响应式断点 后面支持紧凑模式可以迁移过去
6
+ :root {
7
+ --td-screen-xs: #{$screen-xs};
8
+ --td-screen-sm: #{$screen-sm};
9
+ --td-screen-md: #{$screen-md};
10
+ --td-screen-lg: #{$screen-lg};
11
+ --td-screen-xl: #{$screen-xl};
12
+ --td-screen-xxl: #{$screen-xxl};
13
+ }
14
+
15
+ // 统一的scrollbar
16
+ .narrow-scrollbar {
17
+ @include scrollbar(8px, 2px);
18
+ }
19
+
20
+ // 统一的可旋转箭头
21
+ .#{$prefix}-fake-arrow {
22
+ path {
23
+ transition: d $anim-duration-base;
24
+ stroke: currentcolor;
25
+ }
26
+
27
+ &--active {
28
+ path {
29
+ d: path('M3.75 10.2002L7.99274 5.7998L12.2361 10.0425');
30
+ }
31
+ }
32
+ }
33
+
34
+ .#{$prefix}-slide-down-enter-active,
35
+ .#{$prefix}-slide-down-leave-active {
36
+ transition:
37
+ height $anim-duration-base $anim-time-fn-easing,
38
+ max-height $anim-duration-base $anim-time-fn-easing;
39
+ }