@utilitywarehouse/hearth-react-native 0.20.0 → 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 (123) 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 +249 -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 +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/core/themes.d.ts +188 -8
  24. package/build/core/themes.js +18 -2
  25. package/build/hooks/useStyleProps.js +22 -5
  26. package/build/tokens/color.d.ts +4 -0
  27. package/build/tokens/color.js +2 -0
  28. package/build/tokens/components/dark/modal.d.ts +6 -0
  29. package/build/tokens/components/dark/modal.js +6 -0
  30. package/build/tokens/components/dark/navigation.d.ts +1 -0
  31. package/build/tokens/components/dark/navigation.js +1 -0
  32. package/build/tokens/components/light/modal.d.ts +6 -0
  33. package/build/tokens/components/light/modal.js +6 -0
  34. package/build/tokens/components/light/navigation.d.ts +1 -0
  35. package/build/tokens/components/light/navigation.js +1 -0
  36. package/build/tokens/components/light/skeleton.d.ts +1 -1
  37. package/build/tokens/components/light/skeleton.js +1 -1
  38. package/build/tokens/font.d.ts +2 -0
  39. package/build/tokens/font.js +2 -0
  40. package/build/tokens/line-height.d.ts +2 -0
  41. package/build/tokens/line-height.js +2 -0
  42. package/build/tokens/primitive.d.ts +4 -0
  43. package/build/tokens/primitive.js +4 -0
  44. package/build/tokens/semantic-dark.d.ts +1 -0
  45. package/build/tokens/semantic-dark.js +1 -0
  46. package/build/tokens/semantic-light.d.ts +1 -0
  47. package/build/tokens/semantic-light.js +1 -0
  48. package/build/tokens/typography.d.ts +30 -0
  49. package/build/tokens/typography.js +15 -0
  50. package/build/types/index.d.ts +4 -2
  51. package/build/types/index.js +4 -2
  52. package/build/types/semanticColorValues.d.ts +22 -0
  53. package/build/types/semanticColorValues.js +1 -0
  54. package/build/types/utilityProps.d.ts +326 -0
  55. package/build/types/utilityProps.js +1 -0
  56. package/build/types/values.d.ts +4 -3
  57. package/build/utils/coloursAsArray.d.ts +4 -0
  58. package/build/utils/coloursAsArray.js +5 -0
  59. package/build/utils/index.d.ts +1 -1
  60. package/build/utils/index.js +1 -1
  61. package/build/utils/styleUtils.d.ts +26 -2
  62. package/build/utils/styleUtils.js +42 -13
  63. package/build/utils/themeValueHelpers.d.ts +13 -0
  64. package/build/utils/themeValueHelpers.js +29 -0
  65. package/docs/changelog.mdx +74 -2
  66. package/docs/components/AllComponents.web.tsx +23 -24
  67. package/docs/components/UsageWrap.tsx +2 -2
  68. package/docs/introduction.mdx +0 -7
  69. package/package.json +5 -3
  70. package/src/components/BodyText/BodyText.props.ts +5 -19
  71. package/src/components/BodyText/BodyText.stories.tsx +2 -1
  72. package/src/components/BodyText/BodyText.tsx +17 -6
  73. package/src/components/Box/Box.docs.mdx +5 -4
  74. package/src/components/Box/Box.props.ts +3 -231
  75. package/src/components/Box/Box.stories.tsx +2 -2
  76. package/src/components/Box/Box.tsx +38 -9
  77. package/src/components/Button/Button.docs.mdx +46 -1
  78. package/src/components/Card/Card.docs.mdx +1 -1
  79. package/src/components/Card/Card.props.ts +2 -5
  80. package/src/components/Card/Card.stories.tsx +54 -23
  81. package/src/components/Carousel/Carousel.docs.mdx +49 -44
  82. package/src/components/Center/Center.docs.mdx +6 -4
  83. package/src/components/Container/Container.docs.mdx +13 -8
  84. package/src/components/Container/Container.props.ts +9 -80
  85. package/src/components/Container/Container.stories.tsx +81 -65
  86. package/src/components/DateInput/DateInput.docs.mdx +43 -0
  87. package/src/components/DateInput/DateInput.props.ts +15 -1
  88. package/src/components/DateInput/DateInput.stories.tsx +37 -2
  89. package/src/components/DateInput/DateInput.tsx +6 -0
  90. package/src/components/DateInput/DateInputSegment.tsx +2 -0
  91. package/src/components/DetailText/DetailText.props.ts +4 -17
  92. package/src/components/DetailText/DetailText.stories.tsx +2 -3
  93. package/src/components/DetailText/DetailText.tsx +16 -17
  94. package/src/components/Flex/Flex.props.ts +2 -2
  95. package/src/components/Flex/Flex.stories.tsx +1 -1
  96. package/src/components/Flex/Flex.tsx +4 -1
  97. package/src/components/Grid/Grid.docs.mdx +53 -49
  98. package/src/components/Heading/Heading.props.ts +4 -18
  99. package/src/components/Heading/Heading.stories.tsx +2 -1
  100. package/src/components/Heading/Heading.tsx +40 -18
  101. package/src/components/Toast/ToastItem.figma.tsx +1 -8
  102. package/src/core/themes.ts +19 -2
  103. package/src/hooks/useStyleProps.ts +40 -5
  104. package/src/tokens/color.ts +2 -0
  105. package/src/tokens/components/dark/modal.ts +6 -0
  106. package/src/tokens/components/dark/navigation.ts +1 -0
  107. package/src/tokens/components/light/modal.ts +6 -0
  108. package/src/tokens/components/light/navigation.ts +1 -0
  109. package/src/tokens/components/light/skeleton.ts +1 -1
  110. package/src/tokens/font.ts +2 -0
  111. package/src/tokens/line-height.ts +2 -0
  112. package/src/tokens/primitive.ts +4 -0
  113. package/src/tokens/semantic-dark.ts +1 -0
  114. package/src/tokens/semantic-light.ts +1 -0
  115. package/src/tokens/typography.ts +15 -0
  116. package/src/types/index.ts +4 -2
  117. package/src/types/semanticColorValues.ts +26 -0
  118. package/src/types/utilityProps.ts +410 -0
  119. package/src/types/values.ts +4 -7
  120. package/src/utils/coloursAsArray.ts +6 -0
  121. package/src/utils/index.ts +8 -1
  122. package/src/utils/styleUtils.ts +45 -14
  123. package/src/utils/themeValueHelpers.ts +38 -0
@@ -1,9 +1,7 @@
1
- import { useMemo } from 'react';
2
1
  import { Text, TextStyle } from 'react-native';
3
2
  import { StyleSheet } from 'react-native-unistyles';
4
- import { useTheme } from '../../hooks';
5
- import type { ColorValue } from '../../types';
6
- import { getFlattenedColorValue } from '../../utils';
3
+ import { useStyleProps } from '../../hooks';
4
+ import { getFlattenedColorValue, resolveThemeValueWithFallback } from '../../utils';
7
5
  import type HeadingProps from './Heading.props';
8
6
 
9
7
  const Heading = ({
@@ -23,26 +21,19 @@ const Heading = ({
23
21
  inverted,
24
22
  ...props
25
23
  }: HeadingProps) => {
24
+ // Extract margin utility props from remaining props
25
+ const { computedStyles: utilityStyles, remainingProps } = useStyleProps(props);
26
+
26
27
  styles.useVariants({
27
28
  size,
28
29
  underline,
29
30
  strikeThrough,
30
31
  inverted,
31
32
  });
32
- const { color: themeColor, colorMode } = useTheme();
33
- const colorValue: ColorValue = useMemo(
34
- () => getFlattenedColorValue(color, themeColor),
35
- // eslint-disable-next-line react-hooks/exhaustive-deps
36
- [color, colorMode]
37
- );
38
- const decorationColor = useMemo(
39
- () => getFlattenedColorValue(textDecorationColor, themeColor),
40
- // eslint-disable-next-line react-hooks/exhaustive-deps
41
- [textDecorationColor, colorMode]
42
- );
33
+
43
34
  return (
44
35
  <Text
45
- {...props}
36
+ {...remainingProps}
46
37
  {...(truncated
47
38
  ? {
48
39
  numberOfLines: 1,
@@ -51,16 +42,16 @@ const Heading = ({
51
42
  : {})}
52
43
  style={[
53
44
  styles.text,
45
+ utilityStyles,
54
46
  {
55
- ...(colorValue ? { color: colorValue } : {}),
56
47
  ...(textTransform ? { textTransform } : {}),
57
48
  ...(textAlign ? { textAlign } : {}),
58
49
  ...(textAlignVertical ? { textAlignVertical } : {}),
59
- ...(decorationColor && { textDecorationColor: decorationColor }),
60
50
  ...(textDecorationLine && { textDecorationLine }),
61
51
  ...(textDecorationStyle && { textDecorationStyle }),
62
52
  ...(userSelect && { userSelect }),
63
53
  },
54
+ styles.getColours(color, textDecorationColor),
64
55
  props.style,
65
56
  ]}
66
57
  >
@@ -147,6 +138,23 @@ const styles = StyleSheet.create(theme => ({
147
138
  lg: theme.typography.desktop.heading.xl.lineHeight,
148
139
  },
149
140
  },
141
+ '2xl': {
142
+ fontSize: {
143
+ base: theme.typography.mobile.heading['2xl'].fontSize,
144
+ md: theme.typography.tablet.heading['2xl'].fontSize,
145
+ lg: theme.typography.desktop.heading['2xl'].fontSize,
146
+ },
147
+ fontWeight: {
148
+ base: theme.typography.mobile.heading['2xl'].fontWeight,
149
+ md: theme.typography.tablet.heading['2xl'].fontWeight,
150
+ lg: theme.typography.desktop.heading['2xl'].fontWeight,
151
+ },
152
+ lineHeight: {
153
+ base: theme.typography.mobile.heading['2xl'].lineHeight,
154
+ md: theme.typography.tablet.heading['2xl'].lineHeight,
155
+ lg: theme.typography.desktop.heading['2xl'].lineHeight,
156
+ },
157
+ },
150
158
  },
151
159
  underline: {
152
160
  true: {
@@ -165,6 +173,20 @@ const styles = StyleSheet.create(theme => ({
165
173
  },
166
174
  },
167
175
  },
176
+ getColours: (color?: string, textDecorationColor?: string) => ({
177
+ ...(color
178
+ ? {
179
+ color: resolveThemeValueWithFallback(
180
+ color,
181
+ theme.helpers.semanticColor.text,
182
+ theme.color
183
+ ),
184
+ }
185
+ : {}),
186
+ ...(textDecorationColor
187
+ ? { textDecorationColor: getFlattenedColorValue(textDecorationColor, theme.color) }
188
+ : {}),
189
+ }),
168
190
  }));
169
191
 
170
192
  export default Heading;
@@ -1,13 +1,6 @@
1
1
  import figma from '@figma/code-connect';
2
2
  import ToastItem from './ToastItem';
3
3
 
4
- /**
5
- * -- This file was auto-generated by Code Connect --
6
- * None of your props could be automatically mapped to Figma properties.
7
- * You should update the `props` object to include a mapping from your
8
- * code props to Figma properties, and update the `example` function to
9
- * return the code example you'd like to see in Figma
10
- */
11
4
 
12
5
  figma.connect(ToastItem, 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR?node-id=7072%3A913', {
13
6
  props: {
@@ -18,5 +11,5 @@ figma.connect(ToastItem, 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR?no
18
11
  // "icon24": figma.instance('Icon-24'),
19
12
  // "dismiss": figma.boolean('Dismiss?')
20
13
  },
21
- example: props => <ToastItem toast={null} onClose={null} />,
14
+ example: props => <ToastItem />,
22
15
  });
@@ -306,9 +306,18 @@ export const lightTheme = {
306
306
  white: '#ffffff',
307
307
  black: '#000000',
308
308
  } as const,
309
+
309
310
  components: components.light,
310
311
  ...shared,
311
- helpers: lightHelpers,
312
+ helpers: {
313
+ ...lightHelpers /** Simplified semantic color tokens grouped by category */,
314
+ semanticColor: {
315
+ background: light.background,
316
+ border: light.border,
317
+ text: light.text,
318
+ icon: light.icon,
319
+ },
320
+ },
312
321
  } as const;
313
322
 
314
323
  const darkHelpers = {
@@ -364,7 +373,15 @@ export const darkTheme = {
364
373
  },
365
374
  components: components.dark,
366
375
  ...shared,
367
- helpers: darkHelpers,
376
+ helpers: {
377
+ ...darkHelpers /** Simplified semantic color tokens grouped by category */,
378
+ semanticColor: {
379
+ background: dark.background,
380
+ border: dark.border,
381
+ text: dark.text,
382
+ icon: dark.icon,
383
+ },
384
+ },
368
385
  } as const;
369
386
 
370
387
  export const themes = {
@@ -1,6 +1,14 @@
1
1
  import { useMemo } from 'react';
2
2
  import { ViewStyle } from 'react-native';
3
- import { propStyleMapping, resolveThemeValue, themeStyleMapping, viewStyleProps } from '../utils';
3
+ import {
4
+ propStyleMapping,
5
+ resolveThemeKey,
6
+ resolveThemeValueWithFallback,
7
+ semanticPropMapping,
8
+ themeStyleFallbackMapping,
9
+ themeStyleMapping,
10
+ viewStyleProps,
11
+ } from '../utils';
4
12
  import useTheme from './useTheme';
5
13
 
6
14
  /**
@@ -28,8 +36,23 @@ export const useStyleProps = (props: Record<string, any>): StylePropsResult => {
28
36
  Object.entries(props).forEach(([propName, propValue]) => {
29
37
  if (propValue === undefined) return;
30
38
 
39
+ // Check for semantic prop mappings first (e.g., iconColor, color)
40
+ const semanticMapping = semanticPropMapping[propName];
41
+ if (semanticMapping) {
42
+ const { styleProp, themeKey } = semanticMapping;
43
+ const themeMapping = resolveThemeKey(theme, themeKey);
44
+ const fallbackKey = themeStyleFallbackMapping[themeKey];
45
+ const fallbackMapping = fallbackKey ? resolveThemeKey(theme, fallbackKey) : undefined;
46
+
47
+ computedStyles[styleProp] = resolveThemeValueWithFallback(
48
+ propValue,
49
+ themeMapping,
50
+ fallbackMapping
51
+ );
52
+ return;
53
+ }
54
+
31
55
  let stylePropName: keyof ViewStyle | undefined;
32
- let themeKey: keyof typeof theme | undefined;
33
56
 
34
57
  // Handle shorthand props
35
58
  if (propStyleMapping[propName]) {
@@ -42,10 +65,22 @@ export const useStyleProps = (props: Record<string, any>): StylePropsResult => {
42
65
 
43
66
  if (stylePropName) {
44
67
  // Resolve theme value if needed
45
- themeKey = themeStyleMapping[stylePropName] as keyof typeof theme;
68
+ const themeKey = themeStyleMapping[stylePropName as string];
69
+
70
+ if (themeKey) {
71
+ const themeObj = resolveThemeKey(theme, themeKey);
72
+ const fallbackKey = themeStyleFallbackMapping[themeKey];
73
+ const fallbackMapping = fallbackKey ? resolveThemeKey(theme, fallbackKey) : undefined;
46
74
 
47
- if (themeKey && theme[themeKey]) {
48
- computedStyles[stylePropName] = resolveThemeValue(propValue, theme[themeKey]);
75
+ if (themeObj) {
76
+ computedStyles[stylePropName] = resolveThemeValueWithFallback(
77
+ propValue,
78
+ themeObj,
79
+ fallbackMapping
80
+ );
81
+ } else {
82
+ computedStyles[stylePropName] = propValue;
83
+ }
49
84
  } else {
50
85
  computedStyles[stylePropName] = propValue;
51
86
  }
@@ -232,6 +232,7 @@ export const yellow = {
232
232
  export const light = {
233
233
  background: {
234
234
  brand: '#7a42c8',
235
+ loading: '#f1efe4',
235
236
  primary: '#fcfbf2',
236
237
  secondary: '#ffffff',
237
238
  },
@@ -480,6 +481,7 @@ export const light = {
480
481
  export const dark = {
481
482
  background: {
482
483
  brand: '#7a42c8',
484
+ loading: '#30302c',
483
485
  primary: '#191917',
484
486
  secondary: '#232323',
485
487
  },
@@ -9,8 +9,14 @@ export default {
9
9
  borderRadius: 16,
10
10
  content: {
11
11
  gap: 12,
12
+ mobile: {
13
+ paddingBottom: 16,
14
+ },
12
15
  },
13
16
  gap: 24,
17
+ handle: {
18
+ paddingBottom: 16,
19
+ },
14
20
  heading: {
15
21
  gap: 24,
16
22
  },
@@ -7,6 +7,7 @@ export default {
7
7
  borderRadiusNone: 0,
8
8
  borderRadiusRounded: 4,
9
9
  },
10
+ borderBottom: '#5c2ca9',
10
11
  borderRadius: 6,
11
12
  desktop: {
12
13
  height: 88,
@@ -9,8 +9,14 @@ export default {
9
9
  borderRadius: 16,
10
10
  content: {
11
11
  gap: 12,
12
+ mobile: {
13
+ paddingBottom: 16,
14
+ },
12
15
  },
13
16
  gap: 24,
17
+ handle: {
18
+ paddingBottom: 16,
19
+ },
14
20
  heading: {
15
21
  gap: 24,
16
22
  },
@@ -7,6 +7,7 @@ export default {
7
7
  borderRadiusNone: 0,
8
8
  borderRadiusRounded: 4,
9
9
  },
10
+ borderBottom: '#5c2ca9',
10
11
  borderRadius: 6,
11
12
  desktop: {
12
13
  height: 88,
@@ -3,5 +3,5 @@
3
3
  */
4
4
 
5
5
  export default {
6
- loadingColor: '#f7f6eb',
6
+ loadingColor: '#f1efe4',
7
7
  } as const;
@@ -19,7 +19,9 @@ export default {
19
19
  '400': 30,
20
20
  '500': 36,
21
21
  '550': 40,
22
+ '575': 44,
22
23
  '600': 48,
24
+ '650': 54,
23
25
  '700': 60,
24
26
  '800': 72,
25
27
  '900': 96,
@@ -15,7 +15,9 @@ export default {
15
15
  '800': 36,
16
16
  '900': 40,
17
17
  '950': 48,
18
+ '975': 52,
18
19
  '1000': 56,
20
+ '1050': 62,
19
21
  '1100': 72,
20
22
  '1200': 90,
21
23
  } as const;
@@ -33,7 +33,9 @@ export default {
33
33
  '400': 30,
34
34
  '500': 36,
35
35
  '550': 40,
36
+ '575': 44,
36
37
  '600': 48,
38
+ '650': 54,
37
39
  '700': 60,
38
40
  '800': 72,
39
41
  '900': 96,
@@ -78,7 +80,9 @@ export default {
78
80
  '800': 36,
79
81
  '900': 40,
80
82
  '950': 48,
83
+ '975': 52,
81
84
  '1000': 56,
85
+ '1050': 62,
82
86
  '1100': 72,
83
87
  '1200': 90,
84
88
  },
@@ -5,6 +5,7 @@
5
5
  export default {
6
6
  background: {
7
7
  brand: '#7a42c8',
8
+ loading: '#30302c',
8
9
  primary: '#191917',
9
10
  secondary: '#232323',
10
11
  },
@@ -5,6 +5,7 @@
5
5
  export default {
6
6
  background: {
7
7
  brand: '#7a42c8',
8
+ loading: '#f1efe4',
8
9
  primary: '#fcfbf2',
9
10
  secondary: '#ffffff',
10
11
  },
@@ -64,6 +64,11 @@ export const mobile = {
64
64
  },
65
65
  },
66
66
  heading: {
67
+ '2xl': {
68
+ fontSize: 44,
69
+ fontWeight: 700,
70
+ lineHeight: 52,
71
+ },
67
72
  fontFamily: 'Comic Hams',
68
73
  lg: {
69
74
  fontSize: 24,
@@ -151,6 +156,11 @@ export const tablet = {
151
156
  },
152
157
  },
153
158
  heading: {
159
+ '2xl': {
160
+ fontSize: 44,
161
+ fontWeight: 700,
162
+ lineHeight: 52,
163
+ },
154
164
  fontFamily: 'Comic Hams',
155
165
  lg: {
156
166
  fontSize: 24,
@@ -238,6 +248,11 @@ export const desktop = {
238
248
  },
239
249
  },
240
250
  heading: {
251
+ '2xl': {
252
+ fontSize: 54,
253
+ fontWeight: 700,
254
+ lineHeight: 62,
255
+ },
241
256
  fontFamily: 'Comic Hams',
242
257
  lg: {
243
258
  fontSize: 30,
@@ -1,4 +1,6 @@
1
- export * from './states';
2
1
  export * from './refs';
3
- export * from './values';
2
+ export * from './semanticColorValues';
3
+ export * from './states';
4
4
  export * from './unistyles';
5
+ export * from './utilityProps';
6
+ export * from './values';
@@ -0,0 +1,26 @@
1
+ import type semanticLight from '../tokens/semantic-light';
2
+
3
+ /**
4
+ * Simplified background color values derived from the semantic token `background` keys.
5
+ * e.g., 'brand' | 'primary' | 'secondary'
6
+ */
7
+ export type BackgroundColorValue = keyof typeof semanticLight.background;
8
+
9
+ /**
10
+ * Simplified border color values derived from the semantic token `border` keys.
11
+ * e.g., 'strong' | 'subtle'
12
+ */
13
+ export type BorderColorValue = keyof typeof semanticLight.border;
14
+
15
+ /**
16
+ * Simplified text color values derived from the semantic token `text` keys.
17
+ * e.g., 'affirmative' | 'brand' | 'inverted' | 'primary' | 'secondary'
18
+ * Also accepts any raw color value or undefined.
19
+ */
20
+ export type TextColorValue = keyof typeof semanticLight.text;
21
+
22
+ /**
23
+ * Simplified icon color values derived from the semantic token `icon` keys.
24
+ * e.g., 'inverted' | 'primary'
25
+ */
26
+ export type IconColorValue = keyof typeof semanticLight.icon;