@utilitywarehouse/hearth-react-native 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/CHANGELOG.md +44 -0
  4. package/build/components/Alert/AlertTitle.js +6 -6
  5. package/build/components/Badge/Badge.js +3 -3
  6. package/build/components/Badge/Badge.props.d.ts +1 -0
  7. package/build/components/Button/ButtonRoot.js +4 -0
  8. package/build/components/Button/ButtonText.js +2 -2
  9. package/build/components/Card/CardRoot.js +1 -1
  10. package/build/components/Carousel/Carousel.context.d.ts +4 -0
  11. package/build/components/Carousel/Carousel.context.js +4 -0
  12. package/build/components/Carousel/Carousel.d.ts +6 -0
  13. package/build/components/Carousel/Carousel.js +278 -0
  14. package/build/components/Carousel/Carousel.props.d.ts +65 -0
  15. package/build/components/Carousel/Carousel.props.js +1 -0
  16. package/build/components/Carousel/CarouselControlItem.d.ts +24 -0
  17. package/build/components/Carousel/CarouselControlItem.js +64 -0
  18. package/build/components/Carousel/CarouselControls.d.ts +4 -0
  19. package/build/components/Carousel/CarouselControls.js +74 -0
  20. package/build/components/Carousel/CarouselItem.d.ts +6 -0
  21. package/build/components/Carousel/CarouselItem.js +38 -0
  22. package/build/components/Carousel/index.d.ts +5 -0
  23. package/build/components/Carousel/index.js +5 -0
  24. package/build/components/DescriptionList/DescriptionList.d.ts +1 -1
  25. package/build/components/DescriptionList/DescriptionList.js +2 -2
  26. package/build/components/DescriptionList/DescriptionList.props.d.ts +1 -8
  27. package/build/components/DescriptionList/DescriptionListItem.d.ts +1 -1
  28. package/build/components/DescriptionList/DescriptionListItem.js +4 -3
  29. package/build/components/DescriptionList/DescriptionListItem.props.d.ts +3 -8
  30. package/build/components/IndicatorIconButton/IndicatorIconButton.d.ts +6 -0
  31. package/build/components/IndicatorIconButton/IndicatorIconButton.js +26 -0
  32. package/build/components/IndicatorIconButton/IndicatorIconButton.props.d.ts +8 -0
  33. package/build/components/IndicatorIconButton/IndicatorIconButton.props.js +1 -0
  34. package/build/components/IndicatorIconButton/index.d.ts +2 -0
  35. package/build/components/IndicatorIconButton/index.js +1 -0
  36. package/build/components/Link/LinkText.js +3 -3
  37. package/build/components/List/List.context.d.ts +0 -2
  38. package/build/components/List/List.d.ts +1 -1
  39. package/build/components/List/List.js +5 -5
  40. package/build/components/List/List.props.d.ts +1 -9
  41. package/build/components/List/ListAction/ListAction.d.ts +18 -0
  42. package/build/components/List/ListAction/ListAction.js +103 -0
  43. package/build/components/List/ListAction/ListAction.props.d.ts +8 -0
  44. package/build/components/List/ListAction/ListAction.props.js +1 -0
  45. package/build/components/List/ListAction/ListActionContent.d.ts +6 -0
  46. package/build/components/List/ListAction/ListActionContent.js +14 -0
  47. package/build/components/List/ListAction/ListActionText.d.ts +6 -0
  48. package/build/components/List/ListAction/ListActionText.js +7 -0
  49. package/build/components/List/ListAction/ListActionTrailingContent.d.ts +6 -0
  50. package/build/components/List/ListAction/ListActionTrailingContent.js +5 -0
  51. package/build/components/List/ListAction/ListActionTrailingIcon.d.ts +9 -0
  52. package/build/components/List/ListAction/ListActionTrailingIcon.js +18 -0
  53. package/build/components/List/ListAction/index.d.ts +6 -0
  54. package/build/components/List/ListAction/index.js +5 -0
  55. package/build/components/List/ListItem/ListItem.context.d.ts +1 -1
  56. package/build/components/List/ListItem/ListItem.props.d.ts +9 -5
  57. package/build/components/List/ListItem/ListItemRoot.d.ts +1 -1
  58. package/build/components/List/ListItem/ListItemRoot.js +10 -12
  59. package/build/components/List/ListItem/index.d.ts +4 -4
  60. package/build/components/List/ListItem/index.js +3 -3
  61. package/build/components/List/index.d.ts +1 -0
  62. package/build/components/List/index.js +1 -0
  63. package/build/components/ProgressStepper/ProgressStep.d.ts +10 -0
  64. package/build/components/ProgressStepper/ProgressStep.js +100 -0
  65. package/build/components/ProgressStepper/ProgressStepper.d.ts +6 -0
  66. package/build/components/ProgressStepper/ProgressStepper.js +22 -0
  67. package/build/components/ProgressStepper/ProgressStepper.props.d.ts +22 -0
  68. package/build/components/ProgressStepper/ProgressStepper.props.js +1 -0
  69. package/build/components/ProgressStepper/ProgressStepperRoot.d.ts +6 -0
  70. package/build/components/ProgressStepper/ProgressStepperRoot.js +16 -0
  71. package/build/components/ProgressStepper/index.d.ts +3 -0
  72. package/build/components/ProgressStepper/index.js +2 -0
  73. package/build/components/SectionHeader/SectionHeader.d.ts +1 -1
  74. package/build/components/SectionHeader/SectionHeader.js +6 -3
  75. package/build/components/SectionHeader/SectionHeader.props.d.ts +9 -16
  76. package/build/components/SectionHeader/SectionHeaderTrailingContent.d.ts +6 -0
  77. package/build/components/SectionHeader/SectionHeaderTrailingContent.js +13 -0
  78. package/build/components/SectionHeader/index.d.ts +1 -0
  79. package/build/components/SectionHeader/index.js +1 -0
  80. package/build/components/Tabs/Tab.js +2 -2
  81. package/build/components/ToggleButton/ToggleButtonText.js +2 -2
  82. package/build/components/UnstyledIconButton/UnstyledIconButton.props.d.ts +4 -1
  83. package/build/components/index.d.ts +3 -0
  84. package/build/components/index.js +3 -0
  85. package/build/core/themes.d.ts +12 -24
  86. package/build/tokens/components/dark/button.d.ts +1 -1
  87. package/build/tokens/components/dark/button.js +1 -1
  88. package/build/tokens/components/dark/dialog.d.ts +1 -0
  89. package/build/tokens/components/dark/dialog.js +1 -0
  90. package/build/tokens/components/dark/illustrations.d.ts +1 -0
  91. package/build/tokens/components/dark/illustrations.js +1 -0
  92. package/build/tokens/components/dark/toast.d.ts +4 -1
  93. package/build/tokens/components/dark/toast.js +4 -1
  94. package/build/tokens/components/light/button.d.ts +1 -1
  95. package/build/tokens/components/light/button.js +1 -1
  96. package/build/tokens/components/light/dialog.d.ts +1 -0
  97. package/build/tokens/components/light/dialog.js +1 -0
  98. package/build/tokens/components/light/illustrations.d.ts +1 -0
  99. package/build/tokens/components/light/illustrations.js +1 -0
  100. package/build/tokens/components/light/toast.d.ts +4 -1
  101. package/build/tokens/components/light/toast.js +4 -1
  102. package/build/tokens/layout.d.ts +6 -12
  103. package/build/tokens/layout.js +3 -6
  104. package/docs/components/AllComponents.web.tsx +86 -4
  105. package/docs/components/BadgeList.tsx +20 -56
  106. package/docs/components/SwitchList.tsx +4 -8
  107. package/docs/getting-started.mdx +30 -14
  108. package/docs/introduction.mdx +1 -1
  109. package/package.json +4 -4
  110. package/src/components/Alert/AlertTitle.tsx +7 -7
  111. package/src/components/Badge/Badge.props.ts +1 -0
  112. package/src/components/Badge/Badge.tsx +3 -2
  113. package/src/components/Button/ButtonRoot.tsx +4 -0
  114. package/src/components/Button/ButtonText.tsx +3 -3
  115. package/src/components/Card/CardRoot.tsx +2 -0
  116. package/src/components/Carousel/Carousel.context.tsx +8 -0
  117. package/src/components/Carousel/Carousel.docs.mdx +389 -0
  118. package/src/components/Carousel/Carousel.props.ts +89 -0
  119. package/src/components/Carousel/Carousel.stories.tsx +317 -0
  120. package/src/components/Carousel/Carousel.tsx +444 -0
  121. package/src/components/Carousel/CarouselControlItem.tsx +87 -0
  122. package/src/components/Carousel/CarouselControls.tsx +150 -0
  123. package/src/components/Carousel/CarouselItem.tsx +68 -0
  124. package/src/components/Carousel/index.ts +6 -0
  125. package/src/components/DescriptionList/DescriptionList.docs.mdx +24 -27
  126. package/src/components/DescriptionList/DescriptionList.props.ts +1 -8
  127. package/src/components/DescriptionList/DescriptionList.stories.tsx +13 -19
  128. package/src/components/DescriptionList/DescriptionList.tsx +2 -14
  129. package/src/components/DescriptionList/DescriptionListItem.props.ts +3 -8
  130. package/src/components/DescriptionList/DescriptionListItem.tsx +13 -21
  131. package/src/components/IndicatorIconButton/IndicatorIconButton.docs.mdx +85 -0
  132. package/src/components/IndicatorIconButton/IndicatorIconButton.props.ts +12 -0
  133. package/src/components/IndicatorIconButton/IndicatorIconButton.stories.tsx +142 -0
  134. package/src/components/IndicatorIconButton/IndicatorIconButton.tsx +36 -0
  135. package/src/components/IndicatorIconButton/index.tsx +2 -0
  136. package/src/components/Link/LinkText.tsx +4 -4
  137. package/src/components/List/List.context.ts +0 -1
  138. package/src/components/List/List.docs.mdx +376 -179
  139. package/src/components/List/List.props.ts +1 -9
  140. package/src/components/List/List.stories.tsx +289 -38
  141. package/src/components/List/List.tsx +5 -26
  142. package/src/components/List/ListAction/ListAction.props.ts +10 -0
  143. package/src/components/List/ListAction/ListAction.tsx +133 -0
  144. package/src/components/List/ListAction/ListActionContent.tsx +21 -0
  145. package/src/components/List/ListAction/ListActionText.tsx +14 -0
  146. package/src/components/List/ListAction/ListActionTrailingContent.tsx +9 -0
  147. package/src/components/List/ListAction/ListActionTrailingIcon.tsx +32 -0
  148. package/src/components/List/ListAction/index.ts +6 -0
  149. package/src/components/List/ListItem/ListItem.context.ts +1 -1
  150. package/src/components/List/ListItem/ListItem.props.ts +9 -5
  151. package/src/components/List/ListItem/ListItemRoot.tsx +18 -14
  152. package/src/components/List/ListItem/index.ts +4 -4
  153. package/src/components/List/index.ts +1 -0
  154. package/src/components/ProgressStepper/ProgressStep.tsx +134 -0
  155. package/src/components/ProgressStepper/ProgressStepper.docs.mdx +87 -0
  156. package/src/components/ProgressStepper/ProgressStepper.props.ts +27 -0
  157. package/src/components/ProgressStepper/ProgressStepper.stories.tsx +108 -0
  158. package/src/components/ProgressStepper/ProgressStepper.tsx +26 -0
  159. package/src/components/ProgressStepper/ProgressStepperRoot.tsx +32 -0
  160. package/src/components/ProgressStepper/index.ts +3 -0
  161. package/src/components/SectionHeader/SectionHeader.props.ts +9 -16
  162. package/src/components/SectionHeader/SectionHeader.stories.tsx +28 -18
  163. package/src/components/SectionHeader/SectionHeader.tsx +18 -19
  164. package/src/components/SectionHeader/SectionHeaderTrailingContent.tsx +20 -0
  165. package/src/components/SectionHeader/Sectionheader.docs.mdx +9 -24
  166. package/src/components/SectionHeader/index.ts +1 -0
  167. package/src/components/Switch/Switch.docs.mdx +0 -4
  168. package/src/components/Tabs/Tab.tsx +4 -2
  169. package/src/components/ToggleButton/ToggleButtonText.tsx +3 -3
  170. package/src/components/UnstyledIconButton/UnstyledIconButton.props.ts +2 -1
  171. package/src/components/index.ts +3 -0
  172. package/src/tokens/components/dark/button.ts +1 -1
  173. package/src/tokens/components/dark/dialog.ts +1 -0
  174. package/src/tokens/components/dark/illustrations.ts +1 -0
  175. package/src/tokens/components/dark/toast.ts +4 -1
  176. package/src/tokens/components/light/button.ts +1 -1
  177. package/src/tokens/components/light/dialog.ts +1 -0
  178. package/src/tokens/components/light/illustrations.ts +1 -0
  179. package/src/tokens/components/light/toast.ts +4 -1
  180. package/src/tokens/layout.ts +3 -6
@@ -1,9 +1,23 @@
1
- import React, { FC, PropsWithChildren } from 'react';
2
- import { List, ListItem, ListItemIcon, ListItemTrailingIcon } from '.';
3
1
  import { Meta, StoryObj } from '@storybook/react-vite';
2
+ import {
3
+ BillMediumIcon,
4
+ ChevronRightSmallIcon,
5
+ ElectricityMediumIcon,
6
+ GasMediumIcon,
7
+ HomeMediumIcon,
8
+ PaymentMediumIcon,
9
+ SettingsMediumIcon,
10
+ UserMediumIcon,
11
+ } from '@utilitywarehouse/hearth-react-native-icons';
12
+ import { FC, PropsWithChildren, useState } from 'react';
13
+ import { List, ListAction, ListItem, ListItemIcon, ListItemTrailingIcon } from '.';
4
14
  import { VariantTitle } from '../../../docs/components';
5
- import { SettingsMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
15
+ import { Badge } from '../Badge';
16
+ import { BodyText } from '../BodyText';
6
17
  import { Flex } from '../Flex';
18
+ import { IconContainer } from '../IconContainer';
19
+ import { Link } from '../Link';
20
+ import { Switch } from '../Switch';
7
21
  // import { Card } from '../Card';
8
22
 
9
23
  const Card: FC<PropsWithChildren> = ({ children }) => <div>{children}</div>;
@@ -27,11 +41,6 @@ const meta = {
27
41
  description:
28
42
  'The heading supporting text to be displayed on the list. \n _Note: This is a playground prop, use helperText on the SectionHeader component._',
29
43
  },
30
- divider: {
31
- control: 'boolean',
32
- description: 'Whether to display a divider below the list item.',
33
- },
34
-
35
44
  disabled: {
36
45
  control: 'boolean',
37
46
  description: 'Whether the list item is disabled.',
@@ -45,7 +54,6 @@ const meta = {
45
54
  container: 'none',
46
55
  heading: 'This is the list heading',
47
56
  helperText: 'Supporting text',
48
- divider: true,
49
57
  disabled: false,
50
58
  loading: false,
51
59
  },
@@ -55,24 +63,275 @@ export default meta;
55
63
  type Story = StoryObj<typeof meta>;
56
64
 
57
65
  export const Playground: Story = {
58
- render: ({ container, divider, ...args }) => {
59
- const listItems = Array.from({ length: 4 }).map((_, index) => (
66
+ render: ({ container, ...args }) => {
67
+ return (
68
+ <List {...args} container={container}>
69
+ {Array.from({ length: 4 }).map((_, index) => (
70
+ <ListItem key={index} heading="List item text" helperText="Supporting text" />
71
+ ))}
72
+ </List>
73
+ );
74
+ },
75
+ };
76
+
77
+ export const WithAction: Story = {
78
+ args: {
79
+ container: 'subtleWhite',
80
+ },
81
+ render: ({ container, ...args }) => (
82
+ <List {...args} container={container}>
83
+ {Array.from({ length: 4 }).map((_, index) => (
84
+ <ListItem key={index} heading="List item text" helperText="Supporting text" />
85
+ ))}
86
+ <ListAction heading="List action" onPress={() => console.log('List Action Pressed')} />
87
+ </List>
88
+ ),
89
+ };
90
+
91
+ export const WithContainer: Story = {
92
+ parameters: {
93
+ controls: { include: [] },
94
+ },
95
+ render: () => (
96
+ <List container="subtleWhite">
97
+ <ListItem
98
+ leadingContent={<BillMediumIcon />}
99
+ heading="Bills"
100
+ onPress={() => console.log('Bills pressed')}
101
+ />
102
+ <ListItem
103
+ leadingContent={<PaymentMediumIcon />}
104
+ heading="Payments"
105
+ onPress={() => console.log('Payments pressed')}
106
+ />
60
107
  <ListItem
61
- key={index}
62
- text="List item text"
63
- helperText="Supporting text"
64
- divider={container === 'none' ? divider : divider && index !== 3}
108
+ leadingContent={<HomeMediumIcon />}
109
+ heading="Moving Home"
110
+ onPress={() => console.log('Moving Home pressed')}
65
111
  />
66
- ));
112
+ </List>
113
+ ),
114
+ };
115
+
116
+ export const WithBadge: Story = {
117
+ parameters: {
118
+ controls: { include: [] },
119
+ },
120
+ render: () => (
121
+ <List>
122
+ <ListItem
123
+ heading="Electricity"
124
+ helperText="Last reading 23/03/24"
125
+ onPress={() => console.log('Electricity pressed')}
126
+ leadingContent={
127
+ <IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
128
+ }
129
+ badge={{ text: 'Text' }}
130
+ />
131
+ <ListItem
132
+ heading="Gas"
133
+ helperText="Last reading 23/03/24"
134
+ onPress={() => console.log('Gas pressed')}
135
+ leadingContent={
136
+ <IconContainer icon={GasMediumIcon} size="md" variant="emphasis" color="energy" />
137
+ }
138
+ badge={{ text: 'Smart Meter' }}
139
+ />
140
+ </List>
141
+ ),
142
+ };
143
+
144
+ export const WithSwitch: Story = {
145
+ parameters: {
146
+ controls: { include: [] },
147
+ },
148
+ render: () => {
149
+ const [notifications, setNotifications] = useState(true);
150
+ const [darkMode, setDarkMode] = useState(false);
151
+
67
152
  return (
68
- <List {...args} container={container}>
69
- {container !== 'none' && <Card>{listItems}</Card>}
70
- {container === 'none' && listItems}
153
+ <List container="subtleWhite">
154
+ <ListItem
155
+ heading="Enable notifications"
156
+ helperText="Receive updates and alerts"
157
+ onPress={() => console.log('Notifications pressed')}
158
+ trailingContent={
159
+ <Switch size="small" value={notifications} onValueChange={setNotifications} />
160
+ }
161
+ />
162
+ <ListItem
163
+ heading="Dark mode"
164
+ helperText="Use dark theme throughout the app"
165
+ onPress={() => console.log('Dark mode pressed')}
166
+ trailingContent={<Switch size="small" value={darkMode} onValueChange={setDarkMode} />}
167
+ />
71
168
  </List>
72
169
  );
73
170
  },
74
171
  };
75
172
 
173
+ export const WithSectionHeader: Story = {
174
+ parameters: {
175
+ controls: { include: [] },
176
+ },
177
+ render: () => (
178
+ <List
179
+ heading="Your account"
180
+ helperText="Tap the links below to view your account"
181
+ headerTrailingContent={<Link onPress={() => console.log('View all pressed')}>View all</Link>}
182
+ >
183
+ <ListItem
184
+ heading="Bills"
185
+ helperText="View your bills"
186
+ leadingContent={<ListItemIcon as={BillMediumIcon} />}
187
+ trailingContent={<ListItemTrailingIcon as={ChevronRightSmallIcon} />}
188
+ onPress={() => console.log('Bills pressed')}
189
+ />
190
+ <ListItem
191
+ heading="Payments"
192
+ helperText="Make a payment"
193
+ leadingContent={<ListItemIcon as={PaymentMediumIcon} />}
194
+ trailingContent={<ListItemTrailingIcon as={ChevronRightSmallIcon} />}
195
+ onPress={() => console.log('Payments pressed')}
196
+ />
197
+ <ListItem
198
+ heading="Moving home"
199
+ helperText="Tell us if you're moving"
200
+ leadingContent={<ListItemIcon as={HomeMediumIcon} />}
201
+ trailingContent={<ListItemTrailingIcon as={ChevronRightSmallIcon} />}
202
+ onPress={() => console.log('Moving home pressed')}
203
+ />
204
+ <ListItem
205
+ heading="Refer a friend"
206
+ helperText="Get rewarded with a friend"
207
+ leadingContent={<ListItemIcon as={UserMediumIcon} />}
208
+ trailingContent={<ListItemTrailingIcon as={ChevronRightSmallIcon} />}
209
+ onPress={() => console.log('Refer a friend pressed')}
210
+ />
211
+ </List>
212
+ ),
213
+ };
214
+
215
+ export const WithListAction: Story = {
216
+ parameters: {
217
+ controls: { include: [] },
218
+ },
219
+ render: () => (
220
+ <List container="subtleWarmWhite">
221
+ <ListItem
222
+ heading="Upgrade your plan"
223
+ helperText="Get more features with a premium plan"
224
+ onPress={() => console.log('Upgrade pressed')}
225
+ />
226
+ <ListItem
227
+ heading="Manage payment methods"
228
+ helperText="Update your credit or debit cards"
229
+ onPress={() => console.log('Manage pressed')}
230
+ />
231
+ <ListAction heading="Contact support" onPress={() => console.log('Contact pressed')} />
232
+ </List>
233
+ ),
234
+ };
235
+
236
+ export const WithTransactions: Story = {
237
+ parameters: {
238
+ controls: { include: [] },
239
+ },
240
+ render: () => (
241
+ <List container="subtleWhite">
242
+ <ListItem
243
+ heading="Coffee Shop"
244
+ helperText="Apr 5, 2024"
245
+ trailingContent={
246
+ <>
247
+ <BodyText>-£100.00</BodyText>
248
+ <BodyText color="textBrand">+£1.00 CB</BodyText>
249
+ </>
250
+ }
251
+ onPress={() => console.log('Transaction pressed')}
252
+ />
253
+ <ListItem
254
+ heading="Top up"
255
+ helperText="Apr 4, 2024"
256
+ trailingContent={
257
+ <>
258
+ <BodyText color="textAffirmative">+£100.00</BodyText>
259
+ </>
260
+ }
261
+ onPress={() => console.log('Transaction pressed')}
262
+ />
263
+ </List>
264
+ ),
265
+ };
266
+
267
+ export const WithNumericValue: Story = {
268
+ parameters: {
269
+ controls: { include: [] },
270
+ },
271
+ render: () => (
272
+ <List container="subtleWhite">
273
+ <ListItem
274
+ heading="Steps today"
275
+ numericValue="8,542"
276
+ onPress={() => console.log('Steps pressed')}
277
+ />
278
+ <ListItem
279
+ heading="Calories burned"
280
+ numericValue="2,300 kcal"
281
+ onPress={() => console.log('Calories pressed')}
282
+ />
283
+ </List>
284
+ ),
285
+ };
286
+
287
+ export const WithLink: Story = {
288
+ parameters: {
289
+ controls: { include: [] },
290
+ },
291
+ render: () => (
292
+ <List container="subtleWhite">
293
+ <ListItem
294
+ heading="Terms of Service"
295
+ onPress={() => console.log('Terms pressed')}
296
+ trailingContent={<Link onPress={() => console.log('View link pressed')}>View</Link>}
297
+ />
298
+ <ListItem
299
+ heading="Privacy Policy"
300
+ onPress={() => console.log('Privacy pressed')}
301
+ trailingContent={<Link onPress={() => console.log('View link pressed')}>View</Link>}
302
+ />
303
+ </List>
304
+ ),
305
+ };
306
+
307
+ export const Loading: Story = {
308
+ parameters: {
309
+ controls: { include: [] },
310
+ },
311
+ render: () => (
312
+ <List loading container="subtleWhite">
313
+ <ListItem
314
+ heading="Loading item 1"
315
+ helperText="Supporting text 1"
316
+ leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
317
+ onPress={() => console.log('List Item Pressed')}
318
+ />
319
+ <ListItem
320
+ heading="Loading item 2"
321
+ helperText="Supporting text 2"
322
+ leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
323
+ onPress={() => console.log('List Item Pressed')}
324
+ />
325
+ <ListItem
326
+ heading="Loading item 3"
327
+ helperText="Supporting text 3"
328
+ leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
329
+ onPress={() => console.log('List Item Pressed')}
330
+ />
331
+ </List>
332
+ ),
333
+ };
334
+
76
335
  export const KitchenSink: Story = {
77
336
  parameters: {
78
337
  controls: { include: [] },
@@ -88,7 +347,7 @@ export const KitchenSink: Story = {
88
347
  <VariantTitle title="List with title and supporting text">
89
348
  <List heading="List Heading" helperText="Supporting Text">
90
349
  {list.map((item, index) => (
91
- <ListItem key={index} text={item.text} helperText={item.helperText} />
350
+ <ListItem key={index} heading={item.text} helperText={item.helperText} />
92
351
  ))}
93
352
  </List>
94
353
  </VariantTitle>
@@ -97,7 +356,7 @@ export const KitchenSink: Story = {
97
356
  {list.map((item, index) => (
98
357
  <ListItem
99
358
  key={index}
100
- text={item.text}
359
+ heading={item.text}
101
360
  helperText={item.helperText}
102
361
  leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
103
362
  />
@@ -109,7 +368,7 @@ export const KitchenSink: Story = {
109
368
  {list.map((item, index) => (
110
369
  <ListItem
111
370
  key={index}
112
- text={item.text}
371
+ heading={item.text}
113
372
  helperText={item.helperText}
114
373
  trailingContent={<ListItemTrailingIcon as={SettingsMediumIcon} />}
115
374
  />
@@ -121,18 +380,7 @@ export const KitchenSink: Story = {
121
380
  {list.map((item, index) => (
122
381
  <ListItem
123
382
  key={index}
124
- text={item.text}
125
- onPress={() => console.log('List Item Pressed')}
126
- />
127
- ))}
128
- </List>
129
- </VariantTitle>
130
- <VariantTitle title="List without divider">
131
- <List divider={false}>
132
- {list.map((item, index) => (
133
- <ListItem
134
- key={index}
135
- text={item.text}
383
+ heading={item.text}
136
384
  onPress={() => console.log('List Item Pressed')}
137
385
  />
138
386
  ))}
@@ -143,7 +391,7 @@ export const KitchenSink: Story = {
143
391
  {list.map((item, index) => (
144
392
  <ListItem
145
393
  key={index}
146
- text={item.text}
394
+ heading={item.text}
147
395
  helperText={item.helperText}
148
396
  leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
149
397
  onPress={() => console.log('List Item Pressed')}
@@ -156,7 +404,7 @@ export const KitchenSink: Story = {
156
404
  {list.map((item, index) => (
157
405
  <ListItem
158
406
  key={index}
159
- text={item.text}
407
+ heading={item.text}
160
408
  helperText={item.helperText}
161
409
  leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
162
410
  onPress={() => console.log('List Item Pressed')}
@@ -165,11 +413,14 @@ export const KitchenSink: Story = {
165
413
  </List>
166
414
  </VariantTitle>
167
415
  <VariantTitle title="List with heading link">
168
- <List heading="Heading" linkText="View all" linkHref="http://uw.co.uk">
416
+ <List
417
+ heading="Heading"
418
+ headerTrailingContent={<Link href="http://uw.co.uk">View all</Link>}
419
+ >
169
420
  {list.map((item, index) => (
170
421
  <ListItem
171
422
  key={index}
172
- text={item.text}
423
+ heading={item.text}
173
424
  helperText={item.helperText}
174
425
  leadingContent={<ListItemIcon as={SettingsMediumIcon} />}
175
426
  onPress={() => console.log('List Item Pressed')}
@@ -2,9 +2,9 @@ import React, { ReactNode, useMemo } from 'react';
2
2
  import { View, ViewProps } from 'react-native';
3
3
  import { StyleSheet } from 'react-native-unistyles';
4
4
  import { Card } from '../Card';
5
+ import { SectionHeader } from '../SectionHeader';
5
6
  import { ListContext } from './List.context';
6
7
  import type ListProps from './List.props';
7
- import { SectionHeader } from '../SectionHeader';
8
8
  import { ListItem, ListItemProps } from './ListItem';
9
9
 
10
10
  const markFirstListItem = (children: ReactNode): ViewProps['children'] => {
@@ -41,20 +41,8 @@ const markFirstListItem = (children: ReactNode): ViewProps['children'] => {
41
41
  return recursiveClone(children) as ViewProps['children'];
42
42
  };
43
43
 
44
- const List = ({
45
- children,
46
- heading,
47
- helperText,
48
- linkText,
49
- linkHref,
50
- linkIcon,
51
- linkIconPosition,
52
- linkOnPress,
53
- linkTarget,
54
- linkShowIcon,
55
- ...props
56
- }: ListProps) => {
57
- const { loading, disabled, divider = true, container = 'none' } = props;
44
+ const List = ({ children, heading, helperText, headerTrailingContent, ...props }: ListProps) => {
45
+ const { loading, disabled, container = 'none' } = props;
58
46
  const containerToCard: {
59
47
  variant: 'subtle' | 'emphasis';
60
48
  colorScheme: 'neutralStrong' | 'neutralSubtle';
@@ -66,10 +54,7 @@ const List = ({
66
54
  : 'neutralSubtle',
67
55
  };
68
56
  const updatedChildren = markFirstListItem(children);
69
- const value = useMemo(
70
- () => ({ loading, disabled, divider, container }),
71
- [loading, disabled, divider, container]
72
- );
57
+ const value = useMemo(() => ({ loading, disabled, container }), [loading, disabled, container]);
73
58
  styles.useVariants({ disabled });
74
59
  return (
75
60
  <ListContext.Provider value={value}>
@@ -78,13 +63,7 @@ const List = ({
78
63
  <SectionHeader
79
64
  heading={heading}
80
65
  helperText={helperText}
81
- linkText={linkText}
82
- linkHref={linkHref}
83
- linkOnPress={linkOnPress}
84
- linkTarget={linkTarget}
85
- linkIcon={linkIcon}
86
- linkIconPosition={linkIconPosition}
87
- linkShowIcon={linkShowIcon}
66
+ trailingContent={headerTrailingContent}
88
67
  />
89
68
  ) : null}
90
69
  {container === 'none' ? (
@@ -0,0 +1,10 @@
1
+ import type { PressableProps } from 'react-native';
2
+
3
+ interface ListActionProps extends Omit<PressableProps, 'children'> {
4
+ heading: string;
5
+ disabled?: boolean;
6
+ variant?: 'subtle' | 'emphasis';
7
+ isFirst?: boolean;
8
+ }
9
+
10
+ export default ListActionProps;
@@ -0,0 +1,133 @@
1
+ import { createPressable } from '@gluestack-ui/pressable';
2
+ import { ChevronRightSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
3
+ import { Pressable, ViewStyle } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { useListContext } from '../List.context';
6
+ import type ListActionProps from './ListAction.props';
7
+ import ListActionContent from './ListActionContent';
8
+ import ListActionText from './ListActionText';
9
+ import ListActionTrailingContent from './ListActionTrailingContent';
10
+ import ListActionTrailingIcon from './ListActionTrailingIcon';
11
+
12
+ const ListActionRoot = ({
13
+ heading,
14
+ disabled,
15
+ variant = 'subtle',
16
+ ...props
17
+ }: ListActionProps & { states?: { active?: boolean; disabled?: boolean } }) => {
18
+ const { onPress } = props;
19
+ const listContext = useListContext();
20
+
21
+ const { active } = props.states || { active: false };
22
+
23
+ const getListContainer = (): ListActionProps['variant'] => {
24
+ if (listContext?.container?.includes('subtle')) {
25
+ return 'subtle';
26
+ }
27
+ if (listContext?.container?.includes('emphasis')) {
28
+ return 'emphasis';
29
+ }
30
+ return undefined;
31
+ };
32
+
33
+ const isDisabled = disabled || listContext?.disabled || false;
34
+ const listItemVariant = getListContainer() || variant;
35
+
36
+ const testID = props.testID || 'list-action';
37
+
38
+ styles.useVariants({
39
+ variant: listItemVariant,
40
+ disabled: isDisabled,
41
+ active,
42
+ showDisabled: !listContext?.disabled && disabled,
43
+ isFirstChild: props.isFirst,
44
+ container: listContext?.container,
45
+ });
46
+
47
+ return (
48
+ <Pressable
49
+ {...props}
50
+ testID={testID}
51
+ style={[styles.container, props.style as ViewStyle]}
52
+ disabled={isDisabled || !onPress}
53
+ >
54
+ <ListActionContent>
55
+ <ListActionText>{heading}</ListActionText>
56
+ </ListActionContent>
57
+ <ListActionTrailingContent style={styles.centeredTrailingIcon}>
58
+ <ListActionTrailingIcon as={ChevronRightSmallIcon} />
59
+ </ListActionTrailingContent>
60
+ </Pressable>
61
+ );
62
+ };
63
+
64
+ const ListAction = createPressable({
65
+ Root: ListActionRoot,
66
+ });
67
+
68
+ ListAction.displayName = 'ListAction';
69
+
70
+ const styles = StyleSheet.create(theme => ({
71
+ container: {
72
+ paddingVertical: theme.components.list.item.functional.padding,
73
+ paddingHorizontal: theme.components.list.item.functional.padding,
74
+ flexDirection: 'row',
75
+ gap: theme.components.list.item.gap,
76
+ borderTopWidth: theme.borderWidth['1'],
77
+ borderStyle: 'solid',
78
+ variants: {
79
+ isFirstChild: {
80
+ true: {
81
+ borderTopWidth: 0,
82
+ },
83
+ },
84
+ variant: {
85
+ subtle: {
86
+ borderTopColor: theme.color.border.subtle,
87
+ },
88
+ emphasis: {
89
+ borderTopColor: theme.color.border.strong,
90
+ },
91
+ },
92
+ active: {
93
+ true: {
94
+ backgroundColor: theme.color.interactive.neutral.surface.subtle.active,
95
+ },
96
+ },
97
+ disabled: {
98
+ true: {
99
+ cursor: 'auto',
100
+ },
101
+ false: {
102
+ _web: {
103
+ _hover: {
104
+ backgroundColor: theme.color.interactive.neutral.surface.subtle.hover,
105
+ },
106
+ _active: {
107
+ backgroundColor: theme.color.interactive.neutral.surface.subtle.active,
108
+ },
109
+ },
110
+ },
111
+ },
112
+ showDisabled: {
113
+ true: {
114
+ opacity: theme.opacity.disabled,
115
+ },
116
+ },
117
+ container: {
118
+ none: {
119
+ paddingHorizontal: 0,
120
+ },
121
+ subtleWhite: {},
122
+ emphasisWhite: {},
123
+ subtleWarmWhite: {},
124
+ emphasisWarmWhite: {},
125
+ },
126
+ },
127
+ },
128
+ centeredTrailingIcon: {
129
+ justifyContent: 'center',
130
+ },
131
+ }));
132
+
133
+ export default ListAction;
@@ -0,0 +1,21 @@
1
+ import { View, type ViewProps } from 'react-native';
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+
4
+ const ListActionContent = ({ children, ...props }: ViewProps) => {
5
+ return (
6
+ <View {...props} style={[styles.container, props.style]}>
7
+ {children}
8
+ </View>
9
+ );
10
+ };
11
+
12
+ ListActionContent.displayName = 'ListActionContent';
13
+
14
+ const styles = StyleSheet.create(theme => ({
15
+ container: {
16
+ gap: theme.components.list.item.contentGap,
17
+ flex: 1,
18
+ },
19
+ }));
20
+
21
+ export default ListActionContent;
@@ -0,0 +1,14 @@
1
+ import { TextProps } from 'react-native';
2
+ import { BodyText } from '../../BodyText';
3
+
4
+ const ListActionText = ({ children, ...props }: TextProps) => {
5
+ return (
6
+ <BodyText size="md" weight="semibold" {...props}>
7
+ {children}
8
+ </BodyText>
9
+ );
10
+ };
11
+
12
+ ListActionText.displayName = 'ListActionText';
13
+
14
+ export default ListActionText;
@@ -0,0 +1,9 @@
1
+ import { View, type ViewProps } from 'react-native';
2
+
3
+ const ListActionTrailingContent = ({ children, ...props }: ViewProps) => (
4
+ <View {...props}>{children}</View>
5
+ );
6
+
7
+ ListActionTrailingContent.displayName = 'ListActionTrailingContent';
8
+
9
+ export default ListActionTrailingContent;
@@ -0,0 +1,32 @@
1
+ import { ComponentType } from 'react';
2
+ import { Platform, type StyleProp, type ViewStyle } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+
5
+ import { Icon, IconProps } from '../../Icon';
6
+
7
+ const ListActionTrailingIcon = ({ children, ...props }: IconProps & { as?: ComponentType }) => {
8
+ return (
9
+ <Icon
10
+ {...props}
11
+ style={
12
+ Platform.OS === 'web'
13
+ ? StyleSheet.compose(styles.icon as StyleProp<ViewStyle>, props.style)
14
+ : ([styles.icon as StyleProp<ViewStyle>, props.style] as any)
15
+ }
16
+ >
17
+ {children}
18
+ </Icon>
19
+ );
20
+ };
21
+
22
+ ListActionTrailingIcon.displayName = 'ListActionTrailingIcon';
23
+
24
+ const styles = StyleSheet.create(theme => ({
25
+ icon: {
26
+ color: theme.color.icon.primary,
27
+ width: 24,
28
+ height: 24,
29
+ },
30
+ }));
31
+
32
+ export default ListActionTrailingIcon;