@react-native-ohos/slider 4.4.4-rc.1 → 5.0.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.
- package/CHANGELOG.md +181 -0
- package/COMMITTERS.md +6 -0
- package/LICENSE +9 -0
- package/OAT.xml +73 -0
- package/README.OpenSource +11 -0
- package/README.md +13 -0
- package/babel.config.json +1 -1
- package/dist/RNCSliderNativeComponent.js +1 -1
- package/dist/Slider.js +1 -1
- package/dist/components/StepNumber.js +1 -0
- package/dist/components/StepsIndicator.js +1 -0
- package/dist/components/TrackMark.js +1 -0
- package/dist/utils/constants.js +1 -0
- package/dist/utils/styles.js +1 -0
- package/example/.eslintrc +19 -0
- package/example/.node-version +6 -0
- package/example/.prettierrc.js +7 -0
- package/example/.watchmanconfig +6 -0
- package/example/app.json +4 -0
- package/example/babel.config.js +9 -0
- package/example/contexts.ts +9 -0
- package/example/harmony/AppScope/app.json5 +10 -0
- package/example/harmony/AppScope/resources/base/element/string.json +8 -0
- package/example/harmony/AppScope/resources/base/media/app_icon.png +0 -0
- package/example/harmony/build-profile.template.json5 +36 -0
- package/example/harmony/codelinter.json +32 -0
- package/example/harmony/entry/build-profile.json5 +22 -0
- package/example/harmony/entry/hvigorfile.ts +8 -0
- package/example/harmony/entry/oh-package.json5 +11 -0
- package/example/harmony/entry/src/main/cpp/CMakeLists.txt +41 -0
- package/example/harmony/entry/src/main/cpp/PackageProvider.cpp +17 -0
- package/example/harmony/entry/src/main/ets/RNPackagesFactory.ets +13 -0
- package/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf +0 -0
- package/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf +0 -0
- package/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets +27 -0
- package/example/harmony/entry/src/main/ets/pages/Index.ets +125 -0
- package/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets +135 -0
- package/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets +44 -0
- package/example/harmony/entry/src/main/module.json5 +52 -0
- package/example/harmony/entry/src/main/resources/base/element/color.json +8 -0
- package/example/harmony/entry/src/main/resources/base/element/string.json +16 -0
- package/example/harmony/entry/src/main/resources/base/media/icon.png +0 -0
- package/example/harmony/entry/src/main/resources/base/profile/main_pages.json +5 -0
- package/example/harmony/entry/src/main/resources/rawfile/1.txt +1 -0
- package/example/harmony/format.ps1 +18 -0
- package/example/harmony/hvigor/hvigor-config.json5 +21 -0
- package/example/harmony/hvigorfile.ts +9 -0
- package/example/harmony/oh-package.json5 +12 -0
- package/example/index.js +11 -0
- package/example/jest.config.js +11 -0
- package/example/metro.config.js +30 -0
- package/example/package.json +58 -0
- package/example/react-native.config.js +11 -0
- package/example/scripts/create-build-profile.js +46 -0
- package/example/src/index.tsx +22 -0
- package/example/tsconfig.json +20 -0
- package/harmony/slider/OAT.xml +42 -0
- package/harmony/slider/index.ets +1 -2
- package/harmony/slider/oh-package.json5 +2 -2
- package/harmony/slider/src/main/cpp/ComponentDescriptor.h +2 -4
- package/harmony/slider/src/main/cpp/EventEmitters.cpp +13 -13
- package/harmony/slider/src/main/cpp/EventEmitters.h +15 -9
- package/harmony/slider/src/main/cpp/Props.cpp +9 -5
- package/harmony/slider/src/main/cpp/Props.h +15 -10
- package/harmony/slider/src/main/cpp/ShadowNodes.cpp +1 -1
- package/harmony/slider/src/main/cpp/ShadowNodes.h +6 -6
- package/harmony/slider/src/main/cpp/SliderEventEmiRequestHandler.h +28 -31
- package/harmony/slider/src/main/cpp/SliderJSIBinder.h +8 -12
- package/harmony/slider/src/main/cpp/SliderNapiBinder.h +2 -6
- package/harmony/slider/src/main/cpp/SliderPackage.h +6 -12
- package/harmony/slider.har +0 -0
- package/package.json +38 -24
- package/react-native.config.js +11 -0
- package/src/RNCSliderNativeComponent.ts +13 -6
- package/src/Slider.tsx +133 -72
- package/src/components/StepNumber.tsx +23 -0
- package/src/components/StepsIndicator.tsx +89 -0
- package/src/components/TrackMark.tsx +56 -0
- package/src/index.ts +7 -1
- package/src/utils/constants.ts +17 -0
- package/src/utils/styles.ts +61 -0
- package/tsconfig.json +3 -2
- package/typings/index.d.ts +35 -1
- package/.eslintrc.json +0 -20
- package/.flowconfig +0 -66
- package/harmony/slider/src/main/ets/SliderPackage.ets +0 -34
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
|
-
#define SLIDERPACKAGE_H
|
|
24
|
+
|
|
26
25
|
#include "RNOH/Package.h"
|
|
27
26
|
#include "ComponentDescriptor.h"
|
|
28
27
|
#include "SliderJSIBinder.h"
|
|
@@ -35,25 +34,20 @@ class SliderPackage : public Package {
|
|
|
35
34
|
public:
|
|
36
35
|
SliderPackage(Package::Context ctx): Package(ctx) {}
|
|
37
36
|
|
|
38
|
-
std::vector<facebook::react::ComponentDescriptorProvider> createComponentDescriptorProviders() override
|
|
39
|
-
{
|
|
37
|
+
std::vector<facebook::react::ComponentDescriptorProvider> createComponentDescriptorProviders() override {
|
|
40
38
|
return {facebook::react::concreteComponentDescriptorProvider<facebook::react::RNCSliderComponentDescriptor>()};
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
ComponentNapiBinderByString createComponentNapiBinderByName() override
|
|
44
|
-
{
|
|
41
|
+
ComponentNapiBinderByString createComponentNapiBinderByName() override {
|
|
45
42
|
return {{"RNCSlider", std::make_shared<SliderNapiBinder>()}};
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
ComponentJSIBinderByString createComponentJSIBinderByName() override
|
|
49
|
-
{
|
|
45
|
+
ComponentJSIBinderByString createComponentJSIBinderByName() override {
|
|
50
46
|
return {{"RNCSlider", std::make_shared<SliderJSIBinder>()}};
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
EventEmitRequestHandlers createEventEmitRequestHandlers() override
|
|
54
|
-
{
|
|
49
|
+
EventEmitRequestHandlers createEventEmitRequestHandlers() override {
|
|
55
50
|
return {std::make_shared<SliderEventEmitRequestHandler>()};
|
|
56
51
|
}
|
|
57
52
|
};
|
|
58
|
-
} // namespace rnoh
|
|
59
|
-
#endif
|
|
53
|
+
} // namespace rnoh
|
package/harmony/slider.har
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-ohos/slider",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "react-native-community",
|
|
6
|
-
"homepage": "https://gitcode.com/openharmony-sig/rntpc_react-native-slider#readme",
|
|
6
|
+
"homepage": "https://gitcode.com/openharmony-sig/rntpc_react-native-slider/tree/br_rnoh0.77#readme",
|
|
7
7
|
"description": "React Native component used to select a single value from a range of values.",
|
|
8
8
|
"harmony": {
|
|
9
|
-
"alias": "@react-native-community/slider"
|
|
10
|
-
"autolinking": {
|
|
11
|
-
"etsPackageClassName":"SliderPackage",
|
|
12
|
-
"cppPackageClassName":"SliderPackage",
|
|
13
|
-
"cmakeLibraryTargetName": "rnoh_slider",
|
|
14
|
-
"ohPackageName": "@react-native-ohos/slider"
|
|
15
|
-
}
|
|
9
|
+
"alias": "@react-native-community/slider"
|
|
16
10
|
},
|
|
17
11
|
"publishConfig": {
|
|
18
|
-
"registry": "https://
|
|
19
|
-
"access": "public"
|
|
12
|
+
"registry": "https://npm.pkg.github.com"
|
|
20
13
|
},
|
|
21
14
|
"main": "dist/Slider.js",
|
|
22
15
|
"types": "typings/index.d.ts",
|
|
@@ -31,32 +24,40 @@
|
|
|
31
24
|
"test": "npx jest src"
|
|
32
25
|
},
|
|
33
26
|
"dependencies": {
|
|
34
|
-
"@react-native-community/slider": "
|
|
27
|
+
"@react-native-community/slider": "5.0.0"
|
|
35
28
|
},
|
|
36
29
|
"devDependencies": {
|
|
37
30
|
"@babel/cli": "^7.8.4",
|
|
38
|
-
"@babel/core": "^7.
|
|
31
|
+
"@babel/core": "^7.25.2",
|
|
39
32
|
"@babel/preset-flow": "^7.9.0",
|
|
40
33
|
"@babel/preset-typescript": "^7.18.6",
|
|
41
|
-
"@babel/runtime": "^7.
|
|
42
|
-
"@react-native-community/
|
|
34
|
+
"@babel/runtime": "^7.25.0",
|
|
35
|
+
"@react-native-community/cli": "15.0.1",
|
|
36
|
+
"@react-native-community/cli-platform-android": "15.0.1",
|
|
37
|
+
"@react-native-community/cli-platform-ios": "15.0.1",
|
|
38
|
+
"@react-native-community/eslint-config": "^3.2.0",
|
|
39
|
+
"@react-native/babel-preset": "0.76.3",
|
|
40
|
+
"@react-native/eslint-config": "0.76.3",
|
|
41
|
+
"@react-native/metro-config": "0.76.3",
|
|
42
|
+
"@react-native/typescript-config": "0.76.3",
|
|
43
43
|
"@types/jest": "^28.1.8",
|
|
44
|
-
"@types/react
|
|
44
|
+
"@types/react": "^18.2.6",
|
|
45
45
|
"@types/react-test-renderer": "^18.0.0",
|
|
46
|
-
"babel-jest": "^
|
|
46
|
+
"babel-jest": "^29.7.0",
|
|
47
47
|
"babel-plugin-module-resolver": "5.0.0",
|
|
48
48
|
"copyfiles": "^2.4.1",
|
|
49
|
-
"eslint": "^
|
|
49
|
+
"eslint": "^8.19.0",
|
|
50
|
+
"eslint-plugin-prettier": "4.2.1",
|
|
50
51
|
"eslint-plugin-react": "^7.30.1",
|
|
51
52
|
"eslint-plugin-react-native": "^4.0.0",
|
|
52
53
|
"flow-bin": "^0.163.0",
|
|
53
54
|
"jest": "^29.5.0",
|
|
54
|
-
"
|
|
55
|
-
"react": "^18.
|
|
56
|
-
"react-native": "^0.
|
|
57
|
-
"react-native-windows": "^0.
|
|
58
|
-
"react-test-renderer": "^18.
|
|
59
|
-
"typescript": "^
|
|
55
|
+
"prettier": "2.8.8",
|
|
56
|
+
"react": "^18.3.1",
|
|
57
|
+
"react-native": "^0.77.1",
|
|
58
|
+
"react-native-windows": "^0.76.2",
|
|
59
|
+
"react-test-renderer": "^18.3.1",
|
|
60
|
+
"typescript": "^5.0.4"
|
|
60
61
|
},
|
|
61
62
|
"repository": {
|
|
62
63
|
"type": "git",
|
|
@@ -74,5 +75,18 @@
|
|
|
74
75
|
"trailingComma": "all",
|
|
75
76
|
"bracketSpacing": false,
|
|
76
77
|
"jsxBracketSameLine": true
|
|
78
|
+
},
|
|
79
|
+
"codegenConfig": {
|
|
80
|
+
"name": "RNCSlider",
|
|
81
|
+
"type": "components",
|
|
82
|
+
"jsSrcsDir": "src",
|
|
83
|
+
"android": {
|
|
84
|
+
"javaPackageName": "com.reactnativecommunity.slider"
|
|
85
|
+
},
|
|
86
|
+
"ios": {
|
|
87
|
+
"componentProvider": {
|
|
88
|
+
"RNCSlider": "RNCSliderComponentView"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
77
91
|
}
|
|
78
92
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
import type {ColorValue, HostComponent, ViewProps} from 'react-native';
|
|
2
8
|
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
3
9
|
//@ts-ignore
|
|
@@ -7,6 +13,7 @@ import type {
|
|
|
7
13
|
WithDefault,
|
|
8
14
|
DirectEventHandler,
|
|
9
15
|
BubblingEventHandler,
|
|
16
|
+
Double,
|
|
10
17
|
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
11
18
|
|
|
12
19
|
type Event = Readonly<{
|
|
@@ -23,15 +30,15 @@ export interface NativeProps extends ViewProps {
|
|
|
23
30
|
tapToSeek?: WithDefault<boolean, false>;
|
|
24
31
|
maximumTrackImage?: ImageSource;
|
|
25
32
|
maximumTrackTintColor?: ColorValue;
|
|
26
|
-
maximumValue?:
|
|
33
|
+
maximumValue?: Double;
|
|
27
34
|
minimumTrackImage?: ImageSource;
|
|
28
35
|
minimumTrackTintColor?: ColorValue;
|
|
29
|
-
minimumValue?:
|
|
36
|
+
minimumValue?: Double;
|
|
30
37
|
onChange?: BubblingEventHandler<Event>;
|
|
31
38
|
onRNCSliderSlidingStart?: DirectEventHandler<Event>;
|
|
32
39
|
onRNCSliderSlidingComplete?: DirectEventHandler<Event>;
|
|
33
40
|
onRNCSliderValueChange?: BubblingEventHandler<Event>;
|
|
34
|
-
step?:
|
|
41
|
+
step?: Double;
|
|
35
42
|
testID?: string;
|
|
36
43
|
thumbImage?: ImageSource;
|
|
37
44
|
thumbTintColor?: ColorValue;
|
|
@@ -41,6 +48,6 @@ export interface NativeProps extends ViewProps {
|
|
|
41
48
|
upperLimit?: Float;
|
|
42
49
|
}
|
|
43
50
|
|
|
44
|
-
export default codegenNativeComponent<NativeProps>(
|
|
45
|
-
|
|
46
|
-
) as HostComponent<NativeProps>;
|
|
51
|
+
export default codegenNativeComponent<NativeProps>('RNCSlider', {
|
|
52
|
+
interfaceOnly: true,
|
|
53
|
+
}) as HostComponent<NativeProps>;
|
package/src/Slider.tsx
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, {useEffect, useState} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
Image,
|
|
4
10
|
Platform,
|
|
5
|
-
StyleSheet,
|
|
6
11
|
AccessibilityActionEvent,
|
|
7
12
|
ViewProps,
|
|
8
13
|
ViewStyle,
|
|
9
14
|
ColorValue,
|
|
10
15
|
NativeSyntheticEvent,
|
|
11
16
|
StyleProp,
|
|
17
|
+
View,
|
|
12
18
|
} from 'react-native';
|
|
13
19
|
import RCTSliderNativeComponent from './index';
|
|
14
20
|
//@ts-ignore
|
|
15
21
|
import type {ImageSource} from 'react-native/Libraries/Image/ImageSource';
|
|
16
22
|
|
|
17
|
-
import type {Ref} from 'react';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
import type {FC, Ref} from 'react';
|
|
24
|
+
import {MarkerProps} from './components/TrackMark';
|
|
25
|
+
import {StepsIndicator} from './components/StepsIndicator';
|
|
26
|
+
import {styles} from './utils/styles';
|
|
27
|
+
import {constants} from './utils/constants';
|
|
21
28
|
|
|
22
29
|
type Event = NativeSyntheticEvent<
|
|
23
30
|
Readonly<{
|
|
@@ -139,21 +146,21 @@ type Props = ViewProps &
|
|
|
139
146
|
/**
|
|
140
147
|
* Callback continuously called while the user is dragging the slider.
|
|
141
148
|
*/
|
|
142
|
-
onValueChange?: (
|
|
149
|
+
onValueChange?: (_value: number) => void;
|
|
143
150
|
|
|
144
151
|
/**
|
|
145
152
|
* Callback that is called when the user touches the slider,
|
|
146
153
|
* regardless if the value has changed. The current value is passed
|
|
147
154
|
* as an argument to the callback handler.
|
|
148
155
|
*/
|
|
149
|
-
onSlidingStart?: (
|
|
156
|
+
onSlidingStart?: (_value: number) => void;
|
|
150
157
|
|
|
151
158
|
/**
|
|
152
159
|
* Callback that is called when the user releases the slider,
|
|
153
160
|
* regardless if the value has changed. The current value is passed
|
|
154
161
|
* as an argument to the callback handler.
|
|
155
162
|
*/
|
|
156
|
-
onSlidingComplete?: (
|
|
163
|
+
onSlidingComplete?: (_value: number) => void;
|
|
157
164
|
|
|
158
165
|
/**
|
|
159
166
|
* Used to locate this view in UI automation tests.
|
|
@@ -171,6 +178,16 @@ type Props = ViewProps &
|
|
|
171
178
|
*/
|
|
172
179
|
inverted?: boolean;
|
|
173
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Component to be rendered for each step indicator.
|
|
183
|
+
*/
|
|
184
|
+
StepMarker?: FC<MarkerProps>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
*
|
|
188
|
+
*/
|
|
189
|
+
renderStepNumber?: boolean;
|
|
190
|
+
|
|
174
191
|
/**
|
|
175
192
|
* A string of one or more words to be announced by the screen reader.
|
|
176
193
|
* Otherwise, it will announce the value as a percentage.
|
|
@@ -189,24 +206,55 @@ type Props = ViewProps &
|
|
|
189
206
|
}>;
|
|
190
207
|
|
|
191
208
|
const SliderComponent = (
|
|
192
|
-
|
|
193
|
-
forwardedRef?: Ref<typeof RCTSliderNativeComponent>,
|
|
194
|
-
) => {
|
|
195
|
-
const style = StyleSheet.compose(props.style, styles.slider);
|
|
196
|
-
|
|
197
|
-
const {
|
|
209
|
+
{
|
|
198
210
|
onValueChange,
|
|
199
211
|
onSlidingStart,
|
|
200
212
|
onSlidingComplete,
|
|
201
213
|
onAccessibilityAction,
|
|
202
|
-
|
|
203
|
-
|
|
214
|
+
value = constants.SLIDER_DEFAULT_INITIAL_VALUE,
|
|
215
|
+
minimumValue = 0,
|
|
216
|
+
maximumValue = 1,
|
|
217
|
+
step = 0,
|
|
218
|
+
inverted = false,
|
|
219
|
+
tapToSeek = false,
|
|
220
|
+
lowerLimit = Platform.select({
|
|
221
|
+
web: minimumValue,
|
|
222
|
+
default: constants.LIMIT_MIN_VALUE,
|
|
223
|
+
}),
|
|
224
|
+
upperLimit = Platform.select({
|
|
225
|
+
web: maximumValue,
|
|
226
|
+
default: constants.LIMIT_MAX_VALUE,
|
|
227
|
+
}),
|
|
228
|
+
...props
|
|
229
|
+
}: Props,
|
|
230
|
+
forwardedRef?: Ref<typeof RCTSliderNativeComponent>,
|
|
231
|
+
) => {
|
|
232
|
+
const [currentValue, setCurrentValue] = useState(
|
|
233
|
+
value ?? minimumValue ?? constants.SLIDER_DEFAULT_INITIAL_VALUE,
|
|
234
|
+
);
|
|
235
|
+
const [width, setWidth] = useState(0);
|
|
204
236
|
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
237
|
+
const stepResolution = step ? step : constants.DEFAULT_STEP_RESOLUTION;
|
|
238
|
+
|
|
239
|
+
const defaultStep = (maximumValue - minimumValue) / stepResolution;
|
|
240
|
+
const stepLength = step || defaultStep;
|
|
241
|
+
|
|
242
|
+
const options = Array.from(
|
|
243
|
+
{
|
|
244
|
+
length: (step ? defaultStep : stepResolution) + 1,
|
|
245
|
+
},
|
|
246
|
+
(_, index) => minimumValue + index * stepLength,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const defaultStyle =
|
|
250
|
+
Platform.OS === 'ios' || Platform.OS === 'harmony' ? styles.defaultSlideriOS : styles.defaultSlider;
|
|
251
|
+
const sliderStyle = {zIndex: 1, width: width};
|
|
252
|
+
const style = [defaultStyle, props.style];
|
|
253
|
+
|
|
254
|
+
const onValueChangeEvent = (event: Event) => {
|
|
255
|
+
onValueChange && onValueChange(event.nativeEvent.value);
|
|
256
|
+
setCurrentValue(event.nativeEvent.value);
|
|
257
|
+
};
|
|
210
258
|
|
|
211
259
|
const _disabled =
|
|
212
260
|
typeof props.disabled === 'boolean'
|
|
@@ -234,62 +282,75 @@ const SliderComponent = (
|
|
|
234
282
|
}
|
|
235
283
|
: null;
|
|
236
284
|
|
|
237
|
-
const value
|
|
238
|
-
Number.isNaN(props.value) || !props.value ? undefined : props.value;
|
|
285
|
+
const passedValue = Number.isNaN(value) || !value ? undefined : value;
|
|
239
286
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
? localProps.upperLimit
|
|
248
|
-
: LIMIT_MAX_VALUE;
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
if (lowerLimit >= upperLimit) {
|
|
289
|
+
console.warn(
|
|
290
|
+
'Invalid configuration: lower limit is supposed to be smaller than upper limit',
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}, [lowerLimit, upperLimit]);
|
|
249
294
|
|
|
250
295
|
return (
|
|
251
|
-
<
|
|
252
|
-
{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
296
|
+
<View
|
|
297
|
+
onLayout={(event) => {
|
|
298
|
+
setWidth(event.nativeEvent.layout.width);
|
|
299
|
+
}}
|
|
300
|
+
style={[style, {justifyContent: 'center'}]}>
|
|
301
|
+
{props.StepMarker || !!props.renderStepNumber ? (
|
|
302
|
+
<StepsIndicator
|
|
303
|
+
options={options}
|
|
304
|
+
sliderWidth={width}
|
|
305
|
+
currentValue={currentValue}
|
|
306
|
+
renderStepNumber={props.renderStepNumber}
|
|
307
|
+
thumbImage={props.thumbImage}
|
|
308
|
+
StepMarker={props.StepMarker}
|
|
309
|
+
isLTR={inverted}
|
|
310
|
+
/>
|
|
311
|
+
) : null}
|
|
312
|
+
<RCTSliderNativeComponent
|
|
313
|
+
{...props}
|
|
314
|
+
minimumValue={minimumValue}
|
|
315
|
+
maximumValue={maximumValue}
|
|
316
|
+
step={step}
|
|
317
|
+
inverted={inverted}
|
|
318
|
+
tapToSeek={tapToSeek}
|
|
319
|
+
value={passedValue}
|
|
320
|
+
lowerLimit={lowerLimit}
|
|
321
|
+
upperLimit={upperLimit}
|
|
322
|
+
accessibilityState={_accessibilityState}
|
|
323
|
+
thumbImage={
|
|
324
|
+
Platform.OS === 'web'
|
|
325
|
+
? props.thumbImage
|
|
326
|
+
: props.StepMarker
|
|
327
|
+
? undefined
|
|
328
|
+
: Image.resolveAssetSource(props.thumbImage)
|
|
329
|
+
}
|
|
330
|
+
ref={forwardedRef}
|
|
331
|
+
style={[
|
|
332
|
+
sliderStyle,
|
|
333
|
+
defaultStyle,
|
|
334
|
+
{alignContent: 'center', alignItems: 'center'},
|
|
335
|
+
]}
|
|
336
|
+
onChange={onValueChangeEvent}
|
|
337
|
+
onRNCSliderSlidingStart={onSlidingStartEvent}
|
|
338
|
+
onRNCSliderSlidingComplete={onSlidingCompleteEvent}
|
|
339
|
+
onRNCSliderValueChange={onValueChangeEvent}
|
|
340
|
+
disabled={_disabled}
|
|
341
|
+
onStartShouldSetResponder={() => true}
|
|
342
|
+
onResponderTerminationRequest={() => false}
|
|
343
|
+
onRNCSliderAccessibilityAction={onAccessibilityActionEvent}
|
|
344
|
+
thumbTintColor={
|
|
345
|
+
props.thumbImage && !!props.StepMarker
|
|
346
|
+
? 'transparent'
|
|
347
|
+
: props.thumbTintColor
|
|
348
|
+
}
|
|
349
|
+
/>
|
|
350
|
+
</View>
|
|
275
351
|
);
|
|
276
352
|
};
|
|
277
353
|
|
|
278
354
|
const SliderWithRef = React.forwardRef(SliderComponent);
|
|
279
355
|
|
|
280
|
-
SliderWithRef.defaultProps = {
|
|
281
|
-
value: 0,
|
|
282
|
-
minimumValue: 0,
|
|
283
|
-
maximumValue: 1,
|
|
284
|
-
step: 0,
|
|
285
|
-
inverted: false,
|
|
286
|
-
tapToSeek: false,
|
|
287
|
-
lowerLimit: LIMIT_MIN_VALUE,
|
|
288
|
-
upperLimit: LIMIT_MAX_VALUE,
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
let styles = StyleSheet.create(
|
|
292
|
-
Platform.OS === 'ios' || Platform.OS === 'harmony' ? {slider: {height: 40}} : {slider: {}},
|
|
293
|
-
);
|
|
294
|
-
|
|
295
356
|
export default SliderWithRef;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import {StyleProp, Text, TextStyle, View} from 'react-native';
|
|
9
|
+
import {styles} from '../utils/styles';
|
|
10
|
+
|
|
11
|
+
export const StepNumber = ({
|
|
12
|
+
i,
|
|
13
|
+
style,
|
|
14
|
+
}: {
|
|
15
|
+
i: number;
|
|
16
|
+
style: StyleProp<TextStyle>;
|
|
17
|
+
}) => {
|
|
18
|
+
return (
|
|
19
|
+
<View style={styles.stepNumber}>
|
|
20
|
+
<Text style={style}>{i}</Text>
|
|
21
|
+
</View>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, {FC, Fragment, useCallback, useMemo} from 'react';
|
|
8
|
+
import {View} from 'react-native';
|
|
9
|
+
import {StepNumber} from './StepNumber';
|
|
10
|
+
import {MarkerProps, SliderTrackMark} from './TrackMark';
|
|
11
|
+
//@ts-ignore
|
|
12
|
+
import type {ImageSource} from 'react-native/Libraries/Image/ImageSource';
|
|
13
|
+
import {styles} from '../utils/styles';
|
|
14
|
+
import {constants} from '../utils/constants';
|
|
15
|
+
|
|
16
|
+
export const StepsIndicator = ({
|
|
17
|
+
options,
|
|
18
|
+
sliderWidth,
|
|
19
|
+
currentValue,
|
|
20
|
+
StepMarker,
|
|
21
|
+
renderStepNumber,
|
|
22
|
+
thumbImage,
|
|
23
|
+
isLTR,
|
|
24
|
+
}: {
|
|
25
|
+
options: number[];
|
|
26
|
+
sliderWidth: number;
|
|
27
|
+
currentValue: number;
|
|
28
|
+
StepMarker?: FC<MarkerProps>;
|
|
29
|
+
renderStepNumber?: boolean;
|
|
30
|
+
thumbImage?: ImageSource;
|
|
31
|
+
isLTR?: boolean;
|
|
32
|
+
}) => {
|
|
33
|
+
const stepNumberFontStyle = useMemo(() => {
|
|
34
|
+
return {
|
|
35
|
+
fontSize:
|
|
36
|
+
options.length > 9
|
|
37
|
+
? constants.STEP_NUMBER_TEXT_FONT_SMALL
|
|
38
|
+
: constants.STEP_NUMBER_TEXT_FONT_BIG,
|
|
39
|
+
};
|
|
40
|
+
}, [options.length]);
|
|
41
|
+
const values = isLTR ? options.reverse() : options;
|
|
42
|
+
|
|
43
|
+
const renderStepIndicator = useCallback(
|
|
44
|
+
(i: number, index: number) => {
|
|
45
|
+
return (
|
|
46
|
+
<Fragment key={index}>
|
|
47
|
+
<View style={styles.stepIndicatorElement} key={`${index}-View`}>
|
|
48
|
+
<SliderTrackMark
|
|
49
|
+
key={`${index}-SliderTrackMark`}
|
|
50
|
+
isTrue={currentValue === i}
|
|
51
|
+
index={i}
|
|
52
|
+
thumbImage={thumbImage}
|
|
53
|
+
StepMarker={StepMarker}
|
|
54
|
+
currentValue={currentValue}
|
|
55
|
+
min={options[0]}
|
|
56
|
+
max={options[options.length - 1]}
|
|
57
|
+
/>
|
|
58
|
+
{renderStepNumber ? (
|
|
59
|
+
<StepNumber
|
|
60
|
+
i={i}
|
|
61
|
+
style={stepNumberFontStyle}
|
|
62
|
+
key={`${index}th-step`}
|
|
63
|
+
/>
|
|
64
|
+
) : null}
|
|
65
|
+
</View>
|
|
66
|
+
</Fragment>
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
[
|
|
70
|
+
currentValue,
|
|
71
|
+
StepMarker,
|
|
72
|
+
options,
|
|
73
|
+
thumbImage,
|
|
74
|
+
renderStepNumber,
|
|
75
|
+
stepNumberFontStyle,
|
|
76
|
+
],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<View
|
|
81
|
+
pointerEvents="none"
|
|
82
|
+
style={[
|
|
83
|
+
styles.stepsIndicator,
|
|
84
|
+
{marginHorizontal: sliderWidth * constants.MARGIN_HORIZONTAL_PADDING},
|
|
85
|
+
]}>
|
|
86
|
+
{values.map((i, index) => renderStepIndicator(i, index))}
|
|
87
|
+
</View>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, {FC} from 'react';
|
|
8
|
+
import {Image, ImageURISource, View} from 'react-native';
|
|
9
|
+
import {styles} from '../utils/styles';
|
|
10
|
+
|
|
11
|
+
export type MarkerProps = {
|
|
12
|
+
stepMarked: boolean;
|
|
13
|
+
currentValue: number;
|
|
14
|
+
index: number;
|
|
15
|
+
min: number;
|
|
16
|
+
max: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type TrackMarksProps = {
|
|
20
|
+
isTrue: boolean;
|
|
21
|
+
index: number;
|
|
22
|
+
thumbImage?: ImageURISource;
|
|
23
|
+
StepMarker?: FC<MarkerProps>;
|
|
24
|
+
currentValue: number;
|
|
25
|
+
min: number;
|
|
26
|
+
max: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const SliderTrackMark = ({
|
|
30
|
+
isTrue,
|
|
31
|
+
index,
|
|
32
|
+
thumbImage,
|
|
33
|
+
StepMarker,
|
|
34
|
+
currentValue,
|
|
35
|
+
min,
|
|
36
|
+
max,
|
|
37
|
+
}: TrackMarksProps) => {
|
|
38
|
+
return (
|
|
39
|
+
<View style={styles.trackMarkContainer}>
|
|
40
|
+
{StepMarker ? (
|
|
41
|
+
<StepMarker
|
|
42
|
+
stepMarked={isTrue}
|
|
43
|
+
index={index}
|
|
44
|
+
currentValue={currentValue}
|
|
45
|
+
min={min}
|
|
46
|
+
max={max}
|
|
47
|
+
/>
|
|
48
|
+
) : null}
|
|
49
|
+
{thumbImage && isTrue ? (
|
|
50
|
+
<View style={styles.thumbImageContainer}>
|
|
51
|
+
<Image source={thumbImage} style={styles.thumbImage} />
|
|
52
|
+
</View>
|
|
53
|
+
) : null}
|
|
54
|
+
</View>
|
|
55
|
+
);
|
|
56
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const RNCSlider = require('./RNCSliderNativeComponent').default;
|
|
2
8
|
|
|
3
|
-
export default RNCSlider;
|
|
9
|
+
export default RNCSlider;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved
|
|
3
|
+
* Use of this source code is governed by a MIT license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {Platform} from 'react-native';
|
|
8
|
+
|
|
9
|
+
export const constants = {
|
|
10
|
+
SLIDER_DEFAULT_INITIAL_VALUE: 0,
|
|
11
|
+
MARGIN_HORIZONTAL_PADDING: 0.05,
|
|
12
|
+
STEP_NUMBER_TEXT_FONT_SMALL: 8,
|
|
13
|
+
STEP_NUMBER_TEXT_FONT_BIG: 12,
|
|
14
|
+
LIMIT_MIN_VALUE: Number.MIN_SAFE_INTEGER,
|
|
15
|
+
LIMIT_MAX_VALUE: Number.MAX_SAFE_INTEGER,
|
|
16
|
+
DEFAULT_STEP_RESOLUTION: Platform.OS === 'android' ? 128 : 1000,
|
|
17
|
+
};
|