@utilitywarehouse/hearth-react-native 0.8.0 → 0.8.2
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 +22 -0
- package/build/components/Banner/Banner.js +27 -7
- package/build/components/Banner/Banner.props.d.ts +4 -9
- 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.js +12 -2
- 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/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/core/themes.d.ts +40 -0
- package/build/core/themes.js +20 -0
- package/docs/adding-shadows.mdx +43 -0
- package/package.json +3 -3
- package/src/components/Banner/Banner.docs.mdx +1 -1
- package/src/components/Banner/Banner.props.ts +4 -9
- package/src/components/Banner/Banner.stories.tsx +16 -0
- package/src/components/Banner/Banner.tsx +46 -31
- 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/HighlightBanner/HighlightBanner.docs.mdx +21 -2
- package/src/components/HighlightBanner/HighlightBanner.props.ts +1 -0
- package/src/components/HighlightBanner/HighlightBanner.stories.tsx +31 -1
- package/src/components/HighlightBanner/HighlightBanner.tsx +16 -4
- package/src/components/List/List.tsx +5 -3
- package/src/components/List/ListAction/ListActionTrailingIcon.tsx +2 -2
- 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/core/themes.ts +20 -0
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.8.
|
|
2
|
+
> @utilitywarehouse/hearth-react-native@0.8.2 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,27 @@
|
|
|
1
1
|
# @utilitywarehouse/hearth-react-native
|
|
2
2
|
|
|
3
|
+
## 0.8.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#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
|
|
8
|
+
|
|
9
|
+
- [#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
|
|
10
|
+
|
|
11
|
+
- [#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
|
|
12
|
+
|
|
13
|
+
- [#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
|
|
14
|
+
|
|
15
|
+
- [#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
|
|
16
|
+
|
|
17
|
+
- [#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
|
|
18
|
+
|
|
19
|
+
## 0.8.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [#641](https://github.com/utilitywarehouse/hearth/pull/641) [`251242e`](https://github.com/utilitywarehouse/hearth/commit/251242e218c0b24589c3fb6fb6963b53bda8a367) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `HighlightBanner` when no image is provided
|
|
24
|
+
|
|
3
25
|
## 0.8.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
|
@@ -16,10 +16,10 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
|
|
|
16
16
|
return (_jsx(IconContainer, { icon: icon, variant: iconContainerVariant, size: iconContainerSize, color: iconContainerColor, style: styles.media }));
|
|
17
17
|
}
|
|
18
18
|
if (illustration) {
|
|
19
|
-
return (_jsx(ThemedImage, {
|
|
19
|
+
return (_jsx(ThemedImage, { ...illustration, resizeMode: "cover", style: [styles.media, styles.imageWrapper, illustration.style] }));
|
|
20
20
|
}
|
|
21
21
|
if (image) {
|
|
22
|
-
return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, {
|
|
22
|
+
return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, { ...image, style: [styles.image, image.style] }) }));
|
|
23
23
|
}
|
|
24
24
|
return null;
|
|
25
25
|
};
|
|
@@ -32,7 +32,7 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
|
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
34
34
|
};
|
|
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" }))] })] }));
|
|
35
|
+
const content = (_jsxs(View, { style: styles.container, children: [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 && (_jsx(UnstyledIconButton, { icon: CloseSmallIcon, size: "sm", onPress: onClose, style: styles.closeButton, accessibilityLabel: "Close banner" }))] })] }));
|
|
36
36
|
if (onPress) {
|
|
37
37
|
return (_jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: _jsx(Pressable, { onPress: onPress, accessibilityRole: "button", style: styles.pressable, children: content }) }));
|
|
38
38
|
}
|
|
@@ -92,6 +92,7 @@ const styles = StyleSheet.create(theme => ({
|
|
|
92
92
|
},
|
|
93
93
|
},
|
|
94
94
|
imageWrapper: {
|
|
95
|
+
flexDirection: 'row',
|
|
95
96
|
variants: {
|
|
96
97
|
direction: {
|
|
97
98
|
horizontal: {},
|
|
@@ -103,8 +104,8 @@ const styles = StyleSheet.create(theme => ({
|
|
|
103
104
|
},
|
|
104
105
|
image: {
|
|
105
106
|
borderRadius: theme.borderRadius.md,
|
|
106
|
-
borderWidth: theme.borderWidth[1],
|
|
107
107
|
borderColor: theme.color.border.strong,
|
|
108
|
+
borderWidth: theme.borderWidth[1],
|
|
108
109
|
variants: {
|
|
109
110
|
direction: {
|
|
110
111
|
horizontal: { width: 160, height: 95 },
|
|
@@ -116,15 +117,34 @@ const styles = StyleSheet.create(theme => ({
|
|
|
116
117
|
},
|
|
117
118
|
},
|
|
118
119
|
contentContainer: {
|
|
119
|
-
flex: 1,
|
|
120
|
-
flexDirection: 'row',
|
|
121
120
|
alignItems: 'flex-start',
|
|
122
121
|
justifyContent: 'space-between',
|
|
123
122
|
gap: theme.space.lg,
|
|
123
|
+
variants: {
|
|
124
|
+
direction: {
|
|
125
|
+
horizontal: {
|
|
126
|
+
flex: 1,
|
|
127
|
+
flexDirection: 'row',
|
|
128
|
+
},
|
|
129
|
+
vertical: {
|
|
130
|
+
flexDirection: 'column',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
124
134
|
},
|
|
125
135
|
textContainer: {
|
|
126
|
-
|
|
136
|
+
gap: theme.space.sm,
|
|
137
|
+
},
|
|
138
|
+
contentTextContainer: {
|
|
127
139
|
gap: theme.space.lg,
|
|
140
|
+
variants: {
|
|
141
|
+
direction: {
|
|
142
|
+
horizontal: {
|
|
143
|
+
flex: 1,
|
|
144
|
+
},
|
|
145
|
+
vertical: {},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
128
148
|
},
|
|
129
149
|
heading: {
|
|
130
150
|
compoundVariants: [
|
|
@@ -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
|
*/
|
|
@@ -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,
|
|
@@ -4,8 +4,8 @@ import { StyleSheet } from 'react-native-unistyles';
|
|
|
4
4
|
import { BodyText } from '../BodyText';
|
|
5
5
|
import { Card } from '../Card';
|
|
6
6
|
const HighlightBanner = ({ heading, headingColor, image, imageContainerHeight, description, link, button, variant = 'emphasis', style, ...props }) => {
|
|
7
|
-
styles.useVariants({ headingColor, variant });
|
|
8
|
-
return (_jsx(Card, { variant: variant, noPadding: true, style: style, ...props, children: _jsxs(View, { style: [styles.container], children: [_jsx(View, { style: [styles.header], children: _jsx(BodyText, { size: "md", textAlign: "center", weight: "semibold", children: heading }) }), _jsx(View, { style: styles.imageContainer(imageContainerHeight), children: _jsx(Image, { resizeMode: "cover", ...image, style: [styles.image, image?.style] }) }), _jsxs(View, { style: styles.footer, children: [_jsx(BodyText, { size: "md", textAlign: "center", children: description }), link && _jsx(View, { style: styles.linkContainer, children: link }), button && _jsx(View, { style: styles.buttonContainer, children: button })] })] }) }));
|
|
7
|
+
styles.useVariants({ headingColor, variant, hasImage: Boolean(image) });
|
|
8
|
+
return (_jsx(Card, { variant: variant, noPadding: true, style: style, ...props, children: _jsxs(View, { style: [styles.container], children: [_jsx(View, { style: [styles.header], children: _jsx(BodyText, { size: "md", textAlign: "center", weight: "semibold", children: heading }) }), !!image && (_jsx(View, { style: styles.imageContainer(imageContainerHeight), children: _jsx(Image, { resizeMode: "cover", ...image, style: [styles.image, image?.style] }) })), _jsxs(View, { style: styles.footer, children: [_jsx(BodyText, { size: "md", textAlign: "center", children: description }), link && _jsx(View, { style: styles.linkContainer, children: link }), button && _jsx(View, { style: styles.buttonContainer, children: button })] })] }) }));
|
|
9
9
|
};
|
|
10
10
|
HighlightBanner.displayName = 'HighlightBanner';
|
|
11
11
|
const styles = StyleSheet.create(theme => ({
|
|
@@ -51,6 +51,11 @@ const styles = StyleSheet.create(theme => ({
|
|
|
51
51
|
borderColor: theme.color.border.subtle,
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
+
hasImage: {
|
|
55
|
+
false: {
|
|
56
|
+
borderBottomWidth: 0,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
54
59
|
},
|
|
55
60
|
},
|
|
56
61
|
imageContainer: (height = 200) => ({
|
|
@@ -74,6 +79,11 @@ const styles = StyleSheet.create(theme => ({
|
|
|
74
79
|
borderColor: theme.color.border.subtle,
|
|
75
80
|
},
|
|
76
81
|
},
|
|
82
|
+
hasImage: {
|
|
83
|
+
true: {
|
|
84
|
+
flex: 1,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
77
87
|
},
|
|
78
88
|
},
|
|
79
89
|
linkContainer: {
|
|
@@ -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,12 @@
|
|
|
1
|
+
export declare const RadioCardGroupContext: import("react").Context<{
|
|
2
|
+
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
|
|
3
|
+
flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
|
|
4
|
+
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
5
|
+
alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
|
|
6
|
+
}>;
|
|
7
|
+
export declare const useRadioCardGroupContext: () => {
|
|
8
|
+
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
|
|
9
|
+
flexWrap?: "nowrap" | "wrap" | "wrap-reverse";
|
|
10
|
+
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
|
|
11
|
+
alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
|
|
12
|
+
};
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
2
3
|
import { View } from 'react-native';
|
|
3
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
4
5
|
import { Grid } from '../Grid';
|
|
6
|
+
import { RadioCardGroupContext } from './RadioCardGroup.context';
|
|
5
7
|
const RadioCardGroup = ({ children, gap = '200', style, flexDirection = 'row', flexWrap, justifyContent, alignItems, columns, ...props }) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
const context = useMemo(() => {
|
|
9
|
+
return { flexDirection, flexWrap, justifyContent, alignItems };
|
|
10
|
+
}, [flexDirection, flexWrap, justifyContent, alignItems]);
|
|
11
|
+
return columns ? (_jsx(RadioCardGroupContext.Provider, { value: context, children: _jsx(Grid, { ...props, gap: gap, columns: columns, style: style, children: children }) })) : (_jsx(RadioCardGroupContext.Provider, { value: context, children: _jsx(View, { ...props, style: [
|
|
12
|
+
styles.containerGap(gap),
|
|
13
|
+
{
|
|
14
|
+
flexDirection,
|
|
15
|
+
flexWrap,
|
|
16
|
+
justifyContent,
|
|
17
|
+
alignItems,
|
|
18
|
+
},
|
|
19
|
+
style,
|
|
20
|
+
], children: children }) }));
|
|
16
21
|
};
|
|
17
22
|
const styles = StyleSheet.create(theme => ({
|
|
18
23
|
containerGap: (gap) => ({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import LabelProps from '../Label/Label.props';
|
|
2
2
|
declare const RadioCardLabel: {
|
|
3
|
-
({ children, ...props }: LabelProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
({ children, style, ...props }: LabelProps): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
displayName: string;
|
|
5
5
|
};
|
|
6
6
|
export default RadioCardLabel;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
3
|
import { Label } from '../Label';
|
|
3
|
-
const RadioCardLabel = ({ children, ...props }) => _jsx(Label, { ...props, children: children });
|
|
4
|
+
const RadioCardLabel = ({ children, style, ...props }) => (_jsx(Label, { ...props, style: [styles.label, style], children: children }));
|
|
5
|
+
const styles = StyleSheet.create({
|
|
6
|
+
label: {
|
|
7
|
+
flexShrink: 1,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
4
10
|
RadioCardLabel.displayName = 'RadioCardLabel';
|
|
5
11
|
export default RadioCardLabel;
|
|
@@ -3,14 +3,17 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { StyleSheet } from 'react-native-unistyles';
|
|
4
4
|
import { Pressable } from 'react-native';
|
|
5
5
|
import { RadioCardContext } from './RadioCard.context';
|
|
6
|
+
import { useRadioCardGroupContext } from './RadioCardGroup.context';
|
|
6
7
|
const RadioCardRoot = ({ children, style, states, ...props }) => {
|
|
7
8
|
const { checked, active } = states ?? {};
|
|
9
|
+
const { flexDirection } = useRadioCardGroupContext() ?? {};
|
|
8
10
|
const value = useMemo(() => ({
|
|
9
11
|
checked,
|
|
10
12
|
active,
|
|
11
13
|
}), [checked, active]);
|
|
12
14
|
styles.useVariants({
|
|
13
15
|
selected: checked,
|
|
16
|
+
flexDirection,
|
|
14
17
|
});
|
|
15
18
|
return (_jsx(RadioCardContext.Provider, { value: value, children: _jsx(Pressable, { ...props, style: [styles.container, style], children: children }) }));
|
|
16
19
|
};
|
|
@@ -37,6 +40,16 @@ const styles = StyleSheet.create(theme => ({
|
|
|
37
40
|
margin: -theme.components.card.selectable.borderWidthSelected / 2,
|
|
38
41
|
},
|
|
39
42
|
},
|
|
43
|
+
flexDirection: {
|
|
44
|
+
row: {},
|
|
45
|
+
column: {
|
|
46
|
+
width: '100%',
|
|
47
|
+
},
|
|
48
|
+
'row-reverse': {},
|
|
49
|
+
'column-reverse': {
|
|
50
|
+
width: '100%',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
40
53
|
},
|
|
41
54
|
_web: {
|
|
42
55
|
'_focus-visible': {
|
package/build/core/themes.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import { DimensionValue } from 'react-native';
|
|
|
2
2
|
import { components } from '../tokens';
|
|
3
3
|
export declare const lightTheme: {
|
|
4
4
|
readonly helpers: {
|
|
5
|
+
shadow: {
|
|
6
|
+
functional: string;
|
|
7
|
+
brand: string;
|
|
8
|
+
energy: string;
|
|
9
|
+
broadband: string;
|
|
10
|
+
mobile: string;
|
|
11
|
+
insurance: string;
|
|
12
|
+
cashback: string;
|
|
13
|
+
pig: string;
|
|
14
|
+
};
|
|
5
15
|
focusVisible: {
|
|
6
16
|
outlineStyle: string;
|
|
7
17
|
outlineWidth: number;
|
|
@@ -1352,6 +1362,16 @@ export declare const lightTheme: {
|
|
|
1352
1362
|
};
|
|
1353
1363
|
export declare const darkTheme: {
|
|
1354
1364
|
readonly helpers: {
|
|
1365
|
+
shadow: {
|
|
1366
|
+
functional: string;
|
|
1367
|
+
brand: string;
|
|
1368
|
+
energy: string;
|
|
1369
|
+
broadband: string;
|
|
1370
|
+
mobile: string;
|
|
1371
|
+
insurance: string;
|
|
1372
|
+
cashback: string;
|
|
1373
|
+
pig: string;
|
|
1374
|
+
};
|
|
1355
1375
|
focusVisible: {
|
|
1356
1376
|
outlineStyle: string;
|
|
1357
1377
|
outlineWidth: number;
|
|
@@ -2714,6 +2734,16 @@ export declare const darkTheme: {
|
|
|
2714
2734
|
export declare const themes: {
|
|
2715
2735
|
readonly light: {
|
|
2716
2736
|
readonly helpers: {
|
|
2737
|
+
shadow: {
|
|
2738
|
+
functional: string;
|
|
2739
|
+
brand: string;
|
|
2740
|
+
energy: string;
|
|
2741
|
+
broadband: string;
|
|
2742
|
+
mobile: string;
|
|
2743
|
+
insurance: string;
|
|
2744
|
+
cashback: string;
|
|
2745
|
+
pig: string;
|
|
2746
|
+
};
|
|
2717
2747
|
focusVisible: {
|
|
2718
2748
|
outlineStyle: string;
|
|
2719
2749
|
outlineWidth: number;
|
|
@@ -4064,6 +4094,16 @@ export declare const themes: {
|
|
|
4064
4094
|
};
|
|
4065
4095
|
readonly dark: {
|
|
4066
4096
|
readonly helpers: {
|
|
4097
|
+
shadow: {
|
|
4098
|
+
functional: string;
|
|
4099
|
+
brand: string;
|
|
4100
|
+
energy: string;
|
|
4101
|
+
broadband: string;
|
|
4102
|
+
mobile: string;
|
|
4103
|
+
insurance: string;
|
|
4104
|
+
cashback: string;
|
|
4105
|
+
pig: string;
|
|
4106
|
+
};
|
|
4067
4107
|
focusVisible: {
|
|
4068
4108
|
outlineStyle: string;
|
|
4069
4109
|
outlineWidth: number;
|
package/build/core/themes.js
CHANGED
|
@@ -254,6 +254,16 @@ const shared = {
|
|
|
254
254
|
};
|
|
255
255
|
const lightHelpers = {
|
|
256
256
|
...shared.helpers,
|
|
257
|
+
shadow: {
|
|
258
|
+
functional: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.default}`,
|
|
259
|
+
brand: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.brand}`,
|
|
260
|
+
energy: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.energy}`,
|
|
261
|
+
broadband: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.broadband}`,
|
|
262
|
+
mobile: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.mobile}`,
|
|
263
|
+
insurance: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.insurance}`,
|
|
264
|
+
cashback: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.cashback}`,
|
|
265
|
+
pig: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${light.shadow.pig}`,
|
|
266
|
+
},
|
|
257
267
|
focusVisible: {
|
|
258
268
|
outlineStyle: 'solid',
|
|
259
269
|
outlineWidth: 2,
|
|
@@ -286,6 +296,16 @@ export const lightTheme = {
|
|
|
286
296
|
};
|
|
287
297
|
const darkHelpers = {
|
|
288
298
|
...shared.helpers,
|
|
299
|
+
shadow: {
|
|
300
|
+
functional: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.default}`,
|
|
301
|
+
brand: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.brand}`,
|
|
302
|
+
energy: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.energy}`,
|
|
303
|
+
broadband: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.broadband}`,
|
|
304
|
+
mobile: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.mobile}`,
|
|
305
|
+
insurance: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.insurance}`,
|
|
306
|
+
cashback: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.cashback}`,
|
|
307
|
+
pig: `${shadow.mobile.md.x}px ${shadow.mobile.md.y}px ${shadow.mobile.md.spread}px ${dark.shadow.pig}`,
|
|
308
|
+
},
|
|
289
309
|
focusVisible: {
|
|
290
310
|
outlineStyle: 'solid',
|
|
291
311
|
outlineWidth: 2,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { BackToTopButton, NextPrevPage } from './components';
|
|
3
|
+
|
|
4
|
+
<Meta title="Guides / Adding Shadows" />
|
|
5
|
+
<BackToTopButton />
|
|
6
|
+
|
|
7
|
+
# Adding Shadows
|
|
8
|
+
|
|
9
|
+
You can add shadows to your components in Hearth React Native using the Unistyles styling system. Shadows help create depth and visual hierarchy in your UI.
|
|
10
|
+
|
|
11
|
+
- [Using Predefined Shadows](#using-predefined-shadows)
|
|
12
|
+
- [Components with Shadow Props](#components-with-shadow-props)
|
|
13
|
+
|
|
14
|
+
## Using Predefined Shadows
|
|
15
|
+
|
|
16
|
+
Hearth provides a set of predefined shadow styles that you can easily apply to your components. These shadows are defined in the theme and can be accessed via the `theme.helpers.shadow` object.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { View } from 'react-native';
|
|
20
|
+
import { StyleSheet, Input } from '@utilitywarehouse/hearth-react-native';
|
|
21
|
+
|
|
22
|
+
const styles = StyleSheet.create(theme => ({
|
|
23
|
+
input: {
|
|
24
|
+
boxShadow: theme.helpers.shadow.functional, // Apply a predefined shadow
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
const MyComponent = () => (
|
|
29
|
+
<View>
|
|
30
|
+
<Input placeholder="Input with shadow" style={styles.input} />
|
|
31
|
+
</View>
|
|
32
|
+
);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Components with Shadow Props
|
|
36
|
+
|
|
37
|
+
Some Hearth components, like `Card`, allow you to specify shadow colors directly via props. You can use the `shadowColor` prop to set the shadow color based on the theme.
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Card } from '@utilitywarehouse/hearth-react-native';
|
|
41
|
+
|
|
42
|
+
const MyComponent = () => <Card shadowColor="brand">{/* Card content */}</Card>;
|
|
43
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilitywarehouse/hearth-react-native",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Utility Warehouse React Native UI library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"vite-plugin-svgr": "^4.5.0",
|
|
58
58
|
"vitest": "^3.2.4",
|
|
59
59
|
"@utilitywarehouse/hearth-fonts": "^0.0.4",
|
|
60
|
-
"@utilitywarehouse/hearth-react-icons": "^0.7.
|
|
61
|
-
"@utilitywarehouse/hearth-react-native-icons": "^0.7.
|
|
60
|
+
"@utilitywarehouse/hearth-react-icons": "^0.7.3",
|
|
61
|
+
"@utilitywarehouse/hearth-react-native-icons": "^0.7.3",
|
|
62
62
|
"@utilitywarehouse/hearth-svg-assets": "^0.2.0",
|
|
63
63
|
"@utilitywarehouse/hearth-tokens": "^0.1.3"
|
|
64
64
|
},
|
|
@@ -24,7 +24,7 @@ The `Banner` component is a versatile card-based component for displaying inform
|
|
|
24
24
|
- [With Link](#with-link)
|
|
25
25
|
- [Pressable](#pressable)
|
|
26
26
|
- [With Close Button](#with-close-button)
|
|
27
|
-
- [Vertical Layout](#vertical-layout)
|
|
27
|
+
- [Vertical Layout](#vertical-layout-1)
|
|
28
28
|
- [Color Schemes](#color-schemes)
|
|
29
29
|
- [Complex Examples](#complex-examples)
|
|
30
30
|
|
|
@@ -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
|
|
|
5
6
|
export type BannerDirection = 'horizontal' | 'vertical';
|
|
6
7
|
|
|
@@ -50,18 +51,12 @@ export interface BannerProps
|
|
|
50
51
|
* Illustration to display in the banner
|
|
51
52
|
* Mutually exclusive with icon and image
|
|
52
53
|
*/
|
|
53
|
-
illustration?:
|
|
54
|
-
light: ImageSourcePropType | ReactElement | ComponentType;
|
|
55
|
-
dark: ImageSourcePropType | ReactElement | ComponentType;
|
|
56
|
-
};
|
|
54
|
+
illustration?: ThemedImageProps & ImageProps;
|
|
57
55
|
/**
|
|
58
56
|
* Image to display in the banner
|
|
59
57
|
* Mutually exclusive with icon and illustration
|
|
60
58
|
*/
|
|
61
|
-
image?:
|
|
62
|
-
light: ImageSourcePropType | ReactElement | ComponentType;
|
|
63
|
-
dark: ImageSourcePropType | ReactElement | ComponentType;
|
|
64
|
-
};
|
|
59
|
+
image?: ThemedImageProps & ImageProps;
|
|
65
60
|
/**
|
|
66
61
|
* Heading text
|
|
67
62
|
*/
|