@utilitywarehouse/hearth-react-native 0.5.0 → 0.6.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 (44) hide show
  1. package/.storybook/main.ts +21 -1
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/CHANGELOG.md +8 -0
  5. package/build/components/Container/Container.d.ts +6 -0
  6. package/build/components/Container/Container.js +40 -0
  7. package/build/components/Container/Container.props.d.ts +85 -0
  8. package/build/components/Container/Container.props.js +1 -0
  9. package/build/components/Container/index.d.ts +2 -0
  10. package/build/components/Container/index.js +1 -0
  11. package/build/components/ProgressStepper/ProgressStep.d.ts +1 -1
  12. package/build/components/ProgressStepper/ProgressStep.js +6 -6
  13. package/build/components/ProgressStepper/ProgressStepper.props.d.ts +3 -3
  14. package/build/components/ProgressStepper/index.d.ts +1 -1
  15. package/build/components/ThemedImage/ThemedImage.d.ts +12 -0
  16. package/build/components/ThemedImage/ThemedImage.js +27 -0
  17. package/build/components/ThemedImage/ThemedImage.props.d.ts +13 -0
  18. package/build/components/ThemedImage/ThemedImage.props.js +1 -0
  19. package/build/components/ThemedImage/index.d.ts +2 -0
  20. package/build/components/ThemedImage/index.js +1 -0
  21. package/build/components/index.d.ts +2 -0
  22. package/build/components/index.js +2 -0
  23. package/build/hooks/useStyleProps.js +1 -1
  24. package/docs/components/AllComponents.web.tsx +38 -3
  25. package/docs/layout-components.docs.mdx +30 -0
  26. package/package.json +3 -1
  27. package/src/components/Container/Container.docs.mdx +168 -0
  28. package/src/components/Container/Container.props.ts +89 -0
  29. package/src/components/Container/Container.stories.tsx +274 -0
  30. package/src/components/Container/Container.tsx +52 -0
  31. package/src/components/Container/index.tsx +2 -0
  32. package/src/components/ProgressStepper/ProgressStep.tsx +8 -8
  33. package/src/components/ProgressStepper/ProgressStepper.docs.mdx +11 -11
  34. package/src/components/ProgressStepper/ProgressStepper.props.ts +3 -3
  35. package/src/components/ProgressStepper/ProgressStepper.stories.tsx +27 -27
  36. package/src/components/ProgressStepper/index.ts +1 -1
  37. package/src/components/ThemedImage/ThemedImage.docs.mdx +208 -0
  38. package/src/components/ThemedImage/ThemedImage.props.ts +15 -0
  39. package/src/components/ThemedImage/ThemedImage.stories.tsx +175 -0
  40. package/src/components/ThemedImage/ThemedImage.tsx +34 -0
  41. package/src/components/ThemedImage/index.tsx +2 -0
  42. package/src/components/index.ts +2 -0
  43. package/src/hooks/useStyleProps.ts +1 -1
  44. package/src/vite-env.d.ts +6 -0
@@ -1,4 +1,5 @@
1
1
  import remarkGfm from 'remark-gfm';
2
+ import svgr from 'vite-plugin-svgr';
2
3
 
3
4
  const unistylesPluginOptions = {
4
5
  autoProcessImports: ['@utilitywarehouse/hearth-react-native'],
@@ -39,7 +40,22 @@ const config = {
39
40
  },
40
41
  },
41
42
  },
42
- viteFinal: config => {
43
+ viteFinal: async (config: any) => {
44
+ // Add SVGR plugin for web SVG imports as React components
45
+ config.plugins = [
46
+ ...(config.plugins || []),
47
+ svgr({
48
+ include: '**/*.svg',
49
+ svgrOptions: {
50
+ exportType: 'default',
51
+ ref: true,
52
+ svgo: false,
53
+ titleProp: true,
54
+ icon: true,
55
+ },
56
+ }),
57
+ ];
58
+
43
59
  return {
44
60
  ...config,
45
61
  resolve: {
@@ -49,6 +65,10 @@ const config = {
49
65
  '@utilitywarehouse/hearth-react-native-icons': '@utilitywarehouse/hearth-react-icons',
50
66
  },
51
67
  },
68
+ optimizeDeps: {
69
+ ...config.optimizeDeps,
70
+ exclude: [...(config.optimizeDeps?.exclude || []), '@utilitywarehouse/hearth-svg-assets'],
71
+ },
52
72
  };
53
73
  },
54
74
  };
@@ -1,4 +1,4 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.5.0 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.6.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.5.0 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.6.0 lint /home/runner/work/hearth/hearth/packages/react-native
3
3
  > TIMING=1 eslint --max-warnings 0
4
4
 
5
5
  Rule | Time (ms) | Relative
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#603](https://github.com/utilitywarehouse/hearth/pull/603) [`3f292e9`](https://github.com/utilitywarehouse/hearth/commit/3f292e9960dc708dd6932cff04671dd7ef375c1a) Thanks [@jordmccord](https://github.com/jordmccord)! - Adds `Container` component
8
+
9
+ - [#605](https://github.com/utilitywarehouse/hearth/pull/605) [`f52e0f5`](https://github.com/utilitywarehouse/hearth/commit/f52e0f57eff5f1cfa36dacc45576c08771ca12df) Thanks [@jordmccord](https://github.com/jordmccord)! - Adds `ThemedImage` component
10
+
3
11
  ## 0.5.0
4
12
 
5
13
  ### Minor Changes
@@ -0,0 +1,6 @@
1
+ import type ContainerProps from './Container.props';
2
+ declare const Container: {
3
+ ({ style, children, space, ...props }: ContainerProps): import("react/jsx-runtime").JSX.Element;
4
+ displayName: string;
5
+ };
6
+ export default Container;
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { useStyleProps } from '../../hooks';
5
+ const Container = ({ style, children, space = 'md', ...props }) => {
6
+ const { computedStyles, remainingProps } = useStyleProps(props);
7
+ styles.useVariants({ space });
8
+ return (_jsx(View, { style: [styles.container(computedStyles), style], ...remainingProps, children: children }));
9
+ };
10
+ Container.displayName = 'Container';
11
+ const styles = StyleSheet.create(theme => ({
12
+ container: extra => ({
13
+ paddingTop: typeof extra.padding === 'undefined' && typeof extra.paddingVertical === 'undefined'
14
+ ? {
15
+ base: theme.layout.mobile.container.paddingTop,
16
+ md: theme.layout.tablet.container.paddingTop,
17
+ lg: theme.layout.desktop.container.paddingTop,
18
+ }
19
+ : undefined,
20
+ paddingBottom: typeof extra.padding === 'undefined' && typeof extra.paddingVertical === 'undefined'
21
+ ? {
22
+ base: theme.layout.mobile.container.paddingBottom,
23
+ md: theme.layout.tablet.container.paddingBottom,
24
+ lg: theme.layout.desktop.container.paddingBottom,
25
+ }
26
+ : undefined,
27
+ marginHorizontal: typeof extra.margin === 'undefined' && typeof extra.marginHorizontal === 'undefined'
28
+ ? {
29
+ base: theme.layout.mobile.container.margin,
30
+ md: theme.layout.tablet.container.margin,
31
+ lg: theme.layout.desktop.container.margin,
32
+ }
33
+ : undefined,
34
+ ...extra,
35
+ variants: {
36
+ space: theme.globalStyle.variants.space,
37
+ },
38
+ }),
39
+ }));
40
+ export default Container;
@@ -0,0 +1,85 @@
1
+ import type { ViewProps } from 'react-native';
2
+ import { SpaceValue, SpacingValues } from '../../types';
3
+ interface ContainerProps extends ViewProps {
4
+ /**
5
+ * The padding of the container.
6
+ */
7
+ padding?: SpaceValue;
8
+ /**
9
+ * The horizontal padding of the container.
10
+ */
11
+ paddingHorizontal?: SpaceValue;
12
+ /**
13
+ * The vertical padding of the container.
14
+ */
15
+ paddingVertical?: SpaceValue;
16
+ /**
17
+ * The top padding of the container.
18
+ */
19
+ paddingTop?: SpaceValue;
20
+ /**
21
+ * The bottom padding of the container.
22
+ */
23
+ paddingBottom?: SpaceValue;
24
+ /**
25
+ * The left padding of the container.
26
+ */
27
+ paddingLeft?: SpaceValue;
28
+ /**
29
+ * The right padding of the container.
30
+ */
31
+ paddingRight?: SpaceValue;
32
+ /**
33
+ * The margin of the container.
34
+ */
35
+ margin?: SpaceValue;
36
+ /**
37
+ * The horizontal margin of the container.
38
+ */
39
+ marginHorizontal?: SpaceValue;
40
+ /**
41
+ * The vertical margin of the container.
42
+ */
43
+ marginVertical?: SpaceValue;
44
+ /**
45
+ * The top margin of the container.
46
+ */
47
+ marginTop?: SpaceValue;
48
+ /**
49
+ * The bottom margin of the container.
50
+ */
51
+ marginBottom?: SpaceValue;
52
+ /**
53
+ * The left margin of the container.
54
+ */
55
+ marginLeft?: SpaceValue;
56
+ /**
57
+ * The right margin of the container.
58
+ */
59
+ marginRight?: SpaceValue;
60
+ p?: SpaceValue;
61
+ px?: SpaceValue;
62
+ py?: SpaceValue;
63
+ pt?: SpaceValue;
64
+ pb?: SpaceValue;
65
+ pl?: SpaceValue;
66
+ pr?: SpaceValue;
67
+ m?: SpaceValue;
68
+ mx?: SpaceValue;
69
+ my?: SpaceValue;
70
+ mt?: SpaceValue;
71
+ mb?: SpaceValue;
72
+ ml?: SpaceValue;
73
+ mr?: SpaceValue;
74
+ /**
75
+ * The space between child elements (gap).
76
+ */
77
+ space?: SpacingValues;
78
+ /**
79
+ * The space between child elements.
80
+ */
81
+ gap?: SpaceValue;
82
+ backgroundColor?: 'backgroundBrand' | 'backgroundPrimary' | 'backgroundSecondary' | 'transparent';
83
+ bg?: 'backgroundBrand' | 'backgroundPrimary' | 'backgroundSecondary' | 'transparent';
84
+ }
85
+ export default ContainerProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { default as Container } from './Container';
2
+ export type { default as ContainerProps } from './Container.props';
@@ -0,0 +1 @@
1
+ export { default as Container } from './Container';
@@ -4,7 +4,7 @@ interface ProgressStepInternalProps extends ProgressStepProps {
4
4
  isLast?: boolean;
5
5
  }
6
6
  declare const ProgressStep: {
7
- ({ state, index, isLast, ...rest }: ProgressStepInternalProps): import("react/jsx-runtime").JSX.Element;
7
+ ({ status, index, isLast, ...rest }: ProgressStepInternalProps): import("react/jsx-runtime").JSX.Element;
8
8
  displayName: string;
9
9
  };
10
10
  export default ProgressStep;
@@ -4,12 +4,12 @@ import { StyleSheet } from 'react-native-unistyles';
4
4
  import { TickSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
5
5
  import { Icon } from '../Icon';
6
6
  import { BodyText } from '../BodyText';
7
- const ProgressStep = ({ state, index = 0, isLast = false, ...rest }) => {
8
- styles.useVariants({ state, isLast });
7
+ const ProgressStep = ({ status, index = 0, isLast = false, ...rest }) => {
8
+ styles.useVariants({ status, isLast });
9
9
  const renderStepNumber = () => {
10
10
  return (_jsx(BodyText, { size: "md", weight: "semibold", style: styles.text, children: index + 1 }));
11
11
  };
12
- return (_jsxs(View, { style: styles.container, accessible: true, "aria-label": `Step ${index + 1}, ${rest.id}, ${state}`, ...rest, children: [_jsx(View, { style: styles.step, children: state === 'complete' ? (_jsx(Icon, { as: TickSmallIcon, width: 20, height: 20, style: styles.text })) : state === 'active' ? (_jsx(View, { style: styles.inner, children: renderStepNumber() })) : (renderStepNumber()) }), !isLast && _jsx(View, { style: styles.connector })] }));
12
+ return (_jsxs(View, { style: styles.container, accessible: true, "aria-label": `Step ${index + 1}, ${rest.id}, ${status}`, ...rest, children: [_jsx(View, { style: styles.step, children: status === 'complete' ? (_jsx(Icon, { as: TickSmallIcon, width: 20, height: 20, style: styles.text })) : status === 'active' ? (_jsx(View, { style: styles.inner, children: renderStepNumber() })) : (renderStepNumber()) }), !isLast && _jsx(View, { style: styles.connector })] }));
13
13
  };
14
14
  ProgressStep.displayName = 'ProgressStep';
15
15
  const styles = StyleSheet.create(theme => ({
@@ -37,7 +37,7 @@ const styles = StyleSheet.create(theme => ({
37
37
  alignItems: 'center',
38
38
  justifyContent: 'center',
39
39
  variants: {
40
- state: {
40
+ status: {
41
41
  complete: {
42
42
  backgroundColor: theme.color.surface.brand.default,
43
43
  },
@@ -64,7 +64,7 @@ const styles = StyleSheet.create(theme => ({
64
64
  },
65
65
  text: {
66
66
  variants: {
67
- state: {
67
+ status: {
68
68
  complete: {
69
69
  color: theme.color.text.inverted,
70
70
  },
@@ -83,7 +83,7 @@ const styles = StyleSheet.create(theme => ({
83
83
  flex: 1,
84
84
  height: theme.components.progressStepper.bar.height,
85
85
  variants: {
86
- state: {
86
+ status: {
87
87
  complete: {
88
88
  backgroundColor: theme.components.progressStepper.bar.complete.backgroundColor,
89
89
  },
@@ -1,5 +1,5 @@
1
1
  import { ViewProps } from 'react-native';
2
- export type StepState = 'complete' | 'active' | 'incomplete';
2
+ export type StepStatus = 'complete' | 'active' | 'incomplete';
3
3
  export interface ProgressStepperProps extends ViewProps {
4
4
  /**
5
5
  * Child ProgressStep components
@@ -12,9 +12,9 @@ export interface ProgressStepProps extends ViewProps {
12
12
  */
13
13
  id: string;
14
14
  /**
15
- * Current state of the step
15
+ * Current status of the step
16
16
  */
17
- state: StepState;
17
+ status: StepStatus;
18
18
  }
19
19
  export interface ProgressStepperRootProps extends ViewProps {
20
20
  children: React.ReactNode;
@@ -1,3 +1,3 @@
1
1
  export { default as ProgressStepper } from './ProgressStepper';
2
2
  export { default as ProgressStep } from './ProgressStep';
3
- export type { ProgressStepperProps, ProgressStepProps, StepState } from './ProgressStepper.props';
3
+ export type { ProgressStepperProps, ProgressStepProps, StepStatus } from './ProgressStepper.props';
@@ -0,0 +1,12 @@
1
+ import type ThemedImageProps from './ThemedImage.props';
2
+ /**
3
+ * ThemedImage component that displays different images or components based on the current theme
4
+ * @param light - Image source or SVG component to display in light mode
5
+ * @param dark - Image source or SVG component to display in dark mode
6
+ * @param ...rest - All other Image props including width/height for SVG components
7
+ */
8
+ declare const ThemedImage: {
9
+ ({ light, dark, ...props }: ThemedImageProps): import("react/jsx-runtime").JSX.Element;
10
+ displayName: string;
11
+ };
12
+ export default ThemedImage;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { isValidElement } from 'react';
3
+ import { Image } from 'react-native';
4
+ import useColorMode from '../../hooks/useColorMode';
5
+ /**
6
+ * ThemedImage component that displays different images or components based on the current theme
7
+ * @param light - Image source or SVG component to display in light mode
8
+ * @param dark - Image source or SVG component to display in dark mode
9
+ * @param ...rest - All other Image props including width/height for SVG components
10
+ */
11
+ const ThemedImage = ({ light, dark, ...props }) => {
12
+ const [colorMode] = useColorMode();
13
+ const source = colorMode === 'light' ? light : dark;
14
+ // If the source is a React element (like an SVG component), render it directly
15
+ if (isValidElement(source)) {
16
+ return source;
17
+ }
18
+ // If the source is a component type (function/class), instantiate it with props
19
+ if (typeof source === 'function') {
20
+ const Source = source;
21
+ return _jsx(Source, { ...props });
22
+ }
23
+ // Otherwise, render as a regular Image with the source
24
+ return _jsx(Image, { source: source, ...props });
25
+ };
26
+ ThemedImage.displayName = 'ThemedImage';
27
+ export default ThemedImage;
@@ -0,0 +1,13 @@
1
+ import type { ComponentType, ReactElement } from 'react';
2
+ import type { ImageProps, ImageSourcePropType } from 'react-native';
3
+ interface ThemedImageProps extends Omit<ImageProps, 'source'> {
4
+ /**
5
+ * Image source or component to display in light mode
6
+ */
7
+ light: ImageSourcePropType | ReactElement | ComponentType<any>;
8
+ /**
9
+ * Image source or component to display in dark mode
10
+ */
11
+ dark: ImageSourcePropType | ReactElement | ComponentType<any>;
12
+ }
13
+ export default ThemedImageProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { default as ThemedImage } from './ThemedImage';
2
+ export type { default as ThemedImageProps } from './ThemedImage.props';
@@ -0,0 +1 @@
1
+ export { default as ThemedImage } from './ThemedImage';
@@ -9,6 +9,7 @@ export * from './Card';
9
9
  export * from './Carousel';
10
10
  export * from './Center';
11
11
  export * from './Checkbox';
12
+ export * from './Container';
12
13
  export * from './CurrencyInput';
13
14
  export * from './DatePicker';
14
15
  export * from './DatePickerInput';
@@ -41,6 +42,7 @@ export * from './Spinner';
41
42
  export * from './Switch';
42
43
  export * from './Tabs';
43
44
  export * from './Textarea';
45
+ export * from './ThemedImage';
44
46
  export * from './ToggleButtonCard';
45
47
  export { FlatList, Image, KeyboardAvoidingView, ScrollView, SectionList, StatusBar, View, } from 'react-native';
46
48
  export { Pressable } from 'react-native';
@@ -10,6 +10,7 @@ export * from './Card';
10
10
  export * from './Carousel';
11
11
  export * from './Center';
12
12
  export * from './Checkbox';
13
+ export * from './Container';
13
14
  export * from './CurrencyInput';
14
15
  export * from './DatePicker';
15
16
  export * from './DatePickerInput';
@@ -42,6 +43,7 @@ export * from './Spinner';
42
43
  export * from './Switch';
43
44
  export * from './Tabs';
44
45
  export * from './Textarea';
46
+ export * from './ThemedImage';
45
47
  export * from './ToggleButtonCard';
46
48
  export { FlatList, Image, KeyboardAvoidingView, ScrollView, SectionList, StatusBar, View, } from 'react-native';
47
49
  export { Pressable } from 'react-native';
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
- import useTheme from './useTheme';
3
2
  import { propStyleMapping, resolveThemeValue, themeStyleMapping, viewStyleProps } from '../utils';
3
+ import useTheme from './useTheme';
4
4
  /**
5
5
  * Hook to process utility style props and resolve theme values
6
6
  * @param props Component props to process
@@ -10,6 +10,10 @@ import {
10
10
  InsuranceMediumIcon,
11
11
  MobileMediumIcon,
12
12
  } from '@utilitywarehouse/hearth-react-native-icons';
13
+ // @ts-ignore
14
+ import SpotBillingDark from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-dark.svg';
15
+ // @ts-ignore
16
+ import SpotBillingLight from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-light.svg';
13
17
  import { Pressable, ScrollView, View, ViewProps } from 'react-native';
14
18
  import { StyleSheet } from 'react-native-unistyles';
15
19
  import {
@@ -29,6 +33,7 @@ import {
29
33
  CarouselItem,
30
34
  Center,
31
35
  Checkbox,
36
+ Container,
32
37
  CurrencyInput,
33
38
  DatePicker,
34
39
  DatePickerInput,
@@ -53,8 +58,8 @@ import {
53
58
  ListItem,
54
59
  Modal,
55
60
  OL,
56
- ProgressStepper,
57
61
  ProgressStep,
62
+ ProgressStepper,
58
63
  Radio,
59
64
  RadioCard,
60
65
  RadioCardGroup,
@@ -69,6 +74,7 @@ import {
69
74
  Tabs,
70
75
  TabsList,
71
76
  Textarea,
77
+ ThemedImage,
72
78
  ToggleButtonCard,
73
79
  ToggleButtonCardGroup,
74
80
  UL,
@@ -154,7 +160,7 @@ const AllComponents: React.FC = () => {
154
160
  return (
155
161
  <div className="sb-unstyled">
156
162
  <ScrollView contentContainerStyle={styles.container}>
157
- <Flex direction="row" wrap="wrap" space="md">
163
+ <Flex direction="row" wrap="wrap" space="md" style={styles.grid}>
158
164
  <ComponentWrapper name="Accordion" link="/?path=/docs/components-accordion--docs">
159
165
  <Center flex={1} p="200">
160
166
  <Accordion type="single">
@@ -294,6 +300,13 @@ const AllComponents: React.FC = () => {
294
300
  </View>
295
301
  </Center>
296
302
  </ComponentWrapper>
303
+ <ComponentWrapper name="Container" link="/?path=/docs/primitives-container--docs">
304
+ <Container space="md" backgroundColor="backgroundSecondary">
305
+ <Box h={20} bg="blue300" />
306
+ <Box h={20} bg="blue400" />
307
+ <Box h={20} bg="blue500" />
308
+ </Container>
309
+ </ComponentWrapper>
297
310
  <ComponentWrapper name="Currency Input" link="/?path=/docs/forms-currency-input--docs">
298
311
  <Center flex={1} padding="200">
299
312
  <CurrencyInput />
@@ -514,7 +527,7 @@ const AllComponents: React.FC = () => {
514
527
  name="Progress Stepper"
515
528
  link="/?path=/docs/components-progress-stepper--docs"
516
529
  >
517
- <Center flex={1}>
530
+ <Center flex={1} px="300">
518
531
  <ProgressStepper>
519
532
  <ProgressStep id="customer-data" state="complete" />
520
533
  <ProgressStep id="shipping-data" state="complete" />
@@ -617,6 +630,17 @@ const AllComponents: React.FC = () => {
617
630
  <Textarea numberOfLines={3} placeholder="This is a textarea" />
618
631
  </Center>
619
632
  </ComponentWrapper>
633
+ <ComponentWrapper
634
+ name="Themed Image"
635
+ link="/?path=/docs/utility-components-themed-image--docs"
636
+ >
637
+ <Center flex={1} p="300">
638
+ <ThemedImage
639
+ light={<SpotBillingLight width={160} height={160} />}
640
+ dark={<SpotBillingDark width={160} height={160} />}
641
+ />
642
+ </Center>
643
+ </ComponentWrapper>
620
644
  <ComponentWrapper
621
645
  name="Toggle Button Card"
622
646
  link="/?path=/docs/components-toggle-button-card--docs"
@@ -658,6 +682,17 @@ const AllComponents: React.FC = () => {
658
682
 
659
683
  const styles = StyleSheet.create(theme => ({
660
684
  container: {},
685
+ grid: {
686
+ _web: {
687
+ display: 'grid',
688
+ gridTemplateColumns: {
689
+ xs: '1fr',
690
+ md: 'repeat(3, 1fr)',
691
+ lg: 'repeat(auto-fit, minmax(300px, 1fr))',
692
+ },
693
+ gap: theme.space['200'],
694
+ },
695
+ },
661
696
  component: {
662
697
  borderColor: theme.color.warmWhite[300],
663
698
  borderWidth: theme.borderWidth['1'],
@@ -1,5 +1,6 @@
1
1
  import { ArgTypes, Canvas, Meta } from '@storybook/addon-docs/blocks';
2
2
  import * as BoxStories from '../src/components/Box/Box.stories';
3
+ import * as ContainerStories from '../src/components/Container/Container.stories';
3
4
  import * as FlexStories from '../src/components/Flex/Flex.stories';
4
5
  import * as GridStories from '../src/components/Grid/Grid.stories';
5
6
  import { BackToTopButton, NextPrevPage } from './components';
@@ -15,6 +16,7 @@ upon our design tokens, and providing styling options which make it easier to
15
16
  apply design decisions coherently.
16
17
 
17
18
  - [Box](#box)
19
+ - [Container](#container)
18
20
  - [Flex](#flex)
19
21
  - [Grid](#grid)
20
22
 
@@ -36,6 +38,34 @@ elements within `Flex` and `Grid` containers.
36
38
  </Box>
37
39
  ```
38
40
 
41
+ ## Container
42
+
43
+ <Canvas of={ContainerStories.Playground} sourceState="none" />
44
+
45
+ `Container` is a specialised layout component that provides consistent page-level
46
+ spacing using the design system's responsive layout tokens. It automatically applies
47
+ appropriate margin and padding based on the current breakpoint, making it ideal for
48
+ wrapping page content or major sections.
49
+
50
+ ```tsx
51
+ <Container space="lg">
52
+ <Box>{...}</Box>
53
+ <Box>{...}</Box>
54
+ </Container>
55
+ ```
56
+
57
+ When you need custom spacing, you can override the defaults while maintaining
58
+ the convenience of the component:
59
+
60
+ ```tsx
61
+ <Container
62
+ marginHorizontal="none"
63
+ space="xl"
64
+ >
65
+ {...}
66
+ </Container>
67
+ ```
68
+
39
69
  ## Flex
40
70
 
41
71
  <Canvas of={FlexStories.Playground} sourceState="none" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -52,10 +52,12 @@
52
52
  "storybook": "^9.1.6",
53
53
  "typescript": "^5.7.3",
54
54
  "vite": "^7.1.3",
55
+ "vite-plugin-svgr": "^4.5.0",
55
56
  "vitest": "^3.2.4",
56
57
  "@utilitywarehouse/hearth-fonts": "^0.0.4",
57
58
  "@utilitywarehouse/hearth-react-icons": "^0.7.0",
58
59
  "@utilitywarehouse/hearth-react-native-icons": "^0.7.0",
60
+ "@utilitywarehouse/hearth-svg-assets": "^0.2.0",
59
61
  "@utilitywarehouse/hearth-tokens": "^0.1.3"
60
62
  },
61
63
  "peerDependencies": {