@ledgerhq/lumen-ui-rnative 0.0.71 → 0.0.73

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 (89) hide show
  1. package/.storybook/preview-head.html +1 -0
  2. package/dist/package.json +3 -3
  3. package/dist/src/i18n/locales/de.json +3 -0
  4. package/dist/src/i18n/locales/en.json +3 -0
  5. package/dist/src/i18n/locales/es.json +3 -0
  6. package/dist/src/i18n/locales/fr.json +3 -0
  7. package/dist/src/i18n/locales/ja.json +3 -0
  8. package/dist/src/i18n/locales/ko.json +3 -0
  9. package/dist/src/i18n/locales/pt.json +3 -0
  10. package/dist/src/i18n/locales/ru.json +3 -0
  11. package/dist/src/i18n/locales/th.json +3 -0
  12. package/dist/src/i18n/locales/tr.json +3 -0
  13. package/dist/src/i18n/locales/zh.json +3 -0
  14. package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.d.ts +4 -0
  15. package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.d.ts.map +1 -1
  16. package/dist/src/lib/Components/BottomSheet/BottomSheet.stories.js +4 -0
  17. package/dist/src/lib/Components/Icon/Icon.d.ts.map +1 -1
  18. package/dist/src/lib/Components/Icon/Icon.js +1 -0
  19. package/dist/src/lib/Components/Icon/Icon.stories.js +1 -1
  20. package/dist/src/lib/Components/Icon/types.d.ts +1 -1
  21. package/dist/src/lib/Components/Icon/types.d.ts.map +1 -1
  22. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.d.ts +1 -1
  23. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.d.ts.map +1 -1
  24. package/dist/src/lib/Components/InteractiveIcon/InteractiveIcon.js +10 -2
  25. package/dist/src/lib/Components/InteractiveIcon/types.d.ts +17 -0
  26. package/dist/src/lib/Components/InteractiveIcon/types.d.ts.map +1 -1
  27. package/dist/src/lib/Components/InteractiveIcon/types.js +24 -1
  28. package/dist/src/lib/Components/Skeleton/Skeleton.d.ts +21 -0
  29. package/dist/src/lib/Components/Skeleton/Skeleton.d.ts.map +1 -0
  30. package/dist/src/lib/Components/Skeleton/Skeleton.js +81 -0
  31. package/dist/src/lib/Components/Skeleton/Skeleton.stories.d.ts +11 -0
  32. package/dist/src/lib/Components/Skeleton/Skeleton.stories.d.ts.map +1 -0
  33. package/dist/src/lib/Components/Skeleton/Skeleton.stories.js +49 -0
  34. package/dist/src/lib/Components/Skeleton/index.d.ts +3 -0
  35. package/dist/src/lib/Components/Skeleton/index.d.ts.map +1 -0
  36. package/dist/src/lib/Components/Skeleton/index.js +2 -0
  37. package/dist/src/lib/Components/Skeleton/types.d.ts +10 -0
  38. package/dist/src/lib/Components/Skeleton/types.d.ts.map +1 -0
  39. package/dist/src/lib/Components/Skeleton/types.js +1 -0
  40. package/dist/src/lib/Components/Stepper/Stepper.d.ts +16 -0
  41. package/dist/src/lib/Components/Stepper/Stepper.d.ts.map +1 -0
  42. package/dist/src/lib/Components/Stepper/Stepper.js +74 -0
  43. package/dist/src/lib/Components/Stepper/Stepper.stories.d.ts +9 -0
  44. package/dist/src/lib/Components/Stepper/Stepper.stories.d.ts.map +1 -0
  45. package/dist/src/lib/Components/Stepper/Stepper.stories.js +35 -0
  46. package/dist/src/lib/Components/Stepper/index.d.ts +3 -0
  47. package/dist/src/lib/Components/Stepper/index.d.ts.map +1 -0
  48. package/dist/src/lib/Components/Stepper/index.js +2 -0
  49. package/dist/src/lib/Components/Stepper/types.d.ts +21 -0
  50. package/dist/src/lib/Components/Stepper/types.d.ts.map +1 -0
  51. package/dist/src/lib/Components/Stepper/types.js +1 -0
  52. package/dist/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.d.ts.map +1 -1
  53. package/dist/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.js +0 -2
  54. package/dist/src/lib/Components/index.d.ts +3 -0
  55. package/dist/src/lib/Components/index.d.ts.map +1 -1
  56. package/dist/src/lib/Components/index.js +3 -0
  57. package/package.json +3 -3
  58. package/src/i18n/locales/de.json +3 -0
  59. package/src/i18n/locales/en.json +3 -0
  60. package/src/i18n/locales/es.json +3 -0
  61. package/src/i18n/locales/fr.json +3 -0
  62. package/src/i18n/locales/ja.json +3 -0
  63. package/src/i18n/locales/ko.json +3 -0
  64. package/src/i18n/locales/pt.json +3 -0
  65. package/src/i18n/locales/ru.json +3 -0
  66. package/src/i18n/locales/th.json +3 -0
  67. package/src/i18n/locales/tr.json +3 -0
  68. package/src/i18n/locales/zh.json +3 -0
  69. package/src/lib/Components/BottomSheet/BottomSheet.stories.tsx +4 -0
  70. package/src/lib/Components/Icon/Icon.stories.tsx +1 -1
  71. package/src/lib/Components/Icon/Icon.test.tsx +1 -1
  72. package/src/lib/Components/Icon/Icon.tsx +1 -0
  73. package/src/lib/Components/Icon/types.ts +1 -1
  74. package/src/lib/Components/InteractiveIcon/InteractiveIcon.tsx +15 -2
  75. package/src/lib/Components/InteractiveIcon/types.ts +47 -0
  76. package/src/lib/Components/Skeleton/Skeleton.mdx +200 -0
  77. package/src/lib/Components/Skeleton/Skeleton.stories.tsx +89 -0
  78. package/src/lib/Components/Skeleton/Skeleton.test.tsx +54 -0
  79. package/src/lib/Components/Skeleton/Skeleton.tsx +137 -0
  80. package/src/lib/Components/Skeleton/index.ts +2 -0
  81. package/src/lib/Components/Skeleton/types.ts +10 -0
  82. package/src/lib/Components/Stepper/Stepper.mdx +217 -0
  83. package/src/lib/Components/Stepper/Stepper.stories.tsx +62 -0
  84. package/src/lib/Components/Stepper/Stepper.test.tsx +132 -0
  85. package/src/lib/Components/Stepper/Stepper.tsx +159 -0
  86. package/src/lib/Components/Stepper/index.ts +2 -0
  87. package/src/lib/Components/Stepper/types.ts +21 -0
  88. package/src/lib/Components/Utility/Gradient/LinearGradient/LinearGradient.stories.tsx +0 -2
  89. package/src/lib/Components/index.ts +3 -0
@@ -0,0 +1,9 @@
1
+ import { Meta, StoryObj } from '@storybook/react-native-web-vite';
2
+ import { Stepper } from './Stepper';
3
+ declare const meta: Meta<typeof Stepper>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Stepper>;
6
+ export declare const Base: Story;
7
+ export declare const DisabledShowcase: Story;
8
+ export declare const WithCustomLabel: Story;
9
+ //# sourceMappingURL=Stepper.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.stories.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Stepper/Stepper.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAGlE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,OAAO,CAW9B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,OAAO,CAAC,CAAC;AAEtC,eAAO,MAAM,IAAI,EAAE,KAMlB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAuB9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAO7B,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from '../Utility/Box';
3
+ import { Text } from '../Utility/Text';
4
+ import { Stepper } from './Stepper';
5
+ const meta = {
6
+ title: 'Communication/Stepper',
7
+ component: Stepper,
8
+ parameters: {
9
+ actions: { disable: true },
10
+ },
11
+ argTypes: {
12
+ currentStep: { control: 'number' },
13
+ totalSteps: { control: 'number' },
14
+ disabled: { control: 'boolean' },
15
+ },
16
+ };
17
+ export default meta;
18
+ export const Base = {
19
+ args: {
20
+ currentStep: 2,
21
+ totalSteps: 4,
22
+ },
23
+ render: (args) => _jsx(Stepper, { ...args }),
24
+ };
25
+ export const DisabledShowcase = {
26
+ render: () => (_jsxs(Box, { lx: { gap: 's32', alignItems: 'center' }, children: [_jsxs(Box, { lx: { alignItems: 'center', gap: 's8' }, children: [_jsx(Text, { typography: 'body3', lx: { color: 'muted' }, children: "Default (2/4)" }), _jsx(Stepper, { currentStep: 2, totalSteps: 4 })] }), _jsxs(Box, { lx: { alignItems: 'center', gap: 's8' }, children: [_jsx(Text, { typography: 'body3', lx: { color: 'muted' }, children: "Disabled (2/4)" }), _jsx(Stepper, { currentStep: 2, totalSteps: 4, disabled: true })] }), _jsxs(Box, { lx: { alignItems: 'center', gap: 's8' }, children: [_jsx(Text, { typography: 'body3', lx: { color: 'muted' }, children: "Unstarted (0/9)" }), _jsx(Stepper, { currentStep: 0, totalSteps: 9 })] })] })),
27
+ };
28
+ export const WithCustomLabel = {
29
+ args: {
30
+ currentStep: 5,
31
+ totalSteps: 5,
32
+ label: '🎉',
33
+ },
34
+ render: (args) => _jsx(Stepper, { ...args }),
35
+ };
@@ -0,0 +1,3 @@
1
+ export * from './Stepper';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Stepper/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Stepper';
2
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ import { StyledViewProps } from '../../../styles';
2
+ export type StepperProps = {
3
+ /**
4
+ * Current step number (1-based). Use 0 or negative to show minimal dot (before starting).
5
+ */
6
+ currentStep: number;
7
+ /**
8
+ * Total number of steps.
9
+ */
10
+ totalSteps: number;
11
+ /**
12
+ * Whether the stepper is disabled. Changes the progress arc to a muted style.
13
+ * @default false
14
+ */
15
+ disabled?: boolean;
16
+ /**
17
+ * Optional custom label. Defaults to "{currentStep}/{totalSteps}".
18
+ */
19
+ label?: string;
20
+ } & Omit<StyledViewProps, 'children'>;
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/lib/Components/Stepper/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -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,KA4B/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAyC7B,CAAC"}
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
  };
@@ -17,7 +17,10 @@ export * from './NavBar';
17
17
  export * from './PageIndicator';
18
18
  export * from './SearchInput';
19
19
  export * from './Select';
20
+ export * from './Skeleton';
21
+ export * from './Spinner';
20
22
  export * from './Spot';
23
+ export * from './Stepper';
21
24
  export * from './Subheader';
22
25
  export * from './Switch';
23
26
  export * from './TabBar';
@@ -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,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,QAAQ,CAAC;AACvB,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,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"}
@@ -17,7 +17,10 @@ export * from './NavBar';
17
17
  export * from './PageIndicator';
18
18
  export * from './SearchInput';
19
19
  export * from './Select';
20
+ export * from './Skeleton';
21
+ export * from './Spinner';
20
22
  export * from './Spot';
23
+ export * from './Stepper';
21
24
  export * from './Subheader';
22
25
  export * from './Switch';
23
26
  export * from './TabBar';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/lumen-ui-rnative",
3
- "version": "0.0.71",
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.19",
30
+ "@ledgerhq/lumen-utils-shared": "0.0.20",
31
31
  "i18next": "^23.7.0",
32
32
  "react-i18next": "^14.0.0"
33
33
  },
@@ -37,7 +37,7 @@
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.52",
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",
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(Öffnet in neuem Tab)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Schritt {{currentStep}} von {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(opens in a new tab)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Step {{currentStep}} of {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(se abre en una pestaña nueva)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Paso {{currentStep}} de {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(s'ouvre dans un nouvel onglet)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Étape {{currentStep}} sur {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(新しいタブで開く)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "ステップ {{currentStep}}/{{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(새 탭에서 열기)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "{{totalSteps}}단계 중 {{currentStep}}단계"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(abre em uma nova aba)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Passo {{currentStep}} de {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(открывается в новой вкладке)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "Шаг {{currentStep}} из {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(เปิดในแท็บใหม่)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "ขั้นตอนที่ {{currentStep}} จาก {{totalSteps}}"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(yeni sekmede açılır)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "{{totalSteps}} adımdan {{currentStep}}. adım"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,9 @@
22
22
  },
23
23
  "link": {
24
24
  "opensInNewTabAriaLabel": "(在新选项卡中打开)"
25
+ },
26
+ "stepper": {
27
+ "progressAriaLabel": "第 {{currentStep}} 步,共 {{totalSteps}} 步"
25
28
  }
26
29
  }
27
30
  }
@@ -22,6 +22,10 @@ const meta = {
22
22
  format: true,
23
23
  type: 'code',
24
24
  },
25
+ story: {
26
+ inline: false,
27
+ iframeHeight: 400,
28
+ },
25
29
  },
26
30
  },
27
31
  argTypes: {
@@ -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(
@@ -9,6 +9,7 @@ const iconSizeMap = {
9
9
  16: 's16',
10
10
  20: 's20',
11
11
  24: 's24',
12
+ 32: 's32',
12
13
  40: 's40',
13
14
  48: 's48',
14
15
  56: 's56',
@@ -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'>;
@@ -0,0 +1,200 @@
1
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
2
+ import * as SkeletonStories from './Skeleton.stories';
3
+ import { Skeleton } from './Skeleton';
4
+ import {
5
+ CustomTabs,
6
+ Tab,
7
+ DoVsDontRow,
8
+ DoBlockItem,
9
+ DontBlockItem,
10
+ } from '../../../../.storybook/components';
11
+ import CommonRulesDoAndDont from '../../../../.storybook/components/DoVsDont/CommonRulesDoAndDont.mdx';
12
+
13
+ <Meta title='Communication/Skeleton' of={SkeletonStories} />
14
+
15
+ # Skeleton
16
+
17
+ <CustomTabs>
18
+ <Tab label="Overview">
19
+
20
+ ## Introduction
21
+
22
+ Skeleton components provide visual placeholders for content that is loading. They use a pulsing animation to indicate that content is being fetched or processed, improving perceived performance and user experience.
23
+
24
+ > View in [Figma](https://www.figma.com/design/JxaLVMTWirCpU0rsbZ30k7/2.-Components-Library?node-id=10196-8001&m=dev).
25
+
26
+ ## Anatomy
27
+
28
+ <Canvas of={SkeletonStories.Base} />
29
+
30
+ - **Shape**: Defines the visual placeholder shape (rectangle, circle, etc.)
31
+ - **Animation**: Built-in pulse animation to indicate loading state
32
+
33
+ ## Properties
34
+
35
+ ### Overview
36
+
37
+ <Canvas of={SkeletonStories.Base} />
38
+ <Controls of={SkeletonStories.Base} />
39
+
40
+ ### Component Variants
41
+
42
+ The `component` prop provides pre-built skeleton patterns for common UI elements.
43
+
44
+ #### **List Item**
45
+
46
+ <Canvas of={SkeletonStories.WithListItem} />
47
+
48
+ #### **Tile**
49
+
50
+ <Canvas of={SkeletonStories.WithTile} />
51
+
52
+ > **Note**: List item and Tile width are fixed
53
+
54
+ ### Sizes
55
+
56
+ Skeletons can be sized using the `lx` prop with design system size tokens.
57
+
58
+ <Canvas of={SkeletonStories.SizeShowcase} />
59
+
60
+ ### Shapes
61
+
62
+ Skeletons can take various shapes depending on the content they're representing.
63
+
64
+ <Canvas of={SkeletonStories.ShapeShowcase} />
65
+
66
+ ## Best Practices
67
+
68
+ - **Use Component Variants**: Prefer using the `component` prop for common patterns like list items and tiles
69
+ - **Match Content Shape**: Make skeleton shapes match the actual content they represent
70
+ - **Consistent Spacing**: Use consistent spacing between skeleton elements
71
+ - **Appropriate Sizing**: Size skeletons to match the expected content dimensions
72
+ - **Loading States**: Show skeletons only during actual loading states
73
+
74
+ </Tab>
75
+ <Tab label="Implementation">
76
+
77
+ ```bash
78
+ npm install @ledgerhq/lumen-ui-rnative
79
+ ```
80
+
81
+ > **Note**: `@ledgerhq/lumen-design-core` and other peer dependencies (`react`, `react-native`, etc.) are required. See our [Setup Guide →](?path=/docs/getting-started-setup--docs) for complete installation.
82
+
83
+ ## Basic Usage
84
+
85
+ ```tsx
86
+ import { Skeleton } from '@ledgerhq/lumen-ui-rnative';
87
+
88
+ function MyComponent() {
89
+ return <Skeleton lx={{ height: 's16', width: 's256' }} />;
90
+ }
91
+ ```
92
+
93
+ ### Component Variants
94
+
95
+ Use the `component` prop for pre-built skeleton patterns:
96
+
97
+ ```tsx
98
+ import { Skeleton } from '@ledgerhq/lumen-ui-rnative';
99
+
100
+ // List item skeleton - horizontal layout with avatar and text lines
101
+ <Skeleton component='list-item' />
102
+
103
+ // Tile skeleton - vertical centered layout
104
+ <Skeleton component='tile' />
105
+ ```
106
+
107
+ ### Custom Styling
108
+
109
+ While the component comes with predefined styles, you can extend them using the `lx` prop:
110
+
111
+ ```tsx
112
+ <Skeleton lx={{ height: 's40', width: 's256', borderRadius: 'lg' }} />
113
+ ```
114
+
115
+ ### Manual Composition
116
+
117
+ For custom layouts, compose multiple skeleton elements:
118
+
119
+ ```tsx
120
+ import { Box, Skeleton } from '@ledgerhq/lumen-ui-rnative';
121
+
122
+ <Box lx={{ flexDirection: 'row', alignItems: 'center', gap: 's16' }}>
123
+ <Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'full' }} />
124
+ <Box lx={{ flex: 1, flexDirection: 'column', gap: 's8' }}>
125
+ <Skeleton lx={{ height: 's16', width: 's160' }} />
126
+ <Skeleton lx={{ height: 's16', width: 's128' }} />
127
+ </Box>
128
+ </Box>
129
+ ```
130
+
131
+ ## Do's and Don'ts
132
+
133
+ <div className='flex flex-col gap-24'>
134
+ <DoVsDontRow>
135
+ <DoBlockItem
136
+ title='Use component prop for common patterns'
137
+ description='Use pre-built variants for consistent loading states'
138
+ >
139
+
140
+ {/* prettier-ignore */}
141
+ ```tsx
142
+ <Skeleton component='list-item' />
143
+ <Skeleton component='tile' />
144
+ ```
145
+
146
+ </DoBlockItem>
147
+ <DontBlockItem
148
+ title="Don't manually recreate common patterns"
149
+ description='Avoid recreating patterns that already exist as component variants'
150
+ >
151
+
152
+ {/* prettier-ignore */}
153
+ ```tsx
154
+ import { Box, Skeleton } from '@ledgerhq/lumen-ui-rnative';
155
+
156
+ <Box lx={{ flexDirection: 'row', alignItems: 'center', gap: 's16' }}>
157
+ <Skeleton lx={{ width: 's48', height: 's48', borderRadius: 'full' }} />
158
+ <Box lx={{ flex: 1, flexDirection: 'column', gap: 's8' }}>
159
+ <Skeleton lx={{ height: 's12', width: 's176' }} />
160
+ <Skeleton lx={{ height: 's12', width: 's112' }} />
161
+ </Box>
162
+ </Box>
163
+ ```
164
+
165
+ </DontBlockItem>
166
+
167
+ </DoVsDontRow>
168
+
169
+ <DoVsDontRow>
170
+ <DoBlockItem
171
+ title='Use lx prop for sizing'
172
+ description='Use design system size tokens for consistent sizing'
173
+ >
174
+
175
+ {/* prettier-ignore */}
176
+ ```tsx
177
+ <Skeleton lx={{ height: 's16', width: 's256' }} />
178
+ ```
179
+
180
+ </DoBlockItem>
181
+ <DontBlockItem
182
+ title="Don't use arbitrary style values"
183
+ description='Avoid using the style prop or arbitrary values'
184
+ >
185
+
186
+ {/* prettier-ignore */}
187
+ ```tsx
188
+ <Skeleton style={{ height: 16, width: 200 }} />
189
+ ```
190
+
191
+ </DontBlockItem>
192
+
193
+ </DoVsDontRow>
194
+
195
+ </div>
196
+
197
+ <CommonRulesDoAndDont />
198
+
199
+ </Tab>
200
+ </CustomTabs>