@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.
- package/.storybook/preview.tsx +1 -0
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +24 -0
- package/build/components/Banner/Banner.js +49 -10
- package/build/components/Banner/Banner.props.d.ts +4 -9
- package/build/components/BottomSheet/BottomSheetHandle.js +8 -0
- package/build/components/Card/Card.props.d.ts +1 -0
- package/build/components/Card/CardRoot.d.ts +1 -1
- package/build/components/Card/CardRoot.js +28 -1
- package/build/components/HighlightBanner/HighlightBanner.props.d.ts +1 -1
- package/build/components/List/List.js +1 -1
- package/build/components/List/ListAction/ListActionTrailingIcon.js +2 -2
- package/build/components/Menu/Menu.context.d.ts +5 -0
- package/build/components/Menu/Menu.context.js +9 -0
- package/build/components/Menu/Menu.d.ts +4 -0
- package/build/components/Menu/Menu.js +25 -0
- package/build/components/Menu/Menu.props.d.ts +21 -0
- package/build/components/Menu/Menu.props.js +1 -0
- package/build/components/Menu/MenuItem.d.ts +18 -0
- package/build/components/Menu/MenuItem.js +115 -0
- package/build/components/Menu/MenuItem.props.d.ts +27 -0
- package/build/components/Menu/MenuItem.props.js +1 -0
- package/build/components/Menu/MenuTrigger.d.ts +9 -0
- package/build/components/Menu/MenuTrigger.js +11 -0
- package/build/components/Menu/MenuTrigger.props.d.ts +12 -0
- package/build/components/Menu/MenuTrigger.props.js +1 -0
- package/build/components/Menu/index.d.ts +7 -0
- package/build/components/Menu/index.js +4 -0
- package/build/components/Modal/Modal.d.ts +1 -1
- package/build/components/Modal/Modal.js +32 -30
- package/build/components/Modal/Modal.props.d.ts +1 -0
- package/build/components/Modal/Modal.web.d.ts +1 -1
- package/build/components/Modal/Modal.web.js +25 -25
- package/build/components/RadioCard/RadioCardGroup.context.d.ts +12 -0
- package/build/components/RadioCard/RadioCardGroup.context.js +3 -0
- package/build/components/RadioCard/RadioCardGroup.js +15 -10
- package/build/components/RadioCard/RadioCardLabel.d.ts +1 -1
- package/build/components/RadioCard/RadioCardLabel.js +7 -1
- package/build/components/RadioCard/RadioCardRoot.js +13 -0
- package/build/components/index.d.ts +1 -0
- package/build/components/index.js +1 -0
- package/build/core/themes.d.ts +40 -0
- package/build/core/themes.js +20 -0
- package/build/tokens/components/dark/index.d.ts +3 -1
- package/build/tokens/components/dark/index.js +3 -1
- package/build/tokens/components/dark/input.d.ts +3 -0
- package/build/tokens/components/dark/input.js +3 -0
- package/build/tokens/components/dark/modal.d.ts +7 -4
- package/build/tokens/components/dark/modal.js +7 -4
- package/build/tokens/components/dark/rating.d.ts +8 -0
- package/build/tokens/components/dark/rating.js +7 -0
- package/build/tokens/components/dark/table.d.ts +0 -3
- package/build/tokens/components/dark/table.js +0 -3
- package/build/tokens/components/dark/time-picker.d.ts +29 -0
- package/build/tokens/components/dark/time-picker.js +28 -0
- package/build/tokens/components/dark/timeline.d.ts +27 -0
- package/build/tokens/components/dark/timeline.js +26 -0
- package/build/tokens/components/light/index.d.ts +3 -1
- package/build/tokens/components/light/index.js +3 -1
- package/build/tokens/components/light/input.d.ts +3 -0
- package/build/tokens/components/light/input.js +3 -0
- package/build/tokens/components/light/modal.d.ts +7 -4
- package/build/tokens/components/light/modal.js +7 -4
- package/build/tokens/components/light/rating.d.ts +8 -0
- package/build/tokens/components/light/rating.js +7 -0
- package/build/tokens/components/light/table.d.ts +0 -3
- package/build/tokens/components/light/table.js +0 -3
- package/build/tokens/components/light/time-picker.d.ts +29 -0
- package/build/tokens/components/light/time-picker.js +28 -0
- package/build/tokens/components/light/timeline.d.ts +27 -0
- package/build/tokens/components/light/timeline.js +26 -0
- package/docs/adding-shadows.mdx +43 -0
- package/docs/components/AllComponents.web.tsx +33 -0
- package/docs/components/BackToTopButton.tsx +1 -1
- package/package.json +3 -3
- package/src/components/Banner/Banner.docs.mdx +20 -11
- package/src/components/Banner/Banner.props.ts +4 -9
- package/src/components/Banner/Banner.stories.tsx +17 -4
- package/src/components/Banner/Banner.tsx +92 -37
- package/src/components/BottomSheet/BottomSheetHandle.tsx +12 -0
- package/src/components/Card/Card.docs.mdx +20 -1
- package/src/components/Card/Card.props.ts +9 -0
- package/src/components/Card/Card.stories.tsx +39 -0
- package/src/components/Card/CardRoot.tsx +29 -0
- package/src/components/Checkbox/CheckboxGroup.stories.tsx +19 -1
- package/src/components/DatePickerInput/DatePickerInput.docs.mdx +1 -1
- package/src/components/HighlightBanner/HighlightBanner.docs.mdx +1 -1
- package/src/components/HighlightBanner/HighlightBanner.props.ts +1 -0
- package/src/components/HighlightBanner/HighlightBanner.stories.tsx +15 -1
- package/src/components/List/List.tsx +5 -3
- package/src/components/List/ListAction/ListActionTrailingIcon.tsx +2 -2
- package/src/components/Menu/Menu.context.ts +15 -0
- package/src/components/Menu/Menu.docs.mdx +158 -0
- package/src/components/Menu/Menu.props.ts +24 -0
- package/src/components/Menu/Menu.stories.tsx +292 -0
- package/src/components/Menu/Menu.tsx +54 -0
- package/src/components/Menu/MenuItem.props.ts +29 -0
- package/src/components/Menu/MenuItem.tsx +145 -0
- package/src/components/Menu/MenuTrigger.props.ts +14 -0
- package/src/components/Menu/MenuTrigger.tsx +20 -0
- package/src/components/Menu/index.ts +7 -0
- package/src/components/Modal/Modal.docs.mdx +34 -5
- package/src/components/Modal/Modal.props.ts +1 -0
- package/src/components/Modal/Modal.stories.tsx +46 -0
- package/src/components/Modal/Modal.tsx +37 -33
- package/src/components/Modal/Modal.web.tsx +27 -27
- package/src/components/Radio/RadioGroup.stories.tsx +18 -0
- package/src/components/RadioCard/RadioCardGroup.context.ts +16 -0
- package/src/components/RadioCard/RadioCardGroup.stories.tsx +24 -0
- package/src/components/RadioCard/RadioCardGroup.tsx +28 -19
- package/src/components/RadioCard/RadioCardLabel.tsx +12 -1
- package/src/components/RadioCard/RadioCardRoot.tsx +15 -0
- package/src/components/index.ts +1 -0
- package/src/core/themes.ts +20 -0
- package/src/tokens/components/dark/index.ts +3 -1
- package/src/tokens/components/dark/input.ts +3 -0
- package/src/tokens/components/dark/modal.ts +7 -4
- package/src/tokens/components/dark/rating.ts +8 -0
- package/src/tokens/components/dark/table.ts +0 -3
- package/src/tokens/components/dark/time-picker.ts +29 -0
- package/src/tokens/components/dark/timeline.ts +27 -0
- package/src/tokens/components/light/index.ts +3 -1
- package/src/tokens/components/light/input.ts +3 -0
- package/src/tokens/components/light/modal.ts +7 -4
- package/src/tokens/components/light/rating.ts +8 -0
- package/src/tokens/components/light/table.ts +0 -3
- package/src/tokens/components/light/time-picker.ts +29 -0
- package/src/tokens/components/light/timeline.ts +27 -0
- package/build/tokens/components/dark/dialog.d.ts +0 -25
- package/build/tokens/components/dark/dialog.js +0 -24
- package/build/tokens/components/light/dialog.d.ts +0 -25
- package/build/tokens/components/light/dialog.js +0 -24
- package/src/tokens/components/dark/dialog.ts +0 -25
- package/src/tokens/components/light/dialog.ts +0 -25
package/.storybook/preview.tsx
CHANGED
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @utilitywarehouse/hearth-react-native@0.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16
|
-
|
|
15
|
+
minWidth: 20,
|
|
16
|
+
minHeight: 20,
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
19
|
export default ListActionTrailingIcon;
|
|
@@ -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,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';
|
|
@@ -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,
|
|
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;
|