@utilitywarehouse/hearth-react-native 0.20.0 → 0.22.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 (143) 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 +272 -0
  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 +4 -11
  11. package/build/components/Card/CardRoot.js +0 -1
  12. package/build/components/Checkbox/Checkbox.d.ts +1 -1
  13. package/build/components/Checkbox/Checkbox.js +2 -2
  14. package/build/components/Checkbox/Checkbox.props.d.ts +2 -0
  15. package/build/components/Container/Container.props.d.ts +2 -78
  16. package/build/components/DateInput/DateInput.d.ts +1 -1
  17. package/build/components/DateInput/DateInput.js +2 -2
  18. package/build/components/DateInput/DateInput.props.d.ts +15 -1
  19. package/build/components/DateInput/DateInputSegment.d.ts +1 -1
  20. package/build/components/DateInput/DateInputSegment.js +2 -2
  21. package/build/components/DetailText/DetailText.js +14 -13
  22. package/build/components/DetailText/DetailText.props.d.ts +4 -17
  23. package/build/components/Flex/Flex.js +3 -1
  24. package/build/components/Flex/Flex.props.d.ts +2 -2
  25. package/build/components/Heading/Heading.js +34 -13
  26. package/build/components/Heading/Heading.props.d.ts +4 -18
  27. package/build/components/Modal/Modal.js +1 -1
  28. package/build/components/Radio/Radio.d.ts +1 -1
  29. package/build/components/Radio/Radio.js +2 -2
  30. package/build/components/Radio/Radio.props.d.ts +2 -0
  31. package/build/core/themes.d.ts +188 -8
  32. package/build/core/themes.js +18 -2
  33. package/build/hooks/useStyleProps.js +22 -5
  34. package/build/tokens/color.d.ts +4 -0
  35. package/build/tokens/color.js +2 -0
  36. package/build/tokens/components/dark/modal.d.ts +6 -0
  37. package/build/tokens/components/dark/modal.js +6 -0
  38. package/build/tokens/components/dark/navigation.d.ts +1 -0
  39. package/build/tokens/components/dark/navigation.js +1 -0
  40. package/build/tokens/components/light/modal.d.ts +6 -0
  41. package/build/tokens/components/light/modal.js +6 -0
  42. package/build/tokens/components/light/navigation.d.ts +1 -0
  43. package/build/tokens/components/light/navigation.js +1 -0
  44. package/build/tokens/components/light/skeleton.d.ts +1 -1
  45. package/build/tokens/components/light/skeleton.js +1 -1
  46. package/build/tokens/font.d.ts +2 -0
  47. package/build/tokens/font.js +2 -0
  48. package/build/tokens/line-height.d.ts +2 -0
  49. package/build/tokens/line-height.js +2 -0
  50. package/build/tokens/primitive.d.ts +4 -0
  51. package/build/tokens/primitive.js +4 -0
  52. package/build/tokens/semantic-dark.d.ts +1 -0
  53. package/build/tokens/semantic-dark.js +1 -0
  54. package/build/tokens/semantic-light.d.ts +1 -0
  55. package/build/tokens/semantic-light.js +1 -0
  56. package/build/tokens/typography.d.ts +30 -0
  57. package/build/tokens/typography.js +15 -0
  58. package/build/types/index.d.ts +4 -2
  59. package/build/types/index.js +4 -2
  60. package/build/types/semanticColorValues.d.ts +22 -0
  61. package/build/types/semanticColorValues.js +1 -0
  62. package/build/types/utilityProps.d.ts +326 -0
  63. package/build/types/utilityProps.js +1 -0
  64. package/build/types/values.d.ts +4 -3
  65. package/build/utils/coloursAsArray.d.ts +4 -0
  66. package/build/utils/coloursAsArray.js +5 -0
  67. package/build/utils/index.d.ts +1 -1
  68. package/build/utils/index.js +1 -1
  69. package/build/utils/styleUtils.d.ts +26 -2
  70. package/build/utils/styleUtils.js +42 -13
  71. package/build/utils/themeValueHelpers.d.ts +13 -0
  72. package/build/utils/themeValueHelpers.js +29 -0
  73. package/docs/changelog.mdx +74 -2
  74. package/docs/components/AllComponents.web.tsx +23 -24
  75. package/docs/components/NextPrevPage.tsx +2 -2
  76. package/docs/components/UsageWrap.tsx +2 -2
  77. package/docs/introduction.mdx +0 -7
  78. package/package.json +8 -6
  79. package/src/components/BodyText/BodyText.props.ts +5 -19
  80. package/src/components/BodyText/BodyText.stories.tsx +2 -1
  81. package/src/components/BodyText/BodyText.tsx +17 -6
  82. package/src/components/Box/Box.docs.mdx +5 -4
  83. package/src/components/Box/Box.props.ts +3 -231
  84. package/src/components/Box/Box.stories.tsx +2 -2
  85. package/src/components/Box/Box.tsx +38 -9
  86. package/src/components/Button/Button.docs.mdx +46 -1
  87. package/src/components/Card/Card.docs.mdx +1 -1
  88. package/src/components/Card/Card.props.ts +5 -11
  89. package/src/components/Card/Card.stories.tsx +54 -23
  90. package/src/components/Card/CardRoot.tsx +0 -1
  91. package/src/components/Carousel/Carousel.docs.mdx +49 -44
  92. package/src/components/Center/Center.docs.mdx +6 -4
  93. package/src/components/Checkbox/Checkbox.docs.mdx +1 -0
  94. package/src/components/Checkbox/Checkbox.props.ts +2 -0
  95. package/src/components/Checkbox/Checkbox.stories.tsx +26 -0
  96. package/src/components/Checkbox/Checkbox.tsx +2 -0
  97. package/src/components/Container/Container.docs.mdx +13 -8
  98. package/src/components/Container/Container.props.ts +9 -80
  99. package/src/components/Container/Container.stories.tsx +81 -65
  100. package/src/components/DateInput/DateInput.docs.mdx +43 -0
  101. package/src/components/DateInput/DateInput.props.ts +15 -1
  102. package/src/components/DateInput/DateInput.stories.tsx +37 -2
  103. package/src/components/DateInput/DateInput.tsx +6 -0
  104. package/src/components/DateInput/DateInputSegment.tsx +2 -0
  105. package/src/components/DetailText/DetailText.props.ts +4 -17
  106. package/src/components/DetailText/DetailText.stories.tsx +2 -3
  107. package/src/components/DetailText/DetailText.tsx +16 -17
  108. package/src/components/Flex/Flex.props.ts +2 -2
  109. package/src/components/Flex/Flex.stories.tsx +1 -1
  110. package/src/components/Flex/Flex.tsx +4 -1
  111. package/src/components/Grid/Grid.docs.mdx +53 -49
  112. package/src/components/Heading/Heading.props.ts +4 -18
  113. package/src/components/Heading/Heading.stories.tsx +2 -1
  114. package/src/components/Heading/Heading.tsx +40 -18
  115. package/src/components/Modal/Modal.tsx +1 -1
  116. package/src/components/Radio/Radio.docs.mdx +1 -0
  117. package/src/components/Radio/Radio.props.ts +2 -0
  118. package/src/components/Radio/Radio.stories.tsx +22 -0
  119. package/src/components/Radio/Radio.tsx +2 -0
  120. package/src/components/Radio/RadioTile.figma.tsx +4 -0
  121. package/src/components/Toast/ToastItem.figma.tsx +1 -8
  122. package/src/core/themes.ts +19 -2
  123. package/src/hooks/useStyleProps.ts +40 -5
  124. package/src/tokens/color.ts +2 -0
  125. package/src/tokens/components/dark/modal.ts +6 -0
  126. package/src/tokens/components/dark/navigation.ts +1 -0
  127. package/src/tokens/components/light/modal.ts +6 -0
  128. package/src/tokens/components/light/navigation.ts +1 -0
  129. package/src/tokens/components/light/skeleton.ts +1 -1
  130. package/src/tokens/font.ts +2 -0
  131. package/src/tokens/line-height.ts +2 -0
  132. package/src/tokens/primitive.ts +4 -0
  133. package/src/tokens/semantic-dark.ts +1 -0
  134. package/src/tokens/semantic-light.ts +1 -0
  135. package/src/tokens/typography.ts +15 -0
  136. package/src/types/index.ts +4 -2
  137. package/src/types/semanticColorValues.ts +26 -0
  138. package/src/types/utilityProps.ts +410 -0
  139. package/src/types/values.ts +4 -7
  140. package/src/utils/coloursAsArray.ts +6 -0
  141. package/src/utils/index.ts +8 -1
  142. package/src/utils/styleUtils.ts +45 -14
  143. package/src/utils/themeValueHelpers.ts +38 -0
@@ -1,5 +1,6 @@
1
1
  import '@utilitywarehouse/hearth-fonts';
2
2
  import { addons } from 'storybook/manager-api';
3
+ import '@utilitywarehouse/hearth-tokens/index.css';
3
4
  import '../../../shared/storybook/styles/manager.css';
4
5
  import theme from '../../../shared/storybook/theme';
5
6
 
@@ -1,5 +1,6 @@
1
1
  import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
2
2
  import '@utilitywarehouse/hearth-fonts';
3
+ import '@utilitywarehouse/hearth-tokens/index.css';
3
4
  import { color } from '@utilitywarehouse/hearth-tokens';
4
5
  import { useEffect } from 'react';
5
6
  import '../../../shared/storybook/styles/diff-highlighting.css';
@@ -1,4 +1,4 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.20.0 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.22.0 build /home/runner/work/hearth/hearth/packages/react-native
3
3
  > tsc
4
4
 
@@ -1,5 +1,5 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.20.0 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.22.0 lint /home/runner/work/hearth/hearth/packages/react-native
3
3
  > TIMING=1 eslint .
4
4
 
5
5
 
@@ -58,15 +58,15 @@
58
58
 
59
59
  ✖ 25 problems (0 errors, 25 warnings)
60
60
 
61
- Rule | Time (ms) | Relative
62
- :-----------------------------------------|----------:|--------:
63
- @typescript-eslint/no-unused-vars | 1584.824 | 64.0%
64
- react-hooks/exhaustive-deps | 101.118 | 4.1%
65
- no-global-assign | 70.605 | 2.8%
66
- react-hooks/rules-of-hooks | 63.862 | 2.6%
67
- no-misleading-character-class | 49.106 | 2.0%
68
- @typescript-eslint/ban-ts-comment | 38.021 | 1.5%
69
- no-unexpected-multiline | 35.859 | 1.4%
70
- no-loss-of-precision | 32.618 | 1.3%
71
- @typescript-eslint/triple-slash-reference | 29.048 | 1.2%
72
- no-useless-escape | 27.538 | 1.1%
61
+ Rule | Time (ms) | Relative
62
+ :-------------------------------------------------|----------:|--------:
63
+ @typescript-eslint/no-unused-vars | 1687.263 | 65.5%
64
+ react-hooks/rules-of-hooks | 78.867 | 3.1%
65
+ react-hooks/exhaustive-deps | 78.504 | 3.0%
66
+ no-global-assign | 75.145 | 2.9%
67
+ no-unexpected-multiline | 55.153 | 2.1%
68
+ no-loss-of-precision | 46.457 | 1.8%
69
+ @typescript-eslint/ban-ts-comment | 45.439 | 1.8%
70
+ no-misleading-character-class | 37.162 | 1.4%
71
+ @typescript-eslint/triple-slash-reference | 28.294 | 1.1%
72
+ @typescript-eslint/no-unnecessary-type-constraint | 20.347 | 0.8%
package/CHANGELOG.md CHANGED
@@ -1,5 +1,277 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.22.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#968](https://github.com/utilitywarehouse/hearth/pull/968) [`cee5811`](https://github.com/utilitywarehouse/hearth/commit/cee5811020af02fe754d8311ec8313c1793f108a) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add `badge` support to Radio and Checkbox (including tiles).
8
+
9
+ **Components affected**:
10
+ - `Radio`
11
+ - `RadioTile`
12
+ - `Checkbox`
13
+ - `CheckboxTile`
14
+
15
+ **Developer changes**:
16
+ You can now pass a `badge` React node to render beneath helper text. No changes required unless you want to use the new prop.
17
+
18
+ ### Patch Changes
19
+
20
+ - [#966](https://github.com/utilitywarehouse/hearth/pull/966) [`4e9f3f0`](https://github.com/utilitywarehouse/hearth/commit/4e9f3f0284e50da5ba4e49e132dac745a1a8a68d) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Allow Card layout props and remove forced alignment
21
+
22
+ Card now accepts flex layout and display props, and it no longer forces `alignItems: flex-start` on the root, so custom alignment works as expected.
23
+
24
+ - [#969](https://github.com/utilitywarehouse/hearth/pull/969) [`c5c988b`](https://github.com/utilitywarehouse/hearth/commit/c5c988b65f1133b85b822037b086a524bc1255e3) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Render the Modal footer in navigation modals
25
+
26
+ ## 0.21.0
27
+
28
+ ### Minor Changes
29
+
30
+ - [#917](https://github.com/utilitywarehouse/hearth/pull/917) [`6a016dc`](https://github.com/utilitywarehouse/hearth/commit/6a016dca0d1a06e40a877da15aced590d0c68112) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add 2xl size variant to Heading component
31
+
32
+ The `Heading` component now supports a `2xl` size option, providing a larger heading size for prominent page titles and hero sections. This size is responsive across device sizes with appropriate font sizes and line heights for mobile, tablet, and desktop viewports.
33
+
34
+ **Components affected**:
35
+ - `Heading`
36
+
37
+ **Developer changes**:
38
+
39
+ Use the new `2xl` size prop:
40
+
41
+ ```tsx
42
+ <Heading size="2xl">Welcome to Hearth</Heading>
43
+ ```
44
+
45
+ The `2xl` size will render with:
46
+ - Mobile: 44px font size, 52px line height
47
+ - Tablet: 44px font size, 52px line height
48
+ - Desktop: 54px font size, 62px line height
49
+
50
+ - [#949](https://github.com/utilitywarehouse/hearth/pull/949) [`e1aacf0`](https://github.com/utilitywarehouse/hearth/commit/e1aacf06a58fd8358e9e7546ec35d8194a0d8d74) Thanks [@MichalCiesliczka](https://github.com/MichalCiesliczka)! - 🌟 [FEATURE]: Add segment refs to `DateInput` for programmatic focus control
51
+
52
+ The `DateInput` component now supports direct refs for each segment input via `dayRef`, `monthRef`, and `yearRef`.
53
+ This makes it easier to move focus between segments from custom flows (for example, advancing focus after validation or from custom buttons).
54
+
55
+ Documentation and Storybook examples are also updated to show how to use segment refs in real usage.
56
+
57
+ **Components affected**:
58
+ - `DateInput`
59
+
60
+ **Developer changes**:
61
+
62
+ You can now pass refs to each segment and call `.focus()` when needed:
63
+
64
+ ```tsx
65
+ import { useRef, useState } from 'react';
66
+ import { TextInput } from 'react-native';
67
+ import { Button, DateInput } from '@utilitywarehouse/hearth-react-native';
68
+
69
+ const DateWithSegmentFocus = () => {
70
+ const [day, setDay] = useState('');
71
+ const [month, setMonth] = useState('');
72
+ const [year, setYear] = useState('');
73
+
74
+ const dayRef = useRef<TextInput>(null);
75
+ const monthRef = useRef<TextInput>(null);
76
+ const yearRef = useRef<TextInput>(null);
77
+
78
+ return (
79
+ <>
80
+ <DateInput
81
+ label="Date of birth"
82
+ dayValue={day}
83
+ monthValue={month}
84
+ yearValue={year}
85
+ onDayChange={setDay}
86
+ onMonthChange={setMonth}
87
+ onYearChange={setYear}
88
+ dayRef={dayRef}
89
+ monthRef={monthRef}
90
+ yearRef={yearRef}
91
+ />
92
+
93
+ <Button onPress={() => monthRef.current?.focus()}>Focus month</Button>
94
+ </>
95
+ );
96
+ };
97
+ ```
98
+
99
+ This is a non-breaking enhancement, so existing `DateInput` usage continues to work without any changes.
100
+
101
+ - [#918](https://github.com/utilitywarehouse/hearth/pull/918) [`2db4dbe`](https://github.com/utilitywarehouse/hearth/commit/2db4dbe273583239b148c4399af829df596a00c1) Thanks [@jordmccord](https://github.com/jordmccord)! - 💔 [BREAKING CHANGE]: Simplify semantic token naming and introduce utility prop types
102
+
103
+ This release simplifies the semantic token naming convention and introduces a new utility prop system to make the API more intuitive and consistent across components.
104
+
105
+ **Components affected**:
106
+ - `Box`
107
+ - `Container`
108
+ - `Card`
109
+ - `Flex`
110
+ - `Grid`
111
+ - `Center`
112
+ - `BodyText`
113
+ - `Heading`
114
+ - `DetailText`
115
+ - `Carousel`
116
+ - `CarouselItem`
117
+
118
+ **Developer changes**:
119
+
120
+ ### Background Colors
121
+
122
+ Background color props now accept simplified semantic tokens. Update your code as follows:
123
+
124
+ ```diff
125
+ - <Box backgroundColor="backgroundPrimary">
126
+ + <Box backgroundColor="primary">
127
+
128
+ - <Box backgroundColor="backgroundSecondary">
129
+ + <Box backgroundColor="secondary">
130
+
131
+ - <Box backgroundColor="backgroundBrand">
132
+ + <Box backgroundColor="brand">
133
+
134
+ - <Container bg="backgroundPrimary">
135
+ + <Container bg="primary">
136
+ ```
137
+
138
+ You can still use full color tokens (e.g., `backgroundColor={color.blue[400]}`) by using a `StyleSheet`, the `useTheme` hook, or directly importing from the tokens library:
139
+
140
+ ```tsx
141
+ import { StyleSheet } from 'react-native';
142
+
143
+ const styles = StyleSheet.create(theme => ({
144
+ customBackground: {
145
+ backgroundColor: theme.color.blue[400],
146
+ },
147
+ }));
148
+
149
+ <Box style={styles.customBackground} />;
150
+ ```
151
+
152
+ ```tsx
153
+ import { useTheme } from '@utilitywarehouse/hearth-react-native';
154
+
155
+ const theme = useTheme();
156
+
157
+ <Box backgroundColor={theme.color.purple[800]} />;
158
+ ```
159
+
160
+ ```tsx
161
+ import { color } from '@utilitywarehouse/hearth-tokens';
162
+
163
+ <Box backgroundColor={color.blue[400]} />;
164
+ ```
165
+
166
+ ### Text Colors
167
+
168
+ Text color props now accept simplified semantic tokens:
169
+
170
+ ```diff
171
+ - <BodyText color="white">Text</BodyText>
172
+ + <BodyText color="inverted">Text</BodyText>
173
+
174
+ - <BodyText color="grey1000">Text</BodyText>
175
+ + <BodyText color="primary">Text</BodyText>
176
+
177
+ - <Heading color="textSecondary">Heading</Heading>
178
+ + <Heading color="secondary">Heading</Heading>
179
+ ```
180
+
181
+ ### Border Colors
182
+
183
+ Border color props now accept simplified semantic tokens:
184
+
185
+ ```diff
186
+ - <Box borderColor="grey800">
187
+ + <Box borderColor="strong">
188
+
189
+ - <Box borderColor="borderSubtle">
190
+ + <Box borderColor="subtle">
191
+ ```
192
+
193
+ ### Utility Props
194
+
195
+ Components now support consistent utility props through shared type interfaces. The following components have been updated to support additional utility props:
196
+ - **Container**: Added `MarginProps`, `PaddingProps`, `GapProps`, and `BackgroundColorProps`
197
+ - **Card**: Added `MarginProps` and `GapProps`
198
+ - **Flex**: Now properly supports `MarginProps`, `PaddingProps`, and `GapProps`
199
+ - **Text components** (BodyText, Heading, DetailText): Now support `MarginProps`
200
+
201
+ This means you can now use margin utilities directly on these components:
202
+
203
+ ```tsx
204
+ <BodyText mt="200" mb="100">Text with margin utilities</BodyText>
205
+ <Container mx="300" py="200">Container with spacing utilities</Container>
206
+ <Card mt="200" gap="100">Card with margin and gap utilities</Card>
207
+ ```
208
+
209
+ **Migration guide**:
210
+ 1. Replace semantic background color tokens:
211
+ - `backgroundPrimary` → `primary`
212
+ - `backgroundSecondary` → `secondary`
213
+ - `backgroundBrand` → `brand`
214
+ 2. Replace semantic text color tokens:
215
+ - `white` → `inverted` (for text on dark backgrounds)
216
+ - `grey1000` / `textPrimary` → `primary`
217
+ - `textSecondary` → `secondary`
218
+ 3. Replace semantic border color tokens:
219
+ - `grey800` / `borderStrong` → `strong`
220
+ - `borderSubtle` → `subtle`
221
+ 4. For non-semantic colors, use a `StyleSheet` and use the full color token from the theme:
222
+
223
+ ```tsx
224
+ import { StyleSheet } from 'react-native';
225
+
226
+ const styles = StyleSheet.create(theme => ({
227
+ customBackground: {
228
+ backgroundColor: theme.color.blue[400],
229
+ },
230
+ }));
231
+
232
+ <Box style={styles.customBackground} />;
233
+ ```
234
+
235
+ or the `useTheme` hook:
236
+
237
+ ```tsx
238
+ import { useTheme } from '@utilitywarehouse/hearth-react-native';
239
+
240
+ const theme = useTheme();
241
+ <Box backgroundColor={theme.color.purple[800]} />;
242
+ ```
243
+
244
+ or use the tokens library:
245
+
246
+ ```tsx
247
+ import { color } from '@utilitywarehouse/hearth-tokens';
248
+
249
+ <Box backgroundColor={color.purple[800]} />;
250
+ ```
251
+
252
+ **Backwards compatibility**:
253
+
254
+ The full color tokens (e.g., `backgroundPrimary`, `grey1000`) are still supported as fallbacks but are deprecated and will cause type errors. We recommend migrating to the simplified tokens for a cleaner API.
255
+
256
+ **References**:
257
+ - [Semantic tokens documentation](https://github.com/utilitywarehouse/hearth/blob/main/packages/tokens/src/semantic-light.ts)
258
+
259
+ ### Patch Changes
260
+
261
+ - [#917](https://github.com/utilitywarehouse/hearth/pull/917) [`6a016dc`](https://github.com/utilitywarehouse/hearth/commit/6a016dca0d1a06e40a877da15aced590d0c68112) Thanks [@jordmccord](https://github.com/jordmccord)! - 💅 [ENHANCEMENT]: Update design tokens from Figma
262
+
263
+ Updated design tokens to include new font sizes, line heights, and component-specific tokens:
264
+ - Added `background.loading` colour token for both light and dark modes
265
+ - Added new font sizes: 575 (44px) and 650 (54px)
266
+ - Added new line heights: 975 (52px) and 1050 (62px)
267
+ - Updated `Modal` component tokens with `mobile.paddingBottom` and `handle.paddingBottom` properties
268
+ - Added `borderBottom` property to `Navigation` component tokens
269
+ - Updated `Skeleton` component `loadingColor` value in light mode
270
+
271
+ **Developer changes**:
272
+
273
+ No changes required. These tokens are automatically applied to components that use them.
274
+
3
275
  ## 0.20.0
4
276
 
5
277
  ### Minor Changes
@@ -1,8 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Text } from 'react-native';
3
3
  import { StyleSheet } from 'react-native-unistyles';
4
- import { getFlattenedColorValue } from '../../utils';
4
+ import { useStyleProps } from '../../hooks';
5
+ import { getFlattenedColorValue, resolveThemeValueWithFallback } from '../../utils';
5
6
  const BodyText = ({ children, color, size = 'md', truncated, weight = 'regular', underline, strikeThrough, italic, textTransform, textAlign, textAlignVertical, textDecorationColor, textDecorationLine, textDecorationStyle, userSelect, inverted, ...props }) => {
7
+ // Extract margin utility props from remaining props
8
+ const { computedStyles: utilityStyles, remainingProps } = useStyleProps(props);
6
9
  styles.useVariants({
7
10
  size,
8
11
  weight,
@@ -11,14 +14,14 @@ const BodyText = ({ children, color, size = 'md', truncated, weight = 'regular',
11
14
  italic,
12
15
  inverted,
13
16
  });
14
- return (_jsx(Text, { ...props, ...(truncated
17
+ return (_jsx(Text, { ...remainingProps, ...(truncated
15
18
  ? {
16
19
  numberOfLines: 1,
17
20
  ellipsizeMode: 'tail',
18
21
  }
19
22
  : {}), style: [
20
23
  styles.text,
21
- props.style,
24
+ utilityStyles,
22
25
  {
23
26
  ...(textTransform && { textTransform }),
24
27
  ...(textAlign && { textAlign }),
@@ -28,6 +31,7 @@ const BodyText = ({ children, color, size = 'md', truncated, weight = 'regular',
28
31
  ...(textAlignVertical && { textAlignVertical }),
29
32
  },
30
33
  styles.getColours(color, textDecorationColor),
34
+ props.style,
31
35
  ], children: children }));
32
36
  };
33
37
  BodyText.displayName = 'BodyText';
@@ -85,11 +89,14 @@ const styles = StyleSheet.create(theme => ({
85
89
  },
86
90
  },
87
91
  getColours: (color, textDecorationColor) => ({
88
- ...(color ? { color: getFlattenedColorValue(color, theme.color) } : {}),
92
+ ...(color
93
+ ? {
94
+ color: resolveThemeValueWithFallback(color, theme.helpers.semanticColor.text, theme.color),
95
+ }
96
+ : {}),
89
97
  ...(textDecorationColor
90
98
  ? { textDecorationColor: getFlattenedColorValue(textDecorationColor, theme.color) }
91
99
  : {}),
92
100
  }),
93
101
  }));
94
- BodyText.displayName = 'BodyText';
95
102
  export default BodyText;
@@ -1,22 +1,8 @@
1
- import { Ref } from 'react';
2
- import type { TextProps as RNTextProps, Text, TextStyle } from 'react-native';
3
- import type { ColorValue } from '../../types';
4
- interface TextProps extends RNTextProps {
1
+ import type { CommonTextProps } from '../../types';
2
+ interface BodyTextProps extends CommonTextProps {
3
+ /** Text size variant. */
5
4
  size?: 'sm' | 'md' | 'lg';
6
- strikeThrough?: boolean;
7
- underline?: boolean;
8
- truncated?: boolean;
5
+ /** Font weight variant. */
9
6
  weight?: 'regular' | 'semibold' | 'bold';
10
- italic?: boolean;
11
- color?: ColorValue;
12
- textTransform?: TextStyle['textTransform'];
13
- textAlign?: TextStyle['textAlign'];
14
- textAlignVertical?: TextStyle['textAlignVertical'];
15
- textDecorationLine?: TextStyle['textDecorationLine'];
16
- textDecorationStyle?: TextStyle['textDecorationStyle'];
17
- textDecorationColor?: ColorValue;
18
- userSelect?: TextStyle['userSelect'];
19
- inverted?: boolean;
20
- ref?: Ref<Text>;
21
7
  }
22
- export default TextProps;
8
+ export default BodyTextProps;
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useMemo } from 'react';
3
3
  import { View } from 'react-native';
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
- import { propStyleMapping, resolveThemeValue, themeStyleMapping, viewStyleProps, } from '../../utils';
5
+ import { propStyleMapping, resolveThemeKey, resolveThemeValueWithFallback, semanticPropMapping, themeStyleFallbackMapping, themeStyleMapping, viewStyleProps, } from '../../utils';
6
6
  // --- Box component definition ---
7
7
  const BoxComponent = ({ as, style, children, ...props }) => {
8
8
  const { computedProps } = useMemo(() => {
@@ -10,6 +10,8 @@ const BoxComponent = ({ as, style, children, ...props }) => {
10
10
  Object.entries(props).forEach(([propName, propValue]) => {
11
11
  if (propValue === undefined)
12
12
  return;
13
+ if (semanticPropMapping[propName])
14
+ return;
13
15
  if (propStyleMapping[propName] || viewStyleProps.has(propName)) {
14
16
  return;
15
17
  }
@@ -26,6 +28,16 @@ const styles = StyleSheet.create(theme => ({
26
28
  Object.entries(props).forEach(([propName, propValue]) => {
27
29
  if (propValue === undefined)
28
30
  return;
31
+ // Check for semantic prop mappings first (e.g., iconColor, color)
32
+ const semanticMapping = semanticPropMapping[propName];
33
+ if (semanticMapping) {
34
+ const { styleProp, themeKey } = semanticMapping;
35
+ const themeMapping = resolveThemeKey(theme, themeKey);
36
+ const fallbackKey = themeStyleFallbackMapping[themeKey];
37
+ const fallbackMapping = fallbackKey ? resolveThemeKey(theme, fallbackKey) : undefined;
38
+ computedStyles[styleProp] = resolveThemeValueWithFallback(propValue, themeMapping, fallbackMapping);
39
+ return;
40
+ }
29
41
  let stylePropName;
30
42
  // Handle shorthand props
31
43
  if (propStyleMapping[propName]) {
@@ -39,8 +51,16 @@ const styles = StyleSheet.create(theme => ({
39
51
  return;
40
52
  // Resolve theme value if needed
41
53
  const themeKey = themeStyleMapping[stylePropName];
42
- if (themeKey && theme[themeKey]) {
43
- computedStyles[stylePropName] = resolveThemeValue(propValue, theme[themeKey]);
54
+ if (themeKey) {
55
+ const themeObj = resolveThemeKey(theme, themeKey);
56
+ const fallbackKey = themeStyleFallbackMapping[themeKey];
57
+ const fallbackMapping = fallbackKey ? resolveThemeKey(theme, fallbackKey) : undefined;
58
+ if (themeObj) {
59
+ computedStyles[stylePropName] = resolveThemeValueWithFallback(propValue, themeObj, fallbackMapping);
60
+ }
61
+ else {
62
+ computedStyles[stylePropName] = propValue;
63
+ }
44
64
  }
45
65
  else {
46
66
  computedStyles[stylePropName] = propValue;
@@ -1,102 +1,10 @@
1
1
  import React from 'react';
2
- import type { ViewProps, ViewStyle } from 'react-native';
3
- import type { BorderRadiusValue, BordeWidthValue, ColorValue, OpacityValue, SpaceValue, SpacingValues } from '../../types';
4
- export type OmittedStyles = Omit<ViewStyle, 'backgroundColor' | 'borderBlockColor' | 'borderBlockEndColor' | 'borderBlockStartColor' | 'borderBottomColor' | 'borderBottomEndRadius' | 'borderBottomLeftRadius' | 'borderBottomRightRadius' | 'borderBottomStartRadius' | 'borderBottomWidth' | 'borderColor' | 'borderEndColor' | 'borderEndEndRadius' | 'borderEndStartRadius' | 'borderEndWidth' | 'borderLeftColor' | 'borderLeftWidth' | 'borderRadius' | 'borderRightColor' | 'borderRightWidth' | 'borderStartColor' | 'borderStartEndRadius' | 'borderStartStartRadius' | 'borderStartWidth' | 'borderTopColor' | 'borderTopEndRadius' | 'borderTopLeftRadius' | 'borderTopRightRadius' | 'borderTopStartRadius' | 'borderTopWidth' | 'borderWidth' | 'bottom' | 'columnGap' | 'end' | 'gap' | 'height' | 'left' | 'margin' | 'marginBottom' | 'marginEnd' | 'marginHorizontal' | 'marginLeft' | 'marginRight' | 'marginStart' | 'marginTop' | 'marginVertical' | 'maxHeight' | 'maxWidth' | 'minHeight' | 'minWidth' | 'opacity' | 'outlineColor' | 'padding' | 'paddingBottom' | 'paddingEnd' | 'paddingHorizontal' | 'paddingLeft' | 'paddingRight' | 'paddingStart' | 'paddingTop' | 'paddingVertical' | 'right' | 'rowGap' | 'shadowColor' | 'start' | 'top' | 'width' | 'rotation' | 'scaleX' | 'scaleY' | 'transformMatrix' | 'translateX' | 'translateY'>;
5
- export type OtherBoxViewStyles = Pick<OmittedStyles, 'alignContent' | 'alignItems' | 'alignSelf' | 'aspectRatio' | 'backfaceVisibility' | 'borderCurve' | 'borderStyle' | 'cursor' | 'direction' | 'display' | 'elevation' | 'flex' | 'flexBasis' | 'flexDirection' | 'flexGrow' | 'flexShrink' | 'flexWrap' | 'justifyContent' | 'boxShadow' | 'outlineOffset' | 'outlineStyle' | 'outlineWidth' | 'overflow' | 'pointerEvents' | 'position' | 'shadowOffset' | 'shadowOpacity' | 'shadowRadius' | 'transform' | 'transformOrigin' | 'zIndex'>;
6
- export interface BoxStyleMappingValues {
7
- bg?: ColorValue;
8
- bgColor?: ColorValue;
9
- h?: SpaceValue;
10
- w?: SpaceValue;
11
- p?: SpaceValue;
12
- px?: SpaceValue;
13
- py?: SpaceValue;
14
- pt?: SpaceValue;
15
- pb?: SpaceValue;
16
- pr?: SpaceValue;
17
- pl?: SpaceValue;
18
- m?: SpaceValue;
19
- mx?: SpaceValue;
20
- my?: SpaceValue;
21
- mt?: SpaceValue;
22
- mb?: SpaceValue;
23
- mr?: SpaceValue;
24
- ml?: SpaceValue;
25
- rounded?: BorderRadiusValue;
26
- }
27
- export interface ThemedBoxViewStyleProps {
28
- top?: SpaceValue;
29
- bottom?: SpaceValue;
30
- left?: SpaceValue;
31
- right?: SpaceValue;
32
- padding?: SpaceValue;
33
- paddingHorizontal?: SpaceValue;
34
- paddingVertical?: SpaceValue;
35
- paddingTop?: SpaceValue;
36
- paddingBottom?: SpaceValue;
37
- paddingLeft?: SpaceValue;
38
- paddingRight?: SpaceValue;
39
- paddingEnd?: SpaceValue;
40
- paddingStart?: SpaceValue;
41
- margin?: SpaceValue;
42
- marginHorizontal?: SpaceValue;
43
- marginVertical?: SpaceValue;
44
- marginTop?: SpaceValue;
45
- marginBottom?: SpaceValue;
46
- marginLeft?: SpaceValue;
47
- marginRight?: SpaceValue;
48
- marginEnd?: SpaceValue;
49
- marginStart?: SpaceValue;
50
- columnGap?: SpaceValue;
51
- gap?: SpaceValue;
52
- rowGap?: SpaceValue;
53
- height?: SpaceValue;
54
- width?: SpaceValue;
55
- minHeight?: SpaceValue;
56
- minWidth?: SpaceValue;
57
- maxWidth?: SpaceValue;
58
- maxHeight?: SpaceValue;
59
- start?: SpaceValue;
60
- end?: SpaceValue;
61
- backgroundColor?: ColorValue;
62
- borderColor?: ColorValue;
63
- borderBottomColor?: ColorValue;
64
- borderLeftColor?: ColorValue;
65
- borderRightColor?: ColorValue;
66
- borderTopColor?: ColorValue;
67
- borderBlockColor?: ColorValue;
68
- borderBlockEndColor?: ColorValue;
69
- borderBlockStartColor?: ColorValue;
70
- borderEndColor?: ColorValue;
71
- borderStartColor?: ColorValue;
72
- outlineColor?: ColorValue;
73
- shadowColor?: ColorValue;
74
- borderRadius?: BorderRadiusValue;
75
- borderBottomEndRadius?: BorderRadiusValue;
76
- borderBottomLeftRadius?: BorderRadiusValue;
77
- borderBottomRightRadius?: BorderRadiusValue;
78
- borderBottomStartRadius?: BorderRadiusValue;
79
- borderTopEndRadius?: BorderRadiusValue;
80
- borderTopLeftRadius?: BorderRadiusValue;
81
- borderTopRightRadius?: BorderRadiusValue;
82
- borderTopStartRadius?: BorderRadiusValue;
83
- borderEndEndRadius?: BorderRadiusValue;
84
- borderEndStartRadius?: BorderRadiusValue;
85
- borderStartEndRadius?: BorderRadiusValue;
86
- borderStartStartRadius?: BorderRadiusValue;
87
- opacity?: OpacityValue;
88
- borderBottomWidth?: BordeWidthValue;
89
- borderEndWidth?: BordeWidthValue;
90
- borderLeftWidth?: BordeWidthValue;
91
- borderRightWidth?: BordeWidthValue;
92
- borderStartWidth?: BordeWidthValue;
93
- borderTopWidth?: BordeWidthValue;
94
- borderWidth?: BordeWidthValue;
95
- }
2
+ import type { ViewProps } from 'react-native';
3
+ import type { AllUtilityProps, SpacingValues } from '../../types';
96
4
  interface CustomBoxProps {
97
5
  as?: React.ElementType;
98
6
  spacing?: SpacingValues;
99
7
  }
100
- export interface BoxProps extends BoxStyleMappingValues, ThemedBoxViewStyleProps, OtherBoxViewStyles, ViewProps, CustomBoxProps {
8
+ export interface BoxProps extends AllUtilityProps, ViewProps, CustomBoxProps {
101
9
  }
102
10
  export default BoxProps;
@@ -1,20 +1,13 @@
1
- import { PressableProps, ViewStyle } from 'react-native';
2
- import { SpaceValue, SpacingValues } from '../../types';
3
- interface CardProps extends PressableProps {
1
+ import { PressableProps } from 'react-native';
2
+ import { DisplayProps, FlexLayoutProps, GapProps, MarginProps, SpacingValues } from '../../types';
3
+ interface CardProps extends PressableProps, MarginProps, GapProps, FlexLayoutProps, Omit<DisplayProps, 'direction'> {
4
4
  variant?: 'emphasis' | 'subtle';
5
5
  colorScheme?: 'neutralStrong' | 'neutralSubtle' | 'brand' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'pig';
6
6
  shadowColor?: 'functional' | 'brand' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'pig';
7
7
  noPadding?: boolean;
8
8
  disabled?: boolean;
9
9
  spacing?: SpacingValues;
10
- /** @deprecated Use `spacing` instead. The `gap` prop will be removed in a future release. */
10
+ /** @deprecated Use `spacing` instead. The `space` prop will be removed in a future release. */
11
11
  space?: SpacingValues;
12
- alignItems?: ViewStyle['alignItems'];
13
- justifyContent?: ViewStyle['justifyContent'];
14
- flexDirection?: ViewStyle['flexDirection'];
15
- flexWrap?: ViewStyle['flexWrap'];
16
- gap?: SpaceValue;
17
- rowGap?: SpaceValue;
18
- columnGap?: SpaceValue;
19
12
  }
20
13
  export default CardProps;
@@ -70,7 +70,6 @@ Card.displayName = 'Card';
70
70
  const styles = StyleSheet.create(theme => ({
71
71
  card: {
72
72
  overflow: 'hidden',
73
- alignItems: 'flex-start',
74
73
  borderRadius: theme.components.card.borderRadius,
75
74
  variants: {
76
75
  spacing: theme.globalStyle.variants.spacing,
@@ -10,7 +10,7 @@ declare const CheckboxIcon: import("react").ForwardRefExoticComponent<import("re
10
10
  }>;
11
11
  declare const CheckboxLabel: import("react").ForwardRefExoticComponent<import("react").RefAttributes<import("../Label/Label.props").default> & Omit<import("../Label/Label.props").default, "ref">>;
12
12
  declare const Checkbox: {
13
- ({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type, image, value, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
13
+ ({ children, label, disabled, checked, helperIcon, helperText, badge, invalidText, validText, validationStatus: validation, showValidationIcon, type, image, value, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
14
14
  displayName: string;
15
15
  };
16
16
  declare const CheckboxTile: {
@@ -25,12 +25,12 @@ CheckboxGroup.displayName = 'CheckboxGroup';
25
25
  CheckboxIndicator.displayName = 'CheckboxIndicator';
26
26
  CheckboxIcon.displayName = 'CheckboxIcon';
27
27
  CheckboxLabel.displayName = 'CheckboxLabel';
28
- const Checkbox = ({ children, label, disabled, checked, helperIcon, helperText, invalidText, validText, validationStatus: validation, showValidationIcon, type = 'default', image, value, ...props }) => {
28
+ const Checkbox = ({ children, label, disabled, checked, helperIcon, helperText, badge, invalidText, validText, validationStatus: validation, showValidationIcon, type = 'default', image, value, ...props }) => {
29
29
  const { validationStatus: fieldValidationStatus } = useFormFieldContext();
30
30
  const { validationStatus: groupValidationStatus, type: groupType } = useCheckboxGroupContext();
31
31
  const validationStatus = fieldValidationStatus ?? groupValidationStatus ?? validation ?? 'initial';
32
32
  const checkboxType = groupType ?? type;
33
- const checkboxChildren = children ? (children) : (_jsxs(_Fragment, { children: [_jsx(CheckboxIndicator, { children: _jsx(CheckboxIcon, {}) }), image ? image : null, _jsxs(CheckboxTextContent, { children: [!!label && _jsx(CheckboxLabel, { children: label }), !!helperText && _jsx(Helper, { disabled: disabled, icon: helperIcon, text: helperText }), validationStatus === 'invalid' && !!invalidText && (_jsx(Helper, { showIcon: showValidationIcon, disabled: disabled, validationStatus: "invalid", text: invalidText })), validationStatus === 'valid' && !!validText && (_jsx(Helper, { disabled: disabled, showIcon: showValidationIcon, validationStatus: "valid", text: validText }))] })] }));
33
+ const checkboxChildren = children ? (children) : (_jsxs(_Fragment, { children: [_jsx(CheckboxIndicator, { children: _jsx(CheckboxIcon, {}) }), image ? image : null, _jsxs(CheckboxTextContent, { children: [!!label && _jsx(CheckboxLabel, { children: label }), !!helperText && _jsx(Helper, { disabled: disabled, icon: helperIcon, text: helperText }), badge ? badge : null, validationStatus === 'invalid' && !!invalidText && (_jsx(Helper, { showIcon: showValidationIcon, disabled: disabled, validationStatus: "invalid", text: invalidText })), validationStatus === 'valid' && !!validText && (_jsx(Helper, { disabled: disabled, showIcon: showValidationIcon, validationStatus: "valid", text: validText }))] })] }));
34
34
  return (_jsx(CheckboxComponent, { ...props, value: (value ?? '').toString(), isDisabled: disabled, isChecked: checked, children: checkboxType === 'tile' ? (_jsx(CheckboxTileRoot, { children: checkboxChildren })) : (checkboxChildren) }));
35
35
  };
36
36
  const CheckboxTile = ({ type = 'tile', ...props }) => {
@@ -17,6 +17,7 @@ type CheckboxWithChildrenProps = {
17
17
  label?: never;
18
18
  helperText?: never;
19
19
  helperIcon?: never;
20
+ badge?: never;
20
21
  invalidText?: never;
21
22
  validText?: never;
22
23
  showValidationIcon?: never;
@@ -27,6 +28,7 @@ type CheckboxWithoutChildrenProps = {
27
28
  label?: string;
28
29
  helperText?: string;
29
30
  helperIcon?: ComponentType;
31
+ badge?: ReactNode;
30
32
  invalidText?: string;
31
33
  validText?: string;
32
34
  showValidationIcon?: boolean;