@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.
Files changed (86) hide show
  1. package/CHANGELOG.md +181 -0
  2. package/COMMITTERS.md +6 -0
  3. package/LICENSE +9 -0
  4. package/OAT.xml +73 -0
  5. package/README.OpenSource +11 -0
  6. package/README.md +13 -0
  7. package/babel.config.json +1 -1
  8. package/dist/RNCSliderNativeComponent.js +1 -1
  9. package/dist/Slider.js +1 -1
  10. package/dist/components/StepNumber.js +1 -0
  11. package/dist/components/StepsIndicator.js +1 -0
  12. package/dist/components/TrackMark.js +1 -0
  13. package/dist/utils/constants.js +1 -0
  14. package/dist/utils/styles.js +1 -0
  15. package/example/.eslintrc +19 -0
  16. package/example/.node-version +6 -0
  17. package/example/.prettierrc.js +7 -0
  18. package/example/.watchmanconfig +6 -0
  19. package/example/app.json +4 -0
  20. package/example/babel.config.js +9 -0
  21. package/example/contexts.ts +9 -0
  22. package/example/harmony/AppScope/app.json5 +10 -0
  23. package/example/harmony/AppScope/resources/base/element/string.json +8 -0
  24. package/example/harmony/AppScope/resources/base/media/app_icon.png +0 -0
  25. package/example/harmony/build-profile.template.json5 +36 -0
  26. package/example/harmony/codelinter.json +32 -0
  27. package/example/harmony/entry/build-profile.json5 +22 -0
  28. package/example/harmony/entry/hvigorfile.ts +8 -0
  29. package/example/harmony/entry/oh-package.json5 +11 -0
  30. package/example/harmony/entry/src/main/cpp/CMakeLists.txt +41 -0
  31. package/example/harmony/entry/src/main/cpp/PackageProvider.cpp +17 -0
  32. package/example/harmony/entry/src/main/ets/RNPackagesFactory.ets +13 -0
  33. package/example/harmony/entry/src/main/ets/assets/fonts/Pacifico-Regular.ttf +0 -0
  34. package/example/harmony/entry/src/main/ets/assets/fonts/StintUltraCondensed-Regular.ttf +0 -0
  35. package/example/harmony/entry/src/main/ets/entryability/EntryAbility.ets +27 -0
  36. package/example/harmony/entry/src/main/ets/pages/Index.ets +125 -0
  37. package/example/harmony/entry/src/main/ets/pages/SurfaceDeadlockTest.ets +135 -0
  38. package/example/harmony/entry/src/main/ets/pages/TouchDisplayer.ets +44 -0
  39. package/example/harmony/entry/src/main/module.json5 +52 -0
  40. package/example/harmony/entry/src/main/resources/base/element/color.json +8 -0
  41. package/example/harmony/entry/src/main/resources/base/element/string.json +16 -0
  42. package/example/harmony/entry/src/main/resources/base/media/icon.png +0 -0
  43. package/example/harmony/entry/src/main/resources/base/profile/main_pages.json +5 -0
  44. package/example/harmony/entry/src/main/resources/rawfile/1.txt +1 -0
  45. package/example/harmony/format.ps1 +18 -0
  46. package/example/harmony/hvigor/hvigor-config.json5 +21 -0
  47. package/example/harmony/hvigorfile.ts +9 -0
  48. package/example/harmony/oh-package.json5 +12 -0
  49. package/example/index.js +11 -0
  50. package/example/jest.config.js +11 -0
  51. package/example/metro.config.js +30 -0
  52. package/example/package.json +58 -0
  53. package/example/react-native.config.js +11 -0
  54. package/example/scripts/create-build-profile.js +46 -0
  55. package/example/src/index.tsx +22 -0
  56. package/example/tsconfig.json +20 -0
  57. package/harmony/slider/OAT.xml +42 -0
  58. package/harmony/slider/index.ets +1 -2
  59. package/harmony/slider/oh-package.json5 +2 -2
  60. package/harmony/slider/src/main/cpp/ComponentDescriptor.h +2 -4
  61. package/harmony/slider/src/main/cpp/EventEmitters.cpp +13 -13
  62. package/harmony/slider/src/main/cpp/EventEmitters.h +15 -9
  63. package/harmony/slider/src/main/cpp/Props.cpp +9 -5
  64. package/harmony/slider/src/main/cpp/Props.h +15 -10
  65. package/harmony/slider/src/main/cpp/ShadowNodes.cpp +1 -1
  66. package/harmony/slider/src/main/cpp/ShadowNodes.h +6 -6
  67. package/harmony/slider/src/main/cpp/SliderEventEmiRequestHandler.h +28 -31
  68. package/harmony/slider/src/main/cpp/SliderJSIBinder.h +8 -12
  69. package/harmony/slider/src/main/cpp/SliderNapiBinder.h +2 -6
  70. package/harmony/slider/src/main/cpp/SliderPackage.h +6 -12
  71. package/harmony/slider.har +0 -0
  72. package/package.json +38 -24
  73. package/react-native.config.js +11 -0
  74. package/src/RNCSliderNativeComponent.ts +13 -6
  75. package/src/Slider.tsx +133 -72
  76. package/src/components/StepNumber.tsx +23 -0
  77. package/src/components/StepsIndicator.tsx +89 -0
  78. package/src/components/TrackMark.tsx +56 -0
  79. package/src/index.ts +7 -1
  80. package/src/utils/constants.ts +17 -0
  81. package/src/utils/styles.ts +61 -0
  82. package/tsconfig.json +3 -2
  83. package/typings/index.d.ts +35 -1
  84. package/.eslintrc.json +0 -20
  85. package/.flowconfig +0 -66
  86. 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
- #ifndef SLIDERPACKAGE_H
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
Binary file
package/package.json CHANGED
@@ -1,22 +1,15 @@
1
1
  {
2
2
  "name": "@react-native-ohos/slider",
3
- "version": "4.4.4-rc.1",
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://registry.npmjs.org",
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": "4.4.3"
27
+ "@react-native-community/slider": "5.0.0"
35
28
  },
36
29
  "devDependencies": {
37
30
  "@babel/cli": "^7.8.4",
38
- "@babel/core": "^7.12.9",
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.12.5",
42
- "@react-native-community/eslint-config": "2.0.0",
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-native": "^0.69.5",
44
+ "@types/react": "^18.2.6",
45
45
  "@types/react-test-renderer": "^18.0.0",
46
- "babel-jest": "^26.6.3",
46
+ "babel-jest": "^29.7.0",
47
47
  "babel-plugin-module-resolver": "5.0.0",
48
48
  "copyfiles": "^2.4.1",
49
- "eslint": "^7.32.0",
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
- "metro-react-native-babel-preset": "^0.70.3",
55
- "react": "^18.2.0",
56
- "react-native": "^0.72.1",
57
- "react-native-windows": "^0.72.0",
58
- "react-test-renderer": "^18.2.0",
59
- "typescript": "^4.7.4"
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
  }
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ libraryName: 'RNCSlider',
6
+ componentDescriptors: ['RNCSliderComponentDescriptor'],
7
+ cmakeListsPath: 'src/main/jni/CMakeLists.txt',
8
+ },
9
+ },
10
+ },
11
+ };
@@ -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?: Float;
33
+ maximumValue?: Double;
27
34
  minimumTrackImage?: ImageSource;
28
35
  minimumTrackTintColor?: ColorValue;
29
- minimumValue?: Float;
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?: Float;
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
- 'RNCSlider',
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
- import React from 'react';
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
- const LIMIT_MIN_VALUE = Number.MIN_SAFE_INTEGER;
20
- const LIMIT_MAX_VALUE = Number.MAX_SAFE_INTEGER;
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?: (value: number) => void;
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?: (value: number) => void;
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?: (value: number) => void;
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
- props: Props,
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
- ...localProps
203
- } = props;
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 onValueChangeEvent = onValueChange
206
- ? (event: Event) => {
207
- onValueChange(event.nativeEvent.value);
208
- }
209
- : null;
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
- const lowerLimit =
241
- !!localProps.lowerLimit || localProps.lowerLimit === 0
242
- ? localProps.lowerLimit
243
- : LIMIT_MIN_VALUE;
244
-
245
- const upperLimit =
246
- !!localProps.upperLimit || localProps.upperLimit === 0
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
- <RCTSliderNativeComponent
252
- {...localProps}
253
- value={value}
254
- lowerLimit={lowerLimit}
255
- upperLimit={upperLimit}
256
- accessibilityState={_accessibilityState}
257
- thumbImage={
258
- Platform.OS === 'web'
259
- ? props.thumbImage
260
- : props.thumbImage
261
- ? Image.resolveAssetSource(props.thumbImage)
262
- : undefined
263
- }
264
- ref={forwardedRef}
265
- style={style}
266
- onChange={onValueChangeEvent}
267
- onRNCSliderSlidingStart={onSlidingStartEvent}
268
- onRNCSliderSlidingComplete={onSlidingCompleteEvent}
269
- onRNCSliderValueChange={onValueChangeEvent}
270
- disabled={_disabled}
271
- onStartShouldSetResponder={() => true}
272
- onResponderTerminationRequest={() => false}
273
- onRNCSliderAccessibilityAction={onAccessibilityActionEvent}
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
+ };