@ledgerhq/lumen-ui-rnative 0.1.2 → 0.1.4

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 (98) hide show
  1. package/dist/package.json +3 -3
  2. package/dist/src/i18n/locales/de.json +3 -0
  3. package/dist/src/i18n/locales/en.json +3 -0
  4. package/dist/src/i18n/locales/es.json +3 -0
  5. package/dist/src/i18n/locales/fr.json +3 -0
  6. package/dist/src/i18n/locales/ja.json +3 -0
  7. package/dist/src/i18n/locales/ko.json +3 -0
  8. package/dist/src/i18n/locales/pt.json +3 -0
  9. package/dist/src/i18n/locales/ru.json +3 -0
  10. package/dist/src/i18n/locales/th.json +3 -0
  11. package/dist/src/i18n/locales/tr.json +3 -0
  12. package/dist/src/i18n/locales/zh.json +3 -0
  13. package/dist/src/lib/Animations/constants.d.ts +28 -0
  14. package/dist/src/lib/Animations/constants.d.ts.map +1 -0
  15. package/dist/src/lib/Animations/constants.js +27 -0
  16. package/dist/src/lib/Animations/index.d.ts +1 -0
  17. package/dist/src/lib/Animations/index.d.ts.map +1 -1
  18. package/dist/src/lib/Animations/index.js +1 -0
  19. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.d.ts +1 -1
  20. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.d.ts.map +1 -1
  21. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.js +76 -5
  22. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.stories.d.ts +1 -0
  23. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.stories.d.ts.map +1 -1
  24. package/dist/src/lib/Components/AmountDisplay/AmountDisplay.stories.js +25 -2
  25. package/dist/src/lib/Components/AmountDisplay/types.d.ts +20 -25
  26. package/dist/src/lib/Components/AmountDisplay/types.d.ts.map +1 -1
  27. package/dist/src/lib/Components/AmountDisplay/types.js +1 -1
  28. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.d.ts +10 -0
  29. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.d.ts.map +1 -0
  30. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.js +114 -0
  31. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.stories.d.ts +58 -0
  32. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.stories.d.ts.map +1 -0
  33. package/dist/src/lib/Components/SegmentedControl/SegmentedControl.stories.js +61 -0
  34. package/dist/src/lib/Components/SegmentedControl/SegmentedControlContext.d.ts +11 -0
  35. package/dist/src/lib/Components/SegmentedControl/SegmentedControlContext.d.ts.map +1 -0
  36. package/dist/src/lib/Components/SegmentedControl/SegmentedControlContext.js +7 -0
  37. package/dist/src/lib/Components/SegmentedControl/index.d.ts +3 -0
  38. package/dist/src/lib/Components/SegmentedControl/index.d.ts.map +1 -0
  39. package/dist/src/lib/Components/SegmentedControl/index.js +1 -0
  40. package/dist/src/lib/Components/SegmentedControl/types.d.ts +45 -0
  41. package/dist/src/lib/Components/SegmentedControl/types.d.ts.map +1 -0
  42. package/dist/src/lib/Components/SegmentedControl/types.js +1 -0
  43. package/dist/src/lib/Components/TabBar/TabBar.d.ts.map +1 -1
  44. package/dist/src/lib/Components/TabBar/TabBar.js +10 -4
  45. package/dist/src/lib/Components/TabBar/types.d.ts +0 -1
  46. package/dist/src/lib/Components/TabBar/types.d.ts.map +1 -1
  47. package/dist/src/lib/Components/index.d.ts +1 -0
  48. package/dist/src/lib/Components/index.d.ts.map +1 -1
  49. package/dist/src/lib/Components/index.js +1 -0
  50. package/package.json +1 -1
  51. package/src/i18n/locales/de.json +3 -0
  52. package/src/i18n/locales/en.json +3 -0
  53. package/src/i18n/locales/es.json +3 -0
  54. package/src/i18n/locales/fr.json +3 -0
  55. package/src/i18n/locales/ja.json +3 -0
  56. package/src/i18n/locales/ko.json +3 -0
  57. package/src/i18n/locales/pt.json +3 -0
  58. package/src/i18n/locales/ru.json +3 -0
  59. package/src/i18n/locales/th.json +3 -0
  60. package/src/i18n/locales/tr.json +3 -0
  61. package/src/i18n/locales/zh.json +3 -0
  62. package/src/lib/Animations/constants.ts +31 -0
  63. package/src/lib/Animations/index.ts +1 -0
  64. package/src/lib/Components/AmountDisplay/AmountDisplay.mdx +7 -1
  65. package/src/lib/Components/AmountDisplay/AmountDisplay.stories.tsx +29 -2
  66. package/src/lib/Components/AmountDisplay/AmountDisplay.test.tsx +101 -51
  67. package/src/lib/Components/AmountDisplay/AmountDisplay.tsx +175 -24
  68. package/src/lib/Components/AmountDisplay/types.ts +22 -25
  69. package/src/lib/Components/SegmentedControl/SegmentedControl.mdx +159 -0
  70. package/src/lib/Components/SegmentedControl/SegmentedControl.stories.tsx +102 -0
  71. package/src/lib/Components/SegmentedControl/SegmentedControl.test.tsx +57 -0
  72. package/src/lib/Components/SegmentedControl/SegmentedControl.tsx +202 -0
  73. package/src/lib/Components/SegmentedControl/SegmentedControlContext.tsx +17 -0
  74. package/src/lib/Components/SegmentedControl/index.ts +2 -0
  75. package/src/lib/Components/SegmentedControl/types.ts +46 -0
  76. package/src/lib/Components/TabBar/TabBar.tsx +28 -12
  77. package/src/lib/Components/TabBar/types.ts +0 -1
  78. package/src/lib/Components/index.ts +1 -0
  79. package/dist/src/lib/Components/Banner/Banner.figma.d.ts +0 -2
  80. package/dist/src/lib/Components/Banner/Banner.figma.d.ts.map +0 -1
  81. package/dist/src/lib/Components/Banner/Banner.figma.js +0 -45
  82. package/dist/src/lib/Components/Checkbox/Checkbox.figma.d.ts +0 -2
  83. package/dist/src/lib/Components/Checkbox/Checkbox.figma.d.ts.map +0 -1
  84. package/dist/src/lib/Components/Checkbox/Checkbox.figma.js +0 -32
  85. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.figma.d.ts +0 -2
  86. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.figma.d.ts.map +0 -1
  87. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.figma.js +0 -26
  88. package/dist/src/lib/Components/Switch/Switch.figma.d.ts +0 -2
  89. package/dist/src/lib/Components/Switch/Switch.figma.d.ts.map +0 -1
  90. package/dist/src/lib/Components/Switch/Switch.figma.js +0 -32
  91. package/dist/src/lib/Components/Tile/Tile.figma.d.ts +0 -2
  92. package/dist/src/lib/Components/Tile/Tile.figma.d.ts.map +0 -1
  93. package/dist/src/lib/Components/Tile/Tile.figma.js +0 -28
  94. package/src/lib/Components/Banner/Banner.figma.tsx +0 -59
  95. package/src/lib/Components/Checkbox/Checkbox.figma.tsx +0 -49
  96. package/src/lib/Components/InteractiveIcon/InteractiveIcon.figma.tsx +0 -42
  97. package/src/lib/Components/Switch/Switch.figma.tsx +0 -47
  98. package/src/lib/Components/Tile/Tile.figma.tsx +0 -53
@@ -0,0 +1,58 @@
1
+ import type { StoryObj } from '@storybook/react-native-web-vite';
2
+ import { SegmentedControl, SegmentedControlButton } from './SegmentedControl';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof SegmentedControl;
6
+ subcomponents: {
7
+ SegmentedControlButton: typeof SegmentedControlButton;
8
+ };
9
+ parameters: {
10
+ layout: string;
11
+ backgrounds: {
12
+ default: string;
13
+ };
14
+ };
15
+ argTypes: {
16
+ onSelectedChange: {
17
+ action: string;
18
+ description: string;
19
+ table: {
20
+ type: {
21
+ summary: string;
22
+ };
23
+ };
24
+ };
25
+ accessibilityLabel: {
26
+ control: "text";
27
+ description: string;
28
+ table: {
29
+ type: {
30
+ summary: string;
31
+ };
32
+ };
33
+ };
34
+ selectedValue: {
35
+ control: "text";
36
+ description: string;
37
+ table: {
38
+ type: {
39
+ summary: string;
40
+ };
41
+ };
42
+ };
43
+ children: {
44
+ control: false;
45
+ description: string;
46
+ table: {
47
+ type: {
48
+ summary: string;
49
+ };
50
+ };
51
+ };
52
+ };
53
+ };
54
+ export default meta;
55
+ type Story = StoryObj<typeof meta>;
56
+ export declare const Base: Story;
57
+ export declare const WithIcons: Story;
58
+ //# sourceMappingURL=SegmentedControl.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedControl.stories.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/SegmentedControl/SegmentedControl.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAIvE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyC+B,CAAC;AAE1C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,IAAI,EAAE,KAqBlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KA0BvB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Coins, Nft, TransferHorizontal, Settings } from '../../Symbols';
4
+ import { Box } from '../Utility';
5
+ import { SegmentedControl, SegmentedControlButton } from './SegmentedControl';
6
+ const meta = {
7
+ title: 'Navigation/SegmentedControl',
8
+ component: SegmentedControl,
9
+ subcomponents: {
10
+ SegmentedControlButton,
11
+ },
12
+ parameters: {
13
+ layout: 'centered',
14
+ backgrounds: { default: 'light' },
15
+ },
16
+ argTypes: {
17
+ onSelectedChange: {
18
+ action: 'change',
19
+ description: 'Callback when the selected value changes',
20
+ table: {
21
+ type: { summary: '(value: string) => void' },
22
+ },
23
+ },
24
+ accessibilityLabel: {
25
+ control: 'text',
26
+ description: 'Accessible label for the control',
27
+ table: {
28
+ type: { summary: 'string' },
29
+ },
30
+ },
31
+ selectedValue: {
32
+ control: 'text',
33
+ description: 'The value of the currently selected segment (drives the sliding pill)',
34
+ table: {
35
+ type: { summary: 'string' },
36
+ },
37
+ },
38
+ children: {
39
+ control: false,
40
+ description: 'SegmentedControlButton elements',
41
+ table: {
42
+ type: { summary: 'ReactNode' },
43
+ },
44
+ },
45
+ },
46
+ };
47
+ export default meta;
48
+ export const Base = {
49
+ args: {},
50
+ render: () => {
51
+ const [state, setState] = useState('send');
52
+ return (_jsx(Box, { lx: { width: 's256' }, children: _jsxs(SegmentedControl, { selectedValue: state, onSelectedChange: setState, accessibilityLabel: 'Transaction type', children: [_jsx(SegmentedControlButton, { value: 'send', children: "Send" }), _jsx(SegmentedControlButton, { value: 'receive', children: "Receive" }), _jsx(SegmentedControlButton, { value: 'buy', children: "Buy" })] }) }));
53
+ },
54
+ };
55
+ export const WithIcons = {
56
+ args: {},
57
+ render: () => {
58
+ const [state, setState] = useState('tokens');
59
+ return (_jsxs(SegmentedControl, { selectedValue: state, onSelectedChange: setState, accessibilityLabel: 'Asset section', children: [_jsx(SegmentedControlButton, { value: 'tokens', icon: Coins, children: "Tokens" }), _jsx(SegmentedControlButton, { value: 'nfts', icon: Nft, children: "NFTs" }), _jsx(SegmentedControlButton, { value: 'activity', icon: TransferHorizontal, children: "Activity" }), _jsx(SegmentedControlButton, { value: 'settings', icon: Settings, children: "Settings" })] }));
60
+ },
61
+ };
@@ -0,0 +1,11 @@
1
+ export type SegmentedControlContextValue = {
2
+ selectedValue: string;
3
+ onSelectedChange: (value: string) => void;
4
+ };
5
+ declare const SegmentedControlContextProvider: import("react").FC<{
6
+ children: import("react").ReactNode;
7
+ value: SegmentedControlContextValue;
8
+ }>;
9
+ export declare const useSegmentedControlContext: () => SegmentedControlContextValue;
10
+ export { SegmentedControlContextProvider };
11
+ //# sourceMappingURL=SegmentedControlContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentedControlContext.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/SegmentedControl/SegmentedControlContext.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,QAAA,MAAO,+BAA+B;;;EAC+B,CAAC;AAEtE,eAAO,MAAM,0BAA0B,oCAInC,CAAC;AAEL,OAAO,EAAE,+BAA+B,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { createSafeContext } from '@ledgerhq/lumen-utils-shared';
2
+ const [SegmentedControlContextProvider, _useSegmentedControlSafeContext] = createSafeContext('SegmentedControl');
3
+ export const useSegmentedControlContext = () => _useSegmentedControlSafeContext({
4
+ consumerName: 'SegmentedControlButton',
5
+ contextRequired: true,
6
+ });
7
+ export { SegmentedControlContextProvider };
@@ -0,0 +1,3 @@
1
+ export * from './SegmentedControl';
2
+ export type * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/SegmentedControl/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,mBAAmB,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './SegmentedControl';
@@ -0,0 +1,45 @@
1
+ import { ComponentType, ReactNode } from 'react';
2
+ import { StyledPressableProps } from '../../../styles';
3
+ import { IconSize } from '../Icon';
4
+ import { BoxProps } from '../Utility';
5
+ export type SegmentedControlProps = {
6
+ /**
7
+ * The value of the currently selected segment (drives the sliding pill).
8
+ */
9
+ selectedValue: string;
10
+ /**
11
+ * Callback when the selected segment value changes.
12
+ */
13
+ onSelectedChange: (value: string) => void;
14
+ /**
15
+ * Accessible label for the control (e.g. "File view").
16
+ */
17
+ accessibilityLabel?: string;
18
+ /**
19
+ * Segment buttons (SegmentedControlButton). Can be wrapped (e.g. in Tooltip).
20
+ */
21
+ children: ReactNode;
22
+ } & Omit<BoxProps, 'children'>;
23
+ type IconComponent = ComponentType<{
24
+ size?: IconSize;
25
+ }>;
26
+ export type SegmentedControlButtonProps = {
27
+ /**
28
+ * Value for this segment (must be unique among siblings).
29
+ */
30
+ value: string;
31
+ /**
32
+ * Button label (e.g. "Preview", "Raw").
33
+ */
34
+ children: ReactNode;
35
+ /**
36
+ * Optional icon shown to the left of the label (from Symbols).
37
+ */
38
+ icon?: IconComponent;
39
+ /**
40
+ * Optional callback when the button is pressed (in addition to onSelectedChange on the parent).
41
+ */
42
+ onPress?: () => void;
43
+ } & Omit<StyledPressableProps, 'children'>;
44
+ export {};
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/SegmentedControl/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAE/B,KAAK,aAAa,GAAG,aAAa,CAAC;IACjC,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG;IACxC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,GAAG,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -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,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,eAAe,2CAgGjB;yBAvGe,UAAU;;;AA2G1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,2CAsFb"}
1
+ {"version":3,"file":"TabBar.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/TabBar/TabBar.tsx"],"names":[],"mappings":"AAqBA,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,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,eAAe,2CAgGjB;yBAvGe,UAAU;;;AA2G1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,2CA0Fb"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { BlurView } from '@sbaiahmed1/react-native-blur';
3
3
  import React, { useCallback, useEffect, useRef } from 'react';
4
- import { StyleSheet, Text } from 'react-native';
4
+ import { Platform, StyleSheet, Text, View, } from 'react-native';
5
5
  import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withSequence, withTiming, } from 'react-native-reanimated';
6
6
  import { useStyleSheet, useTheme } from '../../../styles';
7
7
  import { Placeholder } from '../../Symbols';
@@ -127,9 +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.lg, blurType: colorScheme === 'dark' ? 'dark' : 'light', overlayColor: colorScheme === 'dark'
130
+ return (_jsx(TabBarContextProvider, { value: { active, onTabPress: handleTabPress }, children: _jsxs(Box, { style: styles.container, onLayout: onLayout, accessibilityRole: 'tablist', ...props, children: [children, Platform.OS === 'android' ? (_jsx(View, { style: styles.androidBackground })) : (_jsx(BlurView, { style: styles.blur, blurAmount: theme.blur.lg, blurType: colorScheme === 'dark' ? 'dark' : 'light', overlayColor: colorScheme === 'dark'
131
131
  ? 'rgba(0,0,0,0.15)'
132
- : 'rgba(255,255,255,0.2)' }), _jsx(Animated.View, { style: [styles.pill, animatedPillStyle] })] }) }));
132
+ : 'rgba(255,255,255,0.2)' })), _jsx(Animated.View, { style: [styles.pill, animatedPillStyle] })] }) }));
133
133
  }
134
134
  const useStyles = () => useStyleSheet((t) => ({
135
135
  container: {
@@ -144,9 +144,14 @@ const useStyles = () => useStyleSheet((t) => ({
144
144
  },
145
145
  blur: {
146
146
  ...StyleSheet.absoluteFillObject,
147
- bottom: -2,
147
+ height: TAB_BAR_HEIGHT + t.sizes.s16,
148
148
  zIndex: -1,
149
149
  },
150
+ androidBackground: {
151
+ ...StyleSheet.absoluteFillObject,
152
+ zIndex: -1,
153
+ backgroundColor: t.colors.bg.muted,
154
+ },
150
155
  item: {
151
156
  flex: 1,
152
157
  paddingVertical: t.spacings.s4,
@@ -172,6 +177,7 @@ const useStyles = () => useStyleSheet((t) => ({
172
177
  },
173
178
  pill: {
174
179
  position: 'absolute',
180
+ pointerEvents: 'none',
175
181
  top: PILL_INSET,
176
182
  left: PILL_INSET,
177
183
  borderRadius: t.borderRadius.full,
@@ -4,7 +4,6 @@ import { IconSize } from '../Icon';
4
4
  import { BoxProps } from '../Utility';
5
5
  type IconComponent = ComponentType<{
6
6
  size?: IconSize;
7
- className?: string;
8
7
  }>;
9
8
  export type TabBarItemProps = {
10
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/TabBar/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,KAAK,aAAa,GAAG,aAAa,CAAC;IACjC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/TabBar/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,KAAK,aAAa,GAAG,aAAa,CAAC;IACjC,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC"}
@@ -17,6 +17,7 @@ export * from './ListItem';
17
17
  export * from './NavBar';
18
18
  export * from './PageIndicator';
19
19
  export * from './SearchInput';
20
+ export * from './SegmentedControl';
20
21
  export * from './Select';
21
22
  export * from './Skeleton';
22
23
  export * from './Spinner';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/Components/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/Components/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
@@ -17,6 +17,7 @@ export * from './ListItem';
17
17
  export * from './NavBar';
18
18
  export * from './PageIndicator';
19
19
  export * from './SearchInput';
20
+ export * from './SegmentedControl';
20
21
  export * from './Select';
21
22
  export * from './Skeleton';
22
23
  export * from './Spinner';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/lumen-ui-rnative",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "Apache-2.0",
5
5
  "keywords": [
6
6
  "react-native",
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "QR-Code scannen"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Betrag ausgeblendet"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Benutzer-Avatar",
8
11
  "notificationAriaLabel": "Hat Benachrichtigung"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Scan QR code"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Amount hidden"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "User avatar",
8
11
  "notificationAriaLabel": "Has notification"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Escanear código QR"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Importe oculto"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Avatar de usuario",
8
11
  "notificationAriaLabel": "Tiene notificación"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Scanner le code QR"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Montant masqué"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Avatar de l'utilisateur",
8
11
  "notificationAriaLabel": "A une notification"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "QRコードをスキャン"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "金額非表示"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "ユーザーアバター",
8
11
  "notificationAriaLabel": "通知あり"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "QR 코드 스캔"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "금액 숨김"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "사용자 아바타",
8
11
  "notificationAriaLabel": "알림 있음"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Escanear QR Code"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Valor oculto"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Avatar do usuário",
8
11
  "notificationAriaLabel": "Tem notificação"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Сканировать QR-код"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Сумма скрыта"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Аватар пользователя",
8
11
  "notificationAriaLabel": "Есть уведомление"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "สแกน QR Code"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "ยอดเงินถูกซ่อน"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "อวาตาร์ผู้ใช้",
8
11
  "notificationAriaLabel": "มีการแจ้งเตือน"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "Karekodu okut"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "Tutar gizlendi"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "Kullanıcı avatarı",
8
11
  "notificationAriaLabel": "Bildirim var"
@@ -3,6 +3,9 @@
3
3
  "addressInput": {
4
4
  "qrCodeAriaLabel": "扫描二维码"
5
5
  },
6
+ "amountDisplay": {
7
+ "amountHiddenAriaLabel": "金额已隐藏"
8
+ },
6
9
  "avatar": {
7
10
  "defaultAlt": "用户头像",
8
11
  "notificationAriaLabel": "有通知"
@@ -0,0 +1,31 @@
1
+ import { Easing } from 'react-native-reanimated';
2
+
3
+ export const durations = {
4
+ '0': 0,
5
+ '75': 75,
6
+ '100': 100,
7
+ '120': 120,
8
+ '150': 150,
9
+ '200': 200,
10
+ '250': 250,
11
+ '300': 300,
12
+ '500': 500,
13
+ '700': 700,
14
+ '1000': 1000,
15
+ '2000': 2000,
16
+ '3000': 3000,
17
+ } as const;
18
+
19
+ export type DurationKey = keyof typeof durations;
20
+
21
+ export const easingCurves = {
22
+ bezier: {
23
+ default: Easing.bezier(0.4, 0, 0.2, 1),
24
+ emphasize: Easing.bezier(0.05, 0.7, 0.1, 1),
25
+ out: Easing.bezier(0, 0, 0.2, 1),
26
+ in: Easing.bezier(0.4, 0, 1, 1),
27
+ },
28
+ quad: Easing.quad,
29
+ ease: Easing.ease,
30
+ linear: Easing.linear,
31
+ } as const;
@@ -1,3 +1,4 @@
1
1
  export * from './Spin';
2
2
  export * from './Pulse';
3
3
  export * from './types';
4
+ export * from './constants';
@@ -45,9 +45,15 @@ The `hidden` prop allows you to toggle amount visibility for privacy-sensitive a
45
45
 
46
46
  <Canvas of={AmountDisplayStories.WithHideButton} />
47
47
 
48
+ ### Animation
49
+
50
+ The `animate` prop controls whether the odometer-style animation plays when the value changes. When set to `true` (the default), digits smoothly transition between values. Set to `false` to display values instantly without animation.
51
+
52
+ <Canvas of={AmountDisplayStories.AnimationShowcase} />
53
+
48
54
  ### Loading State
49
55
 
50
- The `loading` prop displays a pulse animation around the amount to indicate that data is being fetched or updated. When set to `true`, the component applies a subtle pulsing effect while maintaining the displayed value. This is useful for showing users that the amount is being refreshed in the background.
56
+ The `loading` prop displays a pulse animation to indicate that the amount is being fetched or updated. When set to `true`, the component applies a subtle pulsing effect while maintaining the displayed value.
51
57
 
52
58
  <Canvas of={AmountDisplayStories.Loading} />
53
59
 
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-native-web-vite';
2
- import { useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
3
  import { View } from 'react-native';
4
4
  import { Eye, EyeCross } from '../../Symbols';
5
5
  import { IconButton } from '../IconButton';
@@ -48,6 +48,7 @@ const meta: Meta<typeof AmountDisplay> = {
48
48
  args: {
49
49
  formatter: eurFormatter,
50
50
  hidden: false,
51
+ animate: true,
51
52
  },
52
53
  argTypes: {
53
54
  formatter: {
@@ -72,7 +73,11 @@ const meta: Meta<typeof AmountDisplay> = {
72
73
  control: {
73
74
  type: 'boolean',
74
75
  },
75
- description: 'When true, displays bullet points instead of the amount',
76
+ },
77
+ animate: {
78
+ control: {
79
+ type: 'boolean',
80
+ },
76
81
  },
77
82
  },
78
83
  parameters: {
@@ -127,6 +132,28 @@ export const WithHideButton: Story = {
127
132
  },
128
133
  };
129
134
 
135
+ export const AnimationShowcase: Story = {
136
+ args: {
137
+ value: 1234.56,
138
+ },
139
+ render: (props) => {
140
+ const [currentValue, setCurrentValue] = useState<number>(props.value);
141
+
142
+ useEffect(() => {
143
+ const interval = setInterval(() => {
144
+ setCurrentValue((prev) => {
145
+ const delta = prev * (Math.random() * 0.02 - 0.01);
146
+ return Math.round((prev + delta) * 100) / 100;
147
+ });
148
+ }, 2000);
149
+
150
+ return () => clearInterval(interval);
151
+ }, []);
152
+
153
+ return <AmountDisplay {...props} value={currentValue} />;
154
+ },
155
+ };
156
+
130
157
  export const Loading: Story = {
131
158
  render: (props) => {
132
159
  return (