@utilitywarehouse/hearth-react-native 0.4.1 → 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 (205) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/CHANGELOG.md +54 -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/Checkbox/CheckboxTextContent.d.ts +1 -1
  25. package/build/components/Checkbox/CheckboxTextContent.js +9 -2
  26. package/build/components/CurrencyInput/CurrencyInput.d.ts +1 -1
  27. package/build/components/CurrencyInput/CurrencyInput.js +3 -3
  28. package/build/components/CurrencyInput/CurrencyInput.props.d.ts +2 -2
  29. package/build/components/DescriptionList/DescriptionList.d.ts +1 -1
  30. package/build/components/DescriptionList/DescriptionList.js +2 -2
  31. package/build/components/DescriptionList/DescriptionList.props.d.ts +1 -8
  32. package/build/components/DescriptionList/DescriptionListItem.d.ts +1 -1
  33. package/build/components/DescriptionList/DescriptionListItem.js +4 -3
  34. package/build/components/DescriptionList/DescriptionListItem.props.d.ts +3 -8
  35. package/build/components/IndicatorIconButton/IndicatorIconButton.d.ts +6 -0
  36. package/build/components/IndicatorIconButton/IndicatorIconButton.js +26 -0
  37. package/build/components/IndicatorIconButton/IndicatorIconButton.props.d.ts +8 -0
  38. package/build/components/IndicatorIconButton/IndicatorIconButton.props.js +1 -0
  39. package/build/components/IndicatorIconButton/index.d.ts +2 -0
  40. package/build/components/IndicatorIconButton/index.js +1 -0
  41. package/build/components/Link/LinkText.js +3 -3
  42. package/build/components/List/List.context.d.ts +0 -2
  43. package/build/components/List/List.d.ts +1 -1
  44. package/build/components/List/List.js +5 -5
  45. package/build/components/List/List.props.d.ts +1 -9
  46. package/build/components/List/ListAction/ListAction.d.ts +18 -0
  47. package/build/components/List/ListAction/ListAction.js +103 -0
  48. package/build/components/List/ListAction/ListAction.props.d.ts +8 -0
  49. package/build/components/List/ListAction/ListAction.props.js +1 -0
  50. package/build/components/List/ListAction/ListActionContent.d.ts +6 -0
  51. package/build/components/List/ListAction/ListActionContent.js +14 -0
  52. package/build/components/List/ListAction/ListActionText.d.ts +6 -0
  53. package/build/components/List/ListAction/ListActionText.js +7 -0
  54. package/build/components/List/ListAction/ListActionTrailingContent.d.ts +6 -0
  55. package/build/components/List/ListAction/ListActionTrailingContent.js +5 -0
  56. package/build/components/List/ListAction/ListActionTrailingIcon.d.ts +9 -0
  57. package/build/components/List/ListAction/ListActionTrailingIcon.js +18 -0
  58. package/build/components/List/ListAction/index.d.ts +6 -0
  59. package/build/components/List/ListAction/index.js +5 -0
  60. package/build/components/List/ListItem/ListItem.context.d.ts +1 -1
  61. package/build/components/List/ListItem/ListItem.props.d.ts +9 -5
  62. package/build/components/List/ListItem/ListItemRoot.d.ts +1 -1
  63. package/build/components/List/ListItem/ListItemRoot.js +10 -12
  64. package/build/components/List/ListItem/index.d.ts +4 -4
  65. package/build/components/List/ListItem/index.js +3 -3
  66. package/build/components/List/index.d.ts +1 -0
  67. package/build/components/List/index.js +1 -0
  68. package/build/components/ProgressStepper/ProgressStep.d.ts +10 -0
  69. package/build/components/ProgressStepper/ProgressStep.js +100 -0
  70. package/build/components/ProgressStepper/ProgressStepper.d.ts +6 -0
  71. package/build/components/ProgressStepper/ProgressStepper.js +22 -0
  72. package/build/components/ProgressStepper/ProgressStepper.props.d.ts +22 -0
  73. package/build/components/ProgressStepper/ProgressStepper.props.js +1 -0
  74. package/build/components/ProgressStepper/ProgressStepperRoot.d.ts +6 -0
  75. package/build/components/ProgressStepper/ProgressStepperRoot.js +16 -0
  76. package/build/components/ProgressStepper/index.d.ts +3 -0
  77. package/build/components/ProgressStepper/index.js +2 -0
  78. package/build/components/Radio/RadioTextContent.d.ts +1 -1
  79. package/build/components/Radio/RadioTextContent.js +9 -2
  80. package/build/components/SectionHeader/SectionHeader.d.ts +1 -1
  81. package/build/components/SectionHeader/SectionHeader.js +6 -3
  82. package/build/components/SectionHeader/SectionHeader.props.d.ts +9 -16
  83. package/build/components/SectionHeader/SectionHeaderTrailingContent.d.ts +6 -0
  84. package/build/components/SectionHeader/SectionHeaderTrailingContent.js +13 -0
  85. package/build/components/SectionHeader/index.d.ts +1 -0
  86. package/build/components/SectionHeader/index.js +1 -0
  87. package/build/components/Tabs/Tab.js +2 -2
  88. package/build/components/ToggleButton/ToggleButtonText.js +2 -2
  89. package/build/components/UnstyledIconButton/UnstyledIconButton.props.d.ts +4 -1
  90. package/build/components/index.d.ts +3 -0
  91. package/build/components/index.js +3 -0
  92. package/build/core/themes.d.ts +12 -24
  93. package/build/tokens/components/dark/button.d.ts +1 -1
  94. package/build/tokens/components/dark/button.js +1 -1
  95. package/build/tokens/components/dark/dialog.d.ts +1 -0
  96. package/build/tokens/components/dark/dialog.js +1 -0
  97. package/build/tokens/components/dark/illustrations.d.ts +1 -0
  98. package/build/tokens/components/dark/illustrations.js +1 -0
  99. package/build/tokens/components/dark/toast.d.ts +4 -1
  100. package/build/tokens/components/dark/toast.js +4 -1
  101. package/build/tokens/components/light/button.d.ts +1 -1
  102. package/build/tokens/components/light/button.js +1 -1
  103. package/build/tokens/components/light/dialog.d.ts +1 -0
  104. package/build/tokens/components/light/dialog.js +1 -0
  105. package/build/tokens/components/light/illustrations.d.ts +1 -0
  106. package/build/tokens/components/light/illustrations.js +1 -0
  107. package/build/tokens/components/light/toast.d.ts +4 -1
  108. package/build/tokens/components/light/toast.js +4 -1
  109. package/build/tokens/layout.d.ts +6 -12
  110. package/build/tokens/layout.js +3 -6
  111. package/build/utils/getFlattenedColorValue.js +2 -19
  112. package/build/utils/index.d.ts +1 -0
  113. package/build/utils/index.js +1 -0
  114. package/build/utils/styleUtils.d.ts +0 -4
  115. package/build/utils/styleUtils.js +0 -50
  116. package/build/utils/themeValueHelpers.d.ts +17 -0
  117. package/build/utils/themeValueHelpers.js +54 -0
  118. package/docs/components/AllComponents.web.tsx +86 -4
  119. package/docs/components/BadgeList.tsx +20 -56
  120. package/docs/components/SwitchList.tsx +4 -8
  121. package/docs/getting-started.mdx +37 -13
  122. package/docs/introduction.mdx +51 -6
  123. package/package.json +7 -7
  124. package/src/components/Alert/AlertTitle.tsx +7 -7
  125. package/src/components/Badge/Badge.props.ts +1 -0
  126. package/src/components/Badge/Badge.tsx +3 -2
  127. package/src/components/Button/ButtonRoot.tsx +4 -0
  128. package/src/components/Button/ButtonText.tsx +3 -3
  129. package/src/components/Card/CardRoot.tsx +2 -0
  130. package/src/components/Carousel/Carousel.context.tsx +8 -0
  131. package/src/components/Carousel/Carousel.docs.mdx +389 -0
  132. package/src/components/Carousel/Carousel.props.ts +89 -0
  133. package/src/components/Carousel/Carousel.stories.tsx +317 -0
  134. package/src/components/Carousel/Carousel.tsx +444 -0
  135. package/src/components/Carousel/CarouselControlItem.tsx +87 -0
  136. package/src/components/Carousel/CarouselControls.tsx +150 -0
  137. package/src/components/Carousel/CarouselItem.tsx +68 -0
  138. package/src/components/Carousel/index.ts +6 -0
  139. package/src/components/Checkbox/CheckboxTextContent.tsx +11 -3
  140. package/src/components/CurrencyInput/CurrencyInput.docs.mdx +4 -4
  141. package/src/components/CurrencyInput/CurrencyInput.props.ts +2 -2
  142. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +17 -15
  143. package/src/components/CurrencyInput/CurrencyInput.tsx +3 -3
  144. package/src/components/DescriptionList/DescriptionList.docs.mdx +24 -27
  145. package/src/components/DescriptionList/DescriptionList.props.ts +1 -8
  146. package/src/components/DescriptionList/DescriptionList.stories.tsx +13 -19
  147. package/src/components/DescriptionList/DescriptionList.tsx +2 -14
  148. package/src/components/DescriptionList/DescriptionListItem.props.ts +3 -8
  149. package/src/components/DescriptionList/DescriptionListItem.tsx +13 -21
  150. package/src/components/IndicatorIconButton/IndicatorIconButton.docs.mdx +85 -0
  151. package/src/components/IndicatorIconButton/IndicatorIconButton.props.ts +12 -0
  152. package/src/components/IndicatorIconButton/IndicatorIconButton.stories.tsx +142 -0
  153. package/src/components/IndicatorIconButton/IndicatorIconButton.tsx +36 -0
  154. package/src/components/IndicatorIconButton/index.tsx +2 -0
  155. package/src/components/Link/LinkText.tsx +4 -4
  156. package/src/components/List/List.context.ts +0 -1
  157. package/src/components/List/List.docs.mdx +376 -179
  158. package/src/components/List/List.props.ts +1 -9
  159. package/src/components/List/List.stories.tsx +289 -38
  160. package/src/components/List/List.tsx +5 -26
  161. package/src/components/List/ListAction/ListAction.props.ts +10 -0
  162. package/src/components/List/ListAction/ListAction.tsx +133 -0
  163. package/src/components/List/ListAction/ListActionContent.tsx +21 -0
  164. package/src/components/List/ListAction/ListActionText.tsx +14 -0
  165. package/src/components/List/ListAction/ListActionTrailingContent.tsx +9 -0
  166. package/src/components/List/ListAction/ListActionTrailingIcon.tsx +32 -0
  167. package/src/components/List/ListAction/index.ts +6 -0
  168. package/src/components/List/ListItem/ListItem.context.ts +1 -1
  169. package/src/components/List/ListItem/ListItem.props.ts +9 -5
  170. package/src/components/List/ListItem/ListItemRoot.tsx +18 -14
  171. package/src/components/List/ListItem/index.ts +4 -4
  172. package/src/components/List/index.ts +1 -0
  173. package/src/components/ProgressStepper/ProgressStep.tsx +134 -0
  174. package/src/components/ProgressStepper/ProgressStepper.docs.mdx +87 -0
  175. package/src/components/ProgressStepper/ProgressStepper.props.ts +27 -0
  176. package/src/components/ProgressStepper/ProgressStepper.stories.tsx +108 -0
  177. package/src/components/ProgressStepper/ProgressStepper.tsx +26 -0
  178. package/src/components/ProgressStepper/ProgressStepperRoot.tsx +32 -0
  179. package/src/components/ProgressStepper/index.ts +3 -0
  180. package/src/components/Radio/RadioTextContent.tsx +11 -3
  181. package/src/components/SectionHeader/SectionHeader.props.ts +9 -16
  182. package/src/components/SectionHeader/SectionHeader.stories.tsx +28 -18
  183. package/src/components/SectionHeader/SectionHeader.tsx +18 -19
  184. package/src/components/SectionHeader/SectionHeaderTrailingContent.tsx +20 -0
  185. package/src/components/SectionHeader/Sectionheader.docs.mdx +9 -24
  186. package/src/components/SectionHeader/index.ts +1 -0
  187. package/src/components/Switch/Switch.docs.mdx +0 -4
  188. package/src/components/Tabs/Tab.tsx +4 -2
  189. package/src/components/ToggleButton/ToggleButtonText.tsx +3 -3
  190. package/src/components/UnstyledIconButton/UnstyledIconButton.props.ts +2 -1
  191. package/src/components/index.ts +3 -0
  192. package/src/tokens/components/dark/button.ts +1 -1
  193. package/src/tokens/components/dark/dialog.ts +1 -0
  194. package/src/tokens/components/dark/illustrations.ts +1 -0
  195. package/src/tokens/components/dark/toast.ts +4 -1
  196. package/src/tokens/components/light/button.ts +1 -1
  197. package/src/tokens/components/light/dialog.ts +1 -0
  198. package/src/tokens/components/light/illustrations.ts +1 -0
  199. package/src/tokens/components/light/toast.ts +4 -1
  200. package/src/tokens/layout.ts +3 -6
  201. package/src/utils/getFlattenedColorValue.ts +2 -21
  202. package/src/utils/getStyleValue.ts +0 -3
  203. package/src/utils/index.ts +1 -0
  204. package/src/utils/styleUtils.ts +0 -57
  205. package/src/utils/themeValueHelpers.ts +60 -0
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Helper function to convert camelCase back to nested object path
3
+ * e.g., feedbackDangerSurfaceDefault -> ['feedback', 'danger', 'surface', 'default']
4
+ */
5
+ export declare const camelCaseToPath: (camelCased: string) => string[];
6
+ /**
7
+ * Helper function to get nested value from object using path array
8
+ */
9
+ export declare const getNestedValue: (obj: any, path: string[]) => any;
10
+ /**
11
+ * Helper function to resolve a theme value
12
+ * Supports:
13
+ * - Direct lookup (value -> themeMapping[value])
14
+ * - Camel case to nested path (feedbackDangerSurfaceDefault -> themeMapping.feedback.danger.surface.default)
15
+ * - Numeric suffix pattern (broadbandBlue100 -> themeMapping.broadbandBlue[100])
16
+ */
17
+ export declare const resolveThemeValue: (value: any, themeMapping: any) => any;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Helper function to convert camelCase back to nested object path
3
+ * e.g., feedbackDangerSurfaceDefault -> ['feedback', 'danger', 'surface', 'default']
4
+ */
5
+ export const camelCaseToPath = (camelCased) => {
6
+ // Split on uppercase letters but keep them
7
+ const parts = camelCased.split(/(?=[A-Z])/).map(part => part.toLowerCase());
8
+ return parts;
9
+ };
10
+ /**
11
+ * Helper function to get nested value from object using path array
12
+ */
13
+ export const getNestedValue = (obj, path) => {
14
+ return path.reduce((current, key) => {
15
+ return current && typeof current === 'object' ? current[key] : undefined;
16
+ }, obj);
17
+ };
18
+ /**
19
+ * Helper function to resolve a theme value
20
+ * Supports:
21
+ * - Direct lookup (value -> themeMapping[value])
22
+ * - Camel case to nested path (feedbackDangerSurfaceDefault -> themeMapping.feedback.danger.surface.default)
23
+ * - Numeric suffix pattern (broadbandBlue100 -> themeMapping.broadbandBlue[100])
24
+ */
25
+ export const resolveThemeValue = (value, themeMapping) => {
26
+ if (typeof value !== 'string' || !themeMapping || typeof themeMapping !== 'object') {
27
+ return value;
28
+ }
29
+ // First, try direct lookup for simple values
30
+ if (themeMapping[value] !== undefined) {
31
+ return themeMapping[value];
32
+ }
33
+ // Try camelCase to nested path conversion (e.g., feedbackDangerSurfaceDefault)
34
+ if (/^[a-z][a-zA-Z]*$/.test(value)) {
35
+ // Only camelCase strings without numbers
36
+ const path = camelCaseToPath(value);
37
+ const nestedValue = getNestedValue(themeMapping, path);
38
+ if (nestedValue !== undefined) {
39
+ return nestedValue;
40
+ }
41
+ }
42
+ // Then, try the existing numeric suffix pattern (e.g., broadbandBlue100)
43
+ const shadeMatch = value.match(/\d+$/);
44
+ if (shadeMatch) {
45
+ const shade = shadeMatch[0];
46
+ const base = value.slice(0, -shade.length);
47
+ const nested = themeMapping[base];
48
+ if (nested && typeof nested === 'object') {
49
+ return nested[shade] ?? value;
50
+ }
51
+ }
52
+ // If none of the approaches work, return the original value
53
+ return value;
54
+ };
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
4
4
  import {
5
+ BellMediumIcon,
5
6
  BroadbandMediumIcon,
6
7
  CashbackCardMediumIcon,
7
8
  ChevronRightMediumIcon,
@@ -24,6 +25,8 @@ import {
24
25
  Box,
25
26
  Button,
26
27
  Card,
28
+ Carousel,
29
+ CarouselItem,
27
30
  Center,
28
31
  Checkbox,
29
32
  CurrencyInput,
@@ -41,6 +44,7 @@ import {
41
44
  Icon,
42
45
  IconButton,
43
46
  IconContainer,
47
+ IndicatorIconButton,
44
48
  InlineLink,
45
49
  Input,
46
50
  LI,
@@ -49,6 +53,8 @@ import {
49
53
  ListItem,
50
54
  Modal,
51
55
  OL,
56
+ ProgressStepper,
57
+ ProgressStep,
52
58
  Radio,
53
59
  RadioCard,
54
60
  RadioCardGroup,
@@ -214,12 +220,63 @@ const AllComponents: React.FC = () => {
214
220
  </ComponentWrapper>
215
221
  <ComponentWrapper name="Card" link="/?path=/docs/components-card--docs">
216
222
  <Center flex={1}>
217
- <Card colorScheme="white">
223
+ <Card colorScheme="neutralStrong">
218
224
  <Heading>I am a card</Heading>
219
225
  <BodyText>And do card stuff.</BodyText>
220
226
  </Card>
221
227
  </Center>
222
228
  </ComponentWrapper>
229
+ <ComponentWrapper name="Carousel" link="/?path=/docs/components-carousel--docs">
230
+ <Center flex={1}>
231
+ <Carousel itemWidth={150} centered width={150}>
232
+ <CarouselItem>
233
+ <Box
234
+ backgroundColor="blue700"
235
+ width={150}
236
+ height={100}
237
+ px="100"
238
+ borderRadius="md"
239
+ >
240
+ <Center flex={1}>
241
+ <BodyText color="white" textAlign="center">
242
+ I'm a carousel item
243
+ </BodyText>
244
+ </Center>
245
+ </Box>
246
+ </CarouselItem>
247
+ <CarouselItem>
248
+ <Box
249
+ backgroundColor="purple700"
250
+ width={150}
251
+ height={100}
252
+ px="100"
253
+ borderRadius="md"
254
+ >
255
+ <Center flex={1}>
256
+ <BodyText color="white" textAlign="center">
257
+ I'm another carousel item
258
+ </BodyText>
259
+ </Center>
260
+ </Box>
261
+ </CarouselItem>
262
+ <CarouselItem>
263
+ <Box
264
+ backgroundColor="green700"
265
+ width={150}
266
+ height={100}
267
+ px="100"
268
+ borderRadius="md"
269
+ >
270
+ <Center flex={1}>
271
+ <BodyText color="white" textAlign="center">
272
+ I'm also a carousel item
273
+ </BodyText>
274
+ </Center>
275
+ </Box>
276
+ </CarouselItem>
277
+ </Carousel>
278
+ </Center>
279
+ </ComponentWrapper>
223
280
  <ComponentWrapper name="Center" link="/?path=/docs/primitives-center--docs">
224
281
  <Center flex={1}>
225
282
  <Center backgroundColor="red400" padding="300" width={200} height={100}>
@@ -330,6 +387,14 @@ const AllComponents: React.FC = () => {
330
387
  <Heading>This is a Heading</Heading>
331
388
  </Center>
332
389
  </ComponentWrapper>
390
+ <ComponentWrapper
391
+ name="Indicator Icon Button"
392
+ link="/?path=/docs/components-indicator-icon-button--docs"
393
+ >
394
+ <Center flex={1}>
395
+ <IndicatorIconButton icon={BellMediumIcon} onPress={() => null} indicator={true} />
396
+ </Center>
397
+ </ComponentWrapper>
333
398
  <ComponentWrapper name="Icon Button" link="/?path=/docs/components-icon-button--docs">
334
399
  <Center flex={1}>
335
400
  <IconButton icon={ChevronRightMediumIcon} size="md" onPress={() => null} />
@@ -410,8 +475,8 @@ const AllComponents: React.FC = () => {
410
475
  <ComponentWrapper name="List" link="/?path=/docs/components-list--docs">
411
476
  <Center flex={1} p="300">
412
477
  <List>
413
- <ListItem text="List Item 1" divider onPress={() => console.log('item pressed')} />
414
- <ListItem text="List Item 2" onPress={() => console.log('item pressed')} />
478
+ <ListItem heading="List Item 1" onPress={() => console.log('item pressed')} />
479
+ <ListItem heading="List Item 2" onPress={() => console.log('item pressed')} />
415
480
  </List>
416
481
  </Center>
417
482
  </ComponentWrapper>
@@ -445,6 +510,19 @@ const AllComponents: React.FC = () => {
445
510
  </OL>
446
511
  </Center>
447
512
  </ComponentWrapper>
513
+ <ComponentWrapper
514
+ name="Progress Stepper"
515
+ link="/?path=/docs/components-progress-stepper--docs"
516
+ >
517
+ <Center flex={1}>
518
+ <ProgressStepper>
519
+ <ProgressStep id="customer-data" state="complete" />
520
+ <ProgressStep id="shipping-data" state="complete" />
521
+ <ProgressStep id="payment-data" state="active" />
522
+ <ProgressStep id="summary" state="incomplete" />
523
+ </ProgressStepper>
524
+ </Center>
525
+ </ComponentWrapper>
448
526
  <ComponentWrapper name="Radio" link="/?path=/docs/forms-radio--docs">
449
527
  <Center flex={1}>
450
528
  <RadioGroup>
@@ -469,7 +547,11 @@ const AllComponents: React.FC = () => {
469
547
  link="/?path=/docs/components-section-header--docs"
470
548
  >
471
549
  <Center flex={1} p="300">
472
- <SectionHeader heading="Heading" helperText="Supporting text" linkText="More" />
550
+ <SectionHeader
551
+ heading="Heading"
552
+ helperText="Supporting text"
553
+ trailingContent={<Link href="#">More</Link>}
554
+ />
473
555
  </Center>
474
556
  </ComponentWrapper>
475
557
  <ComponentWrapper name="Select" link="/?path=/docs/forms-select--docs">
@@ -1,64 +1,28 @@
1
- import {
2
- Badge,
3
- BadgeText,
4
- Box,
5
- Flex,
6
- List,
7
- ListItem,
8
- ListItemContent,
9
- ListItemHelperText,
10
- ListItemIcon,
11
- ListItemLeadingContent,
12
- ListItemText,
13
- ListItemTrailingContent,
14
- ListItemTrailingIcon,
15
- } from '../../src';
1
+ import { IconContainer, List, ListItem } from '../../src';
16
2
 
17
- import {
18
- ChevronRightMediumIcon,
19
- ElectricityMediumIcon,
20
- GasMediumIcon,
21
- } from '@utilitywarehouse/hearth-react-native-icons';
3
+ import { ElectricityMediumIcon, GasMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
22
4
 
23
5
  const BadgeList = () => {
24
6
  return (
25
7
  <List>
26
- <ListItem onPress={() => console.log('pressed')} divider>
27
- <ListItemLeadingContent>
28
- <Box padding="300" borderRadius="lg" bg="energyBlue300">
29
- <ListItemIcon as={ElectricityMediumIcon} color="energyBlue600" />
30
- </Box>
31
- </ListItemLeadingContent>
32
- <ListItemContent>
33
- <ListItemText>Electricity</ListItemText>
34
- <Badge colorScheme="info">
35
- <BadgeText>Text</BadgeText>
36
- </Badge>
37
- <ListItemHelperText>Last reading 23/03/24</ListItemHelperText>
38
- </ListItemContent>
39
- <ListItemTrailingContent>
40
- <ListItemTrailingIcon as={ChevronRightMediumIcon} />
41
- </ListItemTrailingContent>
42
- </ListItem>
43
- <ListItem onPress={() => console.log('pressed')} divider={false}>
44
- <ListItemLeadingContent>
45
- <Box padding="300" borderRadius="lg" bg="energyBlue300">
46
- <ListItemIcon as={GasMediumIcon} color="energyBlue600" />
47
- </Box>
48
- </ListItemLeadingContent>
49
- <ListItemContent>
50
- <Flex direction="row" style={{ justifyContent: 'space-between' }}>
51
- <ListItemText>Gas</ListItemText>
52
- <Badge colorScheme="positive">
53
- <BadgeText>Smart meter</BadgeText>
54
- </Badge>
55
- </Flex>
56
- <ListItemHelperText>Last reading 23/03/24</ListItemHelperText>
57
- </ListItemContent>
58
- <ListItemTrailingContent>
59
- <ListItemTrailingIcon as={ChevronRightMediumIcon} />
60
- </ListItemTrailingContent>
61
- </ListItem>
8
+ <ListItem
9
+ heading="Electricity"
10
+ helperText="Last reading 23/03/24"
11
+ onPress={() => console.log('pressed')}
12
+ leadingContent={
13
+ <IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
14
+ }
15
+ badge={{ text: 'Text' }}
16
+ />
17
+ <ListItem
18
+ heading="Gas"
19
+ helperText="Last reading 23/03/24"
20
+ onPress={() => console.log('pressed')}
21
+ leadingContent={
22
+ <IconContainer icon={GasMediumIcon} size="md" variant="emphasis" color="energy" />
23
+ }
24
+ badge={{ text: 'Smart Meter' }}
25
+ />
62
26
  </List>
63
27
  );
64
28
  };
@@ -16,9 +16,8 @@ const SwitchList = () => {
16
16
  return (
17
17
  <List container="subtleWhite">
18
18
  <ListItem
19
- text="Notifications"
19
+ heading="Notifications"
20
20
  helperText="Allow notifications"
21
- divider
22
21
  leadingContent={<ListItemIcon as={BellMediumIcon} />}
23
22
  trailingContent={
24
23
  <Switch value={notifications} onValueChange={setNotifications} size="small" />
@@ -26,25 +25,22 @@ const SwitchList = () => {
26
25
  onPress={() => setNotifications(!notifications)}
27
26
  />
28
27
  <ListItem
29
- text="Secure ID"
28
+ heading="Secure ID"
30
29
  helperText="Use secure ID"
31
- divider
32
30
  leadingContent={<ListItemIcon as={LockMediumIcon} />}
33
31
  trailingContent={<Switch value={secureId} onValueChange={setSecureId} size="small" />}
34
32
  onPress={() => setSecureId(!secureId)}
35
33
  />
36
34
  <ListItem
37
- text="Location"
35
+ heading="Location"
38
36
  helperText="Allow location"
39
- divider
40
37
  leadingContent={<ListItemIcon as={LocationMediumIcon} />}
41
38
  trailingContent={<Switch value={location} onValueChange={setLocation} size="small" />}
42
39
  onPress={() => setLocation(!location)}
43
40
  />
44
41
  <ListItem
45
- text="Dark mode"
42
+ heading="Dark mode"
46
43
  helperText="Enable dark mode"
47
- divider
48
44
  leadingContent={<ListItemIcon as={EyeMediumIcon} />}
49
45
  trailingContent={<Switch value={darkMode} onValueChange={setDarkMode} size="small" />}
50
46
  onPress={() => setDarkMode(!darkMode)}
@@ -7,15 +7,27 @@ import { BackToTopButton, NextPrevPage } from './components';
7
7
  # Getting Started
8
8
 
9
9
  You can just start using the components from the `@utilitywarehouse/hearth-react-native` package.
10
+ Although there are a few components that require a `BottomSheetModalProvider` to be wrapped around your app.
11
+ You should also make sure you're app is wrapped in a `GestureHandlerRootView` from `react-native-gesture-handler`.
10
12
 
11
13
  ```tsx
12
- import { Box, Alert, BodyText } from '@utilitywarehouse/hearth-react-native';
14
+ import {
15
+ Box,
16
+ Alert,
17
+ BodyText,
18
+ BottomSheetModalProvider,
19
+ } from '@utilitywarehouse/hearth-react-native';
20
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
13
21
 
14
22
  const App: React.FC = () => (
15
- <Box p="200">
16
- <Alert variant="info" text="Welcome to Hearth React Native!" />
17
- <BodyText>Start building your app with Hearth React Native components.</BodyText>
18
- </Box>
23
+ <GestureHandlerRootView>
24
+ <BottomSheetModalProvider>
25
+ <Box p="200">
26
+ <Alert colorScheme="positive" text="Welcome to Hearth React Native!" />
27
+ <BodyText>Start building your app with Hearth React Native components.</BodyText>
28
+ </Box>
29
+ </BottomSheetModalProvider>
30
+ </GestureHandlerRootView>
19
31
  );
20
32
  ```
21
33
 
@@ -25,19 +37,31 @@ By default the light colour mode is enabled. If you want to enable dark mode, yo
25
37
  use the `useColorMode` hook to toggle between light and dark modes.
26
38
 
27
39
  ```tsx
28
- import { useColorMode, Box, Alert, BodyText, Button } from '@utilitywarehouse/hearth-react-native';
40
+ import {
41
+ useColorMode,
42
+ Box,
43
+ Alert,
44
+ BodyText,
45
+ Button,
46
+ BottomSheetModalProvider,
47
+ } from '@utilitywarehouse/hearth-react-native';
48
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
29
49
 
30
50
  const App: React.FC = () => {
31
51
  const [colorMode, setColorMode] = useColorMode();
32
52
 
33
53
  return (
34
- <Box p="200">
35
- <Alert variant="info" text="Welcome to Hearth React Native!" />
36
- <BodyText>Start building your app with Hearth React Native components.</BodyText>
37
- <Button onPress={() => setColorMode(colorMode === 'light' ? 'dark' : 'light')}>
38
- Toggle Color Mode
39
- </Button>
40
- </Box>
54
+ <GestureHandlerRootView>
55
+ <BottomSheetModalProvider>
56
+ <Box p="200">
57
+ <Alert colorScheme="positive" text="Welcome to Hearth React Native!" />
58
+ <BodyText>Start building your app with Hearth React Native components.</BodyText>
59
+ <Button onPress={() => setColorMode(colorMode === 'light' ? 'dark' : 'light')}>
60
+ Toggle Color Mode
61
+ </Button>
62
+ </Box>
63
+ </BottomSheetModalProvider>
64
+ </GestureHandlerRootView>
41
65
  );
42
66
  };
43
67
  ```
@@ -23,8 +23,11 @@ Hearth React Native is a comprehensive design system library for React Native, p
23
23
 
24
24
  - [Installation](#installation)
25
25
  - [Additional packages](#additional-packages)
26
+ - [Fonts](#fonts)
27
+ - [iOS Setup](#ios-setup)
26
28
  - [Linking the fonts to be used in your project](#linking-the-fonts-to-be-used-in-your-project)
27
- - [Using Expo](#using-expo)
29
+ - [Android Setup](#android-setup)
30
+ - [Using Expo](#using-expo)
28
31
  - [Babel configuration](#babel-configuration)
29
32
  - [Jest configuration](#jest-configuration)
30
33
 
@@ -39,7 +42,7 @@ npm install @utilitywarehouse/hearth-react-native
39
42
  To install the peer dependencies, you can run the following command:
40
43
 
41
44
  ```console
42
- npm install react-native-unistyles react-native-edge-to-edge react-native-nitro-modules@0.28.1 @gorhom/bottom-sheet react-native-svg react-native-reanimated react-native-worklets react-native-gesture-handler @utilitywarehouse/hearth-react-native-icons
45
+ npm install react-native-unistyles react-native-edge-to-edge react-native-nitro-modules @gorhom/bottom-sheet react-native-svg react-native-reanimated react-native-worklets react-native-gesture-handler @utilitywarehouse/hearth-react-native-icons
43
46
  ```
44
47
 
45
48
  For more information on how to install and configure `react-native-svg`, `react-native-gesture-handler` and `react-native-reanimated`,
@@ -66,6 +69,8 @@ as well as fonts and icons. Feel free to additionally install these packages if
66
69
  npm install @utilitywarehouse/hearth-tokens
67
70
  ```
68
71
 
72
+ ## Fonts
73
+
69
74
  You will need to include the **Comic Hams**, **DM Mono** and **DM Sans** fonts.
70
75
  The easiest way to do this is to use the `@utilitywarehouse/hearth-fonts` package.
71
76
 
@@ -73,6 +78,14 @@ The easiest way to do this is to use the `@utilitywarehouse/hearth-fonts` packag
73
78
  npm install @utilitywarehouse/hearth-fonts
74
79
  ```
75
80
 
81
+ ### iOS Setup
82
+
83
+ For iOS, copy the font files to your project's assets folder:
84
+
85
+ ```console
86
+ mkdir -p src/assets/fonts && cp ./node_modules/@utilitywarehouse/hearth-fonts/files/ttf/* src/assets/fonts/
87
+ ```
88
+
76
89
  Next, create or update your `react-native.config.js` file in the root directory and paste the code below inside it:
77
90
 
78
91
  ```js
@@ -81,7 +94,7 @@ module.exports = {
81
94
  ios: {},
82
95
  android: {},
83
96
  },
84
- assets: ['./node_modules/@utilitywarehouse/hearth-fornts/files/ttf'],
97
+ assets: ['./src/assets/fonts/'],
85
98
  };
86
99
  ```
87
100
 
@@ -93,7 +106,36 @@ Now we need to link them so we'll be able to use them in any files inside the pr
93
106
  npx react-native-asset
94
107
  ```
95
108
 
96
- #### Using Expo
109
+ ### Android Setup
110
+
111
+ For Android, you need to copy the fonts to two locations:
112
+
113
+ 1. Copy TTF files to the assets folder:
114
+
115
+ ```console
116
+ mkdir -p android/app/src/main/assets/fonts && cp ./node_modules/@utilitywarehouse/hearth-fonts/files/ttf/* android/app/src/main/assets/fonts/
117
+ ```
118
+
119
+ 2. Copy XML font family definitions to the resources folder:
120
+
121
+ ```console
122
+ mkdir -p android/app/src/main/res/font && cp ./node_modules/@utilitywarehouse/hearth-fonts/files/xml/* android/app/src/main/res/font/
123
+ ```
124
+
125
+ 3. Update your `android/app/src/main/java/com/{yourapp}/MainApplication.kt` file to register the custom fonts:
126
+
127
+ ```kotlin
128
+ import com.facebook.react.views.text.ReactFontManager;
129
+
130
+ // ... inside your onCreate() or initialization method:
131
+ ReactFontManager.getInstance().addCustomFont(this, "DM Sans", R.font.dm_sans)
132
+ ReactFontManager.getInstance().addCustomFont(this, "DM Mono", R.font.dm_mono)
133
+ ReactFontManager.getInstance().addCustomFont(this, "Comic Hams", R.font.comic_hams)
134
+ ```
135
+
136
+ This approach ensures fonts work consistently across platforms with a single canonical name, as described in [this article](https://ospfranco.com/post/2023/08/11/react-native,-how-to-set-up-fonts-with-a-single-canonical-name/).
137
+
138
+ ### Using Expo
97
139
 
98
140
  If you are using Expo, you can use the `expo-font` and [`expo-xml-font`](https://github.com/Armster15/expo-xml-font) packages to load the fonts.
99
141
  Here is an example of how to load the fonts in your `App.tsx` file:
@@ -131,7 +173,7 @@ You will need to add the following Babel plugin to your `babel.config.js` file:
131
173
  const unistylesPluginOptions = {
132
174
  autoProcessImports: ['@utilitywarehouse/hearth-react-native'],
133
175
  autoProcessPaths: ['@utilitywarehouse/hearth-react-native'],
134
- autoProcessRoot: 'src', // Adjust this to your project's structure
176
+ root: 'src', // Adjust this to your project's structure
135
177
  debug: false, // Set to true for debugging purposes
136
178
  };
137
179
 
@@ -152,7 +194,10 @@ If you are using Jest for testing, you will need to add the following configurat
152
194
  ```js
153
195
  module.exports = {
154
196
  // other Jest configurations...
155
- setupFiles: ['react-native-unistyles/mocks'],
197
+ setupFiles: [
198
+ 'react-native-unistyles/mocks',
199
+ './node_modules/react-native-gesture-handler/jestSetup.js',
200
+ ],
156
201
  // other Jest configurations...
157
202
  };
158
203
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "@vitest/coverage-v8": "^3.2.4",
38
38
  "chromatic": "^13.3.0",
39
39
  "eslint-plugin-storybook": "9.1.6",
40
- "playwright": "^1.53.1",
40
+ "playwright": "^1.55.1",
41
41
  "prismjs": "^1.30.0",
42
42
  "react": "^19.1.0",
43
43
  "react-native": "0.80.0",
@@ -53,14 +53,14 @@
53
53
  "typescript": "^5.7.3",
54
54
  "vite": "^7.1.3",
55
55
  "vitest": "^3.2.4",
56
- "@utilitywarehouse/hearth-fonts": "^0.0.3",
57
- "@utilitywarehouse/hearth-react-icons": "^0.5.0",
58
- "@utilitywarehouse/hearth-react-native-icons": "^0.5.0",
59
- "@utilitywarehouse/hearth-tokens": "^0.1.1"
56
+ "@utilitywarehouse/hearth-fonts": "^0.0.4",
57
+ "@utilitywarehouse/hearth-react-icons": "^0.7.0",
58
+ "@utilitywarehouse/hearth-react-native-icons": "^0.7.0",
59
+ "@utilitywarehouse/hearth-tokens": "^0.1.3"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@gorhom/bottom-sheet": "^5.0.0",
63
- "@utilitywarehouse/hearth-react-native-icons": "0.4.0",
63
+ "@utilitywarehouse/hearth-react-native-icons": "0.6.0",
64
64
  "react": ">=17 || ^18.0.0 || ^19.0.0",
65
65
  "react-native": ">=0.77",
66
66
  "react-native-gesture-handler": "^2.22.0",
@@ -1,15 +1,15 @@
1
1
  import type { TextProps, TextStyle } from 'react-native';
2
2
  import { StyleSheet } from 'react-native-unistyles';
3
- import { DetailText } from '../DetailText';
3
+ import { BodyText } from '../BodyText';
4
4
  import { useAlertContext } from './Alert.context';
5
5
 
6
6
  const AlertTitle = ({ children, style, ...props }: TextProps) => {
7
7
  const { colorScheme } = useAlertContext();
8
8
  styles.useVariants({ colorScheme });
9
9
  return (
10
- <DetailText size="md" style={[styles.title as TextStyle, style]} {...props}>
10
+ <BodyText size="md" weight="semibold" style={[styles.title as TextStyle, style]} {...props}>
11
11
  {children}
12
- </DetailText>
12
+ </BodyText>
13
13
  );
14
14
  };
15
15
 
@@ -18,16 +18,16 @@ const styles = StyleSheet.create(theme => ({
18
18
  variants: {
19
19
  colorScheme: {
20
20
  info: {
21
- color: theme.color.feedback.info.foreground,
21
+ color: theme.color.feedback.info.foreground.default,
22
22
  },
23
23
  positive: {
24
- color: theme.color.feedback.positive.foreground,
24
+ color: theme.color.feedback.positive.foreground.default,
25
25
  },
26
26
  danger: {
27
- color: theme.color.feedback.danger.foreground,
27
+ color: theme.color.feedback.danger.foreground.default,
28
28
  },
29
29
  warning: {
30
- color: theme.color.feedback.warning.foreground,
30
+ color: theme.color.feedback.warning.foreground.default,
31
31
  },
32
32
  },
33
33
  },
@@ -19,6 +19,7 @@ interface BadgeProps extends ViewProps {
19
19
  size?: 'sm' | 'md';
20
20
  icon?: ComponentType;
21
21
  flatBase?: boolean;
22
+ text?: string | number;
22
23
  }
23
24
 
24
25
  export default BadgeProps;
@@ -14,6 +14,7 @@ const Badge = ({ children, ...props }: BadgeProps) => {
14
14
  flatBase = false,
15
15
  size = 'sm',
16
16
  style,
17
+ text,
17
18
  ...rest
18
19
  } = props;
19
20
 
@@ -22,7 +23,7 @@ const Badge = ({ children, ...props }: BadgeProps) => {
22
23
  [colorScheme, flatBase, variant, size]
23
24
  );
24
25
 
25
- const childIsText = typeof children === 'string' || typeof children === 'number';
26
+ const childIsText = typeof children === 'string' || typeof children === 'number' || !!text;
26
27
 
27
28
  styles.useVariants({ colorScheme, flatBase, variant, size });
28
29
 
@@ -30,7 +31,7 @@ const Badge = ({ children, ...props }: BadgeProps) => {
30
31
  <BadgeContext.Provider value={value}>
31
32
  <View {...rest} style={[styles.container, style]}>
32
33
  {!!icon && <BadgeIcon as={icon} />}
33
- {childIsText ? <BadgeText>{children}</BadgeText> : children}
34
+ {childIsText ? <BadgeText>{text ?? children}</BadgeText> : children}
34
35
  </View>
35
36
  </BadgeContext.Provider>
36
37
  );