@utilitywarehouse/hearth-react-native 0.19.1 → 0.21.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 (149) hide show
  1. package/.storybook/manager.ts +1 -0
  2. package/.storybook/preview.tsx +1 -0
  3. package/.turbo/turbo-build.log +1 -1
  4. package/.turbo/turbo-lint.log +13 -13
  5. package/CHANGELOG.md +299 -4
  6. package/build/components/BodyText/BodyText.js +12 -5
  7. package/build/components/BodyText/BodyText.props.d.ts +5 -19
  8. package/build/components/Box/Box.js +23 -3
  9. package/build/components/Box/Box.props.d.ts +3 -95
  10. package/build/components/Card/Card.props.d.ts +2 -5
  11. package/build/components/Container/Container.props.d.ts +2 -78
  12. package/build/components/DateInput/DateInput.d.ts +1 -1
  13. package/build/components/DateInput/DateInput.js +2 -2
  14. package/build/components/DateInput/DateInput.props.d.ts +15 -1
  15. package/build/components/DateInput/DateInputSegment.d.ts +1 -1
  16. package/build/components/DateInput/DateInputSegment.js +2 -2
  17. package/build/components/DetailText/DetailText.js +14 -13
  18. package/build/components/DetailText/DetailText.props.d.ts +4 -17
  19. package/build/components/Flex/Flex.js +3 -1
  20. package/build/components/Flex/Flex.props.d.ts +2 -2
  21. package/build/components/Heading/Heading.js +34 -13
  22. package/build/components/Heading/Heading.props.d.ts +4 -18
  23. package/build/components/Select/Select.d.ts +1 -1
  24. package/build/components/Select/Select.js +9 -10
  25. package/build/components/Select/Select.props.d.ts +16 -0
  26. package/build/core/themes.d.ts +188 -8
  27. package/build/core/themes.js +18 -2
  28. package/build/hooks/useStyleProps.js +22 -5
  29. package/build/tokens/color.d.ts +4 -0
  30. package/build/tokens/color.js +2 -0
  31. package/build/tokens/components/dark/modal.d.ts +6 -0
  32. package/build/tokens/components/dark/modal.js +6 -0
  33. package/build/tokens/components/dark/navigation.d.ts +1 -0
  34. package/build/tokens/components/dark/navigation.js +1 -0
  35. package/build/tokens/components/light/modal.d.ts +6 -0
  36. package/build/tokens/components/light/modal.js +6 -0
  37. package/build/tokens/components/light/navigation.d.ts +1 -0
  38. package/build/tokens/components/light/navigation.js +1 -0
  39. package/build/tokens/components/light/skeleton.d.ts +1 -1
  40. package/build/tokens/components/light/skeleton.js +1 -1
  41. package/build/tokens/font.d.ts +2 -0
  42. package/build/tokens/font.js +2 -0
  43. package/build/tokens/line-height.d.ts +2 -0
  44. package/build/tokens/line-height.js +2 -0
  45. package/build/tokens/primitive.d.ts +4 -0
  46. package/build/tokens/primitive.js +4 -0
  47. package/build/tokens/semantic-dark.d.ts +1 -0
  48. package/build/tokens/semantic-dark.js +1 -0
  49. package/build/tokens/semantic-light.d.ts +1 -0
  50. package/build/tokens/semantic-light.js +1 -0
  51. package/build/tokens/typography.d.ts +30 -0
  52. package/build/tokens/typography.js +15 -0
  53. package/build/types/index.d.ts +4 -2
  54. package/build/types/index.js +4 -2
  55. package/build/types/semanticColorValues.d.ts +22 -0
  56. package/build/types/semanticColorValues.js +1 -0
  57. package/build/types/utilityProps.d.ts +326 -0
  58. package/build/types/utilityProps.js +1 -0
  59. package/build/types/values.d.ts +4 -3
  60. package/build/utils/coloursAsArray.d.ts +4 -0
  61. package/build/utils/coloursAsArray.js +5 -0
  62. package/build/utils/index.d.ts +1 -1
  63. package/build/utils/index.js +1 -1
  64. package/build/utils/styleUtils.d.ts +26 -2
  65. package/build/utils/styleUtils.js +42 -13
  66. package/build/utils/themeValueHelpers.d.ts +13 -0
  67. package/build/utils/themeValueHelpers.js +29 -0
  68. package/docs/changelog.mdx +74 -2
  69. package/docs/components/AllComponents.web.tsx +23 -24
  70. package/docs/components/UsageWrap.tsx +2 -2
  71. package/docs/introduction.mdx +0 -7
  72. package/package.json +5 -3
  73. package/src/components/BodyText/BodyText.props.ts +5 -19
  74. package/src/components/BodyText/BodyText.stories.tsx +2 -1
  75. package/src/components/BodyText/BodyText.tsx +17 -6
  76. package/src/components/Box/Box.docs.mdx +5 -4
  77. package/src/components/Box/Box.props.ts +3 -231
  78. package/src/components/Box/Box.stories.tsx +2 -2
  79. package/src/components/Box/Box.tsx +38 -9
  80. package/src/components/Button/Button.docs.mdx +46 -1
  81. package/src/components/Card/Card.docs.mdx +1 -1
  82. package/src/components/Card/Card.props.ts +2 -5
  83. package/src/components/Card/Card.stories.tsx +54 -23
  84. package/src/components/Carousel/Carousel.docs.mdx +49 -44
  85. package/src/components/Center/Center.docs.mdx +6 -4
  86. package/src/components/Checkbox/CheckboxGroup.figma.tsx +21 -1
  87. package/src/components/Container/Container.docs.mdx +13 -8
  88. package/src/components/Container/Container.props.ts +9 -80
  89. package/src/components/Container/Container.stories.tsx +81 -65
  90. package/src/components/DateInput/DateInput.docs.mdx +43 -0
  91. package/src/components/DateInput/DateInput.props.ts +15 -1
  92. package/src/components/DateInput/DateInput.stories.tsx +37 -2
  93. package/src/components/DateInput/DateInput.tsx +6 -0
  94. package/src/components/DateInput/DateInputSegment.tsx +2 -0
  95. package/src/components/DetailText/DetailText.props.ts +4 -17
  96. package/src/components/DetailText/DetailText.stories.tsx +2 -3
  97. package/src/components/DetailText/DetailText.tsx +16 -17
  98. package/src/components/Flex/Flex.props.ts +2 -2
  99. package/src/components/Flex/Flex.stories.tsx +1 -1
  100. package/src/components/Flex/Flex.tsx +4 -1
  101. package/src/components/Grid/Grid.docs.mdx +53 -49
  102. package/src/components/Heading/Heading.props.ts +4 -18
  103. package/src/components/Heading/Heading.stories.tsx +2 -1
  104. package/src/components/Heading/Heading.tsx +40 -18
  105. package/src/components/PillGroup/Pill.figma.tsx +4 -17
  106. package/src/components/PillGroup/PillGroup.figma.tsx +8 -9
  107. package/src/components/ProgressStepper/ProgressStep.figma.tsx +4 -15
  108. package/src/components/ProgressStepper/ProgressStepper.figma.tsx +9 -16
  109. package/src/components/Radio/Radio.figma.tsx +35 -22
  110. package/src/components/Radio/RadioGroup.figma.tsx +69 -41
  111. package/src/components/Radio/RadioTile.figma.tsx +34 -0
  112. package/src/components/RadioCard/RadioCard.figma.tsx +24 -0
  113. package/src/components/SectionHeader/SectionHeader.figma.tsx +31 -25
  114. package/src/components/Select/Select.docs.mdx +76 -28
  115. package/src/components/Select/Select.figma.tsx +44 -43
  116. package/src/components/Select/Select.props.ts +16 -0
  117. package/src/components/Select/Select.tsx +42 -35
  118. package/src/components/Select/SelectOption.figma.tsx +3 -21
  119. package/src/components/Spinner/Spinner.figma.tsx +12 -25
  120. package/src/components/Switch/Switch.figma.tsx +2 -23
  121. package/src/components/Tabs/Tab.figma.tsx +21 -0
  122. package/src/components/Tabs/Tabs.figma.tsx +18 -27
  123. package/src/components/Textarea/Textarea.figma.tsx +64 -0
  124. package/src/components/Toast/ToastItem.figma.tsx +1 -8
  125. package/src/components/ToggleButtonCard/ToggleButtonCard.figma.tsx +24 -0
  126. package/src/components/VerificationInput/VerificationInput.figma.tsx +53 -0
  127. package/src/core/themes.ts +19 -2
  128. package/src/hooks/useStyleProps.ts +40 -5
  129. package/src/tokens/color.ts +2 -0
  130. package/src/tokens/components/dark/modal.ts +6 -0
  131. package/src/tokens/components/dark/navigation.ts +1 -0
  132. package/src/tokens/components/light/modal.ts +6 -0
  133. package/src/tokens/components/light/navigation.ts +1 -0
  134. package/src/tokens/components/light/skeleton.ts +1 -1
  135. package/src/tokens/font.ts +2 -0
  136. package/src/tokens/line-height.ts +2 -0
  137. package/src/tokens/primitive.ts +4 -0
  138. package/src/tokens/semantic-dark.ts +1 -0
  139. package/src/tokens/semantic-light.ts +1 -0
  140. package/src/tokens/typography.ts +15 -0
  141. package/src/types/index.ts +4 -2
  142. package/src/types/semanticColorValues.ts +26 -0
  143. package/src/types/utilityProps.ts +410 -0
  144. package/src/types/values.ts +4 -7
  145. package/src/utils/coloursAsArray.ts +6 -0
  146. package/src/utils/index.ts +8 -1
  147. package/src/utils/styleUtils.ts +45 -14
  148. package/src/utils/themeValueHelpers.ts +38 -0
  149. package/src/components/Radio/RadioTileRoot.figma.tsx +0 -31
@@ -6,10 +6,34 @@ export declare const propStyleMapping: {
6
6
  [key: string]: keyof ViewStyle;
7
7
  };
8
8
  /**
9
- * Mapping of style props to their theme category
9
+ * Mapping of style props to their theme category.
10
+ *
11
+ * - `backgroundColor` maps to `theme.helpers.semanticColor.background` (simplified semantic background tokens)
12
+ * with fallback to `theme.color` for full color values
13
+ * - `borderColor` (and variants) maps to `theme.helpers.semanticColor.border` (simplified semantic border tokens)
14
+ * with fallback to `theme.color` for full color values
15
+ * - Other color props (shadowColor, outlineColor) still map to the full `theme.color` object
10
16
  */
11
17
  export declare const themeStyleMapping: {
12
- [key in keyof ViewStyle]?: string;
18
+ [key: string]: string;
19
+ };
20
+ /**
21
+ * Mapping of theme categories to their fallback categories.
22
+ * When a value isn't found in the primary theme category, the fallback is tried.
23
+ * This ensures backward compatibility with full color values.
24
+ */
25
+ export declare const themeStyleFallbackMapping: {
26
+ [key: string]: string;
27
+ };
28
+ /**
29
+ * Mapping of custom semantic prop names to their style prop + theme category.
30
+ * These are props that don't correspond 1:1 with ViewStyle keys.
31
+ */
32
+ export declare const semanticPropMapping: {
33
+ [key: string]: {
34
+ styleProp: string;
35
+ themeKey: string;
36
+ };
13
37
  };
14
38
  /**
15
39
  * Set of all possible ViewStyle property names
@@ -31,7 +31,13 @@ export const propStyleMapping = {
31
31
  space: 'gap',
32
32
  };
33
33
  /**
34
- * Mapping of style props to their theme category
34
+ * Mapping of style props to their theme category.
35
+ *
36
+ * - `backgroundColor` maps to `theme.helpers.semanticColor.background` (simplified semantic background tokens)
37
+ * with fallback to `theme.color` for full color values
38
+ * - `borderColor` (and variants) maps to `theme.helpers.semanticColor.border` (simplified semantic border tokens)
39
+ * with fallback to `theme.color` for full color values
40
+ * - Other color props (shadowColor, outlineColor) still map to the full `theme.color` object
35
41
  */
36
42
  export const themeStyleMapping = {
37
43
  // Space related
@@ -68,18 +74,20 @@ export const themeStyleMapping = {
68
74
  maxHeight: 'space',
69
75
  start: 'space',
70
76
  end: 'space',
71
- // Colors
72
- backgroundColor: 'color',
73
- borderColor: 'color',
74
- borderBottomColor: 'color',
75
- borderLeftColor: 'color',
76
- borderRightColor: 'color',
77
- borderTopColor: 'color',
78
- borderBlockColor: 'color',
79
- borderBlockEndColor: 'color',
80
- borderBlockStartColor: 'color',
81
- borderEndColor: 'color',
82
- borderStartColor: 'color',
77
+ // Semantic background color (simplified keys: 'brand', 'primary', 'secondary')
78
+ backgroundColor: 'helpers.semanticColor.background',
79
+ // Semantic border colors (simplified keys: 'strong', 'subtle')
80
+ borderColor: 'helpers.semanticColor.border',
81
+ borderBottomColor: 'helpers.semanticColor.border',
82
+ borderLeftColor: 'helpers.semanticColor.border',
83
+ borderRightColor: 'helpers.semanticColor.border',
84
+ borderTopColor: 'helpers.semanticColor.border',
85
+ borderBlockColor: 'helpers.semanticColor.border',
86
+ borderBlockEndColor: 'helpers.semanticColor.border',
87
+ borderBlockStartColor: 'helpers.semanticColor.border',
88
+ borderEndColor: 'helpers.semanticColor.border',
89
+ borderStartColor: 'helpers.semanticColor.border',
90
+ // Other colors (still use the full color object for flexibility)
83
91
  outlineColor: 'color',
84
92
  shadowColor: 'color',
85
93
  // Border radii
@@ -105,6 +113,27 @@ export const themeStyleMapping = {
105
113
  borderTopWidth: 'borderWidth',
106
114
  borderWidth: 'borderWidth',
107
115
  };
116
+ /**
117
+ * Mapping of theme categories to their fallback categories.
118
+ * When a value isn't found in the primary theme category, the fallback is tried.
119
+ * This ensures backward compatibility with full color values.
120
+ */
121
+ export const themeStyleFallbackMapping = {
122
+ 'helpers.semanticColor.background': 'color',
123
+ 'helpers.semanticColor.border': 'color',
124
+ 'helpers.semanticColor.text': 'color',
125
+ 'helpers.semanticColor.icon': 'color',
126
+ };
127
+ /**
128
+ * Mapping of custom semantic prop names to their style prop + theme category.
129
+ * These are props that don't correspond 1:1 with ViewStyle keys.
130
+ */
131
+ export const semanticPropMapping = {
132
+ /** Maps iconColor prop -> resolves against theme.helpers.semanticColor.icon (semantic icon tokens) */
133
+ iconColor: { styleProp: 'color', themeKey: 'helpers.semanticColor.icon' },
134
+ /** Maps color prop -> resolves against theme.helpers.semanticColor.text (semantic text tokens) */
135
+ color: { styleProp: 'color', themeKey: 'helpers.semanticColor.text' },
136
+ };
108
137
  /**
109
138
  * Set of all possible ViewStyle property names
110
139
  */
@@ -15,3 +15,16 @@ export declare const getNestedValue: (obj: any, path: string[]) => any;
15
15
  * - Numeric suffix pattern (broadbandBlue100 -> themeMapping.broadbandBlue[100])
16
16
  */
17
17
  export declare const resolveThemeValue: (value: any, themeMapping: any) => any;
18
+ /**
19
+ * Resolve a dot-notation key against the theme object.
20
+ * e.g., 'semanticColor.text' -> theme.semanticColor.text
21
+ * Simple keys like 'space' are resolved via direct bracket access.
22
+ */
23
+ export declare const resolveThemeKey: (theme: Record<string, any>, key: string) => any;
24
+ /**
25
+ * Resolve a theme value with a fallback theme mapping.
26
+ * First tries the primary mapping (e.g., theme.semanticColor.background for simplified tokens).
27
+ * If not found, falls back to the secondary mapping (e.g., theme.color for full color values).
28
+ * This ensures backward compatibility while supporting simplified token names.
29
+ */
30
+ export declare const resolveThemeValueWithFallback: (value: any, primaryMapping: any, fallbackMapping?: any) => any;
@@ -52,3 +52,32 @@ export const resolveThemeValue = (value, themeMapping) => {
52
52
  // If none of the approaches work, return the original value
53
53
  return value;
54
54
  };
55
+ /**
56
+ * Resolve a dot-notation key against the theme object.
57
+ * e.g., 'semanticColor.text' -> theme.semanticColor.text
58
+ * Simple keys like 'space' are resolved via direct bracket access.
59
+ */
60
+ export const resolveThemeKey = (theme, key) => {
61
+ if (key.includes('.')) {
62
+ return key.split('.').reduce((obj, k) => obj?.[k], theme);
63
+ }
64
+ return theme[key];
65
+ };
66
+ /**
67
+ * Resolve a theme value with a fallback theme mapping.
68
+ * First tries the primary mapping (e.g., theme.semanticColor.background for simplified tokens).
69
+ * If not found, falls back to the secondary mapping (e.g., theme.color for full color values).
70
+ * This ensures backward compatibility while supporting simplified token names.
71
+ */
72
+ export const resolveThemeValueWithFallback = (value, primaryMapping, fallbackMapping) => {
73
+ const resolved = resolveThemeValue(value, primaryMapping);
74
+ // If the value was resolved (changed from input), return it
75
+ if (resolved !== value) {
76
+ return resolved;
77
+ }
78
+ // If we have a fallback mapping and the primary didn't resolve, try the fallback
79
+ if (fallbackMapping) {
80
+ return resolveThemeValue(value, fallbackMapping);
81
+ }
82
+ return resolved;
83
+ };
@@ -9,6 +9,78 @@ import { BackToTopButton } from './components';
9
9
  The changelog for the Hearth React Native library. Here you can find all the changes, improvements, and bug fixes for each version.
10
10
 
11
11
 
12
+ ## 0.20.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#898](https://github.com/utilitywarehouse/hearth/pull/898) [`d32a188`](https://github.com/utilitywarehouse/hearth/commit/d32a18840c04222b7b1348133137dc5e56745fe3) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add validation and helper text props to `Select` component
17
+
18
+ The `Select` component now supports built-in validation messages and helper text through new props: `invalidText`, `validText`, `helperText`, and `helperIcon`. This provides a more integrated validation experience without needing to wrap the component in FormField.
19
+
20
+ **Components affected**:
21
+ - `Select`
22
+
23
+ **Developer changes**:
24
+
25
+ You can now add helper text and validation messages directly to Select:
26
+
27
+ ```tsx
28
+ import { Select } from '@utilitywarehouse/hearth-react-native';
29
+
30
+ <Select
31
+ label="Choose an option"
32
+ placeholder="Select an option"
33
+ helperText="This is some helper text for the select component."
34
+ validationStatus="invalid"
35
+ invalidText="Please select a valid option"
36
+ options={[
37
+ { label: 'Option 1', value: '1' },
38
+ { label: 'Option 2', value: '2' },
39
+ { label: 'Option 3', value: '3' },
40
+ ]}
41
+ value={value}
42
+ onValueChange={setValue}
43
+ />;
44
+ ```
45
+
46
+ The component now also supports a `labelVariant` prop to control label styling:
47
+
48
+ ```tsx
49
+ <Select
50
+ label="Choose an option"
51
+ labelVariant="heading"
52
+ // ... other props
53
+ />
54
+ ```
55
+
56
+ These new props work seamlessly alongside the existing FormField wrapper if you prefer that approach. No changes are required to existing Select implementations.
57
+
58
+ ## 0.19.1
59
+
60
+ ### Patch Changes
61
+
62
+ - [#886](https://github.com/utilitywarehouse/hearth/pull/886) [`7a948de`](https://github.com/utilitywarehouse/hearth/commit/7a948dea0d15ce7ca34e4d405e86984213c96196) Thanks [@jordmccord](https://github.com/jordmccord)! - 💅 [ENHANCEMENT]: Add `loadingHeading` prop to `Modal` component
63
+
64
+ The `Modal` component now supports a `loadingHeading` prop to customise the heading text displayed during loading states. If not provided, it defaults to 'Loading...'.
65
+
66
+ **Components affected**:
67
+ - `Modal`
68
+
69
+ **Developer changes**:
70
+
71
+ No changes required. To customise the loading heading text, use the new `loadingHeading` prop:
72
+
73
+ ```tsx
74
+ <Modal
75
+ loading={isLoading}
76
+ loadingHeading="Processing your request..."
77
+ heading="Confirm Action"
78
+ description="Please wait while we process your request"
79
+ />
80
+ ```
81
+
82
+ - [#888](https://github.com/utilitywarehouse/hearth/pull/888) [`9b3e172`](https://github.com/utilitywarehouse/hearth/commit/9b3e172f9964026f4f3ba140731432ac63550256) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Align `Toast` icon and dismiss button to the top
83
+
12
84
  ## 0.19.0
13
85
 
14
86
  ### Minor Changes
@@ -126,7 +198,7 @@ The changelog for the Hearth React Native library. Here you can find all the cha
126
198
 
127
199
  **Developer changes**:
128
200
 
129
- You can now customize `IconButton` colors for service-specific branding:
201
+ You can now customise `IconButton` colors for service-specific branding:
130
202
 
131
203
  ```tsx
132
204
  import { IconButton } from '@utilitywarehouse/hearth-react-native';
@@ -147,7 +219,7 @@ The changelog for the Hearth React Native library. Here you can find all the cha
147
219
  - `activeBackgroundColor` - Sets the background color when pressed or in an active state
148
220
  - `shadowColor` - Sets the shadow/elevation color
149
221
 
150
- These overrides work alongside the existing `variant` and `colorScheme` props, allowing you to maintain structural styling while customizing colors for specific branding requirements.
222
+ These overrides work alongside the existing `variant` and `colorScheme` props, allowing you to maintain structural styling while customising colors for specific branding requirements.
151
223
 
152
224
  ### Patch Changes
153
225
 
@@ -17,6 +17,7 @@ import {
17
17
  import SpotBillingDark from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-dark.svg';
18
18
  // @ts-expect-error - Module missing type declarations
19
19
  import SpotBillingLight from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-light.svg';
20
+ import { color } from '@utilitywarehouse/hearth-tokens';
20
21
  import { Pressable, ScrollView, View, ViewProps } from 'react-native';
21
22
  import { StyleSheet } from 'react-native-unistyles';
22
23
  import {
@@ -248,8 +249,8 @@ const AllComponents: React.FC = () => {
248
249
  </ComponentWrapper>
249
250
  <ComponentWrapper name="Box" link="/?path=/docs/primitives-box--docs">
250
251
  <Center flex={1}>
251
- <Box backgroundColor="grey900" padding="300" width={200} height={100}>
252
- <BodyText color={isDark ? 'grey100' : 'white'} weight="semibold">
252
+ <Box backgroundColor={color.grey[900]} padding="300" width={200} height={100}>
253
+ <BodyText color={isDark ? 'primary' : 'inverted'} weight="semibold">
253
254
  This is a Box
254
255
  </BodyText>
255
256
  </Box>
@@ -275,14 +276,14 @@ const AllComponents: React.FC = () => {
275
276
  <Carousel itemWidth={150} centered width={150}>
276
277
  <CarouselItem>
277
278
  <Box
278
- backgroundColor="blue700"
279
+ backgroundColor={color.blue[700]}
279
280
  width={150}
280
281
  height={100}
281
282
  px="100"
282
283
  borderRadius="md"
283
284
  >
284
285
  <Center flex={1}>
285
- <BodyText color="white" textAlign="center">
286
+ <BodyText color="inverted" textAlign="center">
286
287
  I'm a carousel item
287
288
  </BodyText>
288
289
  </Center>
@@ -290,14 +291,14 @@ const AllComponents: React.FC = () => {
290
291
  </CarouselItem>
291
292
  <CarouselItem>
292
293
  <Box
293
- backgroundColor="purple700"
294
+ backgroundColor={color.purple[700]}
294
295
  width={150}
295
296
  height={100}
296
297
  px="100"
297
298
  borderRadius="md"
298
299
  >
299
300
  <Center flex={1}>
300
- <BodyText color="white" textAlign="center">
301
+ <BodyText color="inverted" textAlign="center">
301
302
  I'm another carousel item
302
303
  </BodyText>
303
304
  </Center>
@@ -305,14 +306,14 @@ const AllComponents: React.FC = () => {
305
306
  </CarouselItem>
306
307
  <CarouselItem>
307
308
  <Box
308
- backgroundColor="green700"
309
+ backgroundColor={color.green[700]}
309
310
  width={150}
310
311
  height={100}
311
312
  px="100"
312
313
  borderRadius="md"
313
314
  >
314
315
  <Center flex={1}>
315
- <BodyText color="white" textAlign="center">
316
+ <BodyText color="inverted" textAlign="center">
316
317
  I'm also a carousel item
317
318
  </BodyText>
318
319
  </Center>
@@ -323,8 +324,8 @@ const AllComponents: React.FC = () => {
323
324
  </ComponentWrapper>
324
325
  <ComponentWrapper name="Center" link="/?path=/docs/primitives-center--docs">
325
326
  <Center flex={1}>
326
- <Center backgroundColor="red400" padding="300" width={200} height={100}>
327
- <BodyText color={isDark ? 'grey1000' : 'white'} weight="semibold">
327
+ <Center backgroundColor={color.red[400]} padding="300" width={200} height={100}>
328
+ <BodyText color={isDark ? 'primary' : 'inverted'} weight="semibold">
328
329
  I am in the Center
329
330
  </BodyText>
330
331
  </Center>
@@ -339,10 +340,10 @@ const AllComponents: React.FC = () => {
339
340
  </Center>
340
341
  </ComponentWrapper>
341
342
  <ComponentWrapper name="Container" link="/?path=/docs/primitives-container--docs">
342
- <Container spacing="md" backgroundColor="backgroundSecondary">
343
- <Box h={20} bg="blue300" />
344
- <Box h={20} bg="blue400" />
345
- <Box h={20} bg="blue500" />
343
+ <Container spacing="md" backgroundColor="secondary">
344
+ <Box h={20} bg={color.blue[300]} />
345
+ <Box h={20} bg={color.blue[400]} />
346
+ <Box h={20} bg={color.blue[500]} />
346
347
  </Container>
347
348
  </ComponentWrapper>
348
349
  <ComponentWrapper name="Currency Input" link="/?path=/docs/forms-currency-input--docs">
@@ -445,10 +446,10 @@ const AllComponents: React.FC = () => {
445
446
  <ComponentWrapper name="Flex" link="/?path=/docs/primitives-flex--docs">
446
447
  <Center flex={1}>
447
448
  <Flex direction="row" spacing="md">
448
- <Box w={40} h={40} bg="blue300" />
449
- <Box w={40} h={40} bg="blue400" />
450
- <Box w={40} h={40} bg="blue500" />
451
- <Box w={40} h={40} bg="blue600" />
449
+ <Box w={40} h={40} bg={color.blue[300]} />
450
+ <Box w={40} h={40} bg={color.blue[400]} />
451
+ <Box w={40} h={40} bg={color.blue[500]} />
452
+ <Box w={40} h={40} bg={color.blue[600]} />
452
453
  </Flex>
453
454
  </Center>
454
455
  </ComponentWrapper>
@@ -468,10 +469,10 @@ const AllComponents: React.FC = () => {
468
469
  <Center flex={1}>
469
470
  <Box width={100}>
470
471
  <Grid columns={2} spacing="md">
471
- <Box w={40} h={40} bg="blue300" />
472
- <Box w={40} h={40} bg="blue400" />
473
- <Box w={40} h={40} bg="blue500" />
474
- <Box w={40} h={40} bg="blue600" />
472
+ <Box w={40} h={40} bg={color.blue[300]} />
473
+ <Box w={40} h={40} bg={color.blue[400]} />
474
+ <Box w={40} h={40} bg={color.blue[500]} />
475
+ <Box w={40} h={40} bg={color.blue[600]} />
475
476
  </Grid>
476
477
  </Box>
477
478
  </Center>
@@ -649,7 +650,6 @@ const AllComponents: React.FC = () => {
649
650
  </ComponentWrapper>
650
651
  <ComponentWrapper name="Pill Group" link="/?path=/docs/components-pill-group--docs">
651
652
  <Center flex={1} p="200">
652
- (
653
653
  <PillGroup
654
654
  value={pillValue}
655
655
  onChange={v => setPillValue(v as string[])}
@@ -661,7 +661,6 @@ const AllComponents: React.FC = () => {
661
661
  <Pill value="broadband" label="Broadband" icon={BroadbandMediumIcon} />
662
662
  <Pill value="mobile" label="Mobile" icon={MobileMediumIcon} />
663
663
  </PillGroup>
664
- );
665
664
  </Center>
666
665
  </ComponentWrapper>
667
666
  <ComponentWrapper
@@ -6,10 +6,10 @@ const UsageWrap: FC<PropsWithChildren> = ({ children }) => (
6
6
  <Box
7
7
  mt="300"
8
8
  p="200"
9
- bg="backgroundPrimary"
9
+ bg="primary"
10
10
  borderRadius="md"
11
11
  borderWidth="1"
12
- borderColor="borderSubtle"
12
+ borderColor="subtle"
13
13
  width="100%"
14
14
  position="relative"
15
15
  >
@@ -1,5 +1,4 @@
1
1
  import { Meta } from '@storybook/addon-docs/blocks';
2
- import pig from '../../../shared/storybook/assets/images/react-native-pig.png';
3
2
  import { version } from '../package.json';
4
3
  import { Box } from '../src';
5
4
  import { BackToTopButton, NextPrevPage } from './components';
@@ -8,17 +7,11 @@ import { BackToTopButton, NextPrevPage } from './components';
8
7
 
9
8
  <BackToTopButton />
10
9
 
11
- <Box alignItems='center' style={{textAlign:"center"}}>
12
-
13
- <img src={pig} alt="React Native Package" width={240} height={240} />
14
-
15
10
  # Hearth React Native
16
11
 
17
12
  React Native component library for building UIs at Utility Warehouse.<br/>
18
13
  Current version: v{version}
19
14
 
20
- </Box>
21
-
22
15
  Hearth React Native is a comprehensive design system library for React Native, providing reusable components, consistent styling, and tools to streamline UI development. It is built to enhance productivity and maintain design consistency across projects.
23
16
 
24
17
  - [Installation](#installation)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.19.1",
3
+ "version": "0.21.0",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -58,8 +58,8 @@
58
58
  "@utilitywarehouse/hearth-fonts": "^0.0.4",
59
59
  "@utilitywarehouse/hearth-react-icons": "^0.8.0",
60
60
  "@utilitywarehouse/hearth-react-native-icons": "^0.8.0",
61
- "@utilitywarehouse/hearth-svg-assets": "^0.3.0",
62
- "@utilitywarehouse/hearth-tokens": "^0.2.2"
61
+ "@utilitywarehouse/hearth-svg-assets": "^0.5.0",
62
+ "@utilitywarehouse/hearth-tokens": "^0.2.3"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@gorhom/bottom-sheet": "^5.0.0",
@@ -85,7 +85,9 @@
85
85
  "figma:publish": "figma connect publish",
86
86
  "test": "echo \"Error: no test specified\" && exit 1",
87
87
  "dev": "npm run copyChangelog && storybook dev -p 6006",
88
+ "dev:docs": "storybook dev -p 6002 --no-open --docs",
88
89
  "build:storybook": "npm run copyChangelog && storybook build",
90
+ "build:storybook:docs": "npm run copyChangelog && storybook build --docs",
89
91
  "chromatic": "npx chromatic --project-token=chpt_cce0fb1ebd95d2a --build-script-name build:storybook"
90
92
  }
91
93
  }
@@ -1,24 +1,10 @@
1
- import { Ref } from 'react';
2
- import type { TextProps as RNTextProps, Text, TextStyle } from 'react-native';
3
- import type { ColorValue } from '../../types';
1
+ import type { CommonTextProps } from '../../types';
4
2
 
5
- interface TextProps extends RNTextProps {
3
+ interface BodyTextProps extends CommonTextProps {
4
+ /** Text size variant. */
6
5
  size?: 'sm' | 'md' | 'lg';
7
- strikeThrough?: boolean;
8
- underline?: boolean;
9
- truncated?: boolean;
6
+ /** Font weight variant. */
10
7
  weight?: 'regular' | 'semibold' | 'bold';
11
- italic?: boolean;
12
- color?: ColorValue;
13
- textTransform?: TextStyle['textTransform'];
14
- textAlign?: TextStyle['textAlign'];
15
- textAlignVertical?: TextStyle['textAlignVertical'];
16
- textDecorationLine?: TextStyle['textDecorationLine'];
17
- textDecorationStyle?: TextStyle['textDecorationStyle'];
18
- textDecorationColor?: ColorValue;
19
- userSelect?: TextStyle['userSelect'];
20
- inverted?: boolean;
21
- ref?: Ref<Text>;
22
8
  }
23
9
 
24
- export default TextProps;
10
+ export default BodyTextProps;
@@ -2,6 +2,7 @@ import { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { BodyText } from '.';
3
3
  import { VariantTitle } from '../../../docs/components';
4
4
  import { coloursAsArray } from '../../utils';
5
+ import { textColorKeys } from '../../utils/coloursAsArray';
5
6
  import { Box } from '../Box';
6
7
 
7
8
  // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
@@ -45,7 +46,7 @@ const meta = {
45
46
  description: 'Strike through the text.',
46
47
  },
47
48
  color: {
48
- options: coloursAsArray(),
49
+ options: textColorKeys,
49
50
  control: 'select',
50
51
  description: 'Color of the text. Use the color name from the theme.',
51
52
  },
@@ -1,8 +1,9 @@
1
1
  import { Text } from 'react-native';
2
2
  import { StyleSheet } from 'react-native-unistyles';
3
+ import { useStyleProps } from '../../hooks';
3
4
  import type BodyTextProps from './BodyText.props';
4
5
 
5
- import { getFlattenedColorValue } from '../../utils';
6
+ import { getFlattenedColorValue, resolveThemeValueWithFallback } from '../../utils';
6
7
 
7
8
  const BodyText = ({
8
9
  children,
@@ -23,6 +24,9 @@ const BodyText = ({
23
24
  inverted,
24
25
  ...props
25
26
  }: BodyTextProps) => {
27
+ // Extract margin utility props from remaining props
28
+ const { computedStyles: utilityStyles, remainingProps } = useStyleProps(props);
29
+
26
30
  styles.useVariants({
27
31
  size,
28
32
  weight,
@@ -34,7 +38,7 @@ const BodyText = ({
34
38
 
35
39
  return (
36
40
  <Text
37
- {...props}
41
+ {...remainingProps}
38
42
  {...(truncated
39
43
  ? {
40
44
  numberOfLines: 1,
@@ -43,7 +47,7 @@ const BodyText = ({
43
47
  : {})}
44
48
  style={[
45
49
  styles.text,
46
- props.style,
50
+ utilityStyles,
47
51
  {
48
52
  ...(textTransform && { textTransform }),
49
53
  ...(textAlign && { textAlign }),
@@ -54,6 +58,7 @@ const BodyText = ({
54
58
  ...(textAlignVertical && { textAlignVertical }),
55
59
  },
56
60
  styles.getColours(color, textDecorationColor),
61
+ props.style,
57
62
  ]}
58
63
  >
59
64
  {children}
@@ -117,13 +122,19 @@ const styles = StyleSheet.create(theme => ({
117
122
  },
118
123
  },
119
124
  getColours: (color?: string, textDecorationColor?: string) => ({
120
- ...(color ? { color: getFlattenedColorValue(color, theme.color) } : {}),
125
+ ...(color
126
+ ? {
127
+ color: resolveThemeValueWithFallback(
128
+ color,
129
+ theme.helpers.semanticColor.text,
130
+ theme.color
131
+ ),
132
+ }
133
+ : {}),
121
134
  ...(textDecorationColor
122
135
  ? { textDecorationColor: getFlattenedColorValue(textDecorationColor, theme.color) }
123
136
  : {}),
124
137
  }),
125
138
  }));
126
139
 
127
- BodyText.displayName = 'BodyText';
128
-
129
140
  export default BodyText;
@@ -2,6 +2,7 @@ import { Meta, Canvas, Story, Controls, Primary } from '@storybook/addon-docs/bl
2
2
  import * as Stories from './Box.stories';
3
3
  import { Center, Pressable, Box, BodyText } from '../..';
4
4
  import { UsageWrap, BackToTopButton, ViewFigmaButton } from '../../../docs/components';
5
+ import { color } from '@utilitywarehouse/hearth-tokens';
5
6
 
6
7
  <Meta title="Primitives / Box" />
7
8
 
@@ -25,8 +26,8 @@ When you need to center-align content, the Center component comes in handy. It i
25
26
 
26
27
  <UsageWrap>
27
28
  <Center>
28
- <Box backgroundColor="green400" width={300} height={200} padding="200">
29
- <BodyText color="white">Box.</BodyText>
29
+ <Box backgroundColor={color.green[400]} width={300} height={200} padding="200">
30
+ <BodyText color="inverted">Box.</BodyText>
30
31
  </Box>
31
32
  </Center>
32
33
  </UsageWrap>
@@ -35,8 +36,8 @@ When you need to center-align content, the Center component comes in handy. It i
35
36
  import { Center, BodyText } from '@utilitywarehouse/hearth-react-native';
36
37
 
37
38
  const MyComponent = () => (
38
- <Box backgroundColor="green400" width={300} height={200} padding="200">
39
- <BodyText color="white">Box.</BodyText>
39
+ <Box backgroundColor={color.green[400]} width={300} height={200} padding="200">
40
+ <BodyText color="inverted">Box.</BodyText>
40
41
  </Box>
41
42
  );
42
43
  ```