@ledgerhq/lumen-ui-rnative 0.1.30 → 0.1.32

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 (215) hide show
  1. package/dist/module/i18n/i18n.js +5 -1
  2. package/dist/module/i18n/i18n.js.map +1 -1
  3. package/dist/module/i18n/locales/en.json +5 -0
  4. package/dist/module/lib/Components/AddressInput/AddressInput.mdx +10 -12
  5. package/dist/module/lib/Components/AddressInput/AddressInput.stories.js +2 -1
  6. package/dist/module/lib/Components/AddressInput/AddressInput.stories.js.map +1 -1
  7. package/dist/module/lib/Components/AmountInput/AmountInput.mdx +3 -3
  8. package/dist/module/lib/Components/BaseInput/BaseInput.js +60 -32
  9. package/dist/module/lib/Components/BaseInput/BaseInput.js.map +1 -1
  10. package/dist/module/lib/Components/DotCount/DotCount.stories.js +9 -18
  11. package/dist/module/lib/Components/DotCount/DotCount.stories.js.map +1 -1
  12. package/dist/module/lib/Components/DotIndicator/DotIndicator.stories.js +3 -5
  13. package/dist/module/lib/Components/DotIndicator/DotIndicator.stories.js.map +1 -1
  14. package/dist/module/lib/Components/MediaImage/MediaImage.test.js +7 -3
  15. package/dist/module/lib/Components/MediaImage/MediaImage.test.js.map +1 -1
  16. package/dist/module/lib/Components/SearchInput/SearchInput.mdx +4 -10
  17. package/dist/module/lib/Components/SearchInput/SearchInput.stories.js +2 -1
  18. package/dist/module/lib/Components/SearchInput/SearchInput.stories.js.map +1 -1
  19. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.js +2 -1
  20. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.js.map +1 -1
  21. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.mdx +34 -4
  22. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.stories.js +32 -7
  23. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.stories.js.map +1 -1
  24. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.test.js +26 -0
  25. package/dist/module/lib/Components/SegmentedControl/SegmentedControl.test.js.map +1 -1
  26. package/dist/module/lib/Components/TextInput/TextInput.js +4 -3
  27. package/dist/module/lib/Components/TextInput/TextInput.js.map +1 -1
  28. package/dist/module/lib/Components/TextInput/TextInput.mdx +8 -10
  29. package/dist/module/lib/Components/TextInput/TextInput.stories.js +40 -1
  30. package/dist/module/lib/Components/TextInput/TextInput.stories.js.map +1 -1
  31. package/dist/module/lib/Components/TextInput/TextInput.test.js +76 -0
  32. package/dist/module/lib/Components/TextInput/TextInput.test.js.map +1 -0
  33. package/dist/module/lib/Components/Trend/Trend.js +103 -0
  34. package/dist/module/lib/Components/Trend/Trend.js.map +1 -0
  35. package/dist/module/lib/Components/Trend/Trend.mdx +106 -0
  36. package/dist/module/lib/Components/Trend/Trend.stories.js +79 -0
  37. package/dist/module/lib/Components/Trend/Trend.stories.js.map +1 -0
  38. package/dist/module/lib/Components/Trend/Trend.test.js +149 -0
  39. package/dist/module/lib/Components/Trend/Trend.test.js.map +1 -0
  40. package/dist/module/lib/Components/Trend/index.js +5 -0
  41. package/dist/module/lib/Components/Trend/index.js.map +1 -0
  42. package/dist/module/lib/Components/Trend/types.js +4 -0
  43. package/dist/module/lib/Components/Trend/types.js.map +1 -0
  44. package/dist/module/lib/Components/index.js +5 -4
  45. package/dist/module/lib/Components/index.js.map +1 -1
  46. package/dist/module/lib/Symbols/Icons/Ar.js +2 -2
  47. package/dist/module/lib/Symbols/Icons/Ar.js.map +1 -1
  48. package/dist/module/lib/Symbols/Icons/ArrowLeft.js +1 -1
  49. package/dist/module/lib/Symbols/Icons/ArrowLeft.js.map +1 -1
  50. package/dist/module/lib/Symbols/Icons/ArrowRight.js +1 -1
  51. package/dist/module/lib/Symbols/Icons/ArrowRight.js.map +1 -1
  52. package/dist/module/lib/Symbols/Icons/BasketPutIn.js +1 -1
  53. package/dist/module/lib/Symbols/Icons/BasketPutIn.js.map +1 -1
  54. package/dist/module/lib/Symbols/Icons/Clip.js +1 -1
  55. package/dist/module/lib/Symbols/Icons/ClockFill.js +5 -14
  56. package/dist/module/lib/Symbols/Icons/ClockFill.js.map +1 -1
  57. package/dist/module/lib/Symbols/Icons/CloudDownload.js +1 -1
  58. package/dist/module/lib/Symbols/Icons/CloudDownload.js.map +1 -1
  59. package/dist/module/lib/Symbols/Icons/CloudUpload.js +1 -1
  60. package/dist/module/lib/Symbols/Icons/CloudUpload.js.map +1 -1
  61. package/dist/module/lib/Symbols/Icons/CoinsAddPlus.js +1 -1
  62. package/dist/module/lib/Symbols/Icons/CoinsAddPlus.js.map +1 -1
  63. package/dist/module/lib/Symbols/Icons/CoinsCheck.js +1 -1
  64. package/dist/module/lib/Symbols/Icons/CoinsCheck.js.map +1 -1
  65. package/dist/module/lib/Symbols/Icons/CoinsCross.js +1 -1
  66. package/dist/module/lib/Symbols/Icons/CoinsCross.js.map +1 -1
  67. package/dist/module/lib/Symbols/Icons/ColorPalette.js +1 -1
  68. package/dist/module/lib/Symbols/Icons/ColorPalette.js.map +1 -1
  69. package/dist/module/lib/Symbols/Icons/CryptoBitcoinCoin.js +1 -1
  70. package/dist/module/lib/Symbols/Icons/Csv.js +1 -1
  71. package/dist/module/lib/Symbols/Icons/Csv.js.map +1 -1
  72. package/dist/module/lib/Symbols/Icons/Discord.js +1 -1
  73. package/dist/module/lib/Symbols/Icons/Discord.js.map +1 -1
  74. package/dist/module/lib/Symbols/Icons/Download.js +1 -1
  75. package/dist/module/lib/Symbols/Icons/Download.js.map +1 -1
  76. package/dist/module/lib/Symbols/Icons/Exchange.js +1 -1
  77. package/dist/module/lib/Symbols/Icons/Exchange.js.map +1 -1
  78. package/dist/module/lib/Symbols/Icons/ExchangeFill.js +1 -1
  79. package/dist/module/lib/Symbols/Icons/ExchangeFill.js.map +1 -1
  80. package/dist/module/lib/Symbols/Icons/ExitLogout.js +1 -1
  81. package/dist/module/lib/Symbols/Icons/ExitLogout.js.map +1 -1
  82. package/dist/module/lib/Symbols/Icons/Expand.js +1 -1
  83. package/dist/module/lib/Symbols/Icons/Expand.js.map +1 -1
  84. package/dist/module/lib/Symbols/Icons/Experiment2.js +1 -1
  85. package/dist/module/lib/Symbols/Icons/Experiment2.js.map +1 -1
  86. package/dist/module/lib/Symbols/Icons/ExternalLink.js +1 -1
  87. package/dist/module/lib/Symbols/Icons/ExternalLink.js.map +1 -1
  88. package/dist/module/lib/Symbols/Icons/FileDownload.js +1 -1
  89. package/dist/module/lib/Symbols/Icons/FileDownload.js.map +1 -1
  90. package/dist/module/lib/Symbols/Icons/Github.js +1 -1
  91. package/dist/module/lib/Symbols/Icons/HandCard.js +1 -1
  92. package/dist/module/lib/Symbols/Icons/HandCard.js.map +1 -1
  93. package/dist/module/lib/Symbols/Icons/Infinite.js +1 -1
  94. package/dist/module/lib/Symbols/Icons/MobileArrow.js +1 -1
  95. package/dist/module/lib/Symbols/Icons/MobileArrow.js.map +1 -1
  96. package/dist/module/lib/Symbols/Icons/NftHide.js +1 -1
  97. package/dist/module/lib/Symbols/Icons/NftHide.js.map +1 -1
  98. package/dist/module/lib/Symbols/Icons/Parachute.js +1 -1
  99. package/dist/module/lib/Symbols/Icons/Parachute.js.map +1 -1
  100. package/dist/module/lib/Symbols/Icons/PictureImage.js +1 -1
  101. package/dist/module/lib/Symbols/Icons/Range.js +1 -1
  102. package/dist/module/lib/Symbols/Icons/Range.js.map +1 -1
  103. package/dist/module/lib/Symbols/Icons/Reddit.js +2 -2
  104. package/dist/module/lib/Symbols/Icons/Reduce.js +1 -1
  105. package/dist/module/lib/Symbols/Icons/Reduce.js.map +1 -1
  106. package/dist/module/lib/Symbols/Icons/Screens.js +1 -1
  107. package/dist/module/lib/Symbols/Icons/Screens.js.map +1 -1
  108. package/dist/module/lib/Symbols/Icons/Shapes.js +1 -1
  109. package/dist/module/lib/Symbols/Icons/Share.js +1 -1
  110. package/dist/module/lib/Symbols/Icons/Share.js.map +1 -1
  111. package/dist/module/lib/Symbols/Icons/StarHalf.js +1 -1
  112. package/dist/module/lib/Symbols/Icons/StarHalf.js.map +1 -1
  113. package/dist/module/lib/Symbols/Icons/TransferHorizontal.js +1 -1
  114. package/dist/module/lib/Symbols/Icons/TransferHorizontal.js.map +1 -1
  115. package/dist/module/lib/Symbols/Icons/TransferVertical.js +1 -1
  116. package/dist/module/lib/Symbols/Icons/TransferVertical.js.map +1 -1
  117. package/dist/module/lib/Symbols/Icons/Truck.js +1 -1
  118. package/dist/module/lib/Symbols/Icons/Usb.js +1 -1
  119. package/dist/module/lib/Symbols/Icons/Usb.js.map +1 -1
  120. package/dist/module/lib/Symbols/Icons/UserArrowRight.js +1 -1
  121. package/dist/module/lib/Symbols/Icons/UserArrowRight.js.map +1 -1
  122. package/dist/module/lib/Symbols/Icons/WalletInput.js +1 -1
  123. package/dist/module/lib/Symbols/Icons/WalletInput.js.map +1 -1
  124. package/dist/typescript/src/i18n/i18n.d.ts.map +1 -1
  125. package/dist/typescript/src/lib/Components/BaseInput/BaseInput.d.ts +1 -1
  126. package/dist/typescript/src/lib/Components/BaseInput/BaseInput.d.ts.map +1 -1
  127. package/dist/typescript/src/lib/Components/BaseInput/types.d.ts +9 -2
  128. package/dist/typescript/src/lib/Components/BaseInput/types.d.ts.map +1 -1
  129. package/dist/typescript/src/lib/Components/SegmentedControl/SegmentedControl.d.ts +1 -1
  130. package/dist/typescript/src/lib/Components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  131. package/dist/typescript/src/lib/Components/SegmentedControl/types.d.ts +4 -0
  132. package/dist/typescript/src/lib/Components/SegmentedControl/types.d.ts.map +1 -1
  133. package/dist/typescript/src/lib/Components/TextInput/TextInput.d.ts +4 -3
  134. package/dist/typescript/src/lib/Components/TextInput/TextInput.d.ts.map +1 -1
  135. package/dist/typescript/src/lib/Components/Trend/Trend.d.ts +3 -0
  136. package/dist/typescript/src/lib/Components/Trend/Trend.d.ts.map +1 -0
  137. package/dist/typescript/src/lib/Components/Trend/index.d.ts +3 -0
  138. package/dist/typescript/src/lib/Components/Trend/index.d.ts.map +1 -0
  139. package/dist/typescript/src/lib/Components/Trend/types.d.ts +20 -0
  140. package/dist/typescript/src/lib/Components/Trend/types.d.ts.map +1 -0
  141. package/dist/typescript/src/lib/Components/index.d.ts +5 -4
  142. package/dist/typescript/src/lib/Components/index.d.ts.map +1 -1
  143. package/dist/typescript/src/lib/Symbols/Icons/ClockFill.d.ts.map +1 -1
  144. package/package.json +2 -2
  145. package/src/i18n/i18n.ts +12 -1
  146. package/src/i18n/locales/en.json +5 -0
  147. package/src/lib/Components/AddressInput/AddressInput.mdx +10 -12
  148. package/src/lib/Components/AddressInput/AddressInput.stories.tsx +2 -1
  149. package/src/lib/Components/AmountInput/AmountInput.mdx +3 -3
  150. package/src/lib/Components/BaseInput/BaseInput.tsx +61 -29
  151. package/src/lib/Components/BaseInput/types.ts +10 -2
  152. package/src/lib/Components/DotCount/DotCount.stories.tsx +12 -10
  153. package/src/lib/Components/DotIndicator/DotIndicator.stories.tsx +1 -3
  154. package/src/lib/Components/MediaImage/MediaImage.test.tsx +7 -3
  155. package/src/lib/Components/SearchInput/SearchInput.mdx +4 -10
  156. package/src/lib/Components/SearchInput/SearchInput.stories.tsx +2 -1
  157. package/src/lib/Components/SegmentedControl/SegmentedControl.mdx +34 -4
  158. package/src/lib/Components/SegmentedControl/SegmentedControl.stories.tsx +34 -6
  159. package/src/lib/Components/SegmentedControl/SegmentedControl.test.tsx +27 -0
  160. package/src/lib/Components/SegmentedControl/SegmentedControl.tsx +2 -0
  161. package/src/lib/Components/SegmentedControl/types.ts +4 -0
  162. package/src/lib/Components/TextInput/TextInput.mdx +8 -10
  163. package/src/lib/Components/TextInput/TextInput.stories.tsx +41 -1
  164. package/src/lib/Components/TextInput/TextInput.test.tsx +90 -0
  165. package/src/lib/Components/TextInput/TextInput.tsx +4 -3
  166. package/src/lib/Components/Trend/Trend.mdx +106 -0
  167. package/src/lib/Components/Trend/Trend.stories.tsx +61 -0
  168. package/src/lib/Components/Trend/Trend.test.tsx +125 -0
  169. package/src/lib/Components/Trend/Trend.tsx +118 -0
  170. package/src/lib/Components/Trend/index.ts +2 -0
  171. package/src/lib/Components/Trend/types.ts +20 -0
  172. package/src/lib/Components/index.ts +5 -4
  173. package/src/lib/Symbols/Icons/Ar.tsx +2 -2
  174. package/src/lib/Symbols/Icons/ArrowLeft.tsx +1 -1
  175. package/src/lib/Symbols/Icons/ArrowRight.tsx +1 -1
  176. package/src/lib/Symbols/Icons/BasketPutIn.tsx +1 -1
  177. package/src/lib/Symbols/Icons/Clip.tsx +1 -1
  178. package/src/lib/Symbols/Icons/ClockFill.tsx +1 -9
  179. package/src/lib/Symbols/Icons/CloudDownload.tsx +1 -1
  180. package/src/lib/Symbols/Icons/CloudUpload.tsx +1 -1
  181. package/src/lib/Symbols/Icons/CoinsAddPlus.tsx +1 -1
  182. package/src/lib/Symbols/Icons/CoinsCheck.tsx +1 -1
  183. package/src/lib/Symbols/Icons/CoinsCross.tsx +1 -1
  184. package/src/lib/Symbols/Icons/ColorPalette.tsx +1 -1
  185. package/src/lib/Symbols/Icons/CryptoBitcoinCoin.tsx +1 -1
  186. package/src/lib/Symbols/Icons/Csv.tsx +1 -1
  187. package/src/lib/Symbols/Icons/Discord.tsx +1 -1
  188. package/src/lib/Symbols/Icons/Download.tsx +1 -1
  189. package/src/lib/Symbols/Icons/Exchange.tsx +1 -1
  190. package/src/lib/Symbols/Icons/ExchangeFill.tsx +1 -1
  191. package/src/lib/Symbols/Icons/ExitLogout.tsx +1 -1
  192. package/src/lib/Symbols/Icons/Expand.tsx +1 -1
  193. package/src/lib/Symbols/Icons/Experiment2.tsx +1 -1
  194. package/src/lib/Symbols/Icons/ExternalLink.tsx +1 -1
  195. package/src/lib/Symbols/Icons/FileDownload.tsx +1 -1
  196. package/src/lib/Symbols/Icons/Github.tsx +1 -1
  197. package/src/lib/Symbols/Icons/HandCard.tsx +1 -1
  198. package/src/lib/Symbols/Icons/Infinite.tsx +1 -1
  199. package/src/lib/Symbols/Icons/MobileArrow.tsx +1 -1
  200. package/src/lib/Symbols/Icons/NftHide.tsx +1 -1
  201. package/src/lib/Symbols/Icons/Parachute.tsx +1 -1
  202. package/src/lib/Symbols/Icons/PictureImage.tsx +1 -1
  203. package/src/lib/Symbols/Icons/Range.tsx +1 -1
  204. package/src/lib/Symbols/Icons/Reddit.tsx +2 -2
  205. package/src/lib/Symbols/Icons/Reduce.tsx +1 -1
  206. package/src/lib/Symbols/Icons/Screens.tsx +1 -1
  207. package/src/lib/Symbols/Icons/Shapes.tsx +1 -1
  208. package/src/lib/Symbols/Icons/Share.tsx +1 -1
  209. package/src/lib/Symbols/Icons/StarHalf.tsx +1 -1
  210. package/src/lib/Symbols/Icons/TransferHorizontal.tsx +1 -1
  211. package/src/lib/Symbols/Icons/TransferVertical.tsx +1 -1
  212. package/src/lib/Symbols/Icons/Truck.tsx +1 -1
  213. package/src/lib/Symbols/Icons/Usb.tsx +1 -1
  214. package/src/lib/Symbols/Icons/UserArrowRight.tsx +1 -1
  215. package/src/lib/Symbols/Icons/WalletInput.tsx +1 -1
@@ -66,11 +66,51 @@ export const WithContent: Story = {
66
66
  },
67
67
  };
68
68
 
69
+ export const WithLabelAndPlaceholder: Story = {
70
+ render: (args) => <TextInputStory {...args} />,
71
+ args: {
72
+ label: 'Phone',
73
+ placeholder: '+1 (555) 000-0000',
74
+ editable: true,
75
+ hideClearButton: false,
76
+ keyboardType: 'phone-pad',
77
+ },
78
+ };
79
+
69
80
  export const WithError: Story = {
70
81
  render: (args) => <TextInputStory {...args} initialValue='ab' />,
71
82
  args: {
72
83
  label: 'Username',
73
- errorMessage: 'Username must be at least 3 characters',
84
+ helperText: 'Username must be at least 3 characters',
85
+ status: 'error',
86
+ editable: true,
87
+ hideClearButton: false,
88
+ keyboardType: 'default',
89
+ },
90
+ };
91
+
92
+ export const WithSuccess: Story = {
93
+ render: (args) => (
94
+ <TextInputStory
95
+ {...args}
96
+ initialValue='0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb27'
97
+ />
98
+ ),
99
+ args: {
100
+ label: 'Address',
101
+ helperText: 'Address verified',
102
+ status: 'success',
103
+ editable: true,
104
+ hideClearButton: false,
105
+ keyboardType: 'default',
106
+ },
107
+ };
108
+
109
+ export const WithNeutralHint: Story = {
110
+ render: (args) => <TextInputStory {...args} />,
111
+ args: {
112
+ label: 'Address',
113
+ helperText: 'Enter your ETH address',
74
114
  editable: true,
75
115
  hideClearButton: false,
76
116
  keyboardType: 'default',
@@ -0,0 +1,90 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import { ledgerLiveThemes } from '@ledgerhq/lumen-design-core';
3
+ import { render, screen } from '@testing-library/react-native';
4
+ import type { ReactElement } from 'react';
5
+ import { CheckmarkCircleFill } from '../../Symbols/Icons/CheckmarkCircleFill';
6
+ import { DeleteCircleFill } from '../../Symbols/Icons/DeleteCircleFill';
7
+ import { ThemeProvider } from '../ThemeProvider/ThemeProvider';
8
+ import { TextInput } from './TextInput';
9
+
10
+ const { colors } = ledgerLiveThemes.dark;
11
+
12
+ const renderWithProvider = (
13
+ component: ReactElement,
14
+ ): ReturnType<typeof render> => {
15
+ return render(
16
+ <ThemeProvider themes={ledgerLiveThemes} colorScheme='dark' locale='en'>
17
+ {component}
18
+ </ThemeProvider>,
19
+ );
20
+ };
21
+
22
+ describe('TextInput', () => {
23
+ describe('Placeholder and label (BaseInput parity with web)', () => {
24
+ it('uses the provided placeholder when label and placeholder are both set', async () => {
25
+ await renderWithProvider(
26
+ <TextInput
27
+ label='Username'
28
+ placeholder='jane.doe'
29
+ value=''
30
+ onChangeText={() => {}}
31
+ />,
32
+ );
33
+
34
+ expect(screen.getByPlaceholderText('jane.doe')).toBeTruthy();
35
+ });
36
+ });
37
+
38
+ describe('Helper text', () => {
39
+ it('renders neutral helper text without feedback icons', () => {
40
+ renderWithProvider(
41
+ <TextInput label='Address' helperText='Enter your ETH address' />,
42
+ );
43
+
44
+ const helperText = screen.getByText('Enter your ETH address');
45
+
46
+ expect(helperText).toBeTruthy();
47
+ expect(helperText.props.style).toEqual(
48
+ expect.objectContaining({ color: colors.text.muted }),
49
+ );
50
+ expect(screen.UNSAFE_queryByType(DeleteCircleFill)).toBeNull();
51
+ expect(screen.UNSAFE_queryByType(CheckmarkCircleFill)).toBeNull();
52
+ });
53
+
54
+ it('renders error helper text with an error icon', () => {
55
+ renderWithProvider(
56
+ <TextInput
57
+ label='Address'
58
+ helperText='Invalid address format'
59
+ status='error'
60
+ />,
61
+ );
62
+
63
+ const helperText = screen.getByText('Invalid address format');
64
+
65
+ expect(helperText.props.style).toEqual(
66
+ expect.objectContaining({ color: colors.text.error }),
67
+ );
68
+ expect(screen.UNSAFE_getByType(DeleteCircleFill)).toBeTruthy();
69
+ expect(screen.UNSAFE_queryByType(CheckmarkCircleFill)).toBeNull();
70
+ });
71
+
72
+ it('renders success helper text with a success icon', () => {
73
+ renderWithProvider(
74
+ <TextInput
75
+ label='Address'
76
+ helperText='Address verified'
77
+ status='success'
78
+ />,
79
+ );
80
+
81
+ const helperText = screen.getByText('Address verified');
82
+
83
+ expect(helperText.props.style).toEqual(
84
+ expect.objectContaining({ color: colors.text.success }),
85
+ );
86
+ expect(screen.UNSAFE_getByType(CheckmarkCircleFill)).toBeTruthy();
87
+ expect(screen.UNSAFE_queryByType(DeleteCircleFill)).toBeNull();
88
+ });
89
+ });
90
+ });
@@ -8,7 +8,7 @@ import { type TextInputProps } from './types';
8
8
  * - **Automatic clear button** appears when input has content
9
9
  * - **Floating label** with smooth animations
10
10
  * - **Suffix elements** for icons, buttons, or custom content
11
- * - **Error state styling** with errorMessage support
11
+ * - **Helper text** with optional `status` (`error` | `success`) for border and helper feedback styling
12
12
  * - **Container-based spacing** with padding and gap for clean layout
13
13
  * - **Flexible styling** via style props
14
14
  * - **React Native TextInput** with proper mobile behavior
@@ -28,12 +28,13 @@ import { type TextInputProps } from './types';
28
28
  * // Basic input with automatic clear button
29
29
  * <TextInput label="Title" value={title} onChangeText={setTitle} />
30
30
  *
31
- * // Input with error state
31
+ * // Input with error helper
32
32
  * <TextInput
33
33
  * label="Email"
34
34
  * value={email}
35
35
  * onChangeText={setEmail}
36
- * errorMessage="Please enter a valid email address"
36
+ * helperText="Please enter a valid email address"
37
+ * status="error"
37
38
  * />
38
39
  *
39
40
  * // Input with suffix element
@@ -0,0 +1,106 @@
1
+ import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks';
2
+ import * as TrendStories from './Trend.stories';
3
+ import { CustomTabs, Tab } from '../../../../.storybook/components';
4
+ import { DoVsDontRow, DoBlockItem, DontBlockItem } from '../../../../.storybook/components/DoVsDont';
5
+ import CommonRulesDoAndDont from '../../../../.storybook/components/DoVsDont/CommonRulesDoAndDont.mdx';
6
+
7
+ <Meta title='Communication/Trend' of={TrendStories} />
8
+
9
+ # Trend
10
+
11
+ <CustomTabs>
12
+ <Tab label="Overview">
13
+
14
+ ## Introduction
15
+
16
+ A compact indicator used to communicate directional change in a numeric value, typically a percentage. It combines an icon and a formatted label to convey whether a value has gone up, down, or stayed flat.
17
+
18
+ > View in [Figma](https://www.figma.com/design/JxaLVMTWirCpU0rsbZ30k7/2.-Components-Library?node-id=892-5393).
19
+
20
+ ## Anatomy
21
+
22
+ - **Icon:** A directional triangle (up or down) or a minus symbol that visually reinforces the direction of change at a glance.
23
+ - **Value:** The numeric percentage formatted to exactly two decimal places, ensuring consistent alignment across lists and tables.
24
+
25
+ ## Properties
26
+
27
+ ### Overview
28
+
29
+ <Canvas of={TrendStories.Base} />
30
+ <Controls of={TrendStories.Base} />
31
+
32
+ ### Variants
33
+
34
+ The variant is derived automatically from the `value` prop. No manual selection needed! This ensures the color and icon always stay in sync with the actual data.
35
+
36
+ - **Positive** - value greater than 0: green color, triangle up icon
37
+ - **Negative** - value less than 0: red color, triangle down icon
38
+ - **Neutral** - value equal to 0: muted color, minus icon
39
+
40
+ <Canvas of={TrendStories.VariantShowcase} />
41
+
42
+ ---
43
+
44
+ ### Size
45
+
46
+ Two sizes are available to accommodate different layout densities. Use `md` in most contexts and `sm` when space is constrained, such as inside a table cell or a compact list item.
47
+
48
+ - **md** (default) - standard body text and icon sizes
49
+ - **sm** - smaller text and icon, suitable for dense UIs
50
+
51
+ <Canvas of={TrendStories.SizeShowcase} />
52
+
53
+ ---
54
+
55
+ ### Disabled
56
+
57
+ When `disabled` is `true`, the icon and text both render in a muted, non-interactive style regardless of the underlying value. Use this when the data is unavailable, loading, or the surrounding context is non-interactive.
58
+
59
+ <Canvas of={TrendStories.DisabledShowcase} />
60
+
61
+ </Tab>
62
+ <Tab label="Implementation">
63
+
64
+ ## Setup
65
+
66
+ Install and set up the library with our [Setup Guide →](?path=/docs/getting-started-setup--docs).
67
+
68
+ ### Basic Usage
69
+
70
+ Pass any numeric value - the component handles color, icon, and formatting automatically.
71
+
72
+ ```tsx
73
+ import { Trend } from '@ledgerhq/lumen-ui-rnative';
74
+
75
+ function MyComponent() {
76
+ return <Trend value={5.25} />;
77
+ }
78
+ ```
79
+
80
+ ### Sizes
81
+
82
+ Choose `sm` for dense layouts like tables or compact list rows, and `md` for standard content areas.
83
+
84
+ ```tsx
85
+ <Trend value={3.14} size='md' />
86
+ <Trend value={3.14} size='sm' />
87
+ ```
88
+
89
+ ### Disabled State
90
+
91
+ Wrap or pass `disabled` when the value is unavailable or the parent context is non-interactive. The component style updates automatically - no extra styling needed.
92
+
93
+ ```tsx
94
+ <Trend value={5.25} disabled />
95
+ ```
96
+
97
+ ### Layout Adjustments
98
+
99
+ Use `lx` for layout only - not for overriding colors or typography. The component's visual appearance is controlled exclusively via props.
100
+
101
+ ```tsx
102
+ <Trend value={-1.5} lx={{ marginTop: 's4' }} />
103
+ ```
104
+
105
+ </Tab>
106
+ </CustomTabs>
@@ -0,0 +1,61 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-native-web-vite';
2
+ import { Box } from '../Utility/Box';
3
+ import { Trend } from './Trend';
4
+
5
+ const meta: Meta<typeof Trend> = {
6
+ component: Trend,
7
+ title: 'Communication/Trend',
8
+ argTypes: {
9
+ value: {
10
+ control: 'number',
11
+ },
12
+ size: {
13
+ control: 'radio',
14
+ options: ['sm', 'md'],
15
+ },
16
+ disabled: {
17
+ control: 'boolean',
18
+ },
19
+ },
20
+ };
21
+
22
+ export default meta;
23
+
24
+ type Story = StoryObj<typeof Trend>;
25
+
26
+ export const Base: Story = {
27
+ args: {
28
+ value: 5.25,
29
+ size: 'md',
30
+ disabled: false,
31
+ },
32
+ };
33
+
34
+ export const VariantShowcase: Story = {
35
+ render: () => (
36
+ <Box lx={{ flexDirection: 'column', gap: 's8' }}>
37
+ <Trend value={5.25} />
38
+ <Trend value={-3.14} />
39
+ <Trend value={0} />
40
+ </Box>
41
+ ),
42
+ };
43
+
44
+ export const SizeShowcase: Story = {
45
+ render: () => (
46
+ <Box lx={{ flexDirection: 'row', alignItems: 'center', gap: 's16' }}>
47
+ <Trend value={5.25} size='md' />
48
+ <Trend value={5.25} size='sm' />
49
+ </Box>
50
+ ),
51
+ };
52
+
53
+ export const DisabledShowcase: Story = {
54
+ render: () => (
55
+ <Box lx={{ flexDirection: 'column', gap: 's8' }}>
56
+ <Trend value={5.25} disabled />
57
+ <Trend value={-3.14} disabled />
58
+ <Trend value={0} disabled />
59
+ </Box>
60
+ ),
61
+ };
@@ -0,0 +1,125 @@
1
+ import { describe, it, expect } from '@jest/globals';
2
+ import { ledgerLiveThemes } from '@ledgerhq/lumen-design-core';
3
+ import { render } from '@testing-library/react-native';
4
+ import { ThemeProvider } from '../ThemeProvider/ThemeProvider';
5
+ import { Trend } from './Trend';
6
+
7
+ const TestWrapper = ({ children }: { children: React.ReactNode }) => (
8
+ <ThemeProvider themes={ledgerLiveThemes} colorScheme='dark' locale='en'>
9
+ {children}
10
+ </ThemeProvider>
11
+ );
12
+
13
+ describe('Trend Component', () => {
14
+ it('should render positive value', () => {
15
+ const { getByText } = render(
16
+ <TestWrapper>
17
+ <Trend value={5.5} />
18
+ </TestWrapper>,
19
+ );
20
+ expect(getByText('5.50%')).toBeTruthy();
21
+ });
22
+
23
+ it('should render negative value', () => {
24
+ const { getByText } = render(
25
+ <TestWrapper>
26
+ <Trend value={-3.2} />
27
+ </TestWrapper>,
28
+ );
29
+ expect(getByText('-3.20%')).toBeTruthy();
30
+ });
31
+
32
+ it('should render neutral when value is zero', () => {
33
+ const { getByText } = render(
34
+ <TestWrapper>
35
+ <Trend value={0} />
36
+ </TestWrapper>,
37
+ );
38
+ expect(getByText('0.00%')).toBeTruthy();
39
+ });
40
+
41
+ it('should render with sm size', () => {
42
+ const { getByText } = render(
43
+ <TestWrapper>
44
+ <Trend value={1.5} size='sm' />
45
+ </TestWrapper>,
46
+ );
47
+ expect(getByText('1.50%')).toBeTruthy();
48
+ });
49
+
50
+ it('should render with md size', () => {
51
+ const { getByText } = render(
52
+ <TestWrapper>
53
+ <Trend value={1.5} size='md' />
54
+ </TestWrapper>,
55
+ );
56
+ expect(getByText('1.50%')).toBeTruthy();
57
+ });
58
+
59
+ it('should render in disabled state', () => {
60
+ const { getByText } = render(
61
+ <TestWrapper>
62
+ <Trend value={5} disabled />
63
+ </TestWrapper>,
64
+ );
65
+ expect(getByText('5.00%')).toBeTruthy();
66
+ });
67
+
68
+ it('should pass testID to root element', () => {
69
+ const { getByTestId } = render(
70
+ <TestWrapper>
71
+ <Trend testID='trend-id' value={10} />
72
+ </TestWrapper>,
73
+ );
74
+ expect(getByTestId('trend-id')).toBeTruthy();
75
+ });
76
+
77
+ it('should format value to 2 decimal places', () => {
78
+ const { getByText } = render(
79
+ <TestWrapper>
80
+ <Trend value={1.123456} />
81
+ </TestWrapper>,
82
+ );
83
+ expect(getByText('1.12%')).toBeTruthy();
84
+ });
85
+
86
+ it('should render all variants side by side', () => {
87
+ const { getByText } = render(
88
+ <TestWrapper>
89
+ <Trend value={10} />
90
+ <Trend value={-10} />
91
+ <Trend value={0} />
92
+ </TestWrapper>,
93
+ );
94
+ expect(getByText('10.00%')).toBeTruthy();
95
+ expect(getByText('-10.00%')).toBeTruthy();
96
+ expect(getByText('0.00%')).toBeTruthy();
97
+ });
98
+
99
+ it('should expose positive accessibility label', () => {
100
+ const { getByLabelText } = render(
101
+ <TestWrapper>
102
+ <Trend value={5.5} />
103
+ </TestWrapper>,
104
+ );
105
+ expect(getByLabelText('Trending up by 5.50%')).toBeTruthy();
106
+ });
107
+
108
+ it('should expose negative accessibility label with absolute value', () => {
109
+ const { getByLabelText } = render(
110
+ <TestWrapper>
111
+ <Trend value={-3.2} />
112
+ </TestWrapper>,
113
+ );
114
+ expect(getByLabelText('Trending down by 3.20%')).toBeTruthy();
115
+ });
116
+
117
+ it('should expose neutral accessibility label', () => {
118
+ const { getByLabelText } = render(
119
+ <TestWrapper>
120
+ <Trend value={0} />
121
+ </TestWrapper>,
122
+ );
123
+ expect(getByLabelText('No change, 0.00%')).toBeTruthy();
124
+ });
125
+ });
@@ -0,0 +1,118 @@
1
+ import { useDisabledContext } from '@ledgerhq/lumen-utils-shared';
2
+ import { StyleSheet } from 'react-native';
3
+ import { useCommonTranslation } from '../../../i18n';
4
+ import type { LumenTextStyle } from '../../../styles';
5
+ import { useStyleSheet } from '../../../styles';
6
+ import { Minus, TriangleDown, TriangleUp } from '../../Symbols';
7
+ import type { IconSize } from '../Icon';
8
+ import { Box, Text } from '../Utility';
9
+ import type { TrendProps } from './types';
10
+
11
+ type TrendVariant = 'positive' | 'negative' | 'neutral';
12
+
13
+ function getVariant(value: number): TrendVariant {
14
+ if (value === 0) {
15
+ return 'neutral';
16
+ }
17
+ return value > 0 ? 'positive' : 'negative';
18
+ }
19
+
20
+ export function Trend({
21
+ value,
22
+ size = 'md',
23
+ lx = {},
24
+ disabled: disabledProp = false,
25
+ style,
26
+ ...props
27
+ }: TrendProps) {
28
+ const variant = getVariant(value);
29
+
30
+ const disabled = useDisabledContext({
31
+ consumerName: 'Trend',
32
+ mergeWith: { disabled: disabledProp },
33
+ });
34
+ const { t } = useCommonTranslation();
35
+
36
+ const styles = useStyles({ size, variant, disabled });
37
+
38
+ const Icon = {
39
+ positive: TriangleUp,
40
+ negative: TriangleDown,
41
+ neutral: Minus,
42
+ }[variant];
43
+
44
+ const iconSize = (
45
+ {
46
+ md: 16,
47
+ sm: 12,
48
+ } as const
49
+ )[size] as IconSize;
50
+
51
+ const iconColor = (
52
+ {
53
+ positive: 'success',
54
+ negative: 'error',
55
+ neutral: 'muted',
56
+ } as const
57
+ )[variant] as LumenTextStyle['color'];
58
+
59
+ const absoluteFormattedValue = `${Math.abs(value).toFixed(2)}%`;
60
+ const formattedValue =
61
+ value < 0 ? `-${absoluteFormattedValue}` : absoluteFormattedValue;
62
+
63
+ return (
64
+ <Box
65
+ accessible
66
+ accessibilityLabel={t(`components.trend.${variant}AriaLabel`, {
67
+ value: absoluteFormattedValue,
68
+ })}
69
+ accessibilityState={{ disabled }}
70
+ lx={lx}
71
+ style={[styles.container, style]}
72
+ {...props}
73
+ >
74
+ <Icon size={iconSize} color={disabled ? 'disabled' : iconColor} />
75
+ <Text style={styles.text}>{formattedValue}</Text>
76
+ </Box>
77
+ );
78
+ }
79
+
80
+ const useStyles = ({
81
+ size,
82
+ variant,
83
+ disabled,
84
+ }: {
85
+ size: NonNullable<TrendProps['size']>;
86
+ variant: TrendVariant;
87
+ disabled: boolean;
88
+ }) =>
89
+ useStyleSheet(
90
+ (t) => {
91
+ const color = {
92
+ positive: t.colors.text.success,
93
+ negative: t.colors.text.error,
94
+ neutral: t.colors.text.muted,
95
+ }[variant];
96
+
97
+ const sizeMap = {
98
+ sm: t.typographies.body3,
99
+ md: t.typographies.body2,
100
+ }[size];
101
+
102
+ return {
103
+ container: {
104
+ flexDirection: 'row',
105
+ alignItems: 'center',
106
+ gap: t.spacings.s2,
107
+ },
108
+ text: StyleSheet.flatten([
109
+ {
110
+ ...sizeMap,
111
+ color,
112
+ },
113
+ disabled && { color: t.colors.text.disabled },
114
+ ]),
115
+ };
116
+ },
117
+ [size, variant, disabled],
118
+ );
@@ -0,0 +1,2 @@
1
+ export * from './Trend';
2
+ export * from './types';
@@ -0,0 +1,20 @@
1
+ import type { BoxProps } from '../Utility';
2
+
3
+ export type TrendProps = {
4
+ /**
5
+ * The value to display in the trend. This value affects the appearance of the component in terms of color and icon.
6
+ * @required
7
+ */
8
+ value: number;
9
+ /**
10
+ * The size of the trend component.
11
+ * @default md
12
+ */
13
+ size?: 'sm' | 'md';
14
+ /**
15
+ * When `true`, shows a muted appearance on the trend, regardless of value.
16
+ *
17
+ * @default false
18
+ */
19
+ disabled?: boolean;
20
+ } & Omit<BoxProps, 'children'>;
@@ -4,15 +4,15 @@ export * from './AmountInput';
4
4
  export * from './Avatar';
5
5
  export * from './Banner';
6
6
  export * from './BottomSheet';
7
- export * from './DotCount';
8
- export * from './DotIndicator';
9
7
  export * from './Button';
10
8
  export * from './Card';
11
9
  export * from './CardButton';
12
- export * from './ContentBanner';
13
10
  export * from './Checkbox';
11
+ export * from './ContentBanner';
14
12
  export * from './Divider';
13
+ export * from './DotCount';
15
14
  export * from './DotIcon';
15
+ export * from './DotIndicator';
16
16
  export * from './DotSymbol';
17
17
  export * from './Icon';
18
18
  export * from './IconButton';
@@ -37,9 +37,10 @@ export * from './Subheader';
37
37
  export * from './Switch';
38
38
  export * from './TabBar';
39
39
  export * from './Tag';
40
- export * from './Utility';
41
40
  export * from './TextInput';
42
41
  export * from './ThemeProvider';
43
42
  export * from './Tile';
44
43
  export * from './TileButton';
45
44
  export * from './Tooltip';
45
+ export * from './Trend';
46
+ export * from './Utility';
@@ -36,11 +36,11 @@ export const Ar = createIcon(
36
36
  <Svg width={24} height={24} fill='currentColor' viewBox='0 0 17 16'>
37
37
  <Path
38
38
  fill='currentColor'
39
- d='M8.197 4.967a.166.166 0 1 1-.333 0 .166.166 0 0 1 .333 0m-3.848 6.83a.167.167 0 0 1-.23-.053.167.167 0 0 1 .283-.176.167.167 0 0 1-.053.229m3.848-6.164a.167.167 0 0 1-.166.167.17.17 0 0 1-.168-.167.167.167 0 0 1 .333 0m-3.283 5.812a.166.166 0 1 1-.176-.282.166.166 0 0 1 .176.282M8.197 6.3a.167.167 0 0 1-.166.167.17.17 0 0 1-.167-.167.166.166 0 1 1 .333 0M5.48 11.093a.166.166 0 1 1-.176-.282.166.166 0 0 1 .176.282m2.717-4.126a.166.166 0 1 1-.333 0 .166.166 0 0 1 .333 0m-2.15 3.774a.166.166 0 1 1 .054-.229.166.166 0 0 1-.054.229m2.15-3.108a.167.167 0 0 1-.334 0 .167.167 0 0 1 .334 0M6.612 10.39a.166.166 0 0 1-.228-.054.167.167 0 0 1 .052-.23.167.167 0 1 1 .176.283m.567-.352a.166.166 0 1 1-.175-.283.167.167 0 0 1 .23.054.167.167 0 0 1-.055.229M8.196 8.3a.167.167 0 0 1-.165.167.167.167 0 1 1 0-.334c.092 0 .165.075.165.167m.731 1.777a.167.167 0 1 1-.288-.166.167.167 0 0 1 .288.166m.577.333a.167.167 0 1 1-.289-.165.167.167 0 0 1 .289.165m.578.334a.167.167 0 0 1-.229.061.167.167 0 0 1 .167-.288c.08.046.107.147.062.227m.577.333a.167.167 0 1 1-.288-.166.167.167 0 0 1 .288.166m.577.333a.166.166 0 1 1-.289-.165.166.166 0 0 1 .289.165m.578.334a.167.167 0 0 1-.229.061.166.166 0 1 1 .228-.061'
39
+ d='M8.197 4.967a.166.166 0 1 1-.333 0 .166.166 0 0 1 .333 0m-3.848 6.83a.167.167 0 0 1-.23-.053.167.167 0 0 1 .283-.176.167.167 0 0 1-.053.229m3.848-6.164a.167.167 0 0 1-.166.167.17.17 0 0 1-.167-.167.167.167 0 0 1 .333 0m-3.283 5.812a.166.166 0 1 1-.176-.283.166.166 0 0 1 .176.283M8.197 6.3a.167.167 0 1 1-.334 0 .167.167 0 0 1 .334 0M5.48 11.093a.166.166 0 1 1-.175-.282.166.166 0 0 1 .175.282m2.717-4.126a.166.166 0 1 1-.333 0 .166.166 0 0 1 .333 0m-2.15 3.774a.166.166 0 1 1-.177-.282.166.166 0 0 1 .177.282m2.15-3.108a.167.167 0 0 1-.334 0 .167.167 0 0 1 .334 0M6.612 10.39a.166.166 0 1 1-.175-.283.166.166 0 0 1 .175.283m.567-.352a.166.166 0 1 1-.176-.283.166.166 0 0 1 .176.283M8.197 8.3a.167.167 0 0 1-.166.167.167.167 0 1 1 0-.334c.092 0 .166.075.166.167m.73 1.777a.167.167 0 1 1-.288-.166.167.167 0 0 1 .288.166m.577.333a.167.167 0 1 1-.289-.165.167.167 0 0 1 .289.165m.578.334a.167.167 0 0 1-.228.061.166.166 0 1 1 .228-.061m.577.333a.167.167 0 1 1-.288-.166.167.167 0 0 1 .288.166m.577.333a.167.167 0 1 1-.289-.165.167.167 0 0 1 .29.165m.578.334a.167.167 0 0 1-.228.061.166.166 0 1 1 .228-.061'
40
40
  />
41
41
  <Path
42
42
  fill='currentColor'
43
- d='m3.364 7-.291-.581a.65.65 0 0 0-.36.581zm9 0h.65a.65.65 0 0 0-.342-.572zM8.03 14.667l-.29.581a.65.65 0 0 0 .599-.009zM8.013 1.349l.46-.46-.46-.459-.46.46zm-1.843.924a.65.65 0 1 0 .92.919l-.46-.46zm2.766.919a.65.65 0 1 0 .92-.92l-.46.46zM.775 13.966l-.635-.14-.14.634.635.14zm1.77 1.056a.65.65 0 0 0 .28-1.27l-.14.635zm-.714-2.826a.65.65 0 1 0-1.27-.28l.635.14zm13.116 1.77.14.634.635-.14-.14-.634zm-2.05-.214a.65.65 0 0 0 .28 1.27l-.14-.635zm2.263-1.836a.65.65 0 0 0-1.27.28l.636-.14zm-11.796.417h.65V7h-1.3v5.333zm0-5.333.29.581 4.667-2.333-.29-.581-.291-.582L3.073 6.42zM8.03 4.667l-.308.572 4.334 2.333.308-.572.308-.572-4.333-2.334zM12.364 7h-.65v5.333h1.3V7zm0 5.333-.309-.572-4.333 2.333.308.573.309.572 4.333-2.333zM8.03 14.667l.291-.582-4.667-2.333-.29.581-.291.582 4.667 2.333zM12.364 7l-.327-.562L7.73 8.94l.326.562.327.562 4.308-2.502zM8.055 9.502h-.65v5.172h1.3V9.502zm0 0 .306-.573L3.67 6.426 3.364 7l-.306.574 4.691 2.502zM8.03 4.667l.65-.004-.017-3.317-.65.003-.65.004.017 3.317zm-1.4-1.935.46.46 1.382-1.383-.46-.46-.459-.46L6.17 2.274zM8.013 1.35l-.46.46 1.383 1.383.46-.46.46-.46L8.471.89zm-4.65 10.984-.346-.55-2.589 1.633.347.55.346.55 2.59-1.633zm-.678 2.054.14-.635-1.91-.421-.14.635-.14.634 1.91.422zm-1.91-.421.634.14.422-1.91-.635-.14-.635-.14-.421 1.91zm11.589-1.633-.348.55 2.584 1.632.347-.55.347-.549-2.583-1.632zm.673 2.054.14.635 1.91-.422-.14-.634-.14-.635-1.91.421zm1.91-.421.635-.14-.422-1.91-.634.14-.635.14.421 1.91z'
43
+ d='m3.364 7-.29-.581a.65.65 0 0 0-.36.581zm9 0h.65a.65.65 0 0 0-.342-.572zM8.03 14.667l-.29.581a.65.65 0 0 0 .599-.009zM8.013 1.349l.46-.46-.46-.459-.46.46zm-1.843.924a.65.65 0 1 0 .92.919l-.46-.46zm2.766.919a.65.65 0 1 0 .92-.92l-.46.46zM.775 13.966l-.635-.14-.14.634.635.14zm1.77 1.056a.65.65 0 1 0 .28-1.27l-.14.635zm-.714-2.826a.65.65 0 0 0-1.27-.28l.635.14zm13.116 1.77.14.634.635-.14-.14-.634zm-2.05-.214a.65.65 0 0 0 .28 1.27l-.14-.635zm2.263-1.836a.65.65 0 0 0-1.27.28l.636-.14zm-11.796.417h.65V7h-1.3v5.333zm0-5.333.29.581 4.667-2.333-.29-.581-.291-.582L3.073 6.42zM8.03 4.667l-.308.572 4.334 2.333.308-.572.308-.572-4.333-2.334zM12.364 7h-.65v5.333h1.3V7zm0 5.333-.308-.572-4.334 2.333.308.573.309.572 4.333-2.333zM8.03 14.667l.291-.582-4.667-2.333-.29.581-.29.582 4.666 2.333zM12.364 7l-.327-.562L7.73 8.94l.326.562.327.562 4.308-2.502zM8.055 9.502h-.65v5.172h1.3V9.502zm0 0 .306-.573L3.67 6.426 3.364 7l-.306.574 4.691 2.502zM8.03 4.667l.65-.004-.017-3.317-.65.003-.65.004.017 3.317zm-1.4-1.935.46.46 1.382-1.383-.46-.46-.459-.46L6.17 2.274zM8.013 1.35l-.46.46 1.383 1.383.46-.46.46-.46L8.471.89zm-4.65 10.984-.346-.55-2.589 1.633.347.55.346.55 2.59-1.633zm-.678 2.054.14-.635-1.91-.421-.14.635-.14.634 1.91.422zm-1.91-.421.635.14.42-1.91-.634-.14-.635-.14-.421 1.91zm11.589-1.633-.348.55 2.584 1.632.347-.55.347-.549-2.583-1.632zm.673 2.054.14.635 1.91-.422-.14-.634-.14-.635-1.91.421zm1.91-.421.635-.14-.422-1.91-.634.14-.635.14.421 1.91z'
44
44
  />
45
45
  </Svg>,
46
46
  );
@@ -39,7 +39,7 @@ export const ArrowLeft = createIcon(
39
39
  strokeLinecap='round'
40
40
  strokeLinejoin='round'
41
41
  strokeWidth={1.3}
42
- d='M3.333 8h9.334M3.333 8l3.334-3.333M3.333 8l3.334 3.333'
42
+ d='M3.333 8h9.334m-6 3.333L3.333 8l3.334-3.333'
43
43
  />
44
44
  </Svg>,
45
45
  );
@@ -39,7 +39,7 @@ export const ArrowRight = createIcon(
39
39
  strokeLinecap='round'
40
40
  strokeLinejoin='round'
41
41
  strokeWidth={1.3}
42
- d='M12.667 8H3.333m9.334 0-3.334 3.333M12.667 8 9.333 4.667'
42
+ d='M12.667 8H3.333m6-3.333L12.667 8l-3.334 3.333'
43
43
  />
44
44
  </Svg>,
45
45
  );