@ledvance/base 1.3.65 → 1.3.67

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.
@@ -1,468 +0,0 @@
1
- import React from 'react';
2
- import {
3
- View,
4
- StyleSheet,
5
- PanResponder,
6
- PanResponderInstance,
7
- LayoutChangeEvent,
8
- Animated,
9
- GestureResponderEvent,
10
- PanResponderGestureState,
11
- ViewStyle,
12
- Easing,
13
- StyleProp,
14
- TextStyle,
15
- } from 'react-native';
16
- import { IconFont, TYText } from 'tuya-panel-kit';
17
- import icons from './brightness-icons';
18
-
19
- interface IPercentProps {
20
- percent: number;
21
- colorOver?: string;
22
- colorInner?: string;
23
- width?: number | string;
24
- height?: number | string;
25
- brightWidth: number;
26
- /**
27
- * 图标尺寸
28
- */
29
- iconSize?: number;
30
- /**
31
- * 百分比文字样式
32
- */
33
- percentStyle?: StyleProp<TextStyle>;
34
- }
35
-
36
- export class Percent extends React.Component<IPercentProps, IPercentProps> {
37
- constructor(props: IPercentProps) {
38
- super(props);
39
- this.state = { ...this.props };
40
- }
41
-
42
- // eslint-disable-next-line react/no-deprecated
43
- componentWillReceiveProps(nextProps: IPercentProps) {
44
- this.setState({ ...nextProps });
45
- }
46
-
47
- setNativeProps(nextProps: IPercentProps) {
48
- this.setState({ ...nextProps });
49
- }
50
-
51
- render() {
52
- const {
53
- percent,
54
- height,
55
- width,
56
- brightWidth,
57
- colorOver,
58
- colorInner,
59
- iconSize,
60
- percentStyle,
61
- } = this.state;
62
- let icon = icons.brightLevel1;
63
- if (percent > 20 && percent <= 60) {
64
- icon = icons.brightLevel2;
65
- } else if (percent > 60) {
66
- icon = icons.brightLevel3;
67
- }
68
- const percentText = `${percent}%`;
69
- return (
70
- <View style={[styles.percent, { height, width }]}>
71
- <View style={{ flex: 1, alignItems: 'center', flexDirection: 'row' }}>
72
- <IconFont d={icon} size={iconSize || 32} color={colorOver} style={styles.percentIcon} />
73
- <TYText style={[styles.percentText, percentStyle, { color: colorOver }]}>
74
- {percentText}
75
- </TYText>
76
- </View>
77
- <View
78
- style={{
79
- position: 'absolute',
80
- overflow: 'hidden',
81
- opacity: 1,
82
- height: '100%',
83
- width: brightWidth,
84
- alignItems: 'center',
85
- flexDirection: 'row',
86
- backgroundColor: colorOver,
87
- }}
88
- >
89
- <IconFont style={styles.percentIcon} d={icon} size={iconSize || 32} color={colorInner} />
90
- <TYText style={[styles.percentText, percentStyle, { color: colorInner }]}>
91
- {percentText}
92
- </TYText>
93
- </View>
94
- </View>
95
- );
96
- }
97
- }
98
- const defaultProps = {
99
- value: 0,
100
- min: 10,
101
- max: 1000,
102
- minPercent: 1,
103
- disabled: false,
104
- fontColor: '#000',
105
- trackColor: '#313131',
106
- activeColor: '#fff',
107
- // formatPercent: null,
108
- invalidSwipeDistance: 7,
109
- clickEnabled: false, // 是否可以点击选择
110
- onGrant(_v: number) {},
111
- onMove(_v: number) {},
112
- onRelease(_v: number) {},
113
- onPress(_v: number) {},
114
- showAnimation: true, // 使用动画显示
115
- /**
116
- * 背景透明度动画值
117
- */
118
- opacityAnimationValue: 1,
119
- /**
120
- * 背景透明度动画时间
121
- */
122
- opacityAnimationDuration: 150,
123
- };
124
-
125
- export interface IBrightOption {
126
- /**
127
- * 最小值
128
- */
129
- min?: number;
130
- /**
131
- * 最大值
132
- */
133
- max?: number;
134
- /**
135
- * 最小百分比
136
- */
137
- minPercent?: number;
138
- /**
139
- * 字体颜色
140
- */
141
- fontColor?: string;
142
- /**
143
- * 轨道背景色
144
- */
145
- trackColor?: string;
146
- /**
147
- * 激活区颜色
148
- */
149
- activeColor?: string;
150
- /**
151
- * 滑动生效的开始距离
152
- * 默认为 7 个像素距离
153
- */
154
- invalidSwipeDistance?: number;
155
- formatPercent?: (value: number) => number;
156
- style?: StyleProp<ViewStyle>;
157
- /**
158
- * 图标大小
159
- */
160
- iconSize?: number;
161
- /**
162
- * 百分比样式
163
- */
164
- percentStyle?: StyleProp<TextStyle>;
165
- }
166
-
167
- type DefaultProps = Readonly<typeof defaultProps>;
168
-
169
- type IProps = {
170
- style?: ViewStyle | ViewStyle[];
171
- formatPercent?: (value: number) => number;
172
- iconSize?: number;
173
- percentStyle?: StyleProp<TextStyle>;
174
- } & DefaultProps;
175
-
176
- interface IState {
177
- value: number;
178
- }
179
-
180
- export default class Slider extends React.Component<IProps, IState> {
181
- static defaultProps: DefaultProps = defaultProps;
182
-
183
- constructor(props: IProps) {
184
- super(props);
185
- this.bgOpacityAnim = new Animated.Value(this.props.opacityAnimationValue);
186
- this._panResponder = PanResponder.create({
187
- // 要求成为响应者:
188
- onStartShouldSetPanResponder: this.handleStartPanResponder,
189
- onMoveShouldSetPanResponder: this.handleSetPanResponder,
190
- onPanResponderTerminationRequest: () => !this.moving,
191
- onPanResponderMove: this.onMove,
192
- onPanResponderRelease: this.onRelease,
193
- // 当前有其他的东西成为响应器并且没有释放它。
194
- onPanResponderReject: this.handleTerminate,
195
- onPanResponderTerminate: this.handleTerminate,
196
- });
197
-
198
- this.state = { value: this.props.value };
199
- }
200
-
201
- // eslint-disable-next-line react/no-deprecated
202
- componentWillReceiveProps(nextProps: IProps) {
203
- if (!this.locked) {
204
- this.brightWidth = this.valueToWidth(nextProps.value);
205
- if (nextProps.value !== this.props.value) {
206
- this.setAnimationValue(this.brightWidth);
207
- this.setState({ value: nextProps.value });
208
- }
209
- }
210
- if (this.props.opacityAnimationValue !== nextProps.opacityAnimationValue) {
211
- Animated.timing(this.bgOpacityAnim, {
212
- toValue: nextProps.opacityAnimationValue,
213
- duration: nextProps.opacityAnimationDuration,
214
- useNativeDriver: true,
215
- }).start();
216
- }
217
- }
218
-
219
- shouldComponentUpdate() {
220
- return !this.locked;
221
- }
222
-
223
- onMove = (_e: GestureResponderEvent, gesture: PanResponderGestureState) => {
224
- if (!this.moving) {
225
- // 滑动一定象素后,将不允许其他手势抢权
226
- if (Math.abs(gesture.dx) < this.props.invalidSwipeDistance) {
227
- // 小于一定象素不做滑动
228
- return;
229
- }
230
- // 开始手势
231
- this.props.onGrant(this.state.value);
232
- this.moving = true;
233
- this.locked = true;
234
- }
235
- this.handleMove(gesture, this.props.onMove, false);
236
- };
237
-
238
- onRelease = (e: GestureResponderEvent, gesture: PanResponderGestureState) => {
239
- this.isTouchStart = false;
240
- if (this.moving) {
241
- this.moving = false;
242
- this.locked = false;
243
- this.handleMove(gesture, this.props.onRelease, true);
244
- } else if (this.props.clickEnabled) {
245
- const now = +new Date();
246
- if (Math.abs(gesture.dx) < 4 && Math.abs(gesture.dy) < 4 && now - this.grantTime < 300) {
247
- const { locationX } = e.nativeEvent;
248
- this.handleMove(
249
- { dx: locationX - this.brightWidth } as PanResponderGestureState,
250
- this.props.onPress,
251
- true
252
- );
253
- }
254
- }
255
- };
256
-
257
- setAnimationValue(value: number, isSliding = false) {
258
- if (!isSliding && this.props.showAnimation) {
259
- if (value !== this.brightWidth) {
260
- this.brightAnimate.stopAnimation();
261
- const duration = isSliding
262
- ? 32
263
- : Math.round((300 * Math.abs(value - this.brightWidth)) / this.sliderWidth);
264
- Animated.timing(this.brightAnimate, {
265
- toValue: value,
266
- duration,
267
- easing: Easing.linear,
268
- useNativeDriver: false
269
- }).start();
270
- }
271
- } else {
272
- this.brightAnimate.setValue(value);
273
- }
274
- }
275
-
276
- private _panResponder: PanResponderInstance;
277
- private percentRef: Percent;
278
- private locked = false;
279
- private sliderWidth = 0;
280
- private brightWidth = 0;
281
- private brightAnimate: Animated.Value = new Animated.Value(0);
282
- private showPercent = false;
283
- private moving = false;
284
- private grantTime = 0;
285
- // @ts-ignore
286
- private isTouchStart = false;
287
- private bgOpacityAnim: Animated.Value = new Animated.Value(1);
288
-
289
- handleStartPanResponder = () => {
290
- if (this.props.disabled) {
291
- return false;
292
- }
293
- this.grantTime = +new Date();
294
- return this.props.clickEnabled;
295
- };
296
-
297
- handleSetPanResponder = (_e: GestureResponderEvent, gesture: PanResponderGestureState) => {
298
- if (this.props.disabled) {
299
- return false;
300
- }
301
- // 滑动一定象素后,将不允许其他手势抢权
302
- if (Math.abs(gesture.dx) >= this.props.invalidSwipeDistance) {
303
- // 小于一定象素不做滑动
304
- if (!this.moving) {
305
- this.props.onGrant(this.state.value);
306
- this.moving = true;
307
- this.locked = true;
308
- }
309
- return true;
310
- }
311
- if (this.moving) {
312
- return true;
313
- }
314
- return false;
315
- };
316
-
317
- handleMove(gesture: PanResponderGestureState, callback: (value: number) => void, isEnd = false) {
318
- const { dx } = gesture;
319
- let width: number = this.brightWidth + dx;
320
- // 边界处理
321
- if (width < 0) {
322
- width = 0;
323
- } else if (width > this.sliderWidth) {
324
- width = this.sliderWidth;
325
- }
326
-
327
- const value = this.coorToValue(width);
328
- width = this.valueToWidth(value);
329
- this.setAnimationValue(width, !isEnd);
330
-
331
- this.percentRef &&
332
- this.percentRef.setNativeProps({ percent: this.formatPercent(value), brightWidth: width });
333
-
334
- if (isEnd) {
335
- this.brightWidth = width;
336
- this.setState({ value });
337
- }
338
- callback(value);
339
- }
340
-
341
- handleTerminate = () => {
342
- // 响应器已经从该视图抽离
343
- this.moving = false;
344
- this.locked = false;
345
- this.isTouchStart = false;
346
- };
347
-
348
- handleLayout = (e: LayoutChangeEvent) => {
349
- const { width } = e.nativeEvent.layout;
350
- this.sliderWidth = width;
351
- this.brightWidth = this.valueToWidth(this.state.value);
352
- this.brightAnimate.setValue(this.brightWidth);
353
- this.showPercent = true;
354
- this.forceUpdate();
355
- };
356
-
357
- formatPercent(value: number) {
358
- const { min, max, formatPercent, minPercent } = this.props;
359
- if (formatPercent) {
360
- return formatPercent(value);
361
- }
362
- return Math.round(((value - min) * (100 - minPercent)) / (max - min) + minPercent);
363
- }
364
-
365
- valueToWidth(value: number) {
366
- const { min, max } = this.props;
367
- const percent = (value - min) / (max - min);
368
- return percent * this.sliderWidth;
369
- }
370
-
371
- coorToValue(x: number) {
372
- const { min, max } = this.props;
373
- return Math.round((x / this.sliderWidth) * (max - min) + min);
374
- }
375
-
376
- render() {
377
- const { trackColor, activeColor, fontColor, style, iconSize, percentStyle } = this.props;
378
- const containerStyle = [styles.container, style];
379
- const { height = 44 } = StyleSheet.flatten(containerStyle);
380
- return (
381
- <View
382
- style={containerStyle}
383
- accessibilityLabel="ReactColorPicker_Slider"
384
- onLayout={this.handleLayout}
385
- pointerEvents="box-only"
386
- {...this._panResponder.panHandlers}
387
- >
388
- <Animated.View
389
- style={{
390
- height: '100%',
391
- width: '100%',
392
- opacity: this.bgOpacityAnim,
393
- }}
394
- >
395
- <View
396
- style={[
397
- styles.track,
398
- {
399
- backgroundColor: trackColor,
400
- },
401
- ]}
402
- />
403
- <Animated.View
404
- style={[
405
- styles.mark,
406
- {
407
- backgroundColor: activeColor,
408
- width: this.brightAnimate,
409
- },
410
- ]}
411
- />
412
- {this.showPercent && (
413
- <Percent
414
- ref={(ref: Percent) => {
415
- this.percentRef = ref;
416
- }}
417
- percent={this.formatPercent(this.state.value)}
418
- colorOver={activeColor}
419
- colorInner={fontColor}
420
- width={this.sliderWidth}
421
- height={height}
422
- brightWidth={this.brightWidth}
423
- iconSize={iconSize}
424
- percentStyle={percentStyle}
425
- />
426
- )}
427
- </Animated.View>
428
- </View>
429
- );
430
- }
431
- }
432
-
433
- const styles = StyleSheet.create({
434
- container: {
435
- alignItems: 'center',
436
- flexDirection: 'row',
437
- height: 44,
438
- justifyContent: 'center',
439
- marginTop: 2,
440
- width: '100%',
441
- },
442
- mark: {
443
- backgroundColor: '#fff',
444
- height: '100%',
445
- left: 0,
446
- position: 'absolute',
447
- },
448
- percent: {
449
- alignItems: 'center',
450
- flexDirection: 'row',
451
- height: '100%',
452
- justifyContent: 'flex-start',
453
- left: 0,
454
- position: 'absolute',
455
- },
456
- percentIcon: {
457
- marginLeft: 16,
458
- },
459
- percentText: {
460
- marginLeft: 9,
461
- width: 50,
462
- },
463
- track: {
464
- backgroundColor: '#313131',
465
- height: '100%',
466
- width: '100%',
467
- },
468
- });
@@ -1,78 +0,0 @@
1
- import React, { Component } from 'react';
2
- import { View, Image, StyleSheet, Animated, NativeComponent } from 'react-native';
3
-
4
- interface IProps {
5
- img?: any;
6
- color: string;
7
- size?: number;
8
- x: number;
9
- y: number;
10
- disabled?: boolean;
11
- }
12
-
13
- export default class Thumb extends Component<IProps> {
14
- componentWillReceiveProps(nextProps: IProps) {
15
- this.animateX.setValue(nextProps.x);
16
- this.animateY.setValue(nextProps.y);
17
- }
18
-
19
- setNativeProps(props: IProps) {
20
- const { x, y, color } = props;
21
- if (typeof x === 'number') {
22
- this.animateX.setValue(x);
23
- }
24
- if (typeof y === 'number') {
25
- this.animateY.setValue(y);
26
- }
27
- if (typeof color === 'string') {
28
- this.previewRef.setNativeProps({
29
- style: {
30
- backgroundColor: color,
31
- },
32
- });
33
- }
34
- }
35
-
36
- private animateX = new Animated.Value(this.props.x);
37
- private animateY = new Animated.Value(this.props.y);
38
- private previewRef: NativeComponent;
39
-
40
- render() {
41
- const { color, size, img } = this.props;
42
- const maskWidth = (size / 38) * 62;
43
- const halfWidth = maskWidth / 2;
44
- return (
45
- <Animated.View
46
- style={[
47
- styles.thumb,
48
- {
49
- top: -halfWidth,
50
- left: -halfWidth,
51
- width: maskWidth,
52
- height: maskWidth,
53
- transform: [{ translateX: this.animateX }, { translateY: this.animateY }],
54
- },
55
- ]}
56
- >
57
- <View
58
- ref={(ref: NativeComponent) => {
59
- this.previewRef = ref;
60
- }}
61
- style={{ borderRadius: size / 2, width: size, height: size, backgroundColor: color }}
62
- />
63
- <Image
64
- source={img}
65
- style={[StyleSheet.absoluteFill, { width: maskWidth, height: maskWidth }]}
66
- />
67
- </Animated.View>
68
- );
69
- }
70
- }
71
-
72
- const styles = StyleSheet.create({
73
- thumb: {
74
- alignItems: 'center',
75
- justifyContent: 'center',
76
- position: 'absolute',
77
- },
78
- });