@proximus/lavender-topnavigation-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 +23 -0
- package/dist/PxTopNavigation.d.ts +19 -0
- package/dist/PxTopNavigation.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +41 -0
- package/src/PxTopNavigation.tsx +244 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +8 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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-14)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **BCRI-3998258:** long title-description truncation ([d3cde41](https://github.com/Pxs-Corporate/react-native-lavender/commit/d3cde41c876c8c1fb38e98773b7a5c78635bb9ce))
|
|
11
|
+
- **BCRI-4210372:** fix types field in modules ([68ac126](https://github.com/Pxs-Corporate/react-native-lavender/commit/68ac12657112473ae9e0e683076b1d9172be9ce6))
|
|
12
|
+
- **BCRI-4210372:** topnavigation version number ([675d1c3](https://github.com/Pxs-Corporate/react-native-lavender/commit/675d1c3371d3d9505a3df5c005fc7bd47850654b))
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- **BCRI-000000:** remove default E2E on DEV env build for all components ([a5d27bf](https://github.com/Pxs-Corporate/react-native-lavender/commit/a5d27bfaaebf5b75f3160f31c64b590b7bd00b93))
|
|
17
|
+
- **BCRI-3619796:** top navigation bar ([0b2bcae](https://github.com/Pxs-Corporate/react-native-lavender/commit/0b2bcaee7243b9f00f88e2b2fb97d86cf0cf5b77))
|
|
18
|
+
- **BCRI-3651772:** top navigation module ([8be234c](https://github.com/Pxs-Corporate/react-native-lavender/commit/8be234c30f8a35093ff306b25512ebf1e10e75f2))
|
|
19
|
+
- **BCRI-3660857:** cell components ([af9e45c](https://github.com/Pxs-Corporate/react-native-lavender/commit/af9e45cefc20d08d2338380ff4cd8cd6851abe24))
|
|
20
|
+
- **BCRI-3713127:** demo app ([6907714](https://github.com/Pxs-Corporate/react-native-lavender/commit/6907714ac2313813bf74657a72cf5cb10c99fec3))
|
|
21
|
+
- **BCRI-4002610:** update icon handling and remove deprecated font references ([4399fe4](https://github.com/Pxs-Corporate/react-native-lavender/commit/4399fe4bff06aa70f5c29705fcc89d5243b0e3e7))
|
|
22
|
+
- **BCRI-4002610:** update package versions and add new dependencies for styling and icon handling ([bd36e12](https://github.com/Pxs-Corporate/react-native-lavender/commit/bd36e120c36fd33602f441ceed5f41f15f81f0ea))
|
|
23
|
+
- **BCRI-4210372:** automatic versionning ([9c1f0a0](https://github.com/Pxs-Corporate/react-native-lavender/commit/9c1f0a00e19a9d1a277044ea627632032a674102))
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface PxTopNavigationProps {
|
|
4
|
+
title: string;
|
|
5
|
+
titleColor?: string;
|
|
6
|
+
centerTitle?: boolean;
|
|
7
|
+
colors?: (string | number)[];
|
|
8
|
+
description?: string;
|
|
9
|
+
testId?: string;
|
|
10
|
+
wrapperStyle?: StyleProp<ViewStyle>;
|
|
11
|
+
menuElement?: React.ReactNode;
|
|
12
|
+
searchElement?: React.ReactNode;
|
|
13
|
+
accessibilityLabel?: string;
|
|
14
|
+
prefix?: React.ReactNode;
|
|
15
|
+
suffix?: React.ReactNode;
|
|
16
|
+
descriptionContent?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export declare function PxTopNavigation(props: PxTopNavigationProps): React.JSX.Element;
|
|
19
|
+
//# sourceMappingURL=PxTopNavigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PxTopNavigation.d.ts","sourceRoot":"","sources":["../src/PxTopNavigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EAGT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,KAA8B,MAAM,OAAO,CAAC;AA+BnD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACtC;AAsHD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,qBAqB1D"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proximus/lavender-topnavigation-native",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "Lavender react native top navigation component",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"clean": "rm -rf dist",
|
|
10
|
+
"prepublish": "yarn clean && yarn build",
|
|
11
|
+
"build": "npx tsc -p tsconfig.json"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@proximus/lavender-common-native": "workspace:*",
|
|
15
|
+
"@proximus/lavender-icon-native": "workspace:*",
|
|
16
|
+
"@proximus/lavender-styling-native": "workspace:*",
|
|
17
|
+
"@proximus/lavender-texts-native": "workspace:*",
|
|
18
|
+
"react-native-gesture-handler": "*"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@proximus/lavender-common-native": "0.1.0-alpha.1",
|
|
22
|
+
"@proximus/lavender-icon-native": "0.1.0-alpha.1",
|
|
23
|
+
"@proximus/lavender-styling-native": "0.1.0-alpha.1",
|
|
24
|
+
"@proximus/lavender-texts-native": "0.1.0-alpha.1"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"lerna": {
|
|
30
|
+
"command": {
|
|
31
|
+
"publish": {
|
|
32
|
+
"assets": [
|
|
33
|
+
"dist",
|
|
34
|
+
"src",
|
|
35
|
+
"package.json"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"gitHead": "7883d62b0246c39143275a6759cc287e54caeb40"
|
|
41
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ScrollView,
|
|
3
|
+
StyleProp,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
View,
|
|
6
|
+
ViewStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import React, { useEffect, useState } from 'react';
|
|
9
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
10
|
+
import { a11y } from '@proximus/lavender-common-native';
|
|
11
|
+
import { Body, Header as TextHeader } from '@proximus/lavender-texts-native';
|
|
12
|
+
import { Colors } from '@proximus/lavender-styling-native';
|
|
13
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
14
|
+
import { PxIcon } from '@proximus/lavender-icon-native';
|
|
15
|
+
import {
|
|
16
|
+
BackgroundColorActionNeutralDefault,
|
|
17
|
+
BorderColorActionNeutralDefault,
|
|
18
|
+
IconColorActionBrandDefault,
|
|
19
|
+
BorderSizeM,
|
|
20
|
+
} from '@proximus/lavender-styling/dist/js/proximus/themesTokens.js';
|
|
21
|
+
|
|
22
|
+
function isWhiteColor(color: string | number | undefined): boolean {
|
|
23
|
+
if (!color) return false;
|
|
24
|
+
const str = color.toString().trim();
|
|
25
|
+
// Hex: #fff, #ffffff, fff, ffffff (case-insensitive)
|
|
26
|
+
if (/^#?fff(f)?(f)?$/i.test(str.replace(/^#/, ''))) return true;
|
|
27
|
+
// RGB: rgb(255,255,255) or with spaces
|
|
28
|
+
if (/^rgb\(\s*255\s*,\s*255\s*,\s*255\s*\)$/i.test(str)) return true;
|
|
29
|
+
// RGBA: rgba(255,255,255,1) or with spaces, alpha 1 or 1.0 or 100%
|
|
30
|
+
if (
|
|
31
|
+
/^rgba\(\s*255\s*,\s*255\s*,\s*255\s*,\s*(1(\.0+)?|100%|1\.0+)\s*\)$/i.test(
|
|
32
|
+
str
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
return true;
|
|
36
|
+
return color === Colors.v8_1.white;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PxTopNavigationProps {
|
|
40
|
+
title: string;
|
|
41
|
+
titleColor?: string;
|
|
42
|
+
centerTitle?: boolean;
|
|
43
|
+
colors?: (string | number)[];
|
|
44
|
+
description?: string;
|
|
45
|
+
testId?: string;
|
|
46
|
+
wrapperStyle?: StyleProp<ViewStyle>;
|
|
47
|
+
menuElement?: React.ReactNode;
|
|
48
|
+
searchElement?: React.ReactNode;
|
|
49
|
+
accessibilityLabel?: string;
|
|
50
|
+
prefix?: React.ReactNode;
|
|
51
|
+
suffix?: React.ReactNode;
|
|
52
|
+
descriptionContent?: React.ReactNode;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function LeftComponent({
|
|
56
|
+
title,
|
|
57
|
+
titleColor = Colors.v8_1.white,
|
|
58
|
+
description,
|
|
59
|
+
prefix,
|
|
60
|
+
descriptionContent,
|
|
61
|
+
centerTitle = false,
|
|
62
|
+
}: PxTopNavigationProps) {
|
|
63
|
+
return (
|
|
64
|
+
<View style={styles.leftComponent}>
|
|
65
|
+
{prefix}
|
|
66
|
+
<View style={[styles.title, { flex: 1 }]}>
|
|
67
|
+
<TextHeader
|
|
68
|
+
ellipsizeMode={'tail'}
|
|
69
|
+
numberOfLines={1}
|
|
70
|
+
style={[
|
|
71
|
+
styles.textHeader,
|
|
72
|
+
{
|
|
73
|
+
color: titleColor,
|
|
74
|
+
textAlign: centerTitle ? 'center' : 'left',
|
|
75
|
+
},
|
|
76
|
+
]}
|
|
77
|
+
{...a11y({
|
|
78
|
+
accessibilityRole: 'header',
|
|
79
|
+
})}
|
|
80
|
+
>
|
|
81
|
+
{[title]}
|
|
82
|
+
</TextHeader>
|
|
83
|
+
{(descriptionContent && (
|
|
84
|
+
<View
|
|
85
|
+
style={{
|
|
86
|
+
alignItems: 'flex-start',
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{descriptionContent}
|
|
90
|
+
</View>
|
|
91
|
+
)) ||
|
|
92
|
+
(description && (
|
|
93
|
+
<Body
|
|
94
|
+
ellipsizeMode={'tail'}
|
|
95
|
+
numberOfLines={1}
|
|
96
|
+
style={[
|
|
97
|
+
styles.description,
|
|
98
|
+
{
|
|
99
|
+
color: titleColor,
|
|
100
|
+
textAlign: centerTitle ? 'center' : 'left',
|
|
101
|
+
},
|
|
102
|
+
]}
|
|
103
|
+
>
|
|
104
|
+
{description}
|
|
105
|
+
</Body>
|
|
106
|
+
))}
|
|
107
|
+
</View>
|
|
108
|
+
</View>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function RightComponent({ suffix }: PxTopNavigationProps) {
|
|
113
|
+
return <View style={styles.rightComponent}>{suffix}</View>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function Menu({ menuElement }: PxTopNavigationProps) {
|
|
117
|
+
return (
|
|
118
|
+
<ScrollView
|
|
119
|
+
horizontal={true}
|
|
120
|
+
contentContainerStyle={styles.menu}
|
|
121
|
+
showsHorizontalScrollIndicator={false}
|
|
122
|
+
showsVerticalScrollIndicator={false}
|
|
123
|
+
>
|
|
124
|
+
{menuElement}
|
|
125
|
+
</ScrollView>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function Search({ searchElement, colors }: PxTopNavigationProps) {
|
|
130
|
+
const [isWhiteBackground, setIsWhiteBackground] = useState(false);
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
setIsWhiteBackground(
|
|
134
|
+
isWhiteColor(colors?.[0]) && isWhiteColor(colors?.[1])
|
|
135
|
+
);
|
|
136
|
+
}, [colors]);
|
|
137
|
+
return (
|
|
138
|
+
<View
|
|
139
|
+
style={[
|
|
140
|
+
styles.search,
|
|
141
|
+
{
|
|
142
|
+
...(isWhiteBackground
|
|
143
|
+
? { backgroundColor: BackgroundColorActionNeutralDefault }
|
|
144
|
+
: {}),
|
|
145
|
+
...(isWhiteBackground
|
|
146
|
+
? {
|
|
147
|
+
borderColor: BorderColorActionNeutralDefault,
|
|
148
|
+
borderWidth: BorderSizeM.number,
|
|
149
|
+
}
|
|
150
|
+
: {}),
|
|
151
|
+
},
|
|
152
|
+
]}
|
|
153
|
+
>
|
|
154
|
+
<PxIcon
|
|
155
|
+
name={'search'}
|
|
156
|
+
size={24}
|
|
157
|
+
color={
|
|
158
|
+
isWhiteBackground || !colors?.[0]
|
|
159
|
+
? IconColorActionBrandDefault
|
|
160
|
+
: (colors?.[0] as string)
|
|
161
|
+
}
|
|
162
|
+
accessible={false}
|
|
163
|
+
accessibilityElementsHidden={true}
|
|
164
|
+
importantForAccessibility={'no-hide-descendants'}
|
|
165
|
+
/>
|
|
166
|
+
<View style={{ flex: 1, marginLeft: 8 }}>{searchElement}</View>
|
|
167
|
+
</View>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function PxTopNavigation(props: PxTopNavigationProps) {
|
|
172
|
+
const insets = useSafeAreaInsets();
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<LinearGradient
|
|
176
|
+
colors={props.colors || ['#5C2D91', '#9F3ACE']}
|
|
177
|
+
start={{ x: 0, y: 1.0 }}
|
|
178
|
+
end={{ x: 1.0, y: 1.0 }}
|
|
179
|
+
style={props.wrapperStyle as any}
|
|
180
|
+
>
|
|
181
|
+
<View
|
|
182
|
+
style={[
|
|
183
|
+
{ paddingBottom: 8, paddingTop: insets.top }, // Horizontal padding is added in the children
|
|
184
|
+
]}
|
|
185
|
+
>
|
|
186
|
+
<Header {...props} />
|
|
187
|
+
{props.menuElement && <Menu {...props} />}
|
|
188
|
+
{props.searchElement && <Search {...props} />}
|
|
189
|
+
</View>
|
|
190
|
+
</LinearGradient>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function Header(props: PxTopNavigationProps) {
|
|
195
|
+
return (
|
|
196
|
+
<View style={[styles.container]}>
|
|
197
|
+
<LeftComponent {...props} />
|
|
198
|
+
<RightComponent {...props} />
|
|
199
|
+
</View>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const styles = StyleSheet.create({
|
|
204
|
+
container: {
|
|
205
|
+
flexDirection: 'row',
|
|
206
|
+
paddingHorizontal: 8,
|
|
207
|
+
},
|
|
208
|
+
title: {
|
|
209
|
+
margin: 8,
|
|
210
|
+
},
|
|
211
|
+
textHeader: {
|
|
212
|
+
color: Colors.v8_1.white,
|
|
213
|
+
fontSize: 16,
|
|
214
|
+
},
|
|
215
|
+
description: {
|
|
216
|
+
color: Colors.v8_1.white,
|
|
217
|
+
fontSize: 12,
|
|
218
|
+
},
|
|
219
|
+
leftComponent: {
|
|
220
|
+
flex: 1,
|
|
221
|
+
flexDirection: 'row',
|
|
222
|
+
alignItems: 'center',
|
|
223
|
+
justifyContent: 'flex-start',
|
|
224
|
+
},
|
|
225
|
+
rightComponent: {
|
|
226
|
+
flexDirection: 'row',
|
|
227
|
+
alignItems: 'center',
|
|
228
|
+
},
|
|
229
|
+
menu: {
|
|
230
|
+
paddingBottom: 8,
|
|
231
|
+
paddingTop: 16,
|
|
232
|
+
paddingHorizontal: 16,
|
|
233
|
+
gap: 8,
|
|
234
|
+
},
|
|
235
|
+
search: {
|
|
236
|
+
padding: 11,
|
|
237
|
+
backgroundColor: Colors.v8_1.white,
|
|
238
|
+
borderRadius: 12,
|
|
239
|
+
marginVertical: 8,
|
|
240
|
+
marginHorizontal: 16,
|
|
241
|
+
flexDirection: 'row',
|
|
242
|
+
alignItems: 'center',
|
|
243
|
+
},
|
|
244
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PxTopNavigation } from './PxTopNavigation';
|