@utilitywarehouse/hearth-react-native 0.2.0 → 0.3.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 (187) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/CHANGELOG.md +22 -0
  4. package/build/components/Badge/Badge.js +101 -14
  5. package/build/components/Badge/Badge.props.d.ts +2 -2
  6. package/build/components/Badge/BadgeIcon.js +5 -79
  7. package/build/components/Badge/BadgeText.js +7 -81
  8. package/build/components/Button/Button.d.ts +2 -2
  9. package/build/components/Button/ButtonGroupRoot.d.ts +3 -2
  10. package/build/components/Button/ButtonGroupRoot.js +9 -0
  11. package/build/components/Card/Card.props.d.ts +2 -2
  12. package/build/components/CurrencyInput/CurrencyInput.d.ts +6 -0
  13. package/build/components/CurrencyInput/CurrencyInput.js +47 -0
  14. package/build/components/CurrencyInput/CurrencyInput.props.d.ts +14 -0
  15. package/build/components/CurrencyInput/CurrencyInput.props.js +1 -0
  16. package/build/components/CurrencyInput/index.d.ts +1 -0
  17. package/build/components/CurrencyInput/index.js +1 -0
  18. package/build/components/DescriptionList/DescriptionList.context.d.ts +6 -0
  19. package/build/components/DescriptionList/DescriptionList.context.js +9 -0
  20. package/build/components/DescriptionList/DescriptionList.d.ts +6 -0
  21. package/build/components/DescriptionList/DescriptionList.js +25 -0
  22. package/build/components/DescriptionList/DescriptionList.props.d.ts +18 -0
  23. package/build/components/DescriptionList/DescriptionList.props.js +1 -0
  24. package/build/components/DescriptionList/DescriptionListItem.d.ts +6 -0
  25. package/build/components/DescriptionList/DescriptionListItem.js +49 -0
  26. package/build/components/DescriptionList/DescriptionListItem.props.d.ts +17 -0
  27. package/build/components/DescriptionList/DescriptionListItem.props.js +1 -0
  28. package/build/components/DescriptionList/index.d.ts +4 -0
  29. package/build/components/DescriptionList/index.js +2 -0
  30. package/build/components/Divider/Divider.js +46 -0
  31. package/build/components/Divider/Divider.props.d.ts +2 -2
  32. package/build/components/Flex/Flex.props.d.ts +3 -2
  33. package/build/components/Grid/Grid.props.d.ts +2 -2
  34. package/build/components/IconContainer/IconContainer.d.ts +5 -0
  35. package/build/components/IconContainer/IconContainer.js +161 -0
  36. package/build/components/IconContainer/IconContainer.props.d.ts +15 -0
  37. package/build/components/IconContainer/IconContainer.props.js +1 -0
  38. package/build/components/IconContainer/index.d.ts +2 -0
  39. package/build/components/IconContainer/index.js +1 -0
  40. package/build/components/Icons/CircleIcon.js +3 -3
  41. package/build/components/Input/Input.js +2 -34
  42. package/build/components/Input/Input.props.d.ts +1 -17
  43. package/build/components/Input/InputField.js +0 -7
  44. package/build/components/Modal/Modal.js +17 -1
  45. package/build/components/SectionHeader/SectionHeader.js +1 -0
  46. package/build/components/Tabs/Tab.d.ts +18 -0
  47. package/build/components/Tabs/Tab.js +74 -0
  48. package/build/components/Tabs/Tab.props.d.ts +14 -0
  49. package/build/components/Tabs/Tab.props.js +1 -0
  50. package/build/components/Tabs/TabPanel.d.ts +3 -0
  51. package/build/components/Tabs/TabPanel.js +34 -0
  52. package/build/components/Tabs/TabPanel.props.d.ts +8 -0
  53. package/build/components/Tabs/TabPanel.props.js +1 -0
  54. package/build/components/Tabs/Tabs.context.d.ts +23 -0
  55. package/build/components/Tabs/Tabs.context.js +8 -0
  56. package/build/components/Tabs/Tabs.d.ts +6 -0
  57. package/build/components/Tabs/Tabs.js +114 -0
  58. package/build/components/Tabs/Tabs.props.d.ts +19 -0
  59. package/build/components/Tabs/Tabs.props.js +1 -0
  60. package/build/components/Tabs/TabsList.d.ts +6 -0
  61. package/build/components/Tabs/TabsList.js +112 -0
  62. package/build/components/Tabs/TabsList.props.d.ts +6 -0
  63. package/build/components/Tabs/TabsList.props.js +1 -0
  64. package/build/components/Tabs/index.d.ts +8 -0
  65. package/build/components/Tabs/index.js +4 -0
  66. package/build/components/index.d.ts +4 -0
  67. package/build/components/index.js +4 -0
  68. package/build/core/themes.d.ts +416 -148
  69. package/build/core/themes.js +57 -1
  70. package/build/tokens/color.d.ts +76 -68
  71. package/build/tokens/color.js +38 -34
  72. package/build/tokens/components/dark/button.d.ts +1 -0
  73. package/build/tokens/components/dark/button.js +1 -0
  74. package/build/tokens/components/dark/checkbox.d.ts +1 -1
  75. package/build/tokens/components/dark/checkbox.js +1 -1
  76. package/build/tokens/components/dark/icon-button.d.ts +3 -3
  77. package/build/tokens/components/dark/icon-button.js +3 -3
  78. package/build/tokens/components/dark/radio.d.ts +1 -1
  79. package/build/tokens/components/dark/radio.js +1 -1
  80. package/build/tokens/components/dark/tabs.d.ts +2 -0
  81. package/build/tokens/components/dark/tabs.js +2 -0
  82. package/build/tokens/components/light/badge.d.ts +1 -1
  83. package/build/tokens/components/light/badge.js +1 -1
  84. package/build/tokens/components/light/button.d.ts +1 -0
  85. package/build/tokens/components/light/button.js +1 -0
  86. package/build/tokens/components/light/checkbox.d.ts +3 -3
  87. package/build/tokens/components/light/checkbox.js +3 -3
  88. package/build/tokens/components/light/icon-button.d.ts +1 -1
  89. package/build/tokens/components/light/icon-button.js +1 -1
  90. package/build/tokens/components/light/radio.d.ts +3 -3
  91. package/build/tokens/components/light/radio.js +3 -3
  92. package/build/tokens/components/light/tabs.d.ts +2 -0
  93. package/build/tokens/components/light/tabs.js +2 -0
  94. package/build/tokens/layout.d.ts +48 -30
  95. package/build/tokens/layout.js +24 -15
  96. package/build/tokens/semantic-dark.d.ts +21 -19
  97. package/build/tokens/semantic-dark.js +21 -19
  98. package/build/tokens/semantic-light.d.ts +17 -15
  99. package/build/tokens/semantic-light.js +17 -15
  100. package/build/types/values.d.ts +2 -1
  101. package/build/utils/formatThousands.d.ts +2 -0
  102. package/build/utils/formatThousands.js +16 -0
  103. package/build/utils/index.d.ts +1 -0
  104. package/build/utils/index.js +1 -0
  105. package/docs/components/AllComponents.web.tsx +97 -8
  106. package/docs/components/NextPrevPage.tsx +11 -3
  107. package/docs/components/UsageWrap.tsx +2 -2
  108. package/docs/heplers/addReactNativePrefix.ts +8 -0
  109. package/docs/heplers/index.ts +1 -0
  110. package/docs/theme-tokens.mdx +42 -0
  111. package/package.json +2 -3
  112. package/src/components/Badge/Badge.docs.mdx +7 -7
  113. package/src/components/Badge/Badge.props.ts +3 -2
  114. package/src/components/Badge/Badge.stories.tsx +81 -92
  115. package/src/components/Badge/Badge.tsx +101 -14
  116. package/src/components/Badge/BadgeIcon.tsx +5 -79
  117. package/src/components/Badge/BadgeText.tsx +7 -81
  118. package/src/components/Button/ButtonGroupRoot.tsx +12 -2
  119. package/src/components/Card/Card.docs.mdx +1 -1
  120. package/src/components/Card/Card.props.ts +2 -2
  121. package/src/components/CurrencyInput/CurrencyInput.docs.mdx +120 -0
  122. package/src/components/CurrencyInput/CurrencyInput.props.ts +19 -0
  123. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +116 -0
  124. package/src/components/CurrencyInput/CurrencyInput.tsx +91 -0
  125. package/src/components/CurrencyInput/index.ts +1 -0
  126. package/src/components/DescriptionList/DescriptionList.context.ts +18 -0
  127. package/src/components/DescriptionList/DescriptionList.docs.mdx +98 -0
  128. package/src/components/DescriptionList/DescriptionList.props.ts +20 -0
  129. package/src/components/DescriptionList/DescriptionList.stories.tsx +154 -0
  130. package/src/components/DescriptionList/DescriptionList.tsx +64 -0
  131. package/src/components/DescriptionList/DescriptionListItem.props.ts +19 -0
  132. package/src/components/DescriptionList/DescriptionListItem.tsx +101 -0
  133. package/src/components/DescriptionList/index.ts +4 -0
  134. package/src/components/Divider/Divider.props.ts +2 -2
  135. package/src/components/Divider/Divider.stories.tsx +3 -3
  136. package/src/components/Divider/Divider.tsx +46 -0
  137. package/src/components/Flex/Flex.docs.mdx +4 -4
  138. package/src/components/Flex/Flex.props.ts +3 -2
  139. package/src/components/Flex/Flex.stories.tsx +1 -1
  140. package/src/components/Grid/Grid.docs.mdx +12 -12
  141. package/src/components/Grid/Grid.props.ts +2 -2
  142. package/src/components/Grid/Grid.stories.tsx +2 -2
  143. package/src/components/IconContainer/IconContainer.docs.mdx +90 -0
  144. package/src/components/IconContainer/IconContainer.props.ts +17 -0
  145. package/src/components/IconContainer/IconContainer.stories.tsx +130 -0
  146. package/src/components/IconContainer/IconContainer.tsx +180 -0
  147. package/src/components/IconContainer/index.tsx +2 -0
  148. package/src/components/Icons/CircleIcon.tsx +9 -11
  149. package/src/components/Input/Input.docs.mdx +3 -3
  150. package/src/components/Input/Input.props.ts +0 -20
  151. package/src/components/Input/Input.stories.tsx +0 -6
  152. package/src/components/Input/Input.tsx +2 -49
  153. package/src/components/Input/InputField.tsx +0 -7
  154. package/src/components/Modal/Modal.tsx +18 -0
  155. package/src/components/SectionHeader/SectionHeader.tsx +1 -0
  156. package/src/components/Tabs/Tab.props.ts +16 -0
  157. package/src/components/Tabs/Tab.tsx +113 -0
  158. package/src/components/Tabs/TabPanel.props.ts +10 -0
  159. package/src/components/Tabs/TabPanel.tsx +46 -0
  160. package/src/components/Tabs/Tabs.context.ts +26 -0
  161. package/src/components/Tabs/Tabs.docs.mdx +214 -0
  162. package/src/components/Tabs/Tabs.props.ts +21 -0
  163. package/src/components/Tabs/Tabs.stories.tsx +270 -0
  164. package/src/components/Tabs/Tabs.tsx +139 -0
  165. package/src/components/Tabs/TabsList.props.ts +8 -0
  166. package/src/components/Tabs/TabsList.tsx +194 -0
  167. package/src/components/Tabs/index.ts +8 -0
  168. package/src/components/index.ts +4 -0
  169. package/src/core/themes.ts +57 -1
  170. package/src/tokens/color.ts +38 -34
  171. package/src/tokens/components/dark/button.ts +1 -0
  172. package/src/tokens/components/dark/checkbox.ts +1 -1
  173. package/src/tokens/components/dark/icon-button.ts +3 -3
  174. package/src/tokens/components/dark/radio.ts +1 -1
  175. package/src/tokens/components/dark/tabs.ts +2 -0
  176. package/src/tokens/components/light/badge.ts +1 -1
  177. package/src/tokens/components/light/button.ts +1 -0
  178. package/src/tokens/components/light/checkbox.ts +3 -3
  179. package/src/tokens/components/light/icon-button.ts +1 -1
  180. package/src/tokens/components/light/radio.ts +3 -3
  181. package/src/tokens/components/light/tabs.ts +2 -0
  182. package/src/tokens/layout.ts +24 -15
  183. package/src/tokens/semantic-dark.ts +21 -19
  184. package/src/tokens/semantic-light.ts +17 -15
  185. package/src/types/values.ts +3 -1
  186. package/src/utils/formatThousands.ts +14 -0
  187. package/src/utils/index.ts +1 -0
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { View } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { SectionHeader } from '../SectionHeader';
6
+ import { DescriptionListContext } from './DescriptionList.context';
7
+ const DescriptionList = ({ direction = 'column', itemHeadingWidth, heading, helperText, linkText, linkHref, linkIcon, linkIconPosition, linkOnPress, linkTarget, linkShowIcon, children, style, ...props }) => {
8
+ styles.useVariants({ direction });
9
+ const value = useMemo(() => ({ direction, itemHeadingWidth }), [direction, itemHeadingWidth]);
10
+ return (_jsx(DescriptionListContext.Provider, { value: value, children: _jsxs(View, { accessibilityRole: "list", ...props, style: [styles.container, style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, linkText: linkText, linkHref: linkHref, linkIcon: linkIcon, linkIconPosition: linkIconPosition, linkOnPress: linkOnPress, linkTarget: linkTarget, linkShowIcon: linkShowIcon })) : null, children] }) }));
11
+ };
12
+ DescriptionList.displayName = 'DescriptionList';
13
+ const styles = StyleSheet.create(theme => ({
14
+ container: {
15
+ width: theme.space.full,
16
+ gap: theme.components.descriptionList.gap,
17
+ variants: {
18
+ direction: {
19
+ row: {},
20
+ column: {},
21
+ },
22
+ },
23
+ },
24
+ }));
25
+ export default DescriptionList;
@@ -0,0 +1,18 @@
1
+ import { ComponentType } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ export interface DescriptionListProps extends ViewProps {
4
+ /** Direction orientation for items */
5
+ direction?: 'row' | 'column';
6
+ /** Override heading/term column width when layout is row (defaults to token) */
7
+ itemHeadingWidth?: number;
8
+ heading?: string;
9
+ helperText?: string;
10
+ linkText?: string;
11
+ linkHref?: string;
12
+ linkIcon?: ComponentType;
13
+ linkIconPosition?: 'left' | 'right';
14
+ linkOnPress?: () => void;
15
+ linkTarget?: '_blank' | '_self' | '_parent' | '_top';
16
+ linkShowIcon?: boolean;
17
+ }
18
+ export default DescriptionListProps;
@@ -0,0 +1,6 @@
1
+ import type DescriptionListItemProps from './DescriptionListItem.props';
2
+ declare const DescriptionListItem: {
3
+ ({ heading, description, headingWidth, linkText, linkHref, linkIcon, linkIconPosition, linkOnPress, linkTarget, linkShowIcon, style, ...props }: DescriptionListItemProps): import("react/jsx-runtime").JSX.Element;
4
+ displayName: string;
5
+ };
6
+ export default DescriptionListItem;
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { useTheme } from '../../hooks';
5
+ import { BodyText } from '../BodyText';
6
+ import { Link } from '../Link';
7
+ import { useDescriptionListContext } from './DescriptionList.context';
8
+ const DescriptionListItem = ({ heading, description, headingWidth, linkText, linkHref, linkIcon, linkIconPosition, linkOnPress, linkTarget, linkShowIcon, style, ...props }) => {
9
+ const { components } = useTheme();
10
+ const { direction, itemHeadingWidth = components.descriptionList.item.row.headingWidth } = useDescriptionListContext();
11
+ styles.useVariants({ direction });
12
+ const headingIsText = typeof heading === 'string' || typeof heading === 'number';
13
+ const descIsText = typeof description === 'string' || typeof description === 'number';
14
+ const combinedLabel = headingIsText && descIsText ? `${heading}: ${description}` : undefined;
15
+ const hideDescendants = !!combinedLabel;
16
+ return (_jsxs(View, { accessibilityRole: "text", accessible: !!combinedLabel, accessibilityLabel: combinedLabel, ...props, style: [styles.item, style], children: [_jsxs(View, { style: styles.textWrap, importantForAccessibility: hideDescendants ? 'no-hide-descendants' : undefined, accessibilityElementsHidden: hideDescendants || undefined, children: [_jsx(View, { style: [direction === 'row' && { width: headingWidth || itemHeadingWidth }], children: headingIsText ? _jsx(BodyText, { style: styles.headingText, children: heading }) : heading }), _jsx(View, { style: styles.descriptionWrapper, children: descIsText ? _jsx(BodyText, { children: description }) : description })] }), linkText ? (_jsx(Link, { href: linkHref, onPress: linkOnPress, target: linkTarget, showIcon: linkShowIcon, icon: linkIcon, iconPosition: linkIconPosition, accessibilityRole: "link", children: linkText })) : null] }));
17
+ };
18
+ DescriptionListItem.displayName = 'DescriptionListItem';
19
+ const styles = StyleSheet.create(theme => ({
20
+ item: {
21
+ width: theme.space.full,
22
+ flexDirection: 'row',
23
+ alignItems: 'flex-start',
24
+ gap: theme.components.descriptionList.item.gap,
25
+ },
26
+ textWrap: {
27
+ flex: 1,
28
+ variants: {
29
+ direction: {
30
+ row: {
31
+ flexDirection: 'row',
32
+ alignItems: 'flex-start',
33
+ gap: theme.components.descriptionList.item.row.gap,
34
+ },
35
+ column: {
36
+ flexDirection: 'column',
37
+ gap: theme.components.descriptionList.item.column.gap,
38
+ },
39
+ },
40
+ },
41
+ },
42
+ headingText: {
43
+ color: theme.color.text.secondary,
44
+ },
45
+ descriptionWrapper: {
46
+ flex: 1,
47
+ },
48
+ }));
49
+ export default DescriptionListItem;
@@ -0,0 +1,17 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ export interface DescriptionListItemProps extends ViewProps {
4
+ /** Heading / label part */
5
+ heading: ReactNode;
6
+ /** Description / value part */
7
+ description: ReactNode;
8
+ headingWidth?: number;
9
+ linkText?: string;
10
+ linkHref?: string;
11
+ linkIcon?: ComponentType;
12
+ linkIconPosition?: 'left' | 'right';
13
+ linkOnPress?: () => void;
14
+ linkTarget?: '_blank' | '_self' | '_parent' | '_top';
15
+ linkShowIcon?: boolean;
16
+ }
17
+ export default DescriptionListItemProps;
@@ -0,0 +1,4 @@
1
+ export { default as DescriptionList } from './DescriptionList';
2
+ export type { default as DescriptionListProps } from './DescriptionList.props';
3
+ export { default as DescriptionListItem } from './DescriptionListItem';
4
+ export type { default as DescriptionListItemProps } from './DescriptionListItem.props';
@@ -0,0 +1,2 @@
1
+ export { default as DescriptionList } from './DescriptionList';
2
+ export { default as DescriptionListItem } from './DescriptionListItem';
@@ -28,11 +28,13 @@ const styles = StyleSheet.create(theme => ({
28
28
  },
29
29
  space: {
30
30
  none: {},
31
+ '2xs': {},
31
32
  xs: {},
32
33
  sm: {},
33
34
  md: {},
34
35
  lg: {},
35
36
  xl: {},
37
+ '2xl': {},
36
38
  },
37
39
  flexItem: {
38
40
  true: {
@@ -48,6 +50,17 @@ const styles = StyleSheet.create(theme => ({
48
50
  marginVertical: 0,
49
51
  },
50
52
  },
53
+ {
54
+ orientation: 'horizontal',
55
+ space: '2xs',
56
+ styles: {
57
+ marginVertical: {
58
+ base: theme.layout.mobile.spacing['2xs'],
59
+ md: theme.layout.tablet.spacing['2xs'],
60
+ lg: theme.layout.desktop.spacing['2xs'],
61
+ },
62
+ },
63
+ },
51
64
  {
52
65
  orientation: 'horizontal',
53
66
  space: 'xs',
@@ -103,6 +116,17 @@ const styles = StyleSheet.create(theme => ({
103
116
  },
104
117
  },
105
118
  },
119
+ {
120
+ orientation: 'horizontal',
121
+ space: '2xl',
122
+ styles: {
123
+ marginVertical: {
124
+ base: theme.layout.mobile.spacing['2xl'],
125
+ md: theme.layout.tablet.spacing['2xl'],
126
+ lg: theme.layout.desktop.spacing['2xl'],
127
+ },
128
+ },
129
+ },
106
130
  {
107
131
  orientation: 'vertical',
108
132
  space: 'none',
@@ -110,6 +134,17 @@ const styles = StyleSheet.create(theme => ({
110
134
  marginHorizontal: 0,
111
135
  },
112
136
  },
137
+ {
138
+ orientation: 'vertical',
139
+ space: '2xs',
140
+ styles: {
141
+ marginHorizontal: {
142
+ base: theme.layout.mobile.spacing['2xs'],
143
+ md: theme.layout.tablet.spacing['2xs'],
144
+ lg: theme.layout.desktop.spacing['2xs'],
145
+ },
146
+ },
147
+ },
113
148
  {
114
149
  orientation: 'vertical',
115
150
  space: 'xs',
@@ -165,6 +200,17 @@ const styles = StyleSheet.create(theme => ({
165
200
  },
166
201
  },
167
202
  },
203
+ {
204
+ orientation: 'vertical',
205
+ space: '2xl',
206
+ styles: {
207
+ marginHorizontal: {
208
+ base: theme.layout.mobile.spacing['2xl'],
209
+ md: theme.layout.tablet.spacing['2xl'],
210
+ lg: theme.layout.desktop.spacing['2xl'],
211
+ },
212
+ },
213
+ },
168
214
  ],
169
215
  },
170
216
  extraStyles: (color, width, height) => ({
@@ -1,8 +1,8 @@
1
1
  import type { DimensionValue, ViewProps } from 'react-native';
2
- import type { ColorValue } from '../../types';
2
+ import type { ColorValue, SpacingValues } from '../../types';
3
3
  interface DividerProps extends Omit<ViewProps, 'children'> {
4
4
  color?: ColorValue;
5
- space?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
5
+ space?: SpacingValues;
6
6
  orientation?: 'horizontal' | 'vertical';
7
7
  height?: DimensionValue;
8
8
  width?: DimensionValue;
@@ -1,9 +1,10 @@
1
- import type { ViewProps, ViewStyle, FlexAlignType } from 'react-native';
1
+ import type { FlexAlignType, ViewProps, ViewStyle } from 'react-native';
2
+ import { SpacingValues } from '../../types';
2
3
  interface FlexProps extends ViewProps {
3
4
  direction?: ViewStyle['flexDirection'];
4
5
  align?: FlexAlignType;
5
6
  justify?: ViewStyle['justifyContent'];
6
7
  wrap?: ViewStyle['flexWrap'];
7
- space?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
8
+ space?: SpacingValues;
8
9
  }
9
10
  export default FlexProps;
@@ -1,6 +1,6 @@
1
1
  import { StyleProp, ViewProps, ViewStyle } from 'react-native';
2
2
  import { UnistylesBreakpoints } from 'react-native-unistyles';
3
- import { SpaceValue } from '../../types';
3
+ import { SpaceValue, SpacingValues } from '../../types';
4
4
  export type GridColumns = {
5
5
  [key in keyof UnistylesBreakpoints]?: number;
6
6
  };
@@ -13,7 +13,7 @@ export interface GridProps extends ViewProps {
13
13
  /**
14
14
  * Spacing between grid items (applies to both rows and columns)
15
15
  */
16
- space?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
16
+ space?: SpacingValues;
17
17
  /**
18
18
  * Gap between items (overrides spacing if provided)
19
19
  */
@@ -0,0 +1,5 @@
1
+ import type IconContainerProps from './IconContainer.props';
2
+ declare const IconContainer: import("react").ForwardRefExoticComponent<Partial<IconContainerProps> & {
3
+ uniProps?: import("react-native-unistyles/lib/typescript/src/core/withUnistyles/types").Mappings<IconContainerProps> | undefined;
4
+ } & import("react").RefAttributes<never>>;
5
+ export default IconContainer;
@@ -0,0 +1,161 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View } from 'react-native';
3
+ import { StyleSheet, withUnistyles } from 'react-native-unistyles';
4
+ import { Icon } from '../Icon';
5
+ const IconContainer = withUnistyles(({ icon: IconComp, size = 'md', radiusNone = false, variant = 'subtle', color = 'pig', style, ...props }) => {
6
+ styles.useVariants({ size, radiusNone, variant, color });
7
+ return (_jsx(View, { style: [styles.container, style], ...props, children: IconComp ? _jsx(Icon, { as: IconComp, style: styles.icon }) : null }));
8
+ });
9
+ IconContainer.displayName = 'IconContainer';
10
+ const styles = StyleSheet.create(theme => ({
11
+ container: {
12
+ alignItems: 'center',
13
+ justifyContent: 'center',
14
+ overflow: 'hidden',
15
+ variants: {
16
+ size: {
17
+ sm: {
18
+ width: theme.components.iconContainer.sm.width,
19
+ height: theme.components.iconContainer.sm.height,
20
+ padding: theme.components.iconContainer.sm.padding,
21
+ borderRadius: theme.components.iconContainer.sm.borderRadiusRounded,
22
+ },
23
+ md: {
24
+ width: theme.components.iconContainer.md.width,
25
+ height: theme.components.iconContainer.md.height,
26
+ padding: theme.components.iconContainer.md.padding,
27
+ borderRadius: theme.components.iconContainer.md.borderRadiusRounded,
28
+ },
29
+ lg: {
30
+ width: theme.components.iconContainer.lg.width,
31
+ height: theme.components.iconContainer.lg.height,
32
+ padding: theme.components.iconContainer.lg.padding,
33
+ borderRadius: theme.components.iconContainer.lg.borderRadiusRounded,
34
+ },
35
+ },
36
+ radiusNone: {
37
+ true: {
38
+ borderRadius: 0,
39
+ },
40
+ false: {},
41
+ },
42
+ variant: {
43
+ subtle: {},
44
+ emphasis: {},
45
+ },
46
+ color: {
47
+ pig: {},
48
+ energy: {},
49
+ broadband: {},
50
+ mobile: {},
51
+ insurance: {},
52
+ cashback: {},
53
+ highlight: {},
54
+ },
55
+ },
56
+ compoundVariants: [
57
+ {
58
+ variant: 'emphasis',
59
+ color: 'pig',
60
+ styles: {
61
+ backgroundColor: theme.color.surface.pig.default,
62
+ },
63
+ },
64
+ {
65
+ variant: 'subtle',
66
+ color: 'pig',
67
+ styles: {
68
+ backgroundColor: theme.color.surface.pig.subtle,
69
+ },
70
+ },
71
+ {
72
+ variant: 'emphasis',
73
+ color: 'energy',
74
+ styles: {
75
+ backgroundColor: theme.color.surface.energy.default,
76
+ },
77
+ },
78
+ {
79
+ variant: 'subtle',
80
+ color: 'energy',
81
+ styles: {
82
+ backgroundColor: theme.color.surface.energy.subtle,
83
+ },
84
+ },
85
+ {
86
+ variant: 'emphasis',
87
+ color: 'broadband',
88
+ styles: {
89
+ backgroundColor: theme.color.surface.broadband.default,
90
+ },
91
+ },
92
+ {
93
+ variant: 'subtle',
94
+ color: 'broadband',
95
+ styles: {
96
+ backgroundColor: theme.color.surface.broadband.subtle,
97
+ },
98
+ },
99
+ {
100
+ variant: 'emphasis',
101
+ color: 'mobile',
102
+ styles: {
103
+ backgroundColor: theme.color.surface.mobile.default,
104
+ },
105
+ },
106
+ {
107
+ variant: 'subtle',
108
+ color: 'mobile',
109
+ styles: {
110
+ backgroundColor: theme.color.surface.mobile.subtle,
111
+ },
112
+ },
113
+ {
114
+ variant: 'emphasis',
115
+ color: 'insurance',
116
+ styles: {
117
+ backgroundColor: theme.color.surface.insurance.default,
118
+ },
119
+ },
120
+ {
121
+ variant: 'subtle',
122
+ color: 'insurance',
123
+ styles: {
124
+ backgroundColor: theme.color.surface.insurance.subtle,
125
+ },
126
+ },
127
+ {
128
+ variant: 'emphasis',
129
+ color: 'cashback',
130
+ styles: {
131
+ backgroundColor: theme.color.surface.cashback.default,
132
+ },
133
+ },
134
+ {
135
+ variant: 'subtle',
136
+ color: 'cashback',
137
+ styles: {
138
+ backgroundColor: theme.color.surface.cashback.subtle,
139
+ },
140
+ },
141
+ {
142
+ variant: 'emphasis',
143
+ color: 'highlight',
144
+ styles: {
145
+ backgroundColor: theme.color.surface.highlight.default,
146
+ },
147
+ },
148
+ {
149
+ variant: 'subtle',
150
+ color: 'highlight',
151
+ styles: {
152
+ backgroundColor: theme.color.surface.highlight.subtle,
153
+ },
154
+ },
155
+ ],
156
+ },
157
+ icon: {
158
+ color: theme.color.icon.primary,
159
+ },
160
+ }));
161
+ export default IconContainer;
@@ -0,0 +1,15 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ export interface IconContainerProps extends ViewProps {
4
+ /** Icon component to render inside the container */
5
+ icon: ComponentType;
6
+ /** Size of the container */
7
+ size?: 'sm' | 'md' | 'lg';
8
+ /** If true, removes border radius from the container */
9
+ radiusNone?: boolean;
10
+ /** Background style of the container */
11
+ variant?: 'subtle' | 'emphasis';
12
+ /** Background color token of the container */
13
+ color?: 'pig' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'highlight';
14
+ }
15
+ export default IconContainerProps;
@@ -0,0 +1,2 @@
1
+ export { default as IconContainer } from './IconContainer';
2
+ export type { default as IconContainerProps } from './IconContainer.props';
@@ -0,0 +1 @@
1
+ export { default as IconContainer } from './IconContainer';
@@ -1,10 +1,10 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createIcon } from '@gluestack-ui/icon';
3
- import { Svg, Path } from 'react-native-svg';
3
+ import { Path, Svg } from 'react-native-svg';
4
4
  const CircleIcon = createIcon({
5
5
  Root: Svg,
6
6
  viewBox: '0 0 24 24',
7
- path: (_jsx(_Fragment, { children: _jsx(Path, { d: "M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })),
7
+ path: (_jsx(Path, { d: "M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })),
8
8
  });
9
9
  CircleIcon.displayName = 'CircleIcon';
10
10
  export default CircleIcon;
@@ -1,10 +1,8 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { createInput } from '@gluestack-ui/input';
3
3
  import { useState } from 'react';
4
- import { CalendarMediumIcon, CloseSmallIcon, EyeOffSmallIcon, EyeSmallIcon, SearchMediumIcon, } from '@utilitywarehouse/hearth-react-native-icons';
5
- import { Platform } from 'react-native';
4
+ import { CloseSmallIcon, EyeOffSmallIcon, EyeSmallIcon, SearchMediumIcon, } from '@utilitywarehouse/hearth-react-native-icons';
6
5
  import { useTheme } from '../../hooks';
7
- import { DetailText } from '../DetailText';
8
6
  import { useFormFieldContext } from '../FormField';
9
7
  import { Spinner } from '../Spinner';
10
8
  import { UnstyledIconButton } from '../UnstyledIconButton';
@@ -28,24 +26,6 @@ const Input = ({ validationStatus = 'initial', children, disabled, focused, read
28
26
  const isRequired = formFieldContext?.required ?? required;
29
27
  const [fieldType, setFieldType] = useState(type === 'password' ? 'password' : 'text');
30
28
  const { color } = useTheme();
31
- const defaultFornat = (() => {
32
- if (type === 'currency') {
33
- return '0.00';
34
- }
35
- if (type === 'date') {
36
- return 'DD/MM/YYYY';
37
- }
38
- return;
39
- })();
40
- const getPlaceholder = (() => {
41
- if (type === 'currency') {
42
- return props.placeholder ?? format ?? defaultFornat;
43
- }
44
- if (type === 'date') {
45
- return props.placeholder ?? format ?? defaultFornat;
46
- }
47
- return props.placeholder;
48
- })();
49
29
  const shouldShowPasswordToggle = type === 'password' && showPasswordToggle;
50
30
  const shouldShowClear = clearable && !!props?.value;
51
31
  const toggleFieldType = () => {
@@ -57,25 +37,13 @@ const Input = ({ validationStatus = 'initial', children, disabled, focused, read
57
37
  }
58
38
  return leadingIcon;
59
39
  })();
60
- const trailingIconComponent = (() => {
61
- if (type === 'date') {
62
- return CalendarMediumIcon;
63
- }
64
- return trailingIcon;
65
- })();
66
40
  const getInputMode = (() => {
67
- if (type === 'currency') {
68
- return 'decimal';
69
- }
70
41
  if (type === 'search') {
71
42
  return 'search';
72
43
  }
73
44
  return undefined;
74
45
  })();
75
- return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), type === 'currency' && (_jsx(InputSlot, { children: _jsx(DetailText, { size: "4xl", style: {
76
- // todo: fix this
77
- ...(Platform.OS === 'ios' && { lineHeight: 46 }),
78
- }, children: "\u00A3" }) })), _jsx(InputField, { type: fieldType, inputMode: getInputMode, inBottomSheet: inBottomSheet, ...props, placeholder: getPlaceholder }), shouldShowClear && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: onClear, icon: CloseSmallIcon }) })), loading && (_jsx(InputSlot, { children: _jsx(Spinner, { size: "xs", color: color.icon.primary }) })), shouldShowPasswordToggle && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: toggleFieldType, icon: fieldType === 'password' ? EyeSmallIcon : EyeOffSmallIcon }) })), !!trailingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: trailingIconComponent }) }))] })) }));
46
+ return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), _jsx(InputField, { type: fieldType, inputMode: getInputMode, inBottomSheet: inBottomSheet, ...props }), shouldShowClear && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: onClear, icon: CloseSmallIcon }) })), loading && (_jsx(InputSlot, { children: _jsx(Spinner, { size: "xs", color: color.icon.primary }) })), shouldShowPasswordToggle && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: toggleFieldType, icon: fieldType === 'password' ? EyeSmallIcon : EyeOffSmallIcon }) })), !!trailingIcon && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: trailingIcon }) }))] })) }));
79
47
  };
80
48
  Input.displayName = 'Input';
81
49
  export default Input;
@@ -60,22 +60,6 @@ interface PasswordInputSpecificProps extends InputWithoutChildrenBaseProps {
60
60
  clearable?: never;
61
61
  onClear?: never;
62
62
  }
63
- interface DateInputSpecificProps extends InputWithoutChildrenBaseProps {
64
- type: 'date';
65
- format?: string;
66
- showPasswordToggle?: never;
67
- loading?: never;
68
- clearable?: never;
69
- onClear?: never;
70
- }
71
- interface CurrencyInputSpecificProps extends InputWithoutChildrenBaseProps {
72
- type: 'currency';
73
- format?: string;
74
- showPasswordToggle?: never;
75
- loading?: never;
76
- clearable?: never;
77
- onClear?: never;
78
- }
79
63
  interface SearchInputSpecificProps extends InputWithoutChildrenBaseProps {
80
64
  type: 'search';
81
65
  loading?: boolean;
@@ -84,7 +68,7 @@ interface SearchInputSpecificProps extends InputWithoutChildrenBaseProps {
84
68
  showPasswordToggle?: never;
85
69
  format?: never;
86
70
  }
87
- export type InputWithoutChildrenProps = TextInputSpecificProps | PasswordInputSpecificProps | DateInputSpecificProps | CurrencyInputSpecificProps | SearchInputSpecificProps;
71
+ export type InputWithoutChildrenProps = TextInputSpecificProps | PasswordInputSpecificProps | SearchInputSpecificProps;
88
72
  /**
89
73
  * Props for the Input component.
90
74
  * This is a discriminated union type where the 'type' property
@@ -34,13 +34,6 @@ const styles = StyleSheet.create(theme => ({
34
34
  text: {},
35
35
  password: {},
36
36
  search: {},
37
- currency: {
38
- fontSize: theme.typography.mobile.detailText['4xl'].fontSize,
39
- fontFamily: theme.typography.mobile.detailText.fontFamily,
40
- fontWeight: theme.typography.mobile.detailText.fontWeight,
41
- paddingTop: 0,
42
- paddingBottom: 0,
43
- },
44
37
  date: {},
45
38
  },
46
39
  },
@@ -97,13 +97,21 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
97
97
  bottomSheetModalRef.current?.dismiss();
98
98
  }
99
99
  };
100
+ styles.useVariants({ loading });
100
101
  const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg" }), _jsx(Heading, { size: "lg", textAlign: "center", children: "Loading..." })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, children: heading })) : null, description && !image ? _jsx(BodyText, { accessible: true, children: description }) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [_jsx(Image, { style: styles.image, ...image }), _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, children: description })) : null] })] })) : null, children, _jsxs(View, { style: styles.footer, children: [onPressPrimaryButton && primaryButtonText ? (_jsx(Button, { onPress: handlePrimaryButtonPress, text: primaryButtonText, ...primaryButtonProps, variant: primaryButtonProps?.variant ?? 'solid', colorScheme: primaryButtonProps?.colorScheme ?? 'highlight' })) : null, onPressSecondaryButton && secondaryButtonText ? (_jsx(Button, { onPress: handleSecondaryButtonPress, text: secondaryButtonText, ...secondaryButtonProps, variant: secondaryButtonProps?.variant ?? 'outline', colorScheme: secondaryButtonProps?.colorScheme ?? 'functional' })) : null] })] })) }));
101
- return fullscreen ? (_jsxs(View, { style: { flex: 1, backgroundColor: theme.color.background.primary }, children: [Platform.OS === 'android' ? (_jsx(Animated.View, { style: [styles.androidContainer, animatedBackgroundStyle], children: _jsx(Animated.View, { style: [styles.pretendContent, animatedPretendContentStyle] }) })) : null, _jsx(Animated.View, { style: [styles.fullscreenContainer, Platform.OS === 'android' && animatedFullscreenStyle], children: _jsx(View, { style: styles.fullscreenContent, children: content }) })] })) : (_jsx(BottomSheetModal, { ref: bottomSheetModalRef, enableDynamicSizing: true, snapPoints: image ? ['90%'] : props.snapPoints, showHandle: typeof loading !== 'undefined' && loading ? false : props.showHandle, accessible: false, ...props, onChange: handleChange, children: _jsx(BottomSheetScrollView, { contentContainerStyle: styles.container, ref: scrollViewRef, children: content }) }));
102
+ return fullscreen ? (_jsxs(View, { style: { flex: 1, backgroundColor: theme.color.background.primary }, children: [Platform.OS === 'android' ? (_jsx(Animated.View, { style: [styles.androidContainer, animatedBackgroundStyle], children: _jsx(Animated.View, { style: [styles.pretendContent, animatedPretendContentStyle] }) })) : null, _jsx(Animated.View, { style: [styles.fullscreenContainer, Platform.OS === 'android' && animatedFullscreenStyle], children: _jsx(View, { style: styles.fullscreenContent, children: content }) })] })) : (_jsxs(BottomSheetModal, { ref: bottomSheetModalRef, enableDynamicSizing: true, snapPoints: image ? ['90%'] : props.snapPoints, showHandle: typeof loading !== 'undefined' && loading ? false : props.showHandle, accessible: false, ...props, onChange: handleChange, children: [loading ? _jsx(View, { style: styles.loadingTop }) : null, _jsx(BottomSheetScrollView, { contentContainerStyle: styles.container, ref: scrollViewRef, children: content })] }));
102
103
  };
103
104
  const styles = StyleSheet.create((theme, rt) => ({
104
105
  container: {
105
106
  flex: 1,
106
107
  gap: theme.components.dialog.gap,
108
+ variants: {
109
+ loading: {
110
+ true: {
111
+ paddingTop: 0,
112
+ },
113
+ },
114
+ },
107
115
  },
108
116
  header: {
109
117
  flexDirection: 'row',
@@ -125,7 +133,15 @@ const styles = StyleSheet.create((theme, rt) => ({
125
133
  textContent: {
126
134
  gap: theme.components.dialog.content.gap,
127
135
  },
136
+ loadingTop: {
137
+ borderTopLeftRadius: theme.components.dialog.borderRadius,
138
+ borderTopRightRadius: theme.components.dialog.borderRadius,
139
+ height: 16,
140
+ backgroundColor: theme.color.surface.neutral.strong,
141
+ },
128
142
  loadingContainer: {
143
+ borderTopLeftRadius: theme.components.dialog.borderRadius,
144
+ borderTopRightRadius: theme.components.dialog.borderRadius,
129
145
  flex: 1,
130
146
  alignItems: 'center',
131
147
  justifyContent: 'center',
@@ -14,6 +14,7 @@ const styles = StyleSheet.create(theme => ({
14
14
  flexDirection: 'row',
15
15
  gap: theme.components.sectionHeader.gap,
16
16
  alignItems: 'flex-start',
17
+ width: '100%',
17
18
  },
18
19
  }));
19
20
  export default SectionHeader;