@utilitywarehouse/hearth-react-native 0.11.0 → 0.12.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 (100) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/CHANGELOG.md +10 -0
  4. package/build/components/Banner/Banner.context.d.ts +7 -0
  5. package/build/components/Banner/Banner.context.js +8 -0
  6. package/build/components/Banner/Banner.js +10 -40
  7. package/build/components/Banner/Banner.props.d.ts +3 -5
  8. package/build/components/Banner/BannerIllustration.d.ts +4 -0
  9. package/build/components/Banner/BannerIllustration.js +53 -0
  10. package/build/components/Banner/BannerImage.d.ts +4 -0
  11. package/build/components/Banner/BannerImage.js +53 -0
  12. package/build/components/Banner/index.d.ts +2 -0
  13. package/build/components/Banner/index.js +2 -0
  14. package/build/components/Card/CardAction/CardAction.props.d.ts +2 -3
  15. package/build/components/Card/CardAction/CardActionRoot.js +1 -2
  16. package/build/components/Checkbox/Checkbox.js +1 -2
  17. package/build/components/Checkbox/Checkbox.props.d.ts +3 -3
  18. package/build/components/Checkbox/CheckboxImage.d.ts +2 -1
  19. package/build/components/Checkbox/CheckboxImage.js +8 -1
  20. package/build/components/ExpandableCard/ExpandableCard.props.d.ts +1 -2
  21. package/build/components/ExpandableCard/ExpandableCardTrigger.props.d.ts +4 -5
  22. package/build/components/ExpandableCard/ExpandableCardTriggerRoot.js +1 -14
  23. package/build/components/HighlightBanner/HighlightBanner.js +2 -6
  24. package/build/components/HighlightBanner/HighlightBanner.props.d.ts +2 -3
  25. package/build/components/HighlightBanner/HighlightBannerImage.d.ts +4 -0
  26. package/build/components/HighlightBanner/HighlightBannerImage.js +18 -0
  27. package/build/components/HighlightBanner/index.d.ts +1 -0
  28. package/build/components/HighlightBanner/index.js +1 -0
  29. package/build/components/Input/Input.d.ts +5 -7
  30. package/build/components/Input/Input.js +11 -4
  31. package/build/components/Input/InputField.d.ts +4 -7
  32. package/build/components/Input/InputField.js +6 -5
  33. package/build/components/List/ListItem/ListItem.props.d.ts +2 -2
  34. package/build/components/List/ListItem/ListItemRoot.js +1 -2
  35. package/build/components/Modal/Modal.js +2 -6
  36. package/build/components/Modal/Modal.props.d.ts +3 -2
  37. package/build/components/Modal/Modal.web.js +2 -6
  38. package/build/components/Modal/ModalImage.d.ts +4 -0
  39. package/build/components/Modal/ModalImage.js +18 -0
  40. package/build/components/Modal/index.d.ts +1 -0
  41. package/build/components/Modal/index.js +1 -0
  42. package/build/components/Radio/Radio.js +1 -2
  43. package/build/components/Radio/Radio.props.d.ts +3 -3
  44. package/build/components/Radio/RadioImage.d.ts +2 -1
  45. package/build/components/Radio/RadioImage.js +8 -1
  46. package/build/utils/index.d.ts +2 -1
  47. package/build/utils/index.js +2 -1
  48. package/build/utils/isThemedImageProps.d.ts +4 -0
  49. package/build/utils/isThemedImageProps.js +4 -0
  50. package/package.json +2 -2
  51. package/src/components/Banner/Banner.context.ts +11 -0
  52. package/src/components/Banner/Banner.docs.mdx +55 -37
  53. package/src/components/Banner/Banner.props.ts +3 -5
  54. package/src/components/Banner/Banner.stories.tsx +86 -57
  55. package/src/components/Banner/Banner.tsx +24 -67
  56. package/src/components/Banner/BannerIllustration.tsx +63 -0
  57. package/src/components/Banner/BannerImage.tsx +63 -0
  58. package/src/components/Banner/index.ts +2 -0
  59. package/src/components/Card/Card.docs.mdx +4 -4
  60. package/src/components/Card/CardAction/CardAction.props.ts +2 -3
  61. package/src/components/Card/CardAction/CardAction.stories.tsx +4 -3
  62. package/src/components/Card/CardAction/CardActionRoot.tsx +4 -5
  63. package/src/components/Checkbox/Checkbox.docs.mdx +23 -4
  64. package/src/components/Checkbox/Checkbox.props.ts +3 -3
  65. package/src/components/Checkbox/Checkbox.stories.tsx +14 -8
  66. package/src/components/Checkbox/Checkbox.tsx +1 -2
  67. package/src/components/Checkbox/CheckboxImage.tsx +8 -3
  68. package/src/components/ExpandableCard/ExpandableCard.docs.mdx +2 -2
  69. package/src/components/ExpandableCard/ExpandableCard.props.ts +1 -2
  70. package/src/components/ExpandableCard/ExpandableCard.stories.tsx +3 -3
  71. package/src/components/ExpandableCard/ExpandableCardTrigger.props.ts +4 -5
  72. package/src/components/ExpandableCard/ExpandableCardTriggerRoot.tsx +2 -17
  73. package/src/components/HighlightBanner/HighlightBanner.docs.mdx +73 -42
  74. package/src/components/HighlightBanner/HighlightBanner.props.ts +2 -3
  75. package/src/components/HighlightBanner/HighlightBanner.stories.tsx +85 -60
  76. package/src/components/HighlightBanner/HighlightBanner.tsx +3 -10
  77. package/src/components/HighlightBanner/HighlightBannerImage.tsx +20 -0
  78. package/src/components/HighlightBanner/index.ts +1 -0
  79. package/src/components/Input/Input.stories.tsx +76 -3
  80. package/src/components/Input/Input.tsx +110 -98
  81. package/src/components/Input/InputField.tsx +27 -26
  82. package/src/components/List/List.docs.mdx +15 -9
  83. package/src/components/List/List.stories.tsx +2 -2
  84. package/src/components/List/ListItem/ListItem.props.ts +2 -2
  85. package/src/components/List/ListItem/ListItemRoot.tsx +2 -3
  86. package/src/components/Modal/Modal.docs.mdx +16 -4
  87. package/src/components/Modal/Modal.props.ts +3 -2
  88. package/src/components/Modal/Modal.stories.tsx +2 -5
  89. package/src/components/Modal/Modal.tsx +2 -6
  90. package/src/components/Modal/Modal.web.tsx +2 -6
  91. package/src/components/Modal/ModalImage.tsx +20 -0
  92. package/src/components/Modal/index.ts +1 -0
  93. package/src/components/PillGroup/PillGroup.stories.tsx +1 -1
  94. package/src/components/Radio/Radio.docs.mdx +21 -8
  95. package/src/components/Radio/Radio.props.ts +3 -3
  96. package/src/components/Radio/Radio.stories.tsx +15 -11
  97. package/src/components/Radio/Radio.tsx +1 -2
  98. package/src/components/Radio/RadioImage.tsx +8 -3
  99. package/src/utils/index.ts +2 -1
  100. package/src/utils/isThemedImageProps.ts +8 -0
@@ -13,6 +13,8 @@ import { Button } from '../Button';
13
13
  import { Flex } from '../Flex';
14
14
  import { Link } from '../Link';
15
15
  import Banner from './Banner';
16
+ import BannerIllustration from './BannerIllustration';
17
+ import BannerImage from './BannerImage';
16
18
 
17
19
  const meta = {
18
20
  title: 'Stories / Banner',
@@ -128,23 +130,35 @@ export const WithIllustration: Story = {
128
130
  <View style={{ width: 400 }}>
129
131
  <Flex space="lg" direction="column">
130
132
  <Banner
131
- illustration={{
132
- // @ts-ignore
133
- light: <SpotBillingLight width={80} height={80} />,
134
- // @ts-ignore
135
- dark: <SpotBillingDark width={80} height={80} />,
136
- }}
133
+ illustration={
134
+ <BannerIllustration
135
+ light={
136
+ // @ts-ignore
137
+ <SpotBillingLight width={80} height={80} />
138
+ }
139
+ dark={
140
+ // @ts-ignore
141
+ <SpotBillingDark width={80} height={80} />
142
+ }
143
+ />
144
+ }
137
145
  heading="Featured Content"
138
146
  description="Discover amazing content curated just for you."
139
147
  />
140
148
  <Banner
141
149
  direction="vertical"
142
- illustration={{
143
- // @ts-ignore
144
- light: <SpotBillingLight width={120} height={120} />,
145
- // @ts-ignore
146
- dark: <SpotBillingDark width={120} height={120} />,
147
- }}
150
+ illustration={
151
+ <BannerIllustration
152
+ light={
153
+ // @ts-ignore
154
+ <SpotBillingLight width={120} height={120} />
155
+ }
156
+ dark={
157
+ // @ts-ignore
158
+ <SpotBillingDark width={120} height={120} />
159
+ }
160
+ />
161
+ }
148
162
  heading="Special Offer"
149
163
  description="Limited time offer on selected services."
150
164
  />
@@ -160,27 +174,31 @@ export const WithImage: Story = {
160
174
  <View style={{ width: 400 }}>
161
175
  <Flex space="lg" direction="column">
162
176
  <Banner
163
- image={{
164
- light: {
165
- uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
166
- },
167
- dark: {
168
- uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
169
- },
170
- }}
177
+ image={
178
+ <BannerImage
179
+ light={{
180
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
181
+ }}
182
+ dark={{
183
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
184
+ }}
185
+ />
186
+ }
171
187
  heading="Featured Content"
172
188
  description="Discover amazing content curated just for you."
173
189
  />
174
190
  <Banner
175
191
  direction="vertical"
176
- image={{
177
- light: {
178
- uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
179
- },
180
- dark: {
181
- uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
182
- },
183
- }}
192
+ image={
193
+ <BannerImage
194
+ light={{
195
+ uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
196
+ }}
197
+ dark={{
198
+ uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
199
+ }}
200
+ />
201
+ }
184
202
  heading="Special Offer"
185
203
  description="Limited time offer on selected services."
186
204
  />
@@ -262,14 +280,16 @@ export const Pressable: Story = {
262
280
  onPress={() => console.log('Banner pressed')}
263
281
  />
264
282
  <Banner
265
- image={{
266
- light: {
267
- uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
268
- },
269
- dark: {
270
- uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
271
- },
272
- }}
283
+ image={
284
+ <BannerImage
285
+ light={{
286
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
287
+ }}
288
+ dark={{
289
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
290
+ }}
291
+ />
292
+ }
273
293
  heading="Account Settings"
274
294
  description="Manage your account preferences."
275
295
  onPress={() => console.log('Banner pressed')}
@@ -325,11 +345,16 @@ export const VerticalLayout: Story = {
325
345
  />
326
346
  <Banner
327
347
  variant="emphasis"
328
- image={{
329
- source: {
330
- uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
331
- },
332
- }}
348
+ image={
349
+ <BannerImage
350
+ light={{
351
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
352
+ }}
353
+ dark={{
354
+ uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=200&q=80',
355
+ }}
356
+ />
357
+ }
333
358
  heading="Featured Content"
334
359
  description="Discover amazing content curated just for you."
335
360
  shadowColor="brand"
@@ -443,14 +468,16 @@ export const EmphasisVariant: Story = {
443
468
  variant="emphasis"
444
469
  />
445
470
  <Banner
446
- image={{
447
- light: {
448
- uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
449
- },
450
- dark: {
451
- uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
452
- },
453
- }}
471
+ image={
472
+ <BannerImage
473
+ light={{
474
+ uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
475
+ }}
476
+ dark={{
477
+ uri: 'https://images.unsplash.com/photo-1473186578172-c141e6798cf4?w=200&q=80',
478
+ }}
479
+ />
480
+ }
454
481
  heading="Featured Offer"
455
482
  description="Limited time deal on premium services."
456
483
  variant="emphasis"
@@ -486,14 +513,16 @@ export const ComplexExample: Story = {
486
513
  onPress={() => console.log('Banner pressed')}
487
514
  />
488
515
  <Banner
489
- image={{
490
- light: {
491
- uri: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=200&q=80',
492
- },
493
- dark: {
494
- uri: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=200&q=80',
495
- },
496
- }}
516
+ image={
517
+ <BannerImage
518
+ light={{
519
+ uri: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=200&q=80',
520
+ }}
521
+ dark={{
522
+ uri: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=200&q=80',
523
+ }}
524
+ />
525
+ }
497
526
  heading="Exclusive Member Benefit"
498
527
  description="As a valued member, you now have access to premium features at no extra cost."
499
528
  variant="emphasis"
@@ -1,18 +1,15 @@
1
1
  import { ChevronRightSmallIcon, CloseSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
2
- import { Image, ImageProps, Pressable, View } from 'react-native';
2
+ import { useMemo } from 'react';
3
+ import { Pressable, View } from 'react-native';
3
4
  import { StyleSheet } from 'react-native-unistyles';
4
5
  import { BodyText } from '../BodyText';
5
6
  import { Card } from '../Card';
6
7
  import { Heading } from '../Heading';
7
8
  import { IconContainer } from '../IconContainer';
8
- import { ThemedImage, ThemedImageProps } from '../ThemedImage';
9
9
  import { UnstyledIconButton } from '../UnstyledIconButton';
10
+ import BannerContext from './Banner.context';
10
11
  import type BannerProps from './Banner.props';
11
12
 
12
- const isThemedImageProps = (props: ThemedImageProps | ImageProps): props is ThemedImageProps => {
13
- return 'light' in props && 'dark' in props;
14
- };
15
-
16
13
  const Banner = ({
17
14
  icon,
18
15
  iconContainerVariant = 'subtle',
@@ -35,6 +32,13 @@ const Banner = ({
35
32
  const hasIllustration = Boolean(illustration);
36
33
  styles.useVariants({ direction, hasIllustration });
37
34
 
35
+ const context = useMemo(
36
+ () => ({
37
+ direction,
38
+ }),
39
+ [direction]
40
+ );
41
+
38
42
  const renderIconOrImage = () => {
39
43
  if (icon) {
40
44
  return (
@@ -48,36 +52,10 @@ const Banner = ({
48
52
  );
49
53
  }
50
54
  if (illustration) {
51
- if (isThemedImageProps(illustration)) {
52
- return (
53
- <ThemedImage
54
- {...illustration}
55
- resizeMode="cover"
56
- style={[styles.media, styles.imageWrapper, illustration.style]}
57
- />
58
- );
59
- }
60
- return (
61
- <Image
62
- {...illustration}
63
- resizeMode="cover"
64
- style={[styles.media, styles.imageWrapper, illustration.style]}
65
- />
66
- );
55
+ return illustration;
67
56
  }
68
57
  if (image) {
69
- if (isThemedImageProps(image)) {
70
- return (
71
- <View style={[styles.media, styles.imageWrapper]}>
72
- <ThemedImage {...image} style={[styles.image, image.style]} />
73
- </View>
74
- );
75
- }
76
- return (
77
- <View style={[styles.media, styles.imageWrapper]}>
78
- <Image {...image} style={[styles.image, image.style]} />
79
- </View>
80
- );
58
+ return image;
81
59
  }
82
60
  return null;
83
61
  };
@@ -149,18 +127,22 @@ const Banner = ({
149
127
 
150
128
  if (onPress) {
151
129
  return (
152
- <Card variant={variant} style={[styles.card, style]} {...props}>
153
- <Pressable onPress={onPress} accessibilityRole="button" style={styles.pressable}>
154
- {content}
155
- </Pressable>
156
- </Card>
130
+ <BannerContext.Provider value={context}>
131
+ <Card variant={variant} style={[styles.card, style]} {...props}>
132
+ <Pressable onPress={onPress} accessibilityRole="button" style={styles.pressable}>
133
+ {content}
134
+ </Pressable>
135
+ </Card>
136
+ </BannerContext.Provider>
157
137
  );
158
138
  }
159
139
 
160
140
  return (
161
- <Card variant={variant} style={[styles.card, style]} {...props}>
162
- {content}
163
- </Card>
141
+ <BannerContext.Provider value={context}>
142
+ <Card variant={variant} style={[styles.card, style]} {...props}>
143
+ {content}
144
+ </Card>
145
+ </BannerContext.Provider>
164
146
  );
165
147
  };
166
148
 
@@ -218,31 +200,6 @@ const styles = StyleSheet.create(theme => ({
218
200
  },
219
201
  },
220
202
  },
221
- imageWrapper: {
222
- flexDirection: 'row',
223
- variants: {
224
- direction: {
225
- horizontal: {},
226
- vertical: {
227
- width: '100%',
228
- },
229
- },
230
- },
231
- },
232
- image: {
233
- borderRadius: theme.borderRadius.md,
234
- borderColor: theme.color.border.strong,
235
- borderWidth: theme.borderWidth[1],
236
- variants: {
237
- direction: {
238
- horizontal: { width: 160, height: 95 },
239
- vertical: {
240
- width: '100%',
241
- height: 160,
242
- },
243
- },
244
- },
245
- },
246
203
  contentContainer: {
247
204
  alignItems: 'flex-start',
248
205
  justifyContent: 'space-between',
@@ -0,0 +1,63 @@
1
+ import { Image, ImageProps, View } from 'react-native';
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+ import { isThemedImageProps } from '../../utils';
4
+ import { ThemedImage, ThemedImageProps } from '../ThemedImage';
5
+ import { useBannerContext } from './Banner.context';
6
+
7
+ const BannerIllustration = (props: ImageProps | ThemedImageProps) => {
8
+ const { direction } = useBannerContext();
9
+ styles.useVariants({ direction });
10
+ if (isThemedImageProps(props)) {
11
+ return (
12
+ <View style={[styles.media, styles.imageWrapper]}>
13
+ <ThemedImage {...props} style={[styles.image, props.style]} />
14
+ </View>
15
+ );
16
+ }
17
+ return (
18
+ <View style={[styles.media, styles.imageWrapper]}>
19
+ <Image {...props} style={[styles.image, props.style]} />
20
+ </View>
21
+ );
22
+ };
23
+
24
+ const styles = StyleSheet.create(theme => ({
25
+ media: {
26
+ flexShrink: 0,
27
+ variants: {
28
+ direction: {
29
+ horizontal: {},
30
+ vertical: {
31
+ alignSelf: 'flex-start',
32
+ },
33
+ },
34
+ },
35
+ },
36
+ imageWrapper: {
37
+ flexDirection: 'row',
38
+ variants: {
39
+ direction: {
40
+ horizontal: {},
41
+ vertical: {
42
+ width: '100%',
43
+ },
44
+ },
45
+ },
46
+ },
47
+ image: {
48
+ borderRadius: theme.borderRadius.md,
49
+ borderColor: theme.color.border.strong,
50
+ borderWidth: theme.borderWidth[1],
51
+ variants: {
52
+ direction: {
53
+ horizontal: { width: 160, height: 95 },
54
+ vertical: {
55
+ width: '100%',
56
+ height: 160,
57
+ },
58
+ },
59
+ },
60
+ },
61
+ }));
62
+
63
+ export default BannerIllustration;
@@ -0,0 +1,63 @@
1
+ import { Image, ImageProps, View } from 'react-native';
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+ import { isThemedImageProps } from '../../utils';
4
+ import { ThemedImage, ThemedImageProps } from '../ThemedImage';
5
+ import { useBannerContext } from './Banner.context';
6
+
7
+ const BannerImage = (props: ImageProps | ThemedImageProps) => {
8
+ const { direction } = useBannerContext();
9
+ styles.useVariants({ direction });
10
+ if (isThemedImageProps(props)) {
11
+ return (
12
+ <View style={[styles.media, styles.imageWrapper]}>
13
+ <ThemedImage {...props} style={[styles.image, props.style]} />
14
+ </View>
15
+ );
16
+ }
17
+ return (
18
+ <View style={[styles.media, styles.imageWrapper]}>
19
+ <Image {...props} style={[styles.image, props.style]} />
20
+ </View>
21
+ );
22
+ };
23
+
24
+ const styles = StyleSheet.create(theme => ({
25
+ media: {
26
+ flexShrink: 0,
27
+ variants: {
28
+ direction: {
29
+ horizontal: {},
30
+ vertical: {
31
+ alignSelf: 'flex-start',
32
+ },
33
+ },
34
+ },
35
+ },
36
+ imageWrapper: {
37
+ flexDirection: 'row',
38
+ variants: {
39
+ direction: {
40
+ horizontal: {},
41
+ vertical: {
42
+ width: '100%',
43
+ },
44
+ },
45
+ },
46
+ },
47
+ image: {
48
+ borderRadius: theme.borderRadius.md,
49
+ borderColor: theme.color.border.strong,
50
+ borderWidth: theme.borderWidth[1],
51
+ variants: {
52
+ direction: {
53
+ horizontal: { width: 160, height: 95 },
54
+ vertical: {
55
+ width: '100%',
56
+ height: 160,
57
+ },
58
+ },
59
+ },
60
+ },
61
+ }));
62
+
63
+ export default BannerImage;
@@ -1,2 +1,4 @@
1
1
  export { default as Banner } from './Banner';
2
2
  export type { default as BannerProps } from './Banner.props';
3
+ export { default as BannerIllustration } from './BannerIllustration';
4
+ export { default as BannerImage } from './BannerImage';
@@ -209,7 +209,7 @@ const MyComponent = () => (
209
209
  The badge can be positioned in three different locations:
210
210
 
211
211
  ```tsx
212
- import { Card, CardAction } from '@utilitywarehouse/hearth-react-native';
212
+ import { Card, CardAction, Badge } from '@utilitywarehouse/hearth-react-native';
213
213
 
214
214
  const MyComponent = () => (
215
215
  <>
@@ -218,7 +218,7 @@ const MyComponent = () => (
218
218
  <CardAction
219
219
  heading="Action"
220
220
  helperText="Helper text"
221
- badge={{ text: 'New' }}
221
+ badge={<Badge text="New" />}
222
222
  badgePosition="bottom"
223
223
  onPress={() => console.log('pressed')}
224
224
  />
@@ -229,7 +229,7 @@ const MyComponent = () => (
229
229
  <CardAction
230
230
  heading="Action"
231
231
  helperText="Helper text"
232
- badge={{ text: 'New' }}
232
+ badge={<Badge text="New" />}
233
233
  badgePosition="middle"
234
234
  onPress={() => console.log('pressed')}
235
235
  />
@@ -240,7 +240,7 @@ const MyComponent = () => (
240
240
  <CardAction
241
241
  heading="Action"
242
242
  helperText="Helper text"
243
- badge={{ text: 'New' }}
243
+ badge={<Badge text="New" />}
244
244
  badgePosition="right"
245
245
  onPress={() => console.log('pressed')}
246
246
  />
@@ -1,6 +1,5 @@
1
- import { ComponentType } from 'react';
1
+ import { ComponentType, ReactNode } from 'react';
2
2
  import type { PressableProps, ViewProps } from 'react-native';
3
- import BadgeProps from '../../Badge/Badge.props';
4
3
  import { IconContainerProps } from '../../IconContainer';
5
4
 
6
5
  interface CardActionBaseProps extends Omit<PressableProps, 'children'> {
@@ -12,7 +11,7 @@ interface CardActionBaseProps extends Omit<PressableProps, 'children'> {
12
11
  interface CardActionContentProps {
13
12
  heading: string;
14
13
  helperText?: string;
15
- badge?: BadgeProps;
14
+ badge?: ReactNode;
16
15
  badgePosition?: 'bottom' | 'middle' | 'right' | 'top';
17
16
  iconContainer?: boolean;
18
17
  iconContainerVariant?: IconContainerProps['variant'];
@@ -2,6 +2,7 @@ import { Meta, StoryObj } from '@storybook/react';
2
2
  import * as Icons from '@utilitywarehouse/hearth-react-native-icons';
3
3
  import { ElectricityMediumIcon, GasMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
4
4
  import { View } from 'react-native';
5
+ import { Badge } from '../../Badge';
5
6
  import { Flex } from '../../Flex';
6
7
  import Card from '../Card';
7
8
  import CardAction from './CardAction';
@@ -169,7 +170,7 @@ export const WithBadge: Story = {
169
170
  heading="Badge at bottom"
170
171
  helperText="Badge positioned below text"
171
172
  leadingIcon={ElectricityMediumIcon}
172
- badge={{ text: 'New' }}
173
+ badge={<Badge text="New" />}
173
174
  badgePosition="bottom"
174
175
  onPress={() => console.log('pressed')}
175
176
  />
@@ -179,7 +180,7 @@ export const WithBadge: Story = {
179
180
  heading="Badge at middle"
180
181
  helperText="Badge positioned between heading and helper text"
181
182
  leadingIcon={ElectricityMediumIcon}
182
- badge={{ text: 'New' }}
183
+ badge={<Badge text="New" />}
183
184
  badgePosition="middle"
184
185
  onPress={() => console.log('pressed')}
185
186
  />
@@ -189,7 +190,7 @@ export const WithBadge: Story = {
189
190
  heading="Badge at right"
190
191
  helperText="Badge positioned on the right side"
191
192
  leadingIcon={ElectricityMediumIcon}
192
- badge={{ text: 'New' }}
193
+ badge={<Badge text="New" />}
193
194
  badgePosition="right"
194
195
  onPress={() => console.log('pressed')}
195
196
  />
@@ -2,7 +2,6 @@ import { ChevronRightSmallIcon } from '@utilitywarehouse/hearth-react-native-ico
2
2
  import { useMemo } from 'react';
3
3
  import { Pressable, View, ViewStyle } from 'react-native';
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
- import { Badge } from '../../Badge';
6
5
  import { IconContainer } from '../../IconContainer';
7
6
  import { Skeleton } from '../../Skeleton';
8
7
  import { useCardContext } from '../Card.context';
@@ -124,14 +123,14 @@ const CardActionRoot = ({
124
123
  </CardActionLeadingContent>
125
124
  ) : null}
126
125
  <CardActionContent>
127
- {badgePosition === 'top' && badge ? <Badge {...badge} /> : null}
126
+ {badgePosition === 'top' && badge ? badge : null}
128
127
  <CardActionText>{heading}</CardActionText>
129
- {badgePosition === 'middle' && badge ? <Badge {...badge} /> : null}
128
+ {badgePosition === 'middle' && badge ? badge : null}
130
129
  {helperText ? <CardActionHelperText>{helperText}</CardActionHelperText> : null}
131
- {badgePosition === 'bottom' && badge ? <Badge {...badge} /> : null}
130
+ {badgePosition === 'bottom' && badge ? badge : null}
132
131
  </CardActionContent>
133
132
  {badgePosition === 'right' && badge ? (
134
- <Badge {...badge} style={[badge.style, styles.alignCenter]} />
133
+ <View style={styles.alignCenter}>{badge}</View>
135
134
  ) : null}
136
135
  {trailingContent ? (
137
136
  <CardActionTrailingContent>{trailingContent}</CardActionTrailingContent>
@@ -91,7 +91,7 @@ const MyComponent = () => {
91
91
  | `validText` | `string` | - | The valid text to be displayed below the checkbox. |
92
92
  | `showValidationIcon` | `boolean` | `true` | Whether to show the validation icon. |
93
93
  | `type` | `'default' \| 'tile'` | `default` | The type of the checkbox. |
94
- | `image` | `ImageProps` | - | The image to be displayed next to the label. |
94
+ | `image` | `ReactNode` | - | The image to be displayed next to the label. |
95
95
 
96
96
  ## Components
97
97
 
@@ -210,6 +210,15 @@ const MyComponent = () => {
210
210
 
211
211
  ### `CheckboxImage`
212
212
 
213
+ | Property | Type | Description |
214
+ | --------- | --------------------- | ------------------------------------------------------------------------ |
215
+ | `source` | `ImageSourcePropType` | The source of the image to display |
216
+ | `light` | `ImageSourcePropType` | The source of the image to display in light mode (use instead of source) |
217
+ | `dark` | `ImageSourcePropType` | The source of the image to display in dark mode (use instead of source) |
218
+ | `...rest` | `ImageProps` | Additional props to pass to the underlying Image component |
219
+
220
+ For more details about the ThemedImage component used internally, refer to the [`ThemedImage` documentation](/docs/utility-components-themed-image--docs).
221
+
213
222
  The `CheckboxImage` component is used to display an image next to the checkbox label. It inherits all the properties of React Native's `Image` component.
214
223
 
215
224
  ## Variants
@@ -336,7 +345,7 @@ The `CheckboxImage` component is used to display an image next to the checkbox l
336
345
  <Canvas of={Stories.WithImage} />
337
346
 
338
347
  ```tsx
339
- import { Checkbox } from '@utilitywarehouse/native-ui';
348
+ import { Checkbox, CheckboxImage } from '@utilitywarehouse/hearth-react-native';
340
349
  import visaLogo from '../../../assets/visa.png';
341
350
  import mastercardLogo from '../../../assets/mastercard.png';
342
351
 
@@ -347,13 +356,23 @@ const MyComponent = () => {
347
356
  value="visa"
348
357
  aria-label="Visa"
349
358
  label="Visa"
350
- image={{ source: visaLogo, style: { width: 40, height: 24, resizeMode: 'contain' } }}
359
+ image={
360
+ <CheckboxImage
361
+ source={visaLogo}
362
+ style={{ width: 40, height: 24, resizeMode: 'contain' }}
363
+ />
364
+ }
351
365
  />
352
366
  <Checkbox
353
367
  value="mastercard"
354
368
  aria-label="Mastercard"
355
369
  label="Mastercard"
356
- image={{ source: mastercardLogo, style: { width: 40, height: 24, resizeMode: 'contain' } }}
370
+ image={
371
+ <CheckboxImage
372
+ source={mastercardLogo}
373
+ style={{ width: 40, height: 24, resizeMode: 'contain' }}
374
+ />
375
+ }
357
376
  />
358
377
  </CheckboxGroup>
359
378
  );
@@ -1,5 +1,5 @@
1
- import type { ComponentType } from 'react';
2
- import type { ImageProps, PressableProps, ViewProps } from 'react-native';
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import type { PressableProps, ViewProps } from 'react-native';
3
3
 
4
4
  type CheckboxBaseProps = {
5
5
  onChange?: (isSelected: boolean) => void;
@@ -37,7 +37,7 @@ type CheckboxWithoutChildrenProps = {
37
37
  invalidText?: string;
38
38
  validText?: string;
39
39
  showValidationIcon?: boolean;
40
- image?: ImageProps;
40
+ image?: ReactNode;
41
41
  } & CheckboxBaseProps;
42
42
 
43
43
  type CheckboxProps = CheckboxWithChildrenProps | CheckboxWithoutChildrenProps;