@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
@@ -1,4 +1,4 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.11.0 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.12.0 build /home/runner/work/hearth/hearth/packages/react-native
3
3
  > tsc
4
4
 
@@ -1,5 +1,5 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.11.0 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.12.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,15 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#685](https://github.com/utilitywarehouse/hearth/pull/685) [`10f5209`](https://github.com/utilitywarehouse/hearth/commit/10f52095e5f36e58f9821e3fec3fdf43f4578fbb) Thanks [@jordmccord](https://github.com/jordmccord)! - [BREAKING] Component props moved from objects to React Nodes
8
+
9
+ ### Patch Changes
10
+
11
+ - [#687](https://github.com/utilitywarehouse/hearth/pull/687) [`11e8176`](https://github.com/utilitywarehouse/hearth/commit/11e8176ced40b0a8b2d27e07c482ed10a7b7ce7a) Thanks [@jordmccord](https://github.com/jordmccord)! - Fixes `Input` refs
12
+
3
13
  ## 0.11.0
4
14
 
5
15
  ### Minor Changes
@@ -0,0 +1,7 @@
1
+ declare const BannerContext: import("react").Context<{
2
+ direction: "horizontal" | "vertical";
3
+ }>;
4
+ export declare const useBannerContext: () => {
5
+ direction: "horizontal" | "vertical";
6
+ };
7
+ export default BannerContext;
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from 'react';
2
+ const BannerContext = createContext({
3
+ direction: 'horizontal',
4
+ });
5
+ export const useBannerContext = () => {
6
+ return useContext(BannerContext);
7
+ };
8
+ export default BannerContext;
@@ -1,34 +1,29 @@
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 { Image, Pressable, View } from 'react-native';
3
+ import { useMemo } from 'react';
4
+ import { Pressable, View } from 'react-native';
4
5
  import { StyleSheet } from 'react-native-unistyles';
5
6
  import { BodyText } from '../BodyText';
6
7
  import { Card } from '../Card';
7
8
  import { Heading } from '../Heading';
8
9
  import { IconContainer } from '../IconContainer';
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
+ import BannerContext from './Banner.context';
14
12
  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 }) => {
15
13
  const hasIllustration = Boolean(illustration);
16
14
  styles.useVariants({ direction, hasIllustration });
15
+ const context = useMemo(() => ({
16
+ direction,
17
+ }), [direction]);
17
18
  const renderIconOrImage = () => {
18
19
  if (icon) {
19
20
  return (_jsx(IconContainer, { icon: icon, variant: iconContainerVariant, size: iconContainerSize, color: iconContainerColor, style: styles.media }));
20
21
  }
21
22
  if (illustration) {
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] }));
23
+ return illustration;
26
24
  }
27
25
  if (image) {
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] }) }));
26
+ return image;
32
27
  }
33
28
  return null;
34
29
  };
@@ -43,9 +38,9 @@ const Banner = ({ icon, iconContainerVariant = 'subtle', iconContainerSize = 'md
43
38
  };
44
39
  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" }))] })] }));
45
40
  if (onPress) {
46
- return (_jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: _jsx(Pressable, { onPress: onPress, accessibilityRole: "button", style: styles.pressable, children: content }) }));
41
+ return (_jsx(BannerContext.Provider, { value: context, children: _jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: _jsx(Pressable, { onPress: onPress, accessibilityRole: "button", style: styles.pressable, children: content }) }) }));
47
42
  }
48
- return (_jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: content }));
43
+ return (_jsx(BannerContext.Provider, { value: context, children: _jsx(Card, { variant: variant, style: [styles.card, style], ...props, children: content }) }));
49
44
  };
50
45
  Banner.displayName = 'Banner';
51
46
  const styles = StyleSheet.create(theme => ({
@@ -100,31 +95,6 @@ const styles = StyleSheet.create(theme => ({
100
95
  },
101
96
  },
102
97
  },
103
- imageWrapper: {
104
- flexDirection: 'row',
105
- variants: {
106
- direction: {
107
- horizontal: {},
108
- vertical: {
109
- width: '100%',
110
- },
111
- },
112
- },
113
- },
114
- image: {
115
- borderRadius: theme.borderRadius.md,
116
- borderColor: theme.color.border.strong,
117
- borderWidth: theme.borderWidth[1],
118
- variants: {
119
- direction: {
120
- horizontal: { width: 160, height: 95 },
121
- vertical: {
122
- width: '100%',
123
- height: 160,
124
- },
125
- },
126
- },
127
- },
128
98
  contentContainer: {
129
99
  alignItems: 'flex-start',
130
100
  justifyContent: 'space-between',
@@ -1,7 +1,5 @@
1
- import type { ComponentType, ReactElement } from 'react';
2
- import { ImageProps } from 'react-native';
1
+ import type { ComponentType, ReactElement, ReactNode } from 'react';
3
2
  import type CardProps from '../Card/Card.props';
4
- import { ThemedImageProps } from '../ThemedImage';
5
3
  export type BannerDirection = 'horizontal' | 'vertical';
6
4
  export interface BannerProps extends Omit<CardProps, 'noPadding' | 'variant' | 'colorScheme' | 'space' | 'gap' | 'rowGap' | 'columnGap' | 'flexDirection' | 'flexWrap' | 'alignItems' | 'justifyContent'> {
7
5
  /**
@@ -28,12 +26,12 @@ export interface BannerProps extends Omit<CardProps, 'noPadding' | 'variant' | '
28
26
  * Illustration to display in the banner
29
27
  * Mutually exclusive with icon and image
30
28
  */
31
- illustration?: ThemedImageProps | ImageProps;
29
+ illustration?: ReactNode;
32
30
  /**
33
31
  * Image to display in the banner
34
32
  * Mutually exclusive with icon and illustration
35
33
  */
36
- image?: ThemedImageProps | ImageProps;
34
+ image?: ReactNode;
37
35
  /**
38
36
  * Heading text
39
37
  */
@@ -0,0 +1,4 @@
1
+ import { ImageProps } from 'react-native';
2
+ import { ThemedImageProps } from '../ThemedImage';
3
+ declare const BannerIllustration: (props: ImageProps | ThemedImageProps) => import("react/jsx-runtime").JSX.Element;
4
+ export default BannerIllustration;
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Image, View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { isThemedImageProps } from '../../utils';
5
+ import { ThemedImage } from '../ThemedImage';
6
+ import { useBannerContext } from './Banner.context';
7
+ const BannerIllustration = (props) => {
8
+ const { direction } = useBannerContext();
9
+ styles.useVariants({ direction });
10
+ if (isThemedImageProps(props)) {
11
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, { ...props, style: [styles.image, props.style] }) }));
12
+ }
13
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(Image, { ...props, style: [styles.image, props.style] }) }));
14
+ };
15
+ const styles = StyleSheet.create(theme => ({
16
+ media: {
17
+ flexShrink: 0,
18
+ variants: {
19
+ direction: {
20
+ horizontal: {},
21
+ vertical: {
22
+ alignSelf: 'flex-start',
23
+ },
24
+ },
25
+ },
26
+ },
27
+ imageWrapper: {
28
+ flexDirection: 'row',
29
+ variants: {
30
+ direction: {
31
+ horizontal: {},
32
+ vertical: {
33
+ width: '100%',
34
+ },
35
+ },
36
+ },
37
+ },
38
+ image: {
39
+ borderRadius: theme.borderRadius.md,
40
+ borderColor: theme.color.border.strong,
41
+ borderWidth: theme.borderWidth[1],
42
+ variants: {
43
+ direction: {
44
+ horizontal: { width: 160, height: 95 },
45
+ vertical: {
46
+ width: '100%',
47
+ height: 160,
48
+ },
49
+ },
50
+ },
51
+ },
52
+ }));
53
+ export default BannerIllustration;
@@ -0,0 +1,4 @@
1
+ import { ImageProps } from 'react-native';
2
+ import { ThemedImageProps } from '../ThemedImage';
3
+ declare const BannerImage: (props: ImageProps | ThemedImageProps) => import("react/jsx-runtime").JSX.Element;
4
+ export default BannerImage;
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Image, View } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { isThemedImageProps } from '../../utils';
5
+ import { ThemedImage } from '../ThemedImage';
6
+ import { useBannerContext } from './Banner.context';
7
+ const BannerImage = (props) => {
8
+ const { direction } = useBannerContext();
9
+ styles.useVariants({ direction });
10
+ if (isThemedImageProps(props)) {
11
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(ThemedImage, { ...props, style: [styles.image, props.style] }) }));
12
+ }
13
+ return (_jsx(View, { style: [styles.media, styles.imageWrapper], children: _jsx(Image, { ...props, style: [styles.image, props.style] }) }));
14
+ };
15
+ const styles = StyleSheet.create(theme => ({
16
+ media: {
17
+ flexShrink: 0,
18
+ variants: {
19
+ direction: {
20
+ horizontal: {},
21
+ vertical: {
22
+ alignSelf: 'flex-start',
23
+ },
24
+ },
25
+ },
26
+ },
27
+ imageWrapper: {
28
+ flexDirection: 'row',
29
+ variants: {
30
+ direction: {
31
+ horizontal: {},
32
+ vertical: {
33
+ width: '100%',
34
+ },
35
+ },
36
+ },
37
+ },
38
+ image: {
39
+ borderRadius: theme.borderRadius.md,
40
+ borderColor: theme.color.border.strong,
41
+ borderWidth: theme.borderWidth[1],
42
+ variants: {
43
+ direction: {
44
+ horizontal: { width: 160, height: 95 },
45
+ vertical: {
46
+ width: '100%',
47
+ height: 160,
48
+ },
49
+ },
50
+ },
51
+ },
52
+ }));
53
+ 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';
@@ -1 +1,3 @@
1
1
  export { default as Banner } from './Banner';
2
+ export { default as BannerIllustration } from './BannerIllustration';
3
+ export { default as BannerImage } from './BannerImage';
@@ -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
  interface CardActionBaseProps extends Omit<PressableProps, 'children'> {
6
5
  loading?: boolean;
@@ -10,7 +9,7 @@ interface CardActionBaseProps extends Omit<PressableProps, 'children'> {
10
9
  interface CardActionContentProps {
11
10
  heading: string;
12
11
  helperText?: string;
13
- badge?: BadgeProps;
12
+ badge?: ReactNode;
14
13
  badgePosition?: 'bottom' | 'middle' | 'right' | 'top';
15
14
  iconContainer?: boolean;
16
15
  iconContainerVariant?: IconContainerProps['variant'];
@@ -3,7 +3,6 @@ import { ChevronRightSmallIcon } from '@utilitywarehouse/hearth-react-native-ico
3
3
  import { useMemo } from 'react';
4
4
  import { Pressable, View } from 'react-native';
5
5
  import { StyleSheet } from 'react-native-unistyles';
6
- import { Badge } from '../../Badge';
7
6
  import { IconContainer } from '../../IconContainer';
8
7
  import { Skeleton } from '../../Skeleton';
9
8
  import { useCardContext } from '../Card.context';
@@ -46,7 +45,7 @@ const CardActionRoot = ({ heading, helperText, leadingContent, trailingContent,
46
45
  if (loading) {
47
46
  return (_jsxs(Pressable, { ...props, testID: loadingTestID, style: [styles.container, styles.alignCenter, props.style], disabled: isDisabled, children: [leadingContent || leadingIcon ? (_jsx(Skeleton, { width: 24, height: 24, style: styles.alignCenter })) : null, _jsxs(CardActionContent, { children: [_jsx(Skeleton, { width: "80%", height: 24, borderRadius: "xs" }), _jsx(Skeleton, { width: "100%", height: 24, borderRadius: "xs" })] }), trailingIcon || trailingContent ? (_jsx(Skeleton, { width: 24, height: 24, borderRadius: "xs", style: styles.alignCenter })) : null] }));
48
47
  }
49
- return (_jsx(CardActionContext.Provider, { value: value, children: _jsx(Pressable, { ...props, testID: testID, style: [styles.container, props.style], disabled: isDisabled, accessibilityRole: onPress ? 'button' : undefined, children: children ? (children) : (_jsxs(_Fragment, { children: [leadingIcon && iconContainer ? (_jsx(View, { style: styles.iconContainerWrap, children: _jsx(IconContainer, { style: styles.iconContainer, icon: leadingIcon, variant: iconContainerVariant, color: iconContainerColor, radiusNone: true }) })) : null, _jsxs(View, { style: styles.withIconContainer, children: [leadingContent ? (_jsx(CardActionLeadingContent, { children: leadingContent })) : null, leadingIcon && !iconContainer && !leadingContent ? (_jsx(CardActionLeadingContent, { children: _jsx(CardActionIcon, { as: leadingIcon }) })) : null, _jsxs(CardActionContent, { children: [badgePosition === 'top' && badge ? _jsx(Badge, { ...badge }) : null, _jsx(CardActionText, { children: heading }), badgePosition === 'middle' && badge ? _jsx(Badge, { ...badge }) : null, helperText ? _jsx(CardActionHelperText, { children: helperText }) : null, badgePosition === 'bottom' && badge ? _jsx(Badge, { ...badge }) : null] }), badgePosition === 'right' && badge ? (_jsx(Badge, { ...badge, style: [badge.style, styles.alignCenter] })) : null, trailingContent ? (_jsx(CardActionTrailingContent, { children: trailingContent })) : null, trailingIcon && !trailingContent ? (_jsx(CardActionTrailingContent, { children: _jsx(CardActionTrailingIcon, { as: trailingIcon }) })) : null] })] })) }) }));
48
+ return (_jsx(CardActionContext.Provider, { value: value, children: _jsx(Pressable, { ...props, testID: testID, style: [styles.container, props.style], disabled: isDisabled, accessibilityRole: onPress ? 'button' : undefined, children: children ? (children) : (_jsxs(_Fragment, { children: [leadingIcon && iconContainer ? (_jsx(View, { style: styles.iconContainerWrap, children: _jsx(IconContainer, { style: styles.iconContainer, icon: leadingIcon, variant: iconContainerVariant, color: iconContainerColor, radiusNone: true }) })) : null, _jsxs(View, { style: styles.withIconContainer, children: [leadingContent ? (_jsx(CardActionLeadingContent, { children: leadingContent })) : null, leadingIcon && !iconContainer && !leadingContent ? (_jsx(CardActionLeadingContent, { children: _jsx(CardActionIcon, { as: leadingIcon }) })) : null, _jsxs(CardActionContent, { children: [badgePosition === 'top' && badge ? badge : null, _jsx(CardActionText, { children: heading }), badgePosition === 'middle' && badge ? badge : null, helperText ? _jsx(CardActionHelperText, { children: helperText }) : null, badgePosition === 'bottom' && badge ? badge : null] }), badgePosition === 'right' && badge ? (_jsx(View, { style: styles.alignCenter, children: badge })) : null, trailingContent ? (_jsx(CardActionTrailingContent, { children: trailingContent })) : null, trailingIcon && !trailingContent ? (_jsx(CardActionTrailingContent, { children: _jsx(CardActionTrailingIcon, { as: trailingIcon }) })) : null] })] })) }) }));
50
49
  };
51
50
  CardActionRoot.displayName = 'CardActionRoot';
52
51
  const styles = StyleSheet.create(theme => ({
@@ -5,7 +5,6 @@ import { Helper } from '../Helper';
5
5
  import { useCheckboxGroupContext } from './CheckboxGroup.context';
6
6
  import StyledCheckboxGroup from './CheckboxGroupRoot';
7
7
  import StyledCheckboxIcon from './CheckboxIcon';
8
- import CheckboxImage from './CheckboxImage';
9
8
  import StyledCheckboxIndicator from './CheckboxIndicator';
10
9
  import StyledCheckboxLabel from './CheckboxLabel';
11
10
  import StyledCheckbox from './CheckboxRoot';
@@ -31,7 +30,7 @@ const Checkbox = ({ children, label, disabled, checked, helperIcon, helperText,
31
30
  const { validationStatus: groupValidationStatus, type: groupType } = useCheckboxGroupContext();
32
31
  const validationStatus = fieldValidationStatus ?? groupValidationStatus ?? validation ?? 'initial';
33
32
  const checkboxType = groupType ?? type;
34
- const checkboxChildren = children ? (children) : (_jsxs(_Fragment, { children: [_jsx(CheckboxIndicator, { children: _jsx(CheckboxIcon, {}) }), image ? _jsx(CheckboxImage, { ...image }) : null, _jsxs(CheckboxTextContent, { children: [!!label && _jsx(CheckboxLabel, { children: label }), !!helperText && _jsx(Helper, { disabled: disabled, icon: helperIcon, text: helperText }), validationStatus === 'invalid' && !!invalidText && (_jsx(Helper, { showIcon: showValidationIcon, disabled: disabled, validationStatus: "invalid", text: invalidText })), validationStatus === 'valid' && !!validText && (_jsx(Helper, { disabled: disabled, showIcon: showValidationIcon, validationStatus: "valid", text: validText }))] })] }));
33
+ const checkboxChildren = children ? (children) : (_jsxs(_Fragment, { children: [_jsx(CheckboxIndicator, { children: _jsx(CheckboxIcon, {}) }), image ? image : null, _jsxs(CheckboxTextContent, { children: [!!label && _jsx(CheckboxLabel, { children: label }), !!helperText && _jsx(Helper, { disabled: disabled, icon: helperIcon, text: helperText }), validationStatus === 'invalid' && !!invalidText && (_jsx(Helper, { showIcon: showValidationIcon, disabled: disabled, validationStatus: "invalid", text: invalidText })), validationStatus === 'valid' && !!validText && (_jsx(Helper, { disabled: disabled, showIcon: showValidationIcon, validationStatus: "valid", text: validText }))] })] }));
35
34
  return (
36
35
  // @ts-expect-error - type
37
36
  _jsx(CheckboxComponent, { ...props, isDisabled: disabled, isChecked: checked, children: checkboxType === 'tile' ? (_jsx(CheckboxTileRoot, { children: checkboxChildren })) : (checkboxChildren) }));
@@ -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
  type CheckboxBaseProps = {
4
4
  onChange?: (isSelected: boolean) => void;
5
5
  disabled?: boolean;
@@ -30,7 +30,7 @@ type CheckboxWithoutChildrenProps = {
30
30
  invalidText?: string;
31
31
  validText?: string;
32
32
  showValidationIcon?: boolean;
33
- image?: ImageProps;
33
+ image?: ReactNode;
34
34
  } & CheckboxBaseProps;
35
35
  type CheckboxProps = CheckboxWithChildrenProps | CheckboxWithoutChildrenProps;
36
36
  export default CheckboxProps;
@@ -1,6 +1,7 @@
1
1
  import { ImageProps } from 'react-native';
2
+ import { ThemedImageProps } from '../ThemedImage';
2
3
  declare const CheckboxImage: {
3
- ({ source, style, ...props }: ImageProps): import("react/jsx-runtime").JSX.Element;
4
+ ({ ...props }: ImageProps | ThemedImageProps): import("react/jsx-runtime").JSX.Element;
4
5
  displayName: string;
5
6
  };
6
7
  export default CheckboxImage;
@@ -1,5 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Image } from 'react-native';
3
- const CheckboxImage = ({ source, style, ...props }) => (_jsx(Image, { source: source, style: style, ...props }));
3
+ import { isThemedImageProps } from '../../utils';
4
+ import { ThemedImage } from '../ThemedImage';
5
+ const CheckboxImage = ({ ...props }) => {
6
+ if (isThemedImageProps(props)) {
7
+ return _jsx(ThemedImage, { ...props });
8
+ }
9
+ return _jsx(Image, { ...props });
10
+ };
4
11
  CheckboxImage.displayName = 'CheckboxImage';
5
12
  export default CheckboxImage;
@@ -1,5 +1,4 @@
1
1
  import type { ComponentType, ReactNode } from 'react';
2
- import type BadgeProps from '../Badge/Badge.props';
3
2
  import type CardProps from '../Card/Card.props';
4
3
  export interface ExpandableCardProps extends Omit<CardProps, 'children'> {
5
4
  /**
@@ -29,7 +28,7 @@ export interface ExpandableCardProps extends Omit<CardProps, 'children'> {
29
28
  /**
30
29
  * Badge to display
31
30
  */
32
- badge?: BadgeProps;
31
+ badge?: ReactNode;
33
32
  /**
34
33
  * Badge position
35
34
  * @default 'bottom'
@@ -1,6 +1,5 @@
1
- import type { ComponentType } from 'react';
1
+ import type { ComponentType, ReactNode } from 'react';
2
2
  import type { PressableProps } from 'react-native';
3
- import type BadgeProps from '../Badge/Badge.props';
4
3
  export interface ExpandableCardTriggerProps extends Omit<PressableProps, 'children'> {
5
4
  /**
6
5
  * The main heading text
@@ -17,11 +16,11 @@ export interface ExpandableCardTriggerProps extends Omit<PressableProps, 'childr
17
16
  /**
18
17
  * Content to display on the left side (e.g., icon, avatar)
19
18
  */
20
- leadingContent?: React.ReactNode;
19
+ leadingContent?: ReactNode;
21
20
  /**
22
21
  * Optional badge to display
23
22
  */
24
- badge?: BadgeProps;
23
+ badge?: ReactNode;
25
24
  /**
26
25
  * Position of the badge relative to the heading
27
26
  * @default 'bottom'
@@ -39,6 +38,6 @@ export interface ExpandableCardTriggerProps extends Omit<PressableProps, 'childr
39
38
  * Whether the trigger is disabled
40
39
  */
41
40
  disabled?: boolean;
42
- children?: React.ReactNode;
41
+ children?: ReactNode;
43
42
  }
44
43
  export default ExpandableCardTriggerProps;
@@ -2,7 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { ChevronDownSmallIcon, ChevronUpSmallIcon, } from '@utilitywarehouse/hearth-react-native-icons';
3
3
  import { Pressable } from 'react-native';
4
4
  import { StyleSheet } from 'react-native-unistyles';
5
- import { Badge } from '../Badge';
6
5
  import { DetailText } from '../DetailText';
7
6
  import ExpandableCardContent from './ExpandableCardContent';
8
7
  import ExpandableCardHelperText from './ExpandableCardHelperText';
@@ -27,19 +26,7 @@ const ExpandableCardTriggerRoot = ({ heading, helperText, leadingIcon, leadingCo
27
26
  }
28
27
  return null;
29
28
  };
30
- const renderTopBadge = () => {
31
- if (badgePosition === 'top' && badge) {
32
- return _jsx(Badge, { ...badge });
33
- }
34
- return null;
35
- };
36
- const renderBottomBadge = () => {
37
- if (badgePosition === 'bottom' && badge) {
38
- return _jsx(Badge, { ...badge });
39
- }
40
- return null;
41
- };
42
- const renderDefaultContent = () => (_jsxs(_Fragment, { children: [renderLeadingContent(), _jsxs(ExpandableCardContent, { children: [renderTopBadge(), _jsx(ExpandableCardText, { children: heading }), helperText && _jsx(ExpandableCardHelperText, { children: helperText }), renderBottomBadge()] }), numericValue && (_jsx(DetailText, { size: "lg", style: styles.numericValue, children: numericValue })), _jsx(ExpandableCardTrailingContent, { style: styles.chevron, children: _jsx(ExpandableCardTrailingIcon, { as: isExpanded ? ChevronUpSmallIcon : ChevronDownSmallIcon }) })] }));
29
+ const renderDefaultContent = () => (_jsxs(_Fragment, { children: [renderLeadingContent(), _jsxs(ExpandableCardContent, { children: [badgePosition === 'top' ? badge : null, _jsx(ExpandableCardText, { children: heading }), helperText && _jsx(ExpandableCardHelperText, { children: helperText }), badgePosition === 'bottom' ? badge : null] }), numericValue && (_jsx(DetailText, { size: "lg", style: styles.numericValue, children: numericValue })), _jsx(ExpandableCardTrailingContent, { style: styles.chevron, children: _jsx(ExpandableCardTrailingIcon, { as: isExpanded ? ChevronUpSmallIcon : ChevronDownSmallIcon }) })] }));
43
30
  return (_jsx(Pressable, { ...props, testID: testID, style: [styles.container, props.style], disabled: disabled, accessibilityRole: "button", accessibilityState: { expanded: isExpanded, disabled }, accessibilityLabel: `${heading}${helperText ? `, ${helperText}` : ''}`, children: children || renderDefaultContent() }));
44
31
  };
45
32
  ExpandableCardTriggerRoot.displayName = 'ExpandableCardTriggerRoot';
@@ -1,11 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Image, View } from 'react-native';
2
+ import { View } from 'react-native';
3
3
  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
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 })] })] }) }));
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: image }), _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 => ({
@@ -62,10 +62,6 @@ const styles = StyleSheet.create(theme => ({
62
62
  width: '100%',
63
63
  height,
64
64
  }),
65
- image: {
66
- width: '100%',
67
- height: '100%',
68
- },
69
65
  footer: {
70
66
  padding: theme.components.banner.highlight.padding,
71
67
  gap: theme.components.banner.highlight.content.gap,
@@ -1,11 +1,10 @@
1
- import { ReactElement } from 'react';
2
- import { ImageProps } from 'react-native';
1
+ import { ReactElement, ReactNode } from 'react';
3
2
  import CardProps from '../Card/Card.props';
4
3
  interface HighlightBannerProps extends Omit<CardProps, 'noPadding' | 'variant' | 'space' | 'gap' | 'rowGap' | 'columnGap' | 'flexDirection' | 'flexWrap' | 'alignItems' | 'justifyContent' | 'colorScheme'> {
5
4
  heading?: string;
6
5
  headingColor?: 'pig' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'highlight';
7
6
  variant?: 'emphasis' | 'subtle';
8
- image?: ImageProps;
7
+ image?: ReactNode;
9
8
  imageContainerHeight?: number;
10
9
  description?: string;
11
10
  link?: ReactElement;
@@ -0,0 +1,4 @@
1
+ import { ImageProps } from 'react-native';
2
+ import { ThemedImageProps } from '../ThemedImage';
3
+ declare const HighlightBannerImage: (props: ImageProps | ThemedImageProps) => import("react/jsx-runtime").JSX.Element;
4
+ export default HighlightBannerImage;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Image } from 'react-native';
3
+ import { StyleSheet } from 'react-native-unistyles';
4
+ import { isThemedImageProps } from '../../utils';
5
+ import { ThemedImage } from '../ThemedImage';
6
+ const HighlightBannerImage = (props) => {
7
+ if (isThemedImageProps(props)) {
8
+ return _jsx(ThemedImage, { ...props, style: [styles.image, props.style] });
9
+ }
10
+ return _jsx(Image, { resizeMode: "cover", ...props, style: [styles.image, props.style] });
11
+ };
12
+ const styles = StyleSheet.create({
13
+ image: {
14
+ width: '100%',
15
+ height: '100%',
16
+ },
17
+ });
18
+ export default HighlightBannerImage;
@@ -1,2 +1,3 @@
1
1
  export { default as HighlightBanner } from './HighlightBanner';
2
2
  export type { default as HighlightBannerProps } from './HighlightBanner.props';
3
+ export { default as HighlightBannerImage } from './HighlightBannerImage';
@@ -1 +1,2 @@
1
1
  export { default as HighlightBanner } from './HighlightBanner';
2
+ export { default as HighlightBannerImage } from './HighlightBannerImage';
@@ -1,4 +1,5 @@
1
1
  import { ComponentType } from 'react';
2
+ import { TextInput } from 'react-native';
2
3
  import type InputProps from './Input.props';
3
4
  export declare const InputComponent: import("@gluestack-ui/input/lib/typescript/types").IInputComponentType<InputProps & {
4
5
  states?: {
@@ -10,20 +11,17 @@ export declare const InputComponent: import("@gluestack-ui/input/lib/typescript/
10
11
  as?: ComponentType;
11
12
  }, import("react-native").ViewProps, import("react-native").TextInputProps & {
12
13
  inBottomSheet?: boolean;
13
- }>;
14
+ } & import("react").RefAttributes<TextInput>>;
14
15
  export declare const InputSlot: import("react").ForwardRefExoticComponent<import("react").RefAttributes<import("react-native").ViewProps> & import("react-native").ViewProps & import("@gluestack-ui/input/lib/typescript/types").IInputSlotProps>;
15
16
  export declare const InputField: import("react").ForwardRefExoticComponent<import("react").RefAttributes<import("react-native").TextInputProps & {
16
17
  inBottomSheet?: boolean;
17
- }> & import("react-native").TextInputProps & {
18
+ } & import("react").RefAttributes<TextInput>> & Omit<import("react-native").TextInputProps & {
18
19
  inBottomSheet?: boolean;
19
- } & import("@gluestack-ui/input/lib/typescript/types").IInputProps>;
20
+ } & import("react").RefAttributes<TextInput>, "ref"> & import("@gluestack-ui/input/lib/typescript/types").IInputProps>;
20
21
  export declare const InputIcon: import("react").ForwardRefExoticComponent<import("react").RefAttributes<import("..").IconProps & {
21
22
  as?: ComponentType;
22
23
  }> & import("..").IconProps & {
23
24
  as?: ComponentType;
24
25
  }>;
25
- declare const Input: {
26
- ({ validationStatus, children, disabled, focused, readonly, leadingIcon, trailingIcon, type, showPasswordToggle, onClear, format, loading, clearable, required, inBottomSheet, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
27
- displayName: string;
28
- };
26
+ declare const Input: import("react").ForwardRefExoticComponent<InputProps & import("react").RefAttributes<TextInput>>;
29
27
  export default Input;
@@ -1,6 +1,6 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { createInput } from '@gluestack-ui/input';
3
- import { useState } from 'react';
3
+ import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
4
4
  import { CloseSmallIcon, EyeOffSmallIcon, EyeSmallIcon, SearchMediumIcon, } from '@utilitywarehouse/hearth-react-native-icons';
5
5
  import { useTheme } from '../../hooks';
6
6
  import { useFormFieldContext } from '../FormField';
@@ -19,13 +19,16 @@ export const InputComponent = createInput({
19
19
  export const InputSlot = InputComponent.Slot;
20
20
  export const InputField = InputComponent.Input;
21
21
  export const InputIcon = InputComponent.Icon;
22
- const Input = ({ validationStatus = 'initial', children, disabled, focused, readonly, leadingIcon, trailingIcon, type, showPasswordToggle = true, onClear, format, loading, clearable = false, required, inBottomSheet = false, ...props }) => {
22
+ const Input = forwardRef(({ validationStatus = 'initial', children, disabled, focused, readonly, leadingIcon, trailingIcon, type, showPasswordToggle = true, onClear, format, loading, clearable = false, required, inBottomSheet = false, ...props }, ref) => {
23
23
  const formFieldContext = useFormFieldContext();
24
24
  const { disabled: formFieldDisabled } = formFieldContext;
25
25
  const validationStatusFromContext = formFieldContext?.validationStatus ?? validationStatus;
26
26
  const isRequired = formFieldContext?.required ?? required;
27
27
  const [fieldType, setFieldType] = useState(type === 'password' ? 'password' : 'text');
28
28
  const { color } = useTheme();
29
+ const inputRef = useRef(null);
30
+ // Expose TextInput methods to parent components
31
+ useImperativeHandle(ref, () => inputRef.current, []);
29
32
  const shouldShowPasswordToggle = type === 'password' && showPasswordToggle;
30
33
  const shouldShowClear = clearable && !!props?.value;
31
34
  const toggleFieldType = () => {
@@ -43,7 +46,11 @@ const Input = ({ validationStatus = 'initial', children, disabled, focused, read
43
46
  }
44
47
  return undefined;
45
48
  })();
46
- return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), _jsx(InputField, { type: fieldType, inputMode: getInputMode, inBottomSheet: inBottomSheet, ...props }), shouldShowClear && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: onClear, icon: CloseSmallIcon }) })), loading && (_jsx(InputSlot, { children: _jsx(Spinner, { size: "xs", color: color.icon.primary }) })), shouldShowPasswordToggle && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: toggleFieldType, icon: fieldType === 'password' ? EyeSmallIcon : EyeOffSmallIcon }) })), !!trailingIcon && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: trailingIcon }) }))] })) }));
47
- };
49
+ return (_jsx(InputComponent, { ...(children ? props : {}), validationStatus: validationStatusFromContext, isInvalid: validationStatusFromContext === 'invalid', isReadOnly: readonly, isDisabled: formFieldDisabled ?? disabled, isFocused: focused, type: type, isRequired: isRequired, children: children ? (_jsx(_Fragment, { children: children })) : (_jsxs(_Fragment, { children: [!!leadingIconComponent && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: leadingIconComponent }) })), _jsx(InputField
50
+ // @ts-expect-error - ref forwarding issue
51
+ , {
52
+ // @ts-expect-error - ref forwarding issue
53
+ ref: inputRef, type: fieldType, inputMode: getInputMode, inBottomSheet: inBottomSheet, ...props }), shouldShowClear && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: onClear, icon: CloseSmallIcon }) })), loading && (_jsx(InputSlot, { children: _jsx(Spinner, { size: "xs", color: color.icon.primary }) })), shouldShowPasswordToggle && (_jsx(InputSlot, { children: _jsx(UnstyledIconButton, { onPress: toggleFieldType, icon: fieldType === 'password' ? EyeSmallIcon : EyeOffSmallIcon }) })), !!trailingIcon && (_jsx(InputSlot, { children: _jsx(InputIcon, { as: trailingIcon }) }))] })) }));
54
+ });
48
55
  Input.displayName = 'Input';
49
56
  export default Input;