@proximus/lavender-switch-native 0.1.0-alpha.0

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 ADDED
@@ -0,0 +1,35 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # 0.1.0-alpha.0 (2025-08-13)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **BCRI-000000:** switch using tokens ([0442cc0](https://github.com/Pxs-Corporate/react-native-lavender/commit/0442cc0aba3fcbbcb21938da0747ea593d413bf6))
11
+ - **BCRI-00000:** mendix widgets ids for backward compatibility ([69e61fd](https://github.com/Pxs-Corporate/react-native-lavender/commit/69e61fde51b203b947ec7a1094f10067a1ecfdbb))
12
+
13
+ ### Features
14
+
15
+ - **BCRI-000000:** remove default E2E on DEV env build for all components ([a5d27bf](https://github.com/Pxs-Corporate/react-native-lavender/commit/a5d27bfaaebf5b75f3160f31c64b590b7bd00b93))
16
+ - **BCRI-3651771:** switch module ([d6f8151](https://github.com/Pxs-Corporate/react-native-lavender/commit/d6f81510e13ca3634f843caa0286c444373a039c))
17
+ - **BCRI-3660857:** cell components ([af9e45c](https://github.com/Pxs-Corporate/react-native-lavender/commit/af9e45cefc20d08d2338380ff4cd8cd6851abe24))
18
+ - **BCRI-4002610:** update icon handling and remove deprecated font references ([4399fe4](https://github.com/Pxs-Corporate/react-native-lavender/commit/4399fe4bff06aa70f5c29705fcc89d5243b0e3e7))
19
+ - **BCRI-4210372:** automatic versionning ([9c1f0a0](https://github.com/Pxs-Corporate/react-native-lavender/commit/9c1f0a00e19a9d1a277044ea627632032a674102))
20
+ - **BCRI-4210372:** fix bad version numbers ([bc6a8ba](https://github.com/Pxs-Corporate/react-native-lavender/commit/bc6a8ba48c15347442f2ac38dacae7ffba3d95eb))
21
+
22
+ # (2025-08-13)
23
+
24
+ ### Bug Fixes
25
+
26
+ - **BCRI-000000:** switch using tokens ([0442cc0](https://github.com/Pxs-Corporate/react-native-lavender/commit/0442cc0aba3fcbbcb21938da0747ea593d413bf6))
27
+ - **BCRI-00000:** mendix widgets ids for backward compatibility ([69e61fd](https://github.com/Pxs-Corporate/react-native-lavender/commit/69e61fde51b203b947ec7a1094f10067a1ecfdbb))
28
+
29
+ ### Features
30
+
31
+ - **BCRI-000000:** remove default E2E on DEV env build for all components ([a5d27bf](https://github.com/Pxs-Corporate/react-native-lavender/commit/a5d27bfaaebf5b75f3160f31c64b590b7bd00b93))
32
+ - **BCRI-3651771:** switch module ([d6f8151](https://github.com/Pxs-Corporate/react-native-lavender/commit/d6f81510e13ca3634f843caa0286c444373a039c))
33
+ - **BCRI-3660857:** cell components ([af9e45c](https://github.com/Pxs-Corporate/react-native-lavender/commit/af9e45cefc20d08d2338380ff4cd8cd6851abe24))
34
+ - **BCRI-4002610:** update icon handling and remove deprecated font references ([4399fe4](https://github.com/Pxs-Corporate/react-native-lavender/commit/4399fe4bff06aa70f5c29705fcc89d5243b0e3e7))
35
+ - **BCRI-4210372:** automatic versionning ([9c1f0a0](https://github.com/Pxs-Corporate/react-native-lavender/commit/9c1f0a00e19a9d1a277044ea627632032a674102))
@@ -0,0 +1,43 @@
1
+ import React, { Component } from 'react';
2
+ import { AccessibilityProps, Animated, StyleProp, ViewStyle } from 'react-native';
3
+ export interface ISwitchProps extends AccessibilityProps {
4
+ onValueChange: (value: boolean) => void;
5
+ disabled?: boolean;
6
+ lookOnlyProps?: boolean;
7
+ value?: boolean;
8
+ isPending?: boolean;
9
+ circleColors?: Array<string>;
10
+ circleStyle?: StyleProp<ViewStyle>;
11
+ trackColors?: Array<string>;
12
+ trackStyle?: StyleProp<ViewStyle>;
13
+ disabledStyle?: StyleProp<ViewStyle>;
14
+ testID?: string;
15
+ height?: number;
16
+ type?: 'order' | 'primary';
17
+ labelAccessibilityProp?: AccessibilityProps;
18
+ containerStyle?: StyleProp<ViewStyle>;
19
+ hasLabel?: boolean;
20
+ }
21
+ interface IState {
22
+ value: boolean;
23
+ transformSwitch: Animated.Value;
24
+ containerBackgroundColor: Animated.Value;
25
+ yesLabelOpacity: Animated.Value;
26
+ pendingOpacity: Animated.Value;
27
+ noLabelOpacity: Animated.Value;
28
+ }
29
+ export declare class PxSwitch extends Component<ISwitchProps, IState> {
30
+ static defaultProps: {
31
+ disabled: boolean;
32
+ value: boolean;
33
+ type: string;
34
+ };
35
+ static contextType: React.Context<import("@proximus/lavender-styling-native").IThemeContext>;
36
+ constructor(props: ISwitchProps);
37
+ componentDidUpdate(prevProps: ISwitchProps): void;
38
+ _handleSwitch: (activate?: boolean) => void;
39
+ _animateSwitch: (value: boolean) => void;
40
+ render(): React.JSX.Element;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=PxSwitch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PxSwitch.d.ts","sourceRoot":"","sources":["../src/PxSwitch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,SAAS,EAIT,SAAS,EACV,MAAM,cAAc,CAAC;AAWtB,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACtD,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,sBAAsB,CAAC,EAAE,kBAAkB,CAAC;IAC5C,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,MAAM;IACd,KAAK,EAAE,OAAO,CAAC;IACf,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC;IAChC,wBAAwB,EAAE,QAAQ,CAAC,KAAK,CAAC;IACzC,eAAe,EAAE,QAAQ,CAAC,KAAK,CAAC;IAChC,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC/B,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC;CAChC;AAQD,qBAAa,QAAS,SAAQ,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC3D,MAAM,CAAC,YAAY;;;;MAIjB;IAEF,MAAM,CAAC,WAAW,2EAAgB;gBAEtB,KAAK,EAAE,YAAY;IA0B/B,kBAAkB,CAAC,SAAS,EAAE,YAAY;IAS1C,aAAa,GAAI,WAAW,OAAO,UAkBjC;IAEF,cAAc,GAAI,OAAO,OAAO,UA+B9B;IAEF,MAAM;CAwIP"}
@@ -0,0 +1,2 @@
1
+ export * from './PxSwitch';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@proximus/lavender-switch-native",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Lavender react native switch component",
5
+ "license": "MIT",
6
+ "main": "src/index.ts",
7
+ "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "scripts": {
10
+ "clean": "rm -rf dist",
11
+ "prepublish": "yarn clean && yarn build",
12
+ "build": "npx tsc -p tsconfig.json"
13
+ },
14
+ "peerDependencies": {
15
+ "@proximus/lavender-common-native": "workspace:*",
16
+ "@proximus/lavender-icon-native": "workspace:*",
17
+ "@proximus/lavender-styling-native": "workspace:*",
18
+ "@proximus/lavender-texts-native": "workspace:*",
19
+ "react-native-gesture-handler": "*"
20
+ },
21
+ "devDependencies": {
22
+ "@proximus/lavender-common-native": "0.1.0-alpha.0",
23
+ "@proximus/lavender-icon-native": "0.1.0-alpha.0",
24
+ "@proximus/lavender-styling-native": "0.1.0-alpha.0",
25
+ "@proximus/lavender-texts-native": "0.1.0-alpha.0"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "lerna": {
31
+ "command": {
32
+ "publish": {
33
+ "assets": [
34
+ "dist",
35
+ "src",
36
+ "package.json"
37
+ ]
38
+ }
39
+ }
40
+ },
41
+ "gitHead": "27525289a448a6e4f3c2d36a88b9dc54d0f15fbf"
42
+ }
@@ -0,0 +1,314 @@
1
+ import React, { Component } from 'react';
2
+ import {
3
+ AccessibilityProps,
4
+ Animated,
5
+ StyleProp,
6
+ StyleSheet,
7
+ TouchableWithoutFeedback,
8
+ View,
9
+ ViewStyle,
10
+ } from 'react-native';
11
+ import {
12
+ Directions,
13
+ FlingGestureHandler,
14
+ State,
15
+ } from 'react-native-gesture-handler';
16
+
17
+ import { a11y, e2eID } from '@proximus/lavender-common-native';
18
+
19
+ import { ThemeContext } from '@proximus/lavender-styling-native';
20
+
21
+ export interface ISwitchProps extends AccessibilityProps {
22
+ onValueChange: (value: boolean) => void;
23
+ disabled?: boolean;
24
+ lookOnlyProps?: boolean;
25
+ value?: boolean;
26
+ isPending?: boolean;
27
+ circleColors?: Array<string>; // Deprecated
28
+ circleStyle?: StyleProp<ViewStyle>; // Deprecated
29
+ trackColors?: Array<string>;
30
+ trackStyle?: StyleProp<ViewStyle>;
31
+ disabledStyle?: StyleProp<ViewStyle>;
32
+ testID?: string;
33
+ height?: number;
34
+ type?: 'order' | 'primary';
35
+ labelAccessibilityProp?: AccessibilityProps;
36
+ containerStyle?: StyleProp<ViewStyle>;
37
+ hasLabel?: boolean;
38
+ }
39
+
40
+ interface IState {
41
+ value: boolean;
42
+ transformSwitch: Animated.Value;
43
+ containerBackgroundColor: Animated.Value;
44
+ yesLabelOpacity: Animated.Value;
45
+ pendingOpacity: Animated.Value;
46
+ noLabelOpacity: Animated.Value;
47
+ }
48
+
49
+ const defaults = {
50
+ circleSize: 20,
51
+ duration: 200,
52
+ interpolationRange: 100,
53
+ };
54
+
55
+ export class PxSwitch extends Component<ISwitchProps, IState> {
56
+ static defaultProps = {
57
+ disabled: false,
58
+ value: false,
59
+ type: 'primary',
60
+ };
61
+
62
+ static contextType = ThemeContext;
63
+
64
+ constructor(props: ISwitchProps) {
65
+ super(props);
66
+
67
+ const { value, isPending, disabled } = props;
68
+ this.state = {
69
+ containerBackgroundColor: new Animated.Value(
70
+ value || isPending
71
+ ? defaults.interpolationRange
72
+ : -defaults.interpolationRange
73
+ ),
74
+ transformSwitch: new Animated.Value(
75
+ value || isPending
76
+ ? defaults.circleSize - 10
77
+ : -defaults.circleSize + 10
78
+ ),
79
+ yesLabelOpacity: new Animated.Value(
80
+ disabled || !props.value || isPending ? 0 : 1
81
+ ),
82
+ pendingOpacity: new Animated.Value(isPending && !disabled ? 1 : 0),
83
+ noLabelOpacity: new Animated.Value(
84
+ disabled || value || isPending ? 0 : 1
85
+ ),
86
+ value: value || false,
87
+ };
88
+ }
89
+
90
+ componentDidUpdate(prevProps: ISwitchProps) {
91
+ const { disabled, value } = this.props;
92
+
93
+ if (prevProps.value !== value && !disabled) {
94
+ this._animateSwitch(!!value);
95
+ this.setState({ value: !!value });
96
+ }
97
+ }
98
+
99
+ _handleSwitch = (activate?: boolean) => {
100
+ const { onValueChange, disabled, lookOnlyProps } = this.props;
101
+
102
+ if (!disabled) {
103
+ if (lookOnlyProps) {
104
+ if (onValueChange) {
105
+ onValueChange(!this.props.value);
106
+ }
107
+ } else {
108
+ const { value } = this.state;
109
+ this._animateSwitch(activate ?? !value);
110
+ this.setState({ value: activate ?? !value }, () => {
111
+ if (onValueChange) {
112
+ onValueChange(this.state.value);
113
+ }
114
+ });
115
+ }
116
+ }
117
+ };
118
+
119
+ _animateSwitch = (value: boolean) => {
120
+ const { isPending } = this.props;
121
+ Animated.parallel([
122
+ Animated.spring(this.state.transformSwitch, {
123
+ useNativeDriver: false,
124
+ toValue:
125
+ value || isPending
126
+ ? defaults.circleSize - 10
127
+ : -defaults.circleSize + 10,
128
+ }),
129
+ Animated.timing(this.state.containerBackgroundColor, {
130
+ duration: defaults.duration,
131
+ useNativeDriver: false,
132
+ toValue:
133
+ value || isPending
134
+ ? defaults.interpolationRange
135
+ : -defaults.interpolationRange,
136
+ }),
137
+ Animated.spring(this.state.yesLabelOpacity, {
138
+ useNativeDriver: false,
139
+ toValue: value && !isPending ? 1 : 0,
140
+ }),
141
+ Animated.spring(this.state.noLabelOpacity, {
142
+ useNativeDriver: false,
143
+ toValue: value || isPending ? 0 : 1,
144
+ }),
145
+ Animated.spring(this.state.pendingOpacity, {
146
+ useNativeDriver: false,
147
+ toValue: isPending ? 1 : 0,
148
+ }),
149
+ ]).start();
150
+ };
151
+
152
+ render() {
153
+ const { containerBackgroundColor, value } = this.state;
154
+
155
+ const {
156
+ circleStyle,
157
+ trackColors,
158
+ trackStyle,
159
+ testID,
160
+ disabled,
161
+ isPending,
162
+ height = 28,
163
+ type,
164
+ ...accessibilityProps
165
+ } = this.props;
166
+
167
+ const containerBackground = containerBackgroundColor.interpolate({
168
+ inputRange: [-defaults.interpolationRange, defaults.interpolationRange],
169
+ outputRange: trackColors || [
170
+ // @ts-ignore
171
+ this.context?.theme?.t('BackgroundColorActionNeutralStrongDefault'),
172
+ type === 'order'
173
+ ? // @ts-ignore
174
+ this.context?.theme?.switchActiveForOrder
175
+ : // @ts-ignore
176
+ this.context?.theme?.t('BackgroundColorPurposeSuccessDefault'),
177
+ ],
178
+ });
179
+
180
+ return (
181
+ // @ts-ignore
182
+ <FlingGestureHandler
183
+ direction={Directions.LEFT}
184
+ numberOfPointers={1}
185
+ onHandlerStateChange={({ nativeEvent }) => {
186
+ if (nativeEvent.state === State.ACTIVE && value) {
187
+ this._handleSwitch(false);
188
+ }
189
+ }}
190
+ >
191
+ {/*
192
+ // @ts-ignore */}
193
+ <FlingGestureHandler
194
+ direction={Directions.RIGHT}
195
+ numberOfPointers={1}
196
+ onHandlerStateChange={({ nativeEvent }) => {
197
+ if (nativeEvent.state === State.ACTIVE && !value) {
198
+ this._handleSwitch(true);
199
+ }
200
+ }}
201
+ >
202
+ <View style={[{ height }, this.props.containerStyle]}>
203
+ <TouchableWithoutFeedback
204
+ disabled={disabled}
205
+ onPress={() => this._handleSwitch()}
206
+ accessible={false}
207
+ {...e2eID(testID)}
208
+ {...a11y({
209
+ accessible: true,
210
+ accessibilityRole: 'switch',
211
+ accessibilityLabel:
212
+ this.props.labelAccessibilityProp?.accessibilityLabel,
213
+ accessibilityHint:
214
+ this.props.labelAccessibilityProp?.accessibilityHint,
215
+ accessibilityState: {
216
+ disabled,
217
+ selected: value,
218
+ },
219
+ ...accessibilityProps,
220
+ })}
221
+ >
222
+ <Animated.View
223
+ style={[
224
+ styles.track,
225
+ {
226
+ backgroundColor: containerBackground,
227
+ },
228
+ trackStyle,
229
+ isPending && {
230
+ // @ts-ignore
231
+ backgroundColor: this.context?.theme?.switchPending,
232
+ },
233
+ disabled && {
234
+ // @ts-ignore
235
+ backgroundColor: this.context?.theme?.t(
236
+ 'BackgroundColorActionDisabledDefault'
237
+ ),
238
+ },
239
+ ]}
240
+ >
241
+ <Animated.View
242
+ style={[
243
+ styles.circle,
244
+ {
245
+ // @ts-ignore
246
+ width: this.context?.theme?.t('AssetsSizeS').number,
247
+ // @ts-ignore
248
+ height: this.context?.theme?.t('AssetsSizeS').number,
249
+ // @ts-ignore
250
+ borderRadius: this.context?.theme?.t('RadiusPill').number,
251
+ backgroundColor: disabled
252
+ ? // @ts-ignore
253
+ this.context?.theme?.t(
254
+ 'BackgroundColorActionDisabledDefault'
255
+ )
256
+ : // @ts-ignore
257
+ this.context?.theme?.t(
258
+ 'BackgroundColorContainerNeutralBareDefault'
259
+ ),
260
+ left: this.state.transformSwitch,
261
+ },
262
+ circleStyle,
263
+ ]}
264
+ ></Animated.View>
265
+ <Animated.View
266
+ style={{
267
+ position: 'absolute',
268
+ opacity: this.state.yesLabelOpacity,
269
+ left: 9,
270
+ }}
271
+ ></Animated.View>
272
+ {!disabled && (
273
+ <Animated.View
274
+ style={{
275
+ position: 'absolute',
276
+ opacity: this.state.noLabelOpacity,
277
+ right: 6,
278
+ }}
279
+ ></Animated.View>
280
+ )}
281
+ </Animated.View>
282
+ </TouchableWithoutFeedback>
283
+ </View>
284
+ </FlingGestureHandler>
285
+ </FlingGestureHandler>
286
+ );
287
+ }
288
+ }
289
+
290
+ const styles = StyleSheet.create({
291
+ circle: {
292
+ borderRadius: 14,
293
+ alignItems: 'center',
294
+ // height: defaults.circleSize,
295
+ // width: defaults.circleSize,
296
+ },
297
+ disabled: {
298
+ bottom: 0,
299
+ left: 0,
300
+ opacity: 0.5,
301
+ position: 'absolute',
302
+ right: 0,
303
+ top: 0,
304
+ },
305
+ track: {
306
+ alignItems: 'center',
307
+ borderRadius: 14,
308
+ flex: 1,
309
+ flexDirection: 'row',
310
+ height: 30,
311
+ justifyContent: 'center',
312
+ width: 48,
313
+ },
314
+ });
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './PxSwitch';
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../../tsconfig.npm.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src","../../../lib.d.ts"],
7
+ "exclude": ["dist", "node_modules", "src/**/*.test.ts", "src/**/*.spec.ts"]
8
+ }