@ledgerhq/lumen-ui-rnative 0.0.72 → 0.0.74
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/.storybook/main.ts +1 -1
- package/.storybook/mocks/blur.tsx +14 -3
- package/.storybook/preview-head.html +1 -0
- package/dist/package.json +4 -4
- package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.d.ts +4 -0
- package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.d.ts.map +1 -1
- package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.js +4 -0
- package/dist/src/lib/Components/Icon/Icon.d.ts.map +1 -1
- package/dist/src/lib/Components/Icon/Icon.js +1 -0
- package/dist/src/lib/Components/Icon/Icon.stories.js +1 -1
- package/dist/src/lib/Components/Icon/types.d.ts +1 -1
- package/dist/src/lib/Components/Icon/types.d.ts.map +1 -1
- package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.d.ts +1 -1
- package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.d.ts.map +1 -1
- package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.js +10 -2
- package/dist/src/lib/Components/InteractiveIcon/types.d.ts +17 -0
- package/dist/src/lib/Components/InteractiveIcon/types.d.ts.map +1 -1
- package/dist/src/lib/Components/InteractiveIcon/types.js +24 -1
- package/dist/src/lib/Components/TabBar/TabBar.d.ts.map +1 -1
- package/dist/src/lib/Components/TabBar/TabBar.js +5 -2
- package/dist/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.d.ts.map +1 -1
- package/dist/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.js +0 -2
- package/jest.config.ts +1 -0
- package/package.json +4 -4
- package/src/lib/Components/BottomSheet/BottomSheet.stories.tsx +4 -0
- package/src/lib/Components/Icon/Icon.stories.tsx +1 -1
- package/src/lib/Components/Icon/Icon.test.tsx +1 -1
- package/src/lib/Components/Icon/Icon.tsx +1 -0
- package/src/lib/Components/Icon/types.ts +1 -1
- package/src/lib/Components/InteractiveIcon/InteractiveIcon.tsx +15 -2
- package/src/lib/Components/InteractiveIcon/types.ts +47 -0
- package/src/lib/Components/TabBar/TabBar.mdx +1 -1
- package/src/lib/Components/TabBar/TabBar.tsx +8 -2
- package/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.tsx +0 -2
package/.storybook/main.ts
CHANGED
|
@@ -28,7 +28,7 @@ const config: StorybookConfig = {
|
|
|
28
28
|
...config.resolve.alias,
|
|
29
29
|
'react-native': 'react-native-web',
|
|
30
30
|
'react-native-svg': 'react-native-svg-web',
|
|
31
|
-
'@react-native-
|
|
31
|
+
'@sbaiahmed1/react-native-blur': fileURLToPath(
|
|
32
32
|
new URL('./mocks/blur.tsx', import.meta.url),
|
|
33
33
|
),
|
|
34
34
|
};
|
|
@@ -2,9 +2,20 @@ import { View, ViewProps } from 'react-native';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Mock BlurView for web/storybook
|
|
5
|
-
* @react-native-
|
|
5
|
+
* @sbaiahmed1/react-native-blur doesn't work on web, so we use a simple View
|
|
6
6
|
*/
|
|
7
|
-
export const BlurView = (
|
|
8
|
-
|
|
7
|
+
export const BlurView = (
|
|
8
|
+
props: ViewProps & {
|
|
9
|
+
blurAmount?: number;
|
|
10
|
+
blurType?: string;
|
|
11
|
+
overlayColor?: string;
|
|
12
|
+
},
|
|
13
|
+
) => {
|
|
14
|
+
const {
|
|
15
|
+
blurAmount: _blurAmount,
|
|
16
|
+
blurType: _blurType,
|
|
17
|
+
overlayColor: _overlayColor,
|
|
18
|
+
...restProps
|
|
19
|
+
} = props;
|
|
9
20
|
return <View {...restProps} />;
|
|
10
21
|
};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/lumen-ui-rnative",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"./styles": "./src/styles/index.ts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@ledgerhq/lumen-utils-shared": "0.0.
|
|
30
|
+
"@ledgerhq/lumen-utils-shared": "0.0.20",
|
|
31
31
|
"i18next": "^23.7.0",
|
|
32
32
|
"react-i18next": "^14.0.0"
|
|
33
33
|
},
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@types/react": "^19.0.0",
|
|
39
39
|
"@gorhom/bottom-sheet": "^5.0.0",
|
|
40
|
-
"@ledgerhq/lumen-design-core": "0.0.
|
|
40
|
+
"@ledgerhq/lumen-design-core": "0.0.53",
|
|
41
41
|
"react": "^19.0.0",
|
|
42
42
|
"react-native": "~0.79.7",
|
|
43
43
|
"react-native-reanimated": "^3.0.0",
|
|
44
44
|
"react-native-safe-area-context": "^4.0.0 || ^5.0.0",
|
|
45
45
|
"react-native-svg": "^15.0.0",
|
|
46
|
-
"@react-native-
|
|
46
|
+
"@sbaiahmed1/react-native-blur": "^4.5.5"
|
|
47
47
|
},
|
|
48
48
|
"nx": {
|
|
49
49
|
"tags": [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheet.stories.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/BottomSheet/BottomSheet.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAU5C,QAAA,MAAM,IAAI
|
|
1
|
+
{"version":3,"file":"BottomSheet.stories.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/BottomSheet/BottomSheet.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAU5C,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8E0B,CAAC;AAErC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1C,eAAO,MAAM,IAAI,EAAE,KAmDlB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAiD3B,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,KAwC5C,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAwCzC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KA4C1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KA2CxB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAoEzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAkF7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Icon/Icon.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Icon/Icon.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;AAsC9C,eAAO,MAAM,IAAI;4DAQd,SAAS;;CAkBX,CAAC"}
|
|
@@ -8,7 +8,7 @@ const meta = {
|
|
|
8
8
|
title: 'Symbols/Interface Icons',
|
|
9
9
|
};
|
|
10
10
|
export default meta;
|
|
11
|
-
const sizes = [12, 16, 20, 24, 40, 48, 56];
|
|
11
|
+
const sizes = [12, 16, 20, 24, 32, 40, 48, 56];
|
|
12
12
|
const iconNames = Object.keys(Icons);
|
|
13
13
|
const IconCard = ({ name, size = 24, color }) => {
|
|
14
14
|
const { theme } = useTheme();
|
|
@@ -2,7 +2,7 @@ import { Ref } from 'react';
|
|
|
2
2
|
import { Svg, SvgProps } from 'react-native-svg';
|
|
3
3
|
import { LumenTextStyle } from '../../../styles';
|
|
4
4
|
import { TextProps } from '../Utility';
|
|
5
|
-
export type IconSize = 12 | 16 | 20 | 24 | 40 | 48 | 56;
|
|
5
|
+
export type IconSize = 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56;
|
|
6
6
|
export type IconProps = {
|
|
7
7
|
/**
|
|
8
8
|
* The size of the icon.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Icon/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Icon/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAE7D,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChC;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;OAEG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;CAChB,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GACxB,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC"}
|
|
@@ -29,7 +29,7 @@ import { InteractiveIconProps } from './types';
|
|
|
29
29
|
* </InteractiveIcon>
|
|
30
30
|
*/
|
|
31
31
|
export declare const InteractiveIcon: {
|
|
32
|
-
({ iconType, children, disabled, style, lx, ...props }: InteractiveIconProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
({ iconType, children, disabled, hitSlop: hitSlopProp, hitSlopType, style, lx, ...props }: InteractiveIconProps): import("react/jsx-runtime").JSX.Element;
|
|
33
33
|
displayName: string;
|
|
34
34
|
};
|
|
35
35
|
//# sourceMappingURL=InteractiveIcon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractiveIcon.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/InteractiveIcon/InteractiveIcon.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InteractiveIcon.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/InteractiveIcon/InteractiveIcon.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAgB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AA0C7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,eAAe;+FASzB,oBAAoB;;CA+BtB,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children, isValidElement } from 'react';
|
|
2
3
|
import { StyleSheet, View } from 'react-native';
|
|
3
4
|
import { useStyleSheet } from '../../../styles';
|
|
4
5
|
import { InjectStylesIntoChildren } from '../../utils/components/InjectStylesIntoChildren';
|
|
5
6
|
import { Pressable } from '../Utility';
|
|
7
|
+
import { HIT_SLOP_MAP } from './types';
|
|
6
8
|
const useStyles = ({ iconType, pressed, disabled, }) => {
|
|
7
9
|
return useStyleSheet((t) => {
|
|
8
10
|
const backgroundStyle = {
|
|
@@ -57,8 +59,14 @@ const useStyles = ({ iconType, pressed, disabled, }) => {
|
|
|
57
59
|
* <Settings size={20} />
|
|
58
60
|
* </InteractiveIcon>
|
|
59
61
|
*/
|
|
60
|
-
export const InteractiveIcon = ({ iconType, children, disabled = false, style, lx, ...props }) => {
|
|
61
|
-
|
|
62
|
+
export const InteractiveIcon = ({ iconType, children, disabled = false, hitSlop: hitSlopProp, hitSlopType = 'comfortable', style, lx, ...props }) => {
|
|
63
|
+
const child = Children.only(children);
|
|
64
|
+
let iconSize = 20;
|
|
65
|
+
if (isValidElement(child) && 'size' in child.props) {
|
|
66
|
+
iconSize = child.props.size ?? 20;
|
|
67
|
+
}
|
|
68
|
+
const resolvedHitSlop = hitSlopProp ?? HIT_SLOP_MAP[hitSlopType]?.[iconSize];
|
|
69
|
+
return (_jsx(Pressable, { lx: lx, style: [style, { alignItems: 'center', justifyContent: 'center' }], accessibilityRole: 'button', accessibilityState: { disabled: !!disabled }, disabled: disabled, hitSlop: resolvedHitSlop, ...props, children: ({ pressed }) => (_jsx(InteractiveIconContent, { iconType: iconType, pressed: pressed, disabled: !!disabled, children: children })) }));
|
|
62
70
|
};
|
|
63
71
|
const InteractiveIconContent = ({ iconType, pressed, disabled, children, }) => {
|
|
64
72
|
const styles = useStyles({ iconType, pressed, disabled });
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { Insets } from 'react-native';
|
|
2
3
|
import { StyledPressableProps } from '../../../styles';
|
|
4
|
+
import { IconSize } from '../Icon';
|
|
5
|
+
export declare const HIT_SLOP_MAP: Partial<Record<HitSlopType, Partial<Record<IconSize, Insets>>>>;
|
|
6
|
+
/**
|
|
7
|
+
* Preset for the touchable area around the icon.
|
|
8
|
+
* - `comfortable`: Increases hit area across both axes in a 1:1 ratio.
|
|
9
|
+
* - `compact-horizontal`: Larger hit area on the horizontal axis.
|
|
10
|
+
* - `compact-vertical`: Larger hit area on the vertical axis.
|
|
11
|
+
*/
|
|
12
|
+
export type HitSlopType = 'comfortable' | 'compact-horizontal' | 'compact-vertical';
|
|
3
13
|
export type InteractiveIconProps = {
|
|
4
14
|
/**
|
|
5
15
|
* The visual style of the icon button.
|
|
6
16
|
* Choose 'filled' for icons with solid backgrounds or 'stroked' for outlined icons.
|
|
7
17
|
*/
|
|
8
18
|
iconType: 'filled' | 'stroked';
|
|
19
|
+
/**
|
|
20
|
+
* Preset for the touchable area. Ignored if `hitSlop` is passed explicitly.
|
|
21
|
+
* Automatically applies insets based on the child's icon size.
|
|
22
|
+
*
|
|
23
|
+
* @default 'comfortable'
|
|
24
|
+
*/
|
|
25
|
+
hitSlopType?: HitSlopType;
|
|
9
26
|
} & PropsWithChildren & Omit<StyledPressableProps, 'children'>;
|
|
10
27
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/InteractiveIcon/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/InteractiveIcon/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,eAAO,MAAM,YAAY,EAAE,OAAO,CAChC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAwBvD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,oBAAoB,GACpB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,iBAAiB,GACnB,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC"}
|
|
@@ -1 +1,24 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export const HIT_SLOP_MAP = {
|
|
2
|
+
comfortable: {
|
|
3
|
+
12: { top: 16, bottom: 16, left: 16, right: 16 },
|
|
4
|
+
16: { top: 14, bottom: 14, left: 14, right: 14 },
|
|
5
|
+
20: { top: 12, bottom: 12, left: 12, right: 12 },
|
|
6
|
+
24: { top: 10, bottom: 10, left: 10, right: 10 },
|
|
7
|
+
32: { top: 6, bottom: 6, left: 6, right: 6 },
|
|
8
|
+
40: { top: 2, bottom: 2, left: 2, right: 2 },
|
|
9
|
+
},
|
|
10
|
+
'compact-vertical': {
|
|
11
|
+
12: { top: 14, bottom: 14, left: 10, right: 10 },
|
|
12
|
+
16: { top: 12, bottom: 12, left: 8, right: 8 },
|
|
13
|
+
20: { top: 10, bottom: 10, left: 6, right: 6 },
|
|
14
|
+
24: { top: 8, bottom: 8, left: 4, right: 4 },
|
|
15
|
+
32: { top: 4, bottom: 4, left: 0, right: 0 },
|
|
16
|
+
},
|
|
17
|
+
'compact-horizontal': {
|
|
18
|
+
12: { top: 10, bottom: 10, left: 14, right: 14 },
|
|
19
|
+
16: { top: 8, bottom: 8, left: 12, right: 12 },
|
|
20
|
+
20: { top: 6, bottom: 6, left: 10, right: 10 },
|
|
21
|
+
24: { top: 4, bottom: 4, left: 8, right: 8 },
|
|
22
|
+
32: { top: 0, bottom: 0, left: 4, right: 4 },
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabBar.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/TabBar/TabBar.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,eAAO,MAAM,cAAc,KAAK,CAAC;AAGjC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,GACX,EAAE,eAAe,2CA+FjB;yBApGe,UAAU;;;AAwG1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"TabBar.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/TabBar/TabBar.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,eAAO,MAAM,cAAc,KAAK,CAAC;AAGjC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,UAAU,GACX,EAAE,eAAe,2CA+FjB;yBApGe,UAAU;;;AAwG1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,2CAsFb"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { BlurView } from '@react-native-
|
|
2
|
+
import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
3
3
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
4
4
|
import { StyleSheet, Text } from 'react-native';
|
|
5
5
|
import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withSequence, withTiming, } from 'react-native-reanimated';
|
|
@@ -127,7 +127,9 @@ export function TabBar({ active, onTabPress, children, ...props }) {
|
|
|
127
127
|
width: itemWidth.value,
|
|
128
128
|
height: itemHeight.value - PILL_INSET * 2,
|
|
129
129
|
}), [pillProgress, itemWidth, itemHeight]);
|
|
130
|
-
return (_jsx(TabBarContextProvider, { value: { active, onTabPress: handleTabPress }, children: _jsxs(Box, { style: styles.container, onLayout: onLayout, accessibilityRole: 'tablist', ...props, children: [children, _jsx(BlurView, { style: styles.blur, blurAmount: theme.blur.
|
|
130
|
+
return (_jsx(TabBarContextProvider, { value: { active, onTabPress: handleTabPress }, children: _jsxs(Box, { style: styles.container, onLayout: onLayout, accessibilityRole: 'tablist', ...props, children: [children, _jsx(BlurView, { style: styles.blur, blurAmount: theme.blur.lg, blurType: colorScheme === 'dark' ? 'dark' : 'light', overlayColor: colorScheme === 'dark'
|
|
131
|
+
? 'rgba(0,0,0,0.15)'
|
|
132
|
+
: 'rgba(255,255,255,0.2)' }), _jsx(Animated.View, { style: [styles.pill, animatedPillStyle] })] }) }));
|
|
131
133
|
}
|
|
132
134
|
const useStyles = () => useStyleSheet((t) => ({
|
|
133
135
|
container: {
|
|
@@ -142,6 +144,7 @@ const useStyles = () => useStyleSheet((t) => ({
|
|
|
142
144
|
},
|
|
143
145
|
blur: {
|
|
144
146
|
...StyleSheet.absoluteFillObject,
|
|
147
|
+
bottom: -2,
|
|
145
148
|
zIndex: -1,
|
|
146
149
|
},
|
|
147
150
|
item: {
|
package/dist/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinearGradient.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAIvE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7C,eAAO,MAAM,IAAI,EAAE,KAUlB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAoC/B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAwB1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"LinearGradient.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAIvE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAcrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7C,eAAO,MAAM,IAAI,EAAE,KAUlB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAoC/B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAwB1B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KA0B/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAyC7B,CAAC"}
|
|
@@ -78,8 +78,6 @@ export const WithMultipleStops = {
|
|
|
78
78
|
},
|
|
79
79
|
},
|
|
80
80
|
render: (args) => {
|
|
81
|
-
const { theme } = useTheme();
|
|
82
|
-
console.log({ theme });
|
|
83
81
|
return (_jsxs(Box, { lx: { gap: 's12' }, children: [_jsx(LinearGradient, { ...args }), _jsxs(Box, { lx: { flexDirection: 'row', justifyContent: 'space-between' }, children: [_jsx(Text, { children: "accent" }), _jsx(Text, { children: "warning" }), _jsx(Text, { children: "errorStrong" })] })] }));
|
|
84
82
|
},
|
|
85
83
|
};
|
package/jest.config.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/lumen-ui-rnative",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.74",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"./styles": "./src/styles/index.ts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@ledgerhq/lumen-utils-shared": "0.0.
|
|
30
|
+
"@ledgerhq/lumen-utils-shared": "0.0.20",
|
|
31
31
|
"i18next": "^23.7.0",
|
|
32
32
|
"react-i18next": "^14.0.0"
|
|
33
33
|
},
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@types/react": "^19.0.0",
|
|
39
39
|
"@gorhom/bottom-sheet": "^5.0.0",
|
|
40
|
-
"@ledgerhq/lumen-design-core": "0.0.
|
|
40
|
+
"@ledgerhq/lumen-design-core": "0.0.53",
|
|
41
41
|
"react": "^19.0.0",
|
|
42
42
|
"react-native": "~0.79.7",
|
|
43
43
|
"react-native-reanimated": "^3.0.0",
|
|
44
44
|
"react-native-safe-area-context": "^4.0.0 || ^5.0.0",
|
|
45
45
|
"react-native-svg": "^15.0.0",
|
|
46
|
-
"@react-native-
|
|
46
|
+
"@sbaiahmed1/react-native-blur": "^4.5.5"
|
|
47
47
|
},
|
|
48
48
|
"nx": {
|
|
49
49
|
"tags": [
|
|
@@ -12,7 +12,7 @@ const meta: Meta = {
|
|
|
12
12
|
|
|
13
13
|
export default meta;
|
|
14
14
|
|
|
15
|
-
const sizes: IconSize[] = [12, 16, 20, 24, 40, 48, 56];
|
|
15
|
+
const sizes: IconSize[] = [12, 16, 20, 24, 32, 40, 48, 56];
|
|
16
16
|
|
|
17
17
|
type IconName = keyof typeof Icons;
|
|
18
18
|
const iconNames = Object.keys(Icons) as IconName[];
|
|
@@ -33,7 +33,7 @@ describe('Icon', () => {
|
|
|
33
33
|
expect(svg.props.strokeWidth).toBe(iconTokens.borderWidth.s24);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
it.each([12, 16, 20, 24, 40, 48, 56] as IconSize[])(
|
|
36
|
+
it.each([12, 16, 20, 24, 32, 40, 48, 56] as IconSize[])(
|
|
37
37
|
'should apply correct dimensions for size %i',
|
|
38
38
|
(size) => {
|
|
39
39
|
renderWithProvider(
|
|
@@ -3,7 +3,7 @@ import { Svg, SvgProps } from 'react-native-svg';
|
|
|
3
3
|
import { LumenTextStyle } from '../../../styles';
|
|
4
4
|
import { TextProps } from '../Utility';
|
|
5
5
|
|
|
6
|
-
export type IconSize = 12 | 16 | 20 | 24 | 40 | 48 | 56;
|
|
6
|
+
export type IconSize = 12 | 16 | 20 | 24 | 32 | 40 | 48 | 56;
|
|
7
7
|
|
|
8
8
|
export type IconProps = {
|
|
9
9
|
/**
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { PropsWithChildren } from 'react';
|
|
1
|
+
import { Children, isValidElement, PropsWithChildren } from 'react';
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { useStyleSheet } from '../../../styles';
|
|
4
4
|
|
|
5
5
|
import { InjectStylesIntoChildren } from '../../utils/components/InjectStylesIntoChildren';
|
|
6
|
+
import { IconProps, IconSize } from '../Icon';
|
|
6
7
|
import { Pressable } from '../Utility';
|
|
7
|
-
import { InteractiveIconProps } from './types';
|
|
8
|
+
import { HIT_SLOP_MAP, InteractiveIconProps } from './types';
|
|
8
9
|
|
|
9
10
|
type IconType = InteractiveIconProps['iconType'];
|
|
10
11
|
|
|
@@ -79,10 +80,21 @@ export const InteractiveIcon = ({
|
|
|
79
80
|
iconType,
|
|
80
81
|
children,
|
|
81
82
|
disabled = false,
|
|
83
|
+
hitSlop: hitSlopProp,
|
|
84
|
+
hitSlopType = 'comfortable',
|
|
82
85
|
style,
|
|
83
86
|
lx,
|
|
84
87
|
...props
|
|
85
88
|
}: InteractiveIconProps) => {
|
|
89
|
+
const child = Children.only(children);
|
|
90
|
+
|
|
91
|
+
let iconSize: IconSize = 20;
|
|
92
|
+
if (isValidElement<IconProps>(child) && 'size' in child.props) {
|
|
93
|
+
iconSize = child.props.size ?? 20;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const resolvedHitSlop = hitSlopProp ?? HIT_SLOP_MAP[hitSlopType]?.[iconSize];
|
|
97
|
+
|
|
86
98
|
return (
|
|
87
99
|
<Pressable
|
|
88
100
|
lx={lx}
|
|
@@ -90,6 +102,7 @@ export const InteractiveIcon = ({
|
|
|
90
102
|
accessibilityRole='button'
|
|
91
103
|
accessibilityState={{ disabled: !!disabled }}
|
|
92
104
|
disabled={disabled}
|
|
105
|
+
hitSlop={resolvedHitSlop}
|
|
93
106
|
{...props}
|
|
94
107
|
>
|
|
95
108
|
{({ pressed }) => (
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { Insets } from 'react-native';
|
|
2
3
|
import { StyledPressableProps } from '../../../styles';
|
|
4
|
+
import { IconSize } from '../Icon';
|
|
5
|
+
|
|
6
|
+
export const HIT_SLOP_MAP: Partial<
|
|
7
|
+
Record<HitSlopType, Partial<Record<IconSize, Insets>>>
|
|
8
|
+
> = {
|
|
9
|
+
comfortable: {
|
|
10
|
+
12: { top: 16, bottom: 16, left: 16, right: 16 },
|
|
11
|
+
16: { top: 14, bottom: 14, left: 14, right: 14 },
|
|
12
|
+
20: { top: 12, bottom: 12, left: 12, right: 12 },
|
|
13
|
+
24: { top: 10, bottom: 10, left: 10, right: 10 },
|
|
14
|
+
32: { top: 6, bottom: 6, left: 6, right: 6 },
|
|
15
|
+
40: { top: 2, bottom: 2, left: 2, right: 2 },
|
|
16
|
+
},
|
|
17
|
+
'compact-vertical': {
|
|
18
|
+
12: { top: 14, bottom: 14, left: 10, right: 10 },
|
|
19
|
+
16: { top: 12, bottom: 12, left: 8, right: 8 },
|
|
20
|
+
20: { top: 10, bottom: 10, left: 6, right: 6 },
|
|
21
|
+
24: { top: 8, bottom: 8, left: 4, right: 4 },
|
|
22
|
+
32: { top: 4, bottom: 4, left: 0, right: 0 },
|
|
23
|
+
},
|
|
24
|
+
'compact-horizontal': {
|
|
25
|
+
12: { top: 10, bottom: 10, left: 14, right: 14 },
|
|
26
|
+
16: { top: 8, bottom: 8, left: 12, right: 12 },
|
|
27
|
+
20: { top: 6, bottom: 6, left: 10, right: 10 },
|
|
28
|
+
24: { top: 4, bottom: 4, left: 8, right: 8 },
|
|
29
|
+
32: { top: 0, bottom: 0, left: 4, right: 4 },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Preset for the touchable area around the icon.
|
|
35
|
+
* - `comfortable`: Increases hit area across both axes in a 1:1 ratio.
|
|
36
|
+
* - `compact-horizontal`: Larger hit area on the horizontal axis.
|
|
37
|
+
* - `compact-vertical`: Larger hit area on the vertical axis.
|
|
38
|
+
*/
|
|
39
|
+
export type HitSlopType =
|
|
40
|
+
| 'comfortable'
|
|
41
|
+
| 'compact-horizontal'
|
|
42
|
+
| 'compact-vertical';
|
|
3
43
|
|
|
4
44
|
export type InteractiveIconProps = {
|
|
5
45
|
/**
|
|
@@ -7,5 +47,12 @@ export type InteractiveIconProps = {
|
|
|
7
47
|
* Choose 'filled' for icons with solid backgrounds or 'stroked' for outlined icons.
|
|
8
48
|
*/
|
|
9
49
|
iconType: 'filled' | 'stroked';
|
|
50
|
+
/**
|
|
51
|
+
* Preset for the touchable area. Ignored if `hitSlop` is passed explicitly.
|
|
52
|
+
* Automatically applies insets based on the child's icon size.
|
|
53
|
+
*
|
|
54
|
+
* @default 'comfortable'
|
|
55
|
+
*/
|
|
56
|
+
hitSlopType?: HitSlopType;
|
|
10
57
|
} & PropsWithChildren &
|
|
11
58
|
Omit<StyledPressableProps, 'children'>;
|
|
@@ -17,7 +17,7 @@ import { Box } from '../Utility';
|
|
|
17
17
|
|
|
18
18
|
TabBar is an animated navigation component that allows users to switch between different pages, views and sections. It features smooth transitions, blur effects, and customizable icons for each tab. Designed specifically for React Native applications, it seamlessly integrates with React Navigation and Expo Router.
|
|
19
19
|
|
|
20
|
-
> **Note:** This component uses `react-native-reanimated` for animations and `@react-native-
|
|
20
|
+
> **Note:** This component uses `react-native-reanimated` for animations and `@sbaiahmed1/react-native-blur` for visual effects. These native libraries have limited support in web-based Storybook environments and may not render with full fidelity. For the complete experience with all animations and blur effects, please test the component in the native sandbox app on iOS or Android.
|
|
21
21
|
|
|
22
22
|
> View in [Figma](https://www.figma.com/design/JxaLVMTWirCpU0rsbZ30k7/2.-Components-Library?node-id=10804-1045&m=dev).
|
|
23
23
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BlurView } from '@react-native-
|
|
1
|
+
import { BlurView } from '@sbaiahmed1/react-native-blur';
|
|
2
2
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
3
3
|
import { LayoutChangeEvent, StyleSheet, Text } from 'react-native';
|
|
4
4
|
import Animated, {
|
|
@@ -227,8 +227,13 @@ export function TabBar({
|
|
|
227
227
|
{children}
|
|
228
228
|
<BlurView
|
|
229
229
|
style={styles.blur}
|
|
230
|
-
blurAmount={theme.blur.
|
|
230
|
+
blurAmount={theme.blur.lg}
|
|
231
231
|
blurType={colorScheme === 'dark' ? 'dark' : 'light'}
|
|
232
|
+
overlayColor={
|
|
233
|
+
colorScheme === 'dark'
|
|
234
|
+
? 'rgba(0,0,0,0.15)'
|
|
235
|
+
: 'rgba(255,255,255,0.2)'
|
|
236
|
+
}
|
|
232
237
|
/>
|
|
233
238
|
<Animated.View style={[styles.pill, animatedPillStyle]} />
|
|
234
239
|
</Box>
|
|
@@ -251,6 +256,7 @@ const useStyles = () =>
|
|
|
251
256
|
},
|
|
252
257
|
blur: {
|
|
253
258
|
...StyleSheet.absoluteFillObject,
|
|
259
|
+
bottom: -2,
|
|
254
260
|
zIndex: -1,
|
|
255
261
|
},
|
|
256
262
|
item: {
|