Skip to content

Commit c33764e

Browse files
authored
refactor: Pure FC with multiple update (#812)
* init * value of it * switch focus * feat: support focus * cache all * reverse support * feat: vertical support * feat: track support * feat: base styles * feat: marks * feat: align with marks * feat: align with steps * feat: click to move to close value * chore: click slide to move * feat: dot * feat: included * feat: dragging mark * ts def update * keyboard of it * multiple ranges * pushable * resolve pushable cache * track draggable * docs: all range * dotStyle & activeDotStyle * fix: dead loop * fix: control draggable * docs: slider examples * docs: all docs * chore: all props * test: base test case * fix: keyboard align logic * test: test case * test: part range test * test: pushable * refactor: move into useOffset * refactor: offset of values * chore: support steps * chore: next values offset * chore: keyboard pushable * refactor: same logic of drag * chore: clean up * test: allowCross & pushable * test: tmp * test: back of react test lib * test: range * test: mv to react test lib * feat: touch-able * test: touch test * test: test of it * test: all legacy test * chore: clean up * test: Slider full coverage * test: More test case * test: full coverage
1 parent 9d6dcc5 commit c33764e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+3064
-3517
lines changed

assets/index.less

+55-47
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
@tooltip-arrow-width: 4px;
99
@tooltip-distance: @tooltip-arrow-width+4;
1010
@tooltip-arrow-color: @tooltip-bg;
11-
@ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1);
12-
@ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06);
11+
@ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
12+
@ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
1313

1414
.borderBox() {
1515
box-sizing: border-box;
@@ -23,40 +23,40 @@
2323

2424
.@{prefixClass} {
2525
position: relative;
26+
width: 100%;
2627
height: 14px;
2728
padding: 5px 0;
28-
width: 100%;
2929
border-radius: @border-radius-base;
3030
touch-action: none;
3131
.borderBox();
3232

3333
&-rail {
3434
position: absolute;
3535
width: 100%;
36-
background-color: #e9e9e9;
3736
height: 4px;
37+
background-color: #e9e9e9;
3838
border-radius: @border-radius-base;
3939
}
4040

4141
&-track {
4242
position: absolute;
43-
left: 0;
4443
height: 4px;
45-
border-radius: @border-radius-base;
4644
background-color: tint(@primary-color, 60%);
45+
border-radius: @border-radius-base;
4746
}
4847

4948
&-handle {
5049
position: absolute;
5150
width: 14px;
5251
height: 14px;
52+
margin-top: -5px;
53+
background-color: #fff;
54+
border: solid 2px tint(@primary-color, 50%);
55+
border-radius: 50%;
5356
cursor: pointer;
5457
cursor: -webkit-grab;
55-
margin-top: -5px;
5658
cursor: grab;
57-
border-radius: 50%;
58-
border: solid 2px tint(@primary-color, 50%);
59-
background-color: #fff;
59+
opacity: 0.8;
6060
touch-action: pan-x;
6161

6262
&-dragging&-dragging&-dragging {
@@ -66,6 +66,7 @@
6666

6767
&:focus {
6868
outline: none;
69+
box-shadow: 0 0 0 3px tint(@primary-color, 50%);
6970
}
7071

7172
&-click-focused:focus {
@@ -96,10 +97,10 @@
9697
&-mark-text {
9798
position: absolute;
9899
display: inline-block;
99-
vertical-align: middle;
100+
color: #999;
100101
text-align: center;
102+
vertical-align: middle;
101103
cursor: pointer;
102-
color: #999;
103104

104105
&-active {
105106
color: #666;
@@ -111,19 +112,20 @@
111112
width: 100%;
112113
height: 4px;
113114
background: transparent;
115+
pointer-events: none;
114116
}
115117

116118
&-dot {
117119
position: absolute;
118120
bottom: -2px;
119-
margin-left: -4px;
120121
width: 8px;
121122
height: 8px;
122-
border: 2px solid #e9e9e9;
123+
// margin-left: -4px;
124+
vertical-align: middle;
123125
background-color: #fff;
124-
cursor: pointer;
126+
border: 2px solid #e9e9e9;
125127
border-radius: 50%;
126-
vertical-align: middle;
128+
cursor: pointer;
127129
&-active {
128130
border-color: tint(@primary-color, 50%);
129131
}
@@ -139,15 +141,17 @@
139141
background-color: @disabledColor;
140142
}
141143

142-
.@{prefixClass}-handle, .@{prefixClass}-dot {
144+
.@{prefixClass}-handle,
145+
.@{prefixClass}-dot {
146+
background-color: #fff;
143147
border-color: @disabledColor;
144148
box-shadow: none;
145-
background-color: #fff;
146149
cursor: not-allowed;
147150
}
148151

149-
.@{prefixClass}-mark-text, .@{prefixClass}-dot {
150-
cursor: not-allowed!important;
152+
.@{prefixClass}-mark-text,
153+
.@{prefixClass}-dot {
154+
cursor: not-allowed !important;
151155
}
152156
}
153157
}
@@ -159,17 +163,18 @@
159163

160164
.@{prefixClass} {
161165
&-rail {
162-
height: 100%;
163166
width: 4px;
167+
height: 100%;
164168
}
165169

166170
&-track {
167-
left: 5px;
168171
bottom: 0;
172+
left: 5px;
169173
width: 4px;
170174
}
171175

172176
&-handle {
177+
margin-top: 0;
173178
margin-left: -5px;
174179
touch-action: pan-y;
175180
}
@@ -181,50 +186,53 @@
181186
}
182187

183188
&-step {
184-
height: 100%;
185189
width: 4px;
190+
height: 100%;
186191
}
187192

188193
&-dot {
189-
left: 2px;
190-
margin-bottom: -4px;
191-
&:first-child {
192-
margin-bottom: -4px;
193-
}
194-
&:last-child {
195-
margin-bottom: -4px;
196-
}
194+
margin-left: -2px;
195+
// margin-bottom: -4px;
196+
// &:first-child {
197+
// margin-bottom: -4px;
198+
// }
199+
// &:last-child {
200+
// margin-bottom: -4px;
201+
// }
197202
}
198203
}
199204
}
200205

201206
.motion-common() {
202-
animation-duration: .3s;
203-
animation-fill-mode: both;
204207
display: block !important;
208+
animation-duration: 0.3s;
209+
animation-fill-mode: both;
205210
}
206211

207212
.make-motion(@className, @keyframeName) {
208-
.@{className}-enter, .@{className}-appear {
213+
.@{className}-enter,
214+
.@{className}-appear {
209215
.motion-common();
210216
animation-play-state: paused;
211217
}
212218
.@{className}-leave {
213219
.motion-common();
214220
animation-play-state: paused;
215221
}
216-
.@{className}-enter.@{className}-enter-active, .@{className}-appear.@{className}-appear-active {
217-
animation-name: ~"@{keyframeName}In";
222+
.@{className}-enter.@{className}-enter-active,
223+
.@{className}-appear.@{className}-appear-active {
224+
animation-name: ~'@{keyframeName}In';
218225
animation-play-state: running;
219226
}
220227
.@{className}-leave.@{className}-leave-active {
221-
animation-name: ~"@{keyframeName}Out";
228+
animation-name: ~'@{keyframeName}Out';
222229
animation-play-state: running;
223230
}
224231
}
225232
.zoom-motion(@className, @keyframeName) {
226233
.make-motion(@className, @keyframeName);
227-
.@{className}-enter, .@{className}-appear {
234+
.@{className}-enter,
235+
.@{className}-appear {
228236
transform: scale(0, 0); // need this by yiminghe
229237
animation-timing-function: @ease-out-quint;
230238
}
@@ -236,32 +244,32 @@
236244

237245
@keyframes rcSliderTooltipZoomDownIn {
238246
0% {
239-
opacity: 0;
240-
transform-origin: 50% 100%;
241247
transform: scale(0, 0);
248+
transform-origin: 50% 100%;
249+
opacity: 0;
242250
}
243251
100% {
244-
transform-origin: 50% 100%;
245252
transform: scale(1, 1);
253+
transform-origin: 50% 100%;
246254
}
247255
}
248256

249257
@keyframes rcSliderTooltipZoomDownOut {
250258
0% {
251-
transform-origin: 50% 100%;
252259
transform: scale(1, 1);
260+
transform-origin: 50% 100%;
253261
}
254262
100% {
255-
opacity: 0;
256-
transform-origin: 50% 100%;
257263
transform: scale(0, 0);
264+
transform-origin: 50% 100%;
265+
opacity: 0;
258266
}
259267
}
260268

261269
.@{prefixClass}-tooltip {
262270
position: absolute;
263-
left: -9999px;
264271
top: -9999px;
272+
left: -9999px;
265273
visibility: visible;
266274

267275
.borderBox();
@@ -275,12 +283,12 @@
275283
}
276284

277285
&-inner {
278-
padding: 6px 2px;
279286
min-width: 24px;
280287
height: 24px;
288+
padding: 6px 2px;
289+
color: @tooltip-color;
281290
font-size: 12px;
282291
line-height: 1;
283-
color: @tooltip-color;
284292
text-align: center;
285293
text-decoration: none;
286294
background-color: @tooltip-bg;

docs/demo/debug.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## debug
2+
3+
<code src="../examples/debug.tsx">

docs/demo/handle.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## handle
22

3-
<code src="../examples/handle.jsx">
3+
<code src="../examples/handle.tsx">

docs/demo/marks.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## marks
22

3-
<code src="../examples/marks.jsx">
3+
<code src="../examples/marks.tsx">

docs/demo/range.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## range
22

3-
<code src="../examples/range.jsx">
3+
<code src="../examples/range.tsx">

docs/demo/slider.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## slider
22

3-
<code src="../examples/slider.jsx">
3+
<code src="../examples/slider.tsx">

docs/demo/vertical.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
## vertical
22

3-
<code src="../examples/vertical.jsx">
3+
<code src="../examples/vertical.tsx">
+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import * as React from 'react';
2+
import 'rc-tooltip/assets/bootstrap.css';
3+
import Slider from 'rc-slider';
4+
import type { SliderProps } from 'rc-slider';
5+
import raf from 'rc-util/lib/raf';
6+
import Tooltip from 'rc-tooltip';
7+
8+
const HandleTooltip = (props: {
9+
value: number;
10+
children: React.ReactElement;
11+
visible: boolean;
12+
tipFormatter?: (value: number) => React.ReactNode;
13+
}) => {
14+
const { value, children, visible, tipFormatter = (val) => `${val} %`, ...restProps } = props;
15+
16+
const tooltipRef = React.useRef<any>();
17+
const rafRef = React.useRef<number | null>(null);
18+
19+
function cancelKeepAlign() {
20+
raf.cancel(rafRef.current!);
21+
}
22+
23+
function keepAlign() {
24+
rafRef.current = raf(() => {
25+
tooltipRef.current?.forcePopupAlign();
26+
});
27+
}
28+
29+
React.useEffect(() => {
30+
if (visible) {
31+
keepAlign();
32+
} else {
33+
cancelKeepAlign();
34+
}
35+
36+
return cancelKeepAlign;
37+
}, [value, visible]);
38+
39+
return (
40+
<Tooltip
41+
placement="top"
42+
overlay={tipFormatter(value)}
43+
overlayInnerStyle={{ minHeight: 'auto' }}
44+
ref={tooltipRef}
45+
visible={visible}
46+
{...restProps}
47+
>
48+
{children}
49+
</Tooltip>
50+
);
51+
};
52+
53+
export const handleRender: SliderProps['handleRender'] = (node, props) => {
54+
return (
55+
<HandleTooltip value={props.value} visible={props.dragging}>
56+
{node}
57+
</HandleTooltip>
58+
);
59+
};
60+
61+
const TooltipSlider = ({
62+
tipFormatter,
63+
tipProps,
64+
...props
65+
}: SliderProps & { tipFormatter?: (value: number) => React.ReactNode; tipProps: any }) => {
66+
const tipHandleRender: SliderProps['handleRender'] = (node, handleProps) => {
67+
return (
68+
<HandleTooltip
69+
value={handleProps.value}
70+
visible={handleProps.dragging}
71+
tipFormatter={tipFormatter}
72+
{...tipProps}
73+
>
74+
{node}
75+
</HandleTooltip>
76+
);
77+
};
78+
79+
return <Slider {...props} handleRender={tipHandleRender} />;
80+
};
81+
82+
export default TooltipSlider;

0 commit comments

Comments
 (0)