@utilitywarehouse/hearth-react-native 0.8.1 → 0.9.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 (135) hide show
  1. package/.storybook/preview.tsx +1 -0
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/CHANGELOG.md +24 -0
  5. package/build/components/Banner/Banner.js +49 -10
  6. package/build/components/Banner/Banner.props.d.ts +4 -9
  7. package/build/components/BottomSheet/BottomSheetHandle.js +8 -0
  8. package/build/components/Card/Card.props.d.ts +1 -0
  9. package/build/components/Card/CardRoot.d.ts +1 -1
  10. package/build/components/Card/CardRoot.js +28 -1
  11. package/build/components/HighlightBanner/HighlightBanner.props.d.ts +1 -1
  12. package/build/components/List/List.js +1 -1
  13. package/build/components/List/ListAction/ListActionTrailingIcon.js +2 -2
  14. package/build/components/Menu/Menu.context.d.ts +5 -0
  15. package/build/components/Menu/Menu.context.js +9 -0
  16. package/build/components/Menu/Menu.d.ts +4 -0
  17. package/build/components/Menu/Menu.js +25 -0
  18. package/build/components/Menu/Menu.props.d.ts +21 -0
  19. package/build/components/Menu/Menu.props.js +1 -0
  20. package/build/components/Menu/MenuItem.d.ts +18 -0
  21. package/build/components/Menu/MenuItem.js +115 -0
  22. package/build/components/Menu/MenuItem.props.d.ts +27 -0
  23. package/build/components/Menu/MenuItem.props.js +1 -0
  24. package/build/components/Menu/MenuTrigger.d.ts +9 -0
  25. package/build/components/Menu/MenuTrigger.js +11 -0
  26. package/build/components/Menu/MenuTrigger.props.d.ts +12 -0
  27. package/build/components/Menu/MenuTrigger.props.js +1 -0
  28. package/build/components/Menu/index.d.ts +7 -0
  29. package/build/components/Menu/index.js +4 -0
  30. package/build/components/Modal/Modal.d.ts +1 -1
  31. package/build/components/Modal/Modal.js +32 -30
  32. package/build/components/Modal/Modal.props.d.ts +1 -0
  33. package/build/components/Modal/Modal.web.d.ts +1 -1
  34. package/build/components/Modal/Modal.web.js +25 -25
  35. package/build/components/RadioCard/RadioCardGroup.context.d.ts +12 -0
  36. package/build/components/RadioCard/RadioCardGroup.context.js +3 -0
  37. package/build/components/RadioCard/RadioCardGroup.js +15 -10
  38. package/build/components/RadioCard/RadioCardLabel.d.ts +1 -1
  39. package/build/components/RadioCard/RadioCardLabel.js +7 -1
  40. package/build/components/RadioCard/RadioCardRoot.js +13 -0
  41. package/build/components/index.d.ts +1 -0
  42. package/build/components/index.js +1 -0
  43. package/build/core/themes.d.ts +40 -0
  44. package/build/core/themes.js +20 -0
  45. package/build/tokens/components/dark/index.d.ts +3 -1
  46. package/build/tokens/components/dark/index.js +3 -1
  47. package/build/tokens/components/dark/input.d.ts +3 -0
  48. package/build/tokens/components/dark/input.js +3 -0
  49. package/build/tokens/components/dark/modal.d.ts +7 -4
  50. package/build/tokens/components/dark/modal.js +7 -4
  51. package/build/tokens/components/dark/rating.d.ts +8 -0
  52. package/build/tokens/components/dark/rating.js +7 -0
  53. package/build/tokens/components/dark/table.d.ts +0 -3
  54. package/build/tokens/components/dark/table.js +0 -3
  55. package/build/tokens/components/dark/time-picker.d.ts +29 -0
  56. package/build/tokens/components/dark/time-picker.js +28 -0
  57. package/build/tokens/components/dark/timeline.d.ts +27 -0
  58. package/build/tokens/components/dark/timeline.js +26 -0
  59. package/build/tokens/components/light/index.d.ts +3 -1
  60. package/build/tokens/components/light/index.js +3 -1
  61. package/build/tokens/components/light/input.d.ts +3 -0
  62. package/build/tokens/components/light/input.js +3 -0
  63. package/build/tokens/components/light/modal.d.ts +7 -4
  64. package/build/tokens/components/light/modal.js +7 -4
  65. package/build/tokens/components/light/rating.d.ts +8 -0
  66. package/build/tokens/components/light/rating.js +7 -0
  67. package/build/tokens/components/light/table.d.ts +0 -3
  68. package/build/tokens/components/light/table.js +0 -3
  69. package/build/tokens/components/light/time-picker.d.ts +29 -0
  70. package/build/tokens/components/light/time-picker.js +28 -0
  71. package/build/tokens/components/light/timeline.d.ts +27 -0
  72. package/build/tokens/components/light/timeline.js +26 -0
  73. package/docs/adding-shadows.mdx +43 -0
  74. package/docs/components/AllComponents.web.tsx +33 -0
  75. package/docs/components/BackToTopButton.tsx +1 -1
  76. package/package.json +3 -3
  77. package/src/components/Banner/Banner.docs.mdx +20 -11
  78. package/src/components/Banner/Banner.props.ts +4 -9
  79. package/src/components/Banner/Banner.stories.tsx +17 -4
  80. package/src/components/Banner/Banner.tsx +92 -37
  81. package/src/components/BottomSheet/BottomSheetHandle.tsx +12 -0
  82. package/src/components/Card/Card.docs.mdx +20 -1
  83. package/src/components/Card/Card.props.ts +9 -0
  84. package/src/components/Card/Card.stories.tsx +39 -0
  85. package/src/components/Card/CardRoot.tsx +29 -0
  86. package/src/components/Checkbox/CheckboxGroup.stories.tsx +19 -1
  87. package/src/components/DatePickerInput/DatePickerInput.docs.mdx +1 -1
  88. package/src/components/HighlightBanner/HighlightBanner.docs.mdx +1 -1
  89. package/src/components/HighlightBanner/HighlightBanner.props.ts +1 -0
  90. package/src/components/HighlightBanner/HighlightBanner.stories.tsx +15 -1
  91. package/src/components/List/List.tsx +5 -3
  92. package/src/components/List/ListAction/ListActionTrailingIcon.tsx +2 -2
  93. package/src/components/Menu/Menu.context.ts +15 -0
  94. package/src/components/Menu/Menu.docs.mdx +158 -0
  95. package/src/components/Menu/Menu.props.ts +24 -0
  96. package/src/components/Menu/Menu.stories.tsx +292 -0
  97. package/src/components/Menu/Menu.tsx +54 -0
  98. package/src/components/Menu/MenuItem.props.ts +29 -0
  99. package/src/components/Menu/MenuItem.tsx +145 -0
  100. package/src/components/Menu/MenuTrigger.props.ts +14 -0
  101. package/src/components/Menu/MenuTrigger.tsx +20 -0
  102. package/src/components/Menu/index.ts +7 -0
  103. package/src/components/Modal/Modal.docs.mdx +34 -5
  104. package/src/components/Modal/Modal.props.ts +1 -0
  105. package/src/components/Modal/Modal.stories.tsx +46 -0
  106. package/src/components/Modal/Modal.tsx +37 -33
  107. package/src/components/Modal/Modal.web.tsx +27 -27
  108. package/src/components/Radio/RadioGroup.stories.tsx +18 -0
  109. package/src/components/RadioCard/RadioCardGroup.context.ts +16 -0
  110. package/src/components/RadioCard/RadioCardGroup.stories.tsx +24 -0
  111. package/src/components/RadioCard/RadioCardGroup.tsx +28 -19
  112. package/src/components/RadioCard/RadioCardLabel.tsx +12 -1
  113. package/src/components/RadioCard/RadioCardRoot.tsx +15 -0
  114. package/src/components/index.ts +1 -0
  115. package/src/core/themes.ts +20 -0
  116. package/src/tokens/components/dark/index.ts +3 -1
  117. package/src/tokens/components/dark/input.ts +3 -0
  118. package/src/tokens/components/dark/modal.ts +7 -4
  119. package/src/tokens/components/dark/rating.ts +8 -0
  120. package/src/tokens/components/dark/table.ts +0 -3
  121. package/src/tokens/components/dark/time-picker.ts +29 -0
  122. package/src/tokens/components/dark/timeline.ts +27 -0
  123. package/src/tokens/components/light/index.ts +3 -1
  124. package/src/tokens/components/light/input.ts +3 -0
  125. package/src/tokens/components/light/modal.ts +7 -4
  126. package/src/tokens/components/light/rating.ts +8 -0
  127. package/src/tokens/components/light/table.ts +0 -3
  128. package/src/tokens/components/light/time-picker.ts +29 -0
  129. package/src/tokens/components/light/timeline.ts +27 -0
  130. package/build/tokens/components/dark/dialog.d.ts +0 -25
  131. package/build/tokens/components/dark/dialog.js +0 -24
  132. package/build/tokens/components/light/dialog.d.ts +0 -25
  133. package/build/tokens/components/light/dialog.js +0 -24
  134. package/src/tokens/components/dark/dialog.ts +0 -25
  135. package/src/tokens/components/light/dialog.ts +0 -25
@@ -72,6 +72,7 @@ const preview = {
72
72
  'Theme Tokens',
73
73
  'Hooks',
74
74
  'Layout Components',
75
+ 'Guides',
75
76
  'All Components',
76
77
  'Primitives',
77
78
  'Typography',
@@ -1,4 +1,4 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.8.1 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.9.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.8.1 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.9.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,29 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#658](https://github.com/utilitywarehouse/hearth/pull/658) [`2ac2366`](https://github.com/utilitywarehouse/hearth/commit/2ac2366aaa7f3b253fd9336664a73a64f1ab91a5) Thanks [@jordmccord](https://github.com/jordmccord)! - Adds `Menu` component
8
+
9
+ - [#656](https://github.com/utilitywarehouse/hearth/pull/656) [`a01a49a`](https://github.com/utilitywarehouse/hearth/commit/a01a49a49ec1dd3c04684ce010281030d45c77a1) Thanks [@jordmccord](https://github.com/jordmccord)! - Adds `fullscreen` and `inNavModal` props to `Modal`
10
+
11
+ ## 0.8.2
12
+
13
+ ### Patch Changes
14
+
15
+ - [#652](https://github.com/utilitywarehouse/hearth/pull/652) [`5119703`](https://github.com/utilitywarehouse/hearth/commit/5119703a31f663cc8c0a8bb2c6ba5b10f9bf72d6) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `RadioCard` label wrapping issue
16
+
17
+ - [#648](https://github.com/utilitywarehouse/hearth/pull/648) [`c90ea5c`](https://github.com/utilitywarehouse/hearth/commit/c90ea5ce165f27ccfc9774ec58ac642d02b349d1) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `ListAction` icon size
18
+
19
+ - [#648](https://github.com/utilitywarehouse/hearth/pull/648) [`c90ea5c`](https://github.com/utilitywarehouse/hearth/commit/c90ea5ce165f27ccfc9774ec58ac642d02b349d1) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `Banner` text gap size
20
+
21
+ - [#651](https://github.com/utilitywarehouse/hearth/pull/651) [`4ee77b7`](https://github.com/utilitywarehouse/hearth/commit/4ee77b75e58ac4abbeba375ecb367d8899c7f1a0) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `Banner` image and height issue
22
+
23
+ - [#649](https://github.com/utilitywarehouse/hearth/pull/649) [`7374535`](https://github.com/utilitywarehouse/hearth/commit/737453598ad5e885b35b5fcd2e4c4ccff4910c43) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `List` to only show `Card` container if it has children
24
+
25
+ - [#648](https://github.com/utilitywarehouse/hearth/pull/648) [`c90ea5c`](https://github.com/utilitywarehouse/hearth/commit/c90ea5ce165f27ccfc9774ec58ac642d02b349d1) Thanks [@jordmccord](https://github.com/jordmccord)! - Adds `shadowColor` prop to `Card` and exposes helpers in theme
26
+
3
27
  ## 0.8.1
4
28
 
5
29
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ChevronRightSmallIcon, CloseSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
3
- import { Pressable, View } from 'react-native';
3
+ import { Image, Pressable, View } from 'react-native';
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
5
  import { BodyText } from '../BodyText';
6
6
  import { Card } from '../Card';
@@ -8,6 +8,9 @@ import { Heading } from '../Heading';
8
8
  import { IconContainer } from '../IconContainer';
9
9
  import { ThemedImage } from '../ThemedImage';
10
10
  import { UnstyledIconButton } from '../UnstyledIconButton';
11
+ const isThemedImageProps = (props) => {
12
+ return 'light' in props && 'dark' in props;
13
+ };
11
14
  const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md', iconContainerColor = 'pig', illustration, image, heading, description, direction = 'horizontal', link, button, onPress, onClose, variant = 'subtle', colorScheme = 'pig', style, ...props }) => {
12
15
  const hasIllustration = Boolean(illustration);
13
16
  styles.useVariants({ direction, hasIllustration });
@@ -16,10 +19,16 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
16
19
  return (_jsx(IconContainer, { icon: icon, variant: iconContainerVariant, size: iconContainerSize, color: iconContainerColor, style: styles.media }));
17
20
  }
18
21
  if (illustration) {
19
- return (_jsx(ThemedImage, { light: illustration.light, dark: illustration.dark, style: styles.image, accessible: true, accessibilityLabel: heading }));
22
+ if (isThemedImageProps(illustration)) {
23
+ return (_jsx(ThemedImage, { ...illustration, resizeMode: "cover", style: [styles.media, styles.imageWrapper, illustration.style] }));
24
+ }
25
+ return (_jsx(Image, { ...illustration, resizeMode: "cover", style: [styles.media, styles.imageWrapper, illustration.style] }));
20
26
  }
21
27
  if (image) {
22
- return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, { light: image.light, dark: image.dark, style: styles.image, accessible: true, accessibilityLabel: heading }) }));
28
+ if (isThemedImageProps(image)) {
29
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, { ...image, style: [styles.image, image.style] }) }));
30
+ }
31
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(Image, { ...image, style: [styles.image, image.style] }) }));
23
32
  }
24
33
  return null;
25
34
  };
@@ -32,7 +41,7 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
32
41
  }
33
42
  return null;
34
43
  };
35
- const content = (_jsxs(View, { style: styles.container, children: [renderIconOrImage(), _jsxs(View, { style: styles.contentContainer, children: [_jsxs(View, { style: styles.textContainer, children: [_jsx(Heading, { size: "sm", style: styles.heading, textAlign: hasIllustration && direction === 'vertical' ? 'center' : 'left', children: heading }), _jsx(BodyText, { size: "md", style: styles.description, textAlign: hasIllustration && direction === 'vertical' ? 'center' : 'left', children: description }), renderAction()] }), onPress && (_jsx(UnstyledIconButton, { icon: ChevronRightSmallIcon, size: "sm", onPress: onPress, style: styles.chevron })), onClose && (_jsx(UnstyledIconButton, { icon: CloseSmallIcon, size: "sm", onPress: onClose, style: styles.closeButton, accessibilityLabel: "Close banner" }))] })] }));
44
+ const content = (_jsxs(View, { style: styles.container, children: [onClose && direction === 'vertical' && (_jsx(UnstyledIconButton, { icon: CloseSmallIcon, size: "sm", onPress: onClose, style: styles.closeButton, accessibilityLabel: "Close banner" })), renderIconOrImage(), _jsxs(View, { style: styles.contentContainer, children: [_jsxs(View, { style: styles.contentTextContainer, children: [_jsxs(View, { style: styles.textContainer, children: [_jsx(Heading, { size: "sm", style: styles.heading, textAlign: hasIllustration && direction === 'vertical' ? 'center' : 'left', children: heading }), _jsx(BodyText, { size: "md", style: styles.description, textAlign: hasIllustration && direction === 'vertical' ? 'center' : 'left', children: description })] }), renderAction()] }), onPress && (_jsx(UnstyledIconButton, { icon: ChevronRightSmallIcon, size: "sm", onPress: onPress, style: styles.chevron })), onClose && direction === 'horizontal' && (_jsx(UnstyledIconButton, { icon: CloseSmallIcon, size: "sm", onPress: onClose, style: styles.closeButton, accessibilityLabel: "Close banner" }))] })] }));
36
45
  if (onPress) {
37
46
  return (_jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: _jsx(Pressable, { onPress: onPress, accessibilityRole: "button", style: styles.pressable, children: content }) }));
38
47
  }
@@ -40,9 +49,9 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
40
49
  };
41
50
  Banner.displayName = 'Banner';
42
51
  const styles = StyleSheet.create(theme => ({
43
- card: {},
52
+ card: { flexDirection: 'row', _web: { flexDirection: 'column' } },
44
53
  pressable: {
45
- width: '100%',
54
+ flex: 1,
46
55
  },
47
56
  container: {
48
57
  flexDirection: 'row',
@@ -92,6 +101,7 @@ const styles = StyleSheet.create(theme => ({
92
101
  },
93
102
  },
94
103
  imageWrapper: {
104
+ flexDirection: 'row',
95
105
  variants: {
96
106
  direction: {
97
107
  horizontal: {},
@@ -103,8 +113,8 @@ const styles = StyleSheet.create(theme => ({
103
113
  },
104
114
  image: {
105
115
  borderRadius: theme.borderRadius.md,
106
- borderWidth: theme.borderWidth[1],
107
116
  borderColor: theme.color.border.strong,
117
+ borderWidth: theme.borderWidth[1],
108
118
  variants: {
109
119
  direction: {
110
120
  horizontal: { width: 160, height: 95 },
@@ -116,15 +126,34 @@ const styles = StyleSheet.create(theme => ({
116
126
  },
117
127
  },
118
128
  contentContainer: {
119
- flex: 1,
120
- flexDirection: 'row',
121
129
  alignItems: 'flex-start',
122
130
  justifyContent: 'space-between',
123
131
  gap: theme.space.lg,
132
+ variants: {
133
+ direction: {
134
+ horizontal: {
135
+ flex: 1,
136
+ flexDirection: 'row',
137
+ },
138
+ vertical: {
139
+ flexDirection: 'column',
140
+ },
141
+ },
142
+ },
124
143
  },
125
144
  textContainer: {
126
- flex: 1,
145
+ gap: theme.space.sm,
146
+ },
147
+ contentTextContainer: {
127
148
  gap: theme.space.lg,
149
+ variants: {
150
+ direction: {
151
+ horizontal: {
152
+ flex: 1,
153
+ },
154
+ vertical: {},
155
+ },
156
+ },
128
157
  },
129
158
  heading: {
130
159
  compoundVariants: [
@@ -156,6 +185,16 @@ const styles = StyleSheet.create(theme => ({
156
185
  },
157
186
  closeButton: {
158
187
  alignSelf: 'flex-start',
188
+ variants: {
189
+ direction: {
190
+ vertical: {
191
+ position: 'absolute',
192
+ top: 0,
193
+ right: 0,
194
+ },
195
+ horizontal: {},
196
+ },
197
+ },
159
198
  },
160
199
  }));
161
200
  export default Banner;
@@ -1,6 +1,7 @@
1
1
  import type { ComponentType, ReactElement } from 'react';
2
- import type { ImageSourcePropType } from 'react-native';
2
+ import { ImageProps } from 'react-native';
3
3
  import type CardProps from '../Card/Card.props';
4
+ import { ThemedImageProps } from '../ThemedImage';
4
5
  export type BannerDirection = 'horizontal' | 'vertical';
5
6
  export interface BannerProps extends Omit<CardProps, 'noPadding' | 'variant' | 'colorScheme' | 'space' | 'gap' | 'rowGap' | 'columnGap' | 'flexDirection' | 'flexWrap' | 'alignItems' | 'justifyContent'> {
6
7
  /**
@@ -27,18 +28,12 @@ export interface BannerProps extends Omit<CardProps, 'noPadding' | 'variant' | '
27
28
  * Illustration to display in the banner
28
29
  * Mutually exclusive with icon and image
29
30
  */
30
- illustration?: {
31
- light: ImageSourcePropType | ReactElement | ComponentType;
32
- dark: ImageSourcePropType | ReactElement | ComponentType;
33
- };
31
+ illustration?: ThemedImageProps | ImageProps;
34
32
  /**
35
33
  * Image to display in the banner
36
34
  * Mutually exclusive with icon and illustration
37
35
  */
38
- image?: {
39
- light: ImageSourcePropType | ReactElement | ComponentType;
40
- dark: ImageSourcePropType | ReactElement | ComponentType;
41
- };
36
+ image?: ThemedImageProps | ImageProps;
42
37
  /**
43
38
  * Heading text
44
39
  */
@@ -1,8 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { BottomSheetHandle as Handle } from '@gorhom/bottom-sheet';
3
+ import { Platform, View } from 'react-native';
3
4
  import { StyleSheet, withUnistyles } from 'react-native-unistyles';
4
5
  const StyledBottomSheetHandle = withUnistyles(Handle);
5
6
  const BottomSheetHandle = ({ style, indicatorStyle, ...props }) => {
7
+ if (Platform.OS === 'web') {
8
+ return (_jsx(View, { style: [styles.handle, style], children: _jsx(View, { style: [styles.indicator, indicatorStyle] }) }));
9
+ }
6
10
  return (_jsx(StyledBottomSheetHandle, { style: [styles.handle, style], indicatorStyle: [styles.indicator, indicatorStyle], ...props }));
7
11
  };
8
12
  const styles = StyleSheet.create(theme => ({
@@ -13,6 +17,10 @@ const styles = StyleSheet.create(theme => ({
13
17
  paddingTop: theme.components.bottomSheet.padding,
14
18
  paddingHorizontal: theme.components.bottomSheet.padding,
15
19
  paddingBottom: theme.components.bottomSheet.gap,
20
+ _web: {
21
+ alignItems: 'center',
22
+ cursor: 'grab',
23
+ },
16
24
  },
17
25
  indicator: {
18
26
  width: theme.components.bottomSheet.handle.width,
@@ -3,6 +3,7 @@ import { SpaceValue, SpacingValues } from '../../types';
3
3
  interface CardProps extends PressableProps {
4
4
  variant?: 'emphasis' | 'subtle';
5
5
  colorScheme?: 'neutralStrong' | 'neutralSubtle' | 'brand' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'pig';
6
+ shadowColor?: 'functional' | 'brand' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'pig';
6
7
  noPadding?: boolean;
7
8
  disabled?: boolean;
8
9
  space?: SpacingValues;
@@ -1,6 +1,6 @@
1
1
  import CardProps from './Card.props';
2
2
  declare const Card: {
3
- ({ children, variant, colorScheme, noPadding, style, states, space, disabled, onPress, ...rest }: CardProps & {
3
+ ({ children, variant, colorScheme, shadowColor, noPadding, style, states, space, disabled, onPress, ...rest }: CardProps & {
4
4
  states?: {
5
5
  active?: boolean;
6
6
  disabled?: boolean;
@@ -83,7 +83,7 @@ const collectChildActionHandlers = (children) => React.Children.toArray(children
83
83
  }
84
84
  return handlers;
85
85
  }, []);
86
- const Card = ({ children, variant = 'subtle', colorScheme = 'neutralStrong', noPadding = false, style, states, space, disabled = false, onPress, ...rest }) => {
86
+ const Card = ({ children, variant = 'subtle', colorScheme = 'neutralStrong', shadowColor, noPadding = false, style, states, space, disabled = false, onPress, ...rest }) => {
87
87
  const { active } = states || { active: false };
88
88
  const childActionHandlers = collectChildActionHandlers(children);
89
89
  const hasActions = checkForComponentType(children, 'CardAction');
@@ -123,6 +123,7 @@ const Card = ({ children, variant = 'subtle', colorScheme = 'neutralStrong', noP
123
123
  showPressed,
124
124
  disabled,
125
125
  space: hasActions || hasContent ? 'none' : space,
126
+ shadowColor,
126
127
  });
127
128
  const renderChildren = () => {
128
129
  // Default: render children as-is
@@ -190,6 +191,32 @@ const styles = StyleSheet.create(theme => ({
190
191
  borderWidth: theme.components.card.brand.borderWidth,
191
192
  },
192
193
  },
194
+ shadowColor: {
195
+ functional: {
196
+ boxShadow: theme.helpers.shadow.functional,
197
+ },
198
+ brand: {
199
+ boxShadow: theme.helpers.shadow.brand,
200
+ },
201
+ energy: {
202
+ boxShadow: theme.helpers.shadow.energy,
203
+ },
204
+ broadband: {
205
+ boxShadow: theme.helpers.shadow.broadband,
206
+ },
207
+ mobile: {
208
+ boxShadow: theme.helpers.shadow.mobile,
209
+ },
210
+ insurance: {
211
+ boxShadow: theme.helpers.shadow.insurance,
212
+ },
213
+ cashback: {
214
+ boxShadow: theme.helpers.shadow.cashback,
215
+ },
216
+ pig: {
217
+ boxShadow: theme.helpers.shadow.pig,
218
+ },
219
+ },
193
220
  noPadding: {
194
221
  true: {
195
222
  padding: theme.components.card.mobile.paddingNone,
@@ -1,7 +1,7 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { ImageProps } from 'react-native';
3
3
  import CardProps from '../Card/Card.props';
4
- interface HighlightBannerProps extends Omit<CardProps, 'noPadding' | 'variant' | 'space' | 'gap' | 'rowGap' | 'columnGap' | 'flexDirection' | 'flexWrap' | 'alignItems' | 'justifyContent'> {
4
+ interface HighlightBannerProps extends Omit<CardProps, 'noPadding' | 'variant' | 'space' | 'gap' | 'rowGap' | 'columnGap' | 'flexDirection' | 'flexWrap' | 'alignItems' | 'justifyContent' | 'colorScheme'> {
5
5
  heading?: string;
6
6
  headingColor?: 'pig' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'highlight';
7
7
  variant?: 'emphasis' | 'subtle';
@@ -44,7 +44,7 @@ const List = ({ children, heading, helperText, headerTrailingContent, ...props }
44
44
  const updatedChildren = markFirstListItem(children);
45
45
  const value = useMemo(() => ({ loading, disabled, container }), [loading, disabled, container]);
46
46
  styles.useVariants({ disabled });
47
- return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...props, style: [styles.container, props.style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent })) : null, container === 'none' ? (_jsx(View, { children: updatedChildren })) : (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, children: _jsx(_Fragment, { children: updatedChildren }) }))] }) }));
47
+ return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...props, style: [styles.container, props.style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent })) : null, container === 'none' ? (_jsx(View, { children: updatedChildren })) : (React.Children.count(updatedChildren) > 0 && (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, children: _jsx(_Fragment, { children: updatedChildren }) })))] }) }));
48
48
  };
49
49
  List.displayName = 'List';
50
50
  const styles = StyleSheet.create(theme => ({
@@ -12,8 +12,8 @@ ListActionTrailingIcon.displayName = 'ListActionTrailingIcon';
12
12
  const styles = StyleSheet.create(theme => ({
13
13
  icon: {
14
14
  color: theme.color.icon.primary,
15
- width: 24,
16
- height: 24,
15
+ minWidth: 20,
16
+ minHeight: 20,
17
17
  },
18
18
  }));
19
19
  export default ListActionTrailingIcon;
@@ -0,0 +1,5 @@
1
+ export interface IMenuContext {
2
+ close: () => void;
3
+ }
4
+ export declare const MenuContext: import("react").Context<IMenuContext | undefined>;
5
+ export declare const useMenuContext: () => IMenuContext;
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from 'react';
2
+ export const MenuContext = createContext(undefined);
3
+ export const useMenuContext = () => {
4
+ const context = useContext(MenuContext);
5
+ if (!context) {
6
+ throw new Error('useMenuContext must be used within a Menu component');
7
+ }
8
+ return context;
9
+ };
@@ -0,0 +1,4 @@
1
+ import type MenuProps from './Menu.props';
2
+ import type { MenuMethods } from './Menu.props';
3
+ declare const Menu: import("react").ForwardRefExoticComponent<MenuProps & import("react").RefAttributes<MenuMethods>>;
4
+ export default Menu;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { BodyText } from '../BodyText';
5
+ import { BottomSheetModal, BottomSheetScrollView } from '../BottomSheet';
6
+ import { MenuContext } from './Menu.context';
7
+ const Menu = forwardRef(({ heading, children, bottomSheetProps }, ref) => {
8
+ const bottomSheetModalRef = useRef(null);
9
+ useImperativeHandle(ref, () => ({
10
+ present: () => bottomSheetModalRef.current?.present(),
11
+ dismiss: () => bottomSheetModalRef.current?.dismiss(),
12
+ }), []);
13
+ const handleClose = useCallback(() => {
14
+ bottomSheetModalRef.current?.dismiss();
15
+ }, []);
16
+ const contextValue = useMemo(() => ({ close: handleClose }), [handleClose]);
17
+ return (_jsx(BottomSheetModal, { ref: bottomSheetModalRef, ...bottomSheetProps, children: _jsx(BottomSheetScrollView, { contentContainerStyle: styles.container, children: _jsxs(MenuContext.Provider, { value: contextValue, children: [heading && (_jsx(BodyText, { size: "md", weight: "semibold", children: heading })), children] }) }) }));
18
+ });
19
+ Menu.displayName = 'Menu';
20
+ const styles = StyleSheet.create(theme => ({
21
+ container: {
22
+ gap: theme.components.bottomSheet.gap,
23
+ },
24
+ }));
25
+ export default Menu;
@@ -0,0 +1,21 @@
1
+ import type { BottomSheetModalProps } from '@gorhom/bottom-sheet';
2
+ import type { ReactNode } from 'react';
3
+ export interface MenuMethods {
4
+ present: () => void;
5
+ dismiss: () => void;
6
+ }
7
+ export interface MenuProps {
8
+ /**
9
+ * Heading text displayed at the top of the menu
10
+ */
11
+ heading?: string;
12
+ /**
13
+ * Menu items to display
14
+ */
15
+ children: ReactNode;
16
+ /**
17
+ * Optional bottom sheet modal props to customise the menu behavior
18
+ */
19
+ bottomSheetProps?: Partial<BottomSheetModalProps>;
20
+ }
21
+ export default MenuProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import type MenuItemProps from './MenuItem.props';
2
+ declare const MenuItem: import("react").ForwardRefExoticComponent<MenuItemProps & {
3
+ states?: {
4
+ active?: boolean;
5
+ disabled?: boolean;
6
+ };
7
+ } & Omit<import("react-native").PressableProps, "children"> & {
8
+ tabIndex?: 0 | -1 | undefined;
9
+ } & {
10
+ children?: import("react").ReactNode | (({ hovered, pressed, focused, focusVisible, disabled, }: {
11
+ hovered?: boolean | undefined;
12
+ pressed?: boolean | undefined;
13
+ focused?: boolean | undefined;
14
+ focusVisible?: boolean | undefined;
15
+ disabled?: boolean | undefined;
16
+ }) => import("react").ReactNode);
17
+ } & import("react").RefAttributes<unknown>>;
18
+ export default MenuItem;
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createPressable } from '@gluestack-ui/pressable';
3
+ import { Pressable } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { BodyText } from '../BodyText';
6
+ import { Icon } from '../Icon';
7
+ import { useMenuContext } from './Menu.context';
8
+ const MenuItemRoot = ({ icon, iconPosition = 'left', text, colorScheme = 'functional', disabled = false, onPress, states = {}, ...props }) => {
9
+ const { active } = states;
10
+ const { close } = useMenuContext();
11
+ styles.useVariants({ colorScheme, disabled, iconPosition, active });
12
+ const handlePress = (event) => {
13
+ if (disabled)
14
+ return;
15
+ onPress?.(event);
16
+ close();
17
+ };
18
+ return (_jsxs(Pressable, { ...props, onPress: handlePress, disabled: disabled, style: styles.container, accessibilityRole: "button", accessibilityState: { disabled }, children: [!!icon && _jsx(Icon, { as: icon, style: styles.icon }), _jsx(BodyText, { size: "lg", style: styles.text, children: text })] }));
19
+ };
20
+ const MenuItem = createPressable({ Root: MenuItemRoot });
21
+ MenuItem.displayName = 'MenuItem';
22
+ const styles = StyleSheet.create(theme => ({
23
+ container: {
24
+ flexDirection: 'row',
25
+ alignItems: 'center',
26
+ paddingVertical: theme.components.menu.item.padding,
27
+ paddingHorizontal: theme.components.menu.mobile.item.padding,
28
+ gap: theme.components.menu.item.gap,
29
+ borderRadius: theme.components.menu.item.borderRadius,
30
+ variants: {
31
+ active: {
32
+ true: {
33
+ backgroundColor: theme.color.interactive.functional.surface.subtle.active,
34
+ },
35
+ },
36
+ disabled: {
37
+ true: {
38
+ opacity: theme.opacity.disabled,
39
+ cursor: 'auto',
40
+ },
41
+ false: {
42
+ _web: {
43
+ _hover: {
44
+ backgroundColor: theme.color.interactive.functional.surface.subtle.hover,
45
+ },
46
+ _active: {
47
+ backgroundColor: theme.color.interactive.functional.surface.subtle.active,
48
+ },
49
+ },
50
+ },
51
+ },
52
+ iconPosition: {
53
+ left: {
54
+ flexDirection: 'row',
55
+ },
56
+ right: {
57
+ flexDirection: 'row-reverse',
58
+ },
59
+ },
60
+ colorScheme: {
61
+ functional: {},
62
+ destructive: {},
63
+ },
64
+ },
65
+ compoundVariants: [
66
+ {
67
+ colorScheme: 'destructive',
68
+ active: true,
69
+ styles: {
70
+ backgroundColor: theme.color.interactive.destructive.surface.subtle.active,
71
+ },
72
+ },
73
+ {
74
+ colorScheme: 'destructive',
75
+ disabled: false,
76
+ styles: {
77
+ _web: {
78
+ _hover: {
79
+ backgroundColor: theme.color.interactive.destructive.surface.subtle.hover,
80
+ },
81
+ _active: {
82
+ backgroundColor: theme.color.interactive.destructive.surface.subtle.active,
83
+ },
84
+ },
85
+ },
86
+ },
87
+ ],
88
+ },
89
+ text: {
90
+ flex: 1,
91
+ variants: {
92
+ colorScheme: {
93
+ functional: {
94
+ color: theme.color.text.primary,
95
+ },
96
+ destructive: {
97
+ color: theme.color.interactive.destructive.foreground.subtle,
98
+ },
99
+ },
100
+ },
101
+ },
102
+ icon: {
103
+ variants: {
104
+ colorScheme: {
105
+ functional: {
106
+ color: theme.color.icon.primary,
107
+ },
108
+ destructive: {
109
+ color: theme.color.interactive.destructive.foreground.subtle,
110
+ },
111
+ },
112
+ },
113
+ },
114
+ }));
115
+ export default MenuItem;
@@ -0,0 +1,27 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { PressableProps } from 'react-native';
3
+ export interface MenuItemProps extends Omit<PressableProps, 'children'> {
4
+ /**
5
+ * Icon component to display
6
+ */
7
+ icon?: ComponentType;
8
+ /**
9
+ * Position of the icon
10
+ * @default 'left'
11
+ */
12
+ iconPosition?: 'left' | 'right';
13
+ /**
14
+ * Text to display in the menu item
15
+ */
16
+ text: string;
17
+ /**
18
+ * Color scheme for the menu item
19
+ * @default 'functional'
20
+ */
21
+ colorScheme?: 'functional' | 'destructive';
22
+ /**
23
+ * Whether the menu item is disabled
24
+ */
25
+ disabled?: boolean;
26
+ }
27
+ export default MenuItemProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type MenuTriggerProps from './MenuTrigger.props';
2
+ interface MenuTriggerInternalProps extends MenuTriggerProps {
3
+ onPress: () => void;
4
+ }
5
+ declare const MenuTrigger: {
6
+ ({ children, onPress }: MenuTriggerInternalProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
7
+ displayName: string;
8
+ };
9
+ export default MenuTrigger;
@@ -0,0 +1,11 @@
1
+ import { cloneElement, isValidElement } from 'react';
2
+ const MenuTrigger = ({ children, onPress }) => {
3
+ if (!isValidElement(children)) {
4
+ throw new Error('MenuTrigger: children must be a valid React element');
5
+ }
6
+ return cloneElement(children, {
7
+ onPress,
8
+ });
9
+ };
10
+ MenuTrigger.displayName = 'MenuTrigger';
11
+ export default MenuTrigger;
@@ -0,0 +1,12 @@
1
+ import type { ReactElement } from 'react';
2
+ export interface MenuTriggerProps {
3
+ /**
4
+ * The child element that triggers the menu (should be a single pressable element like Button)
5
+ */
6
+ children: ReactElement;
7
+ /**
8
+ * Called when the trigger is pressed.
9
+ */
10
+ onPress?: () => void;
11
+ }
12
+ export default MenuTriggerProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export { default as Menu } from './Menu';
2
+ export { useMenuContext } from './Menu.context';
3
+ export type { MenuMethods, default as MenuProps } from './Menu.props';
4
+ export { default as MenuItem } from './MenuItem';
5
+ export type { default as MenuItemProps } from './MenuItem.props';
6
+ export { default as MenuTrigger } from './MenuTrigger';
7
+ export type { default as MenuTriggerProps } from './MenuTrigger.props';
@@ -0,0 +1,4 @@
1
+ export { default as Menu } from './Menu';
2
+ export { useMenuContext } from './Menu.context';
3
+ export { default as MenuItem } from './MenuItem';
4
+ export { default as MenuTrigger } from './MenuTrigger';
@@ -3,5 +3,5 @@ import ModalProps from './Modal.props';
3
3
  type Modal<T = any> = BottomSheetModalMethods<T> & {
4
4
  triggerCloseAnimation?: () => void;
5
5
  };
6
- declare const Modal: ({ ref, children, heading, description, showCloseButton, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress, closeOnSecondaryButtonPress, loading, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, fullscreen, ...props }: ModalProps) => import("react/jsx-runtime").JSX.Element;
6
+ declare const Modal: ({ ref, children, heading, description, showCloseButton, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress, closeOnSecondaryButtonPress, loading, fullscreen, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal, ...props }: ModalProps) => import("react/jsx-runtime").JSX.Element;
7
7
  export default Modal;