@utilitywarehouse/hearth-react-native 0.7.0 → 0.8.1
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +18 -0
- package/build/components/Banner/Banner.d.ts +6 -0
- package/build/components/Banner/Banner.js +161 -0
- package/build/components/Banner/Banner.props.d.ts +82 -0
- package/build/components/Banner/Banner.props.js +1 -0
- package/build/components/Banner/index.d.ts +2 -0
- package/build/components/Banner/index.js +1 -0
- package/build/components/BottomSheet/BottomSheetBackdrop.js +1 -5
- package/build/components/BottomSheet/BottomSheetFlatList.js +1 -5
- package/build/components/BottomSheet/BottomSheetHandle.js +1 -5
- package/build/components/BottomSheet/useBottomSheetLogic.d.ts +1 -1
- package/build/components/Expandable/Expandable.d.ts +6 -0
- package/build/components/Expandable/Expandable.js +44 -0
- package/build/components/Expandable/Expandable.props.d.ts +38 -0
- package/build/components/Expandable/Expandable.props.js +1 -0
- package/build/components/Expandable/index.d.ts +2 -0
- package/build/components/Expandable/index.js +1 -0
- package/build/components/ExpandableCard/ExpandableCard.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCard.js +23 -0
- package/build/components/ExpandableCard/ExpandableCard.props.d.ts +69 -0
- package/build/components/ExpandableCard/ExpandableCard.props.js +1 -0
- package/build/components/ExpandableCard/ExpandableCardContent.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardContent.js +14 -0
- package/build/components/ExpandableCard/ExpandableCardExpandedContent.d.ts +11 -0
- package/build/components/ExpandableCard/ExpandableCardExpandedContent.js +18 -0
- package/build/components/ExpandableCard/ExpandableCardGroup.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardGroup.js +17 -0
- package/build/components/ExpandableCard/ExpandableCardGroup.props.d.ts +25 -0
- package/build/components/ExpandableCard/ExpandableCardGroup.props.js +1 -0
- package/build/components/ExpandableCard/ExpandableCardHelperText.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardHelperText.js +13 -0
- package/build/components/ExpandableCard/ExpandableCardIcon.d.ts +9 -0
- package/build/components/ExpandableCard/ExpandableCardIcon.js +19 -0
- package/build/components/ExpandableCard/ExpandableCardLeadingContent.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardLeadingContent.js +5 -0
- package/build/components/ExpandableCard/ExpandableCardText.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardText.js +7 -0
- package/build/components/ExpandableCard/ExpandableCardTrailingContent.d.ts +6 -0
- package/build/components/ExpandableCard/ExpandableCardTrailingContent.js +5 -0
- package/build/components/ExpandableCard/ExpandableCardTrailingIcon.d.ts +9 -0
- package/build/components/ExpandableCard/ExpandableCardTrailingIcon.js +17 -0
- package/build/components/ExpandableCard/ExpandableCardTrigger.d.ts +17 -0
- package/build/components/ExpandableCard/ExpandableCardTrigger.js +7 -0
- package/build/components/ExpandableCard/ExpandableCardTrigger.props.d.ts +44 -0
- package/build/components/ExpandableCard/ExpandableCardTrigger.props.js +1 -0
- package/build/components/ExpandableCard/ExpandableCardTriggerRoot.d.ts +11 -0
- package/build/components/ExpandableCard/ExpandableCardTriggerRoot.js +91 -0
- package/build/components/ExpandableCard/index.d.ts +14 -0
- package/build/components/ExpandableCard/index.js +11 -0
- package/build/components/HighlightBanner/HighlightBanner.d.ts +6 -0
- package/build/components/HighlightBanner/HighlightBanner.js +96 -0
- package/build/components/HighlightBanner/HighlightBanner.props.d.ts +14 -0
- package/build/components/HighlightBanner/HighlightBanner.props.js +1 -0
- package/build/components/HighlightBanner/index.d.ts +2 -0
- package/build/components/HighlightBanner/index.js +1 -0
- package/build/components/Spinner/Spinner.js +0 -2
- package/build/components/Spinner/Spinner.web.d.ts +2 -1
- package/build/components/Spinner/Spinner.web.js +0 -2
- package/build/components/Switch/Switch.web.js +0 -1
- package/build/components/Tabs/TabsList.js +1 -6
- package/build/components/index.d.ts +4 -0
- package/build/components/index.js +4 -0
- package/docs/components/AllComponents.web.tsx +75 -4
- package/docs/components/VariantTitle.tsx +1 -1
- package/package.json +4 -4
- package/src/components/Banner/Banner.docs.mdx +402 -0
- package/src/components/Banner/Banner.props.ts +106 -0
- package/src/components/Banner/Banner.stories.tsx +494 -0
- package/src/components/Banner/Banner.tsx +264 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BottomSheet/BottomSheetBackdrop.tsx +0 -1
- package/src/components/BottomSheet/BottomSheetFlatList.tsx +0 -1
- package/src/components/BottomSheet/BottomSheetHandle.tsx +0 -1
- package/src/components/Card/Card.docs.mdx +10 -2
- package/src/components/Expandable/Expandable.docs.mdx +201 -0
- package/src/components/Expandable/Expandable.props.ts +46 -0
- package/src/components/Expandable/Expandable.stories.tsx +284 -0
- package/src/components/Expandable/Expandable.tsx +92 -0
- package/src/components/Expandable/index.ts +2 -0
- package/src/components/ExpandableCard/ExpandableCard.docs.mdx +312 -0
- package/src/components/ExpandableCard/ExpandableCard.props.ts +85 -0
- package/src/components/ExpandableCard/ExpandableCard.stories.tsx +326 -0
- package/src/components/ExpandableCard/ExpandableCard.tsx +76 -0
- package/src/components/ExpandableCard/ExpandableCardContent.tsx +21 -0
- package/src/components/ExpandableCard/ExpandableCardExpandedContent.tsx +42 -0
- package/src/components/ExpandableCard/ExpandableCardGroup.props.ts +31 -0
- package/src/components/ExpandableCard/ExpandableCardGroup.tsx +40 -0
- package/src/components/ExpandableCard/ExpandableCardHelperText.tsx +21 -0
- package/src/components/ExpandableCard/ExpandableCardIcon.tsx +32 -0
- package/src/components/ExpandableCard/ExpandableCardLeadingContent.tsx +9 -0
- package/src/components/ExpandableCard/ExpandableCardText.tsx +14 -0
- package/src/components/ExpandableCard/ExpandableCardTrailingContent.tsx +9 -0
- package/src/components/ExpandableCard/ExpandableCardTrailingIcon.tsx +30 -0
- package/src/components/ExpandableCard/ExpandableCardTrigger.props.ts +47 -0
- package/src/components/ExpandableCard/ExpandableCardTrigger.tsx +10 -0
- package/src/components/ExpandableCard/ExpandableCardTriggerRoot.tsx +154 -0
- package/src/components/ExpandableCard/index.ts +14 -0
- package/src/components/HighlightBanner/HighlightBanner.docs.mdx +296 -0
- package/src/components/HighlightBanner/HighlightBanner.props.ts +29 -0
- package/src/components/HighlightBanner/HighlightBanner.stories.tsx +275 -0
- package/src/components/HighlightBanner/HighlightBanner.tsx +134 -0
- package/src/components/HighlightBanner/index.ts +2 -0
- package/src/components/Spinner/Spinner.tsx +0 -2
- package/src/components/Spinner/Spinner.web.tsx +0 -2
- package/src/components/Switch/Switch.web.tsx +1 -5
- package/src/components/Tabs/TabsList.tsx +0 -2
- package/src/components/index.ts +4 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { View, type ViewProps } from 'react-native';
|
|
2
|
+
|
|
3
|
+
const ExpandableCardTrailingContent = ({ children, ...props }: ViewProps) => (
|
|
4
|
+
<View {...props}>{children}</View>
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
ExpandableCardTrailingContent.displayName = 'ExpandableCardTrailingContent';
|
|
8
|
+
|
|
9
|
+
export default ExpandableCardTrailingContent;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { Platform, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
4
|
+
import { Icon, IconProps } from '../Icon';
|
|
5
|
+
|
|
6
|
+
const ExpandableCardTrailingIcon = ({ children, ...props }: IconProps & { as?: ComponentType }) => {
|
|
7
|
+
return (
|
|
8
|
+
<Icon
|
|
9
|
+
{...props}
|
|
10
|
+
style={
|
|
11
|
+
Platform.OS === 'web'
|
|
12
|
+
? // @ts-expect-error - style prop type issue
|
|
13
|
+
{ ...(styles.icon as StyleProp<ViewStyle>), ...props.style }
|
|
14
|
+
: ([styles.icon as StyleProp<ViewStyle>, props.style] as any)
|
|
15
|
+
}
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</Icon>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
ExpandableCardTrailingIcon.displayName = 'ExpandableCardTrailingIcon';
|
|
23
|
+
|
|
24
|
+
const styles = StyleSheet.create(theme => ({
|
|
25
|
+
icon: {
|
|
26
|
+
color: theme.color.icon.primary,
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
export default ExpandableCardTrailingIcon;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { PressableProps } from 'react-native';
|
|
3
|
+
import type BadgeProps from '../Badge/Badge.props';
|
|
4
|
+
|
|
5
|
+
export interface ExpandableCardTriggerProps extends Omit<PressableProps, 'children'> {
|
|
6
|
+
/**
|
|
7
|
+
* The main heading text
|
|
8
|
+
*/
|
|
9
|
+
heading?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional helper text displayed below the heading
|
|
12
|
+
*/
|
|
13
|
+
helperText?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Leading icon component
|
|
16
|
+
*/
|
|
17
|
+
leadingIcon?: ComponentType;
|
|
18
|
+
/**
|
|
19
|
+
* Content to display on the left side (e.g., icon, avatar)
|
|
20
|
+
*/
|
|
21
|
+
leadingContent?: React.ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* Optional badge to display
|
|
24
|
+
*/
|
|
25
|
+
badge?: BadgeProps;
|
|
26
|
+
/**
|
|
27
|
+
* Position of the badge relative to the heading
|
|
28
|
+
* @default 'bottom'
|
|
29
|
+
*/
|
|
30
|
+
badgePosition?: 'top' | 'bottom';
|
|
31
|
+
/**
|
|
32
|
+
* Optional numeric value to display
|
|
33
|
+
*/
|
|
34
|
+
numericValue?: string | number;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the expandable card is expanded
|
|
37
|
+
*/
|
|
38
|
+
isExpanded: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the trigger is disabled
|
|
41
|
+
*/
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
/* Optional children */
|
|
44
|
+
children?: React.ReactNode;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default ExpandableCardTriggerProps;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createPressable } from '@gluestack-ui/pressable';
|
|
2
|
+
import ExpandableCardTriggerRoot from './ExpandableCardTriggerRoot';
|
|
3
|
+
|
|
4
|
+
const ExpandableCardTrigger = createPressable({
|
|
5
|
+
Root: ExpandableCardTriggerRoot,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
ExpandableCardTrigger.displayName = 'ExpandableCardTrigger';
|
|
9
|
+
|
|
10
|
+
export default ExpandableCardTrigger;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChevronDownSmallIcon,
|
|
3
|
+
ChevronUpSmallIcon,
|
|
4
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
5
|
+
import { Pressable, ViewStyle } from 'react-native';
|
|
6
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
7
|
+
import { Badge } from '../Badge';
|
|
8
|
+
import { DetailText } from '../DetailText';
|
|
9
|
+
import ExpandableCardContent from './ExpandableCardContent';
|
|
10
|
+
import ExpandableCardHelperText from './ExpandableCardHelperText';
|
|
11
|
+
import ExpandableCardIcon from './ExpandableCardIcon';
|
|
12
|
+
import ExpandableCardLeadingContent from './ExpandableCardLeadingContent';
|
|
13
|
+
import ExpandableCardText from './ExpandableCardText';
|
|
14
|
+
import ExpandableCardTrailingContent from './ExpandableCardTrailingContent';
|
|
15
|
+
import ExpandableCardTrailingIcon from './ExpandableCardTrailingIcon';
|
|
16
|
+
import type ExpandableCardTriggerProps from './ExpandableCardTrigger.props';
|
|
17
|
+
|
|
18
|
+
const ExpandableCardTriggerRoot = ({
|
|
19
|
+
heading,
|
|
20
|
+
helperText,
|
|
21
|
+
leadingIcon,
|
|
22
|
+
leadingContent,
|
|
23
|
+
badge,
|
|
24
|
+
badgePosition = 'bottom',
|
|
25
|
+
numericValue,
|
|
26
|
+
isExpanded,
|
|
27
|
+
disabled,
|
|
28
|
+
states,
|
|
29
|
+
children,
|
|
30
|
+
...props
|
|
31
|
+
}: ExpandableCardTriggerProps & { states?: { active?: boolean; disabled?: boolean } }) => {
|
|
32
|
+
const { active } = states || { active: false };
|
|
33
|
+
|
|
34
|
+
const testID = props.testID || 'expandable-card-trigger';
|
|
35
|
+
|
|
36
|
+
styles.useVariants({
|
|
37
|
+
active,
|
|
38
|
+
disabled: !!disabled,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const renderLeadingContent = () => {
|
|
42
|
+
if (leadingIcon) {
|
|
43
|
+
return (
|
|
44
|
+
<ExpandableCardLeadingContent>
|
|
45
|
+
<ExpandableCardIcon as={leadingIcon} />
|
|
46
|
+
</ExpandableCardLeadingContent>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (leadingContent) {
|
|
51
|
+
return <ExpandableCardLeadingContent>{leadingContent}</ExpandableCardLeadingContent>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const renderTopBadge = () => {
|
|
58
|
+
if (badgePosition === 'top' && badge) {
|
|
59
|
+
return <Badge {...badge} />;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const renderBottomBadge = () => {
|
|
65
|
+
if (badgePosition === 'bottom' && badge) {
|
|
66
|
+
return <Badge {...badge} />;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const renderDefaultContent = () => (
|
|
72
|
+
<>
|
|
73
|
+
{renderLeadingContent()}
|
|
74
|
+
<ExpandableCardContent>
|
|
75
|
+
{renderTopBadge()}
|
|
76
|
+
<ExpandableCardText>{heading}</ExpandableCardText>
|
|
77
|
+
{helperText && <ExpandableCardHelperText>{helperText}</ExpandableCardHelperText>}
|
|
78
|
+
{renderBottomBadge()}
|
|
79
|
+
</ExpandableCardContent>
|
|
80
|
+
{numericValue && (
|
|
81
|
+
<DetailText size="lg" style={styles.numericValue}>
|
|
82
|
+
{numericValue}
|
|
83
|
+
</DetailText>
|
|
84
|
+
)}
|
|
85
|
+
<ExpandableCardTrailingContent style={styles.chevron}>
|
|
86
|
+
<ExpandableCardTrailingIcon as={isExpanded ? ChevronUpSmallIcon : ChevronDownSmallIcon} />
|
|
87
|
+
</ExpandableCardTrailingContent>
|
|
88
|
+
</>
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<Pressable
|
|
93
|
+
{...props}
|
|
94
|
+
testID={testID}
|
|
95
|
+
style={[styles.container, props.style as ViewStyle]}
|
|
96
|
+
disabled={disabled}
|
|
97
|
+
accessibilityRole="button"
|
|
98
|
+
accessibilityState={{ expanded: isExpanded, disabled }}
|
|
99
|
+
accessibilityLabel={`${heading}${helperText ? `, ${helperText}` : ''}`}
|
|
100
|
+
>
|
|
101
|
+
{children || renderDefaultContent()}
|
|
102
|
+
</Pressable>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
ExpandableCardTriggerRoot.displayName = 'ExpandableCardTriggerRoot';
|
|
107
|
+
|
|
108
|
+
const styles = StyleSheet.create(theme => ({
|
|
109
|
+
container: {
|
|
110
|
+
paddingVertical: theme.components.card.mobile.padding,
|
|
111
|
+
paddingHorizontal: theme.components.card.mobile.padding,
|
|
112
|
+
flexDirection: 'row',
|
|
113
|
+
width: '100%',
|
|
114
|
+
gap: theme.components.expandableCard.gapHorizontal,
|
|
115
|
+
variants: {
|
|
116
|
+
disabled: {
|
|
117
|
+
true: {
|
|
118
|
+
cursor: 'auto',
|
|
119
|
+
opacity: theme.opacity.disabled,
|
|
120
|
+
},
|
|
121
|
+
false: {
|
|
122
|
+
_web: {
|
|
123
|
+
_hover: {
|
|
124
|
+
backgroundColor: theme.color.interactive.neutral.surface.subtle.hover,
|
|
125
|
+
},
|
|
126
|
+
_active: {
|
|
127
|
+
backgroundColor: theme.color.interactive.neutral.surface.subtle.active,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
active: {
|
|
133
|
+
true: {},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
compoundVariants: [
|
|
137
|
+
{
|
|
138
|
+
disabled: false,
|
|
139
|
+
active: true,
|
|
140
|
+
styles: {
|
|
141
|
+
backgroundColor: theme.color.interactive.neutral.surface.subtle.active,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
chevron: {
|
|
147
|
+
justifyContent: 'center',
|
|
148
|
+
},
|
|
149
|
+
numericValue: {
|
|
150
|
+
alignSelf: 'center',
|
|
151
|
+
},
|
|
152
|
+
}));
|
|
153
|
+
|
|
154
|
+
export default ExpandableCardTriggerRoot;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { default as ExpandableCard } from './ExpandableCard';
|
|
2
|
+
export type { default as ExpandableCardProps } from './ExpandableCard.props';
|
|
3
|
+
export { default as ExpandableCardContent } from './ExpandableCardContent';
|
|
4
|
+
export { default as ExpandableCardExpandedContent } from './ExpandableCardExpandedContent';
|
|
5
|
+
export { default as ExpandableCardGroup } from './ExpandableCardGroup';
|
|
6
|
+
export type { default as ExpandableCardGroupProps } from './ExpandableCardGroup.props';
|
|
7
|
+
export { default as ExpandableCardHelperText } from './ExpandableCardHelperText';
|
|
8
|
+
export { default as ExpandableCardIcon } from './ExpandableCardIcon';
|
|
9
|
+
export { default as ExpandableCardLeadingContent } from './ExpandableCardLeadingContent';
|
|
10
|
+
export { default as ExpandableCardText } from './ExpandableCardText';
|
|
11
|
+
export { default as ExpandableCardTrailingContent } from './ExpandableCardTrailingContent';
|
|
12
|
+
export { default as ExpandableCardTrailingIcon } from './ExpandableCardTrailingIcon';
|
|
13
|
+
export { default as ExpandableCardTrigger } from './ExpandableCardTrigger';
|
|
14
|
+
export type { default as ExpandableCardTriggerProps } from './ExpandableCardTrigger.props';
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { Button, Center, HighlightBanner, Link } from '../../';
|
|
3
|
+
import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
|
|
4
|
+
import * as Stories from './HighlightBanner.stories';
|
|
5
|
+
|
|
6
|
+
<Meta title="Components / Highlight Banner" />
|
|
7
|
+
|
|
8
|
+
<ViewFigmaButton url="https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=8306-4665&t=qkAoIRb6rKiYkSIE-4" />
|
|
9
|
+
|
|
10
|
+
<BackToTopButton />
|
|
11
|
+
|
|
12
|
+
# Highlight Banner
|
|
13
|
+
|
|
14
|
+
A `HighlightBanner` component is a specialised card layout designed for highlighting featured content with an image. It combines a colored heading banner, an optional image, and descriptive text with optional action buttons or links. Perfect for promotional content, featured articles, or important announcements.
|
|
15
|
+
|
|
16
|
+
- [Playground](#playground)
|
|
17
|
+
- [Usage](#usage)
|
|
18
|
+
- [Props](#props)
|
|
19
|
+
- [Variants](#variants)
|
|
20
|
+
- [Examples](#examples)
|
|
21
|
+
- [With Button](#with-button)
|
|
22
|
+
- [With Link](#with-link)
|
|
23
|
+
- [Without Image](#without-image)
|
|
24
|
+
- [Color Variants](#color-variants)
|
|
25
|
+
- [Subtle Variant](#subtle-variant)
|
|
26
|
+
- [Different Images](#different-images)
|
|
27
|
+
- [Custom Image Height](#custom-image-height)
|
|
28
|
+
|
|
29
|
+
## Playground
|
|
30
|
+
|
|
31
|
+
<Canvas of={Stories.Playground} />
|
|
32
|
+
|
|
33
|
+
<Controls of={Stories.Playground} />
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
<UsageWrap>
|
|
38
|
+
<Center>
|
|
39
|
+
<HighlightBanner
|
|
40
|
+
heading="Featured Content"
|
|
41
|
+
headingColor="energy"
|
|
42
|
+
image={{
|
|
43
|
+
source: {
|
|
44
|
+
uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=800&q=80',
|
|
45
|
+
},
|
|
46
|
+
}}
|
|
47
|
+
description="This is a description of the featured content that appears below the image."
|
|
48
|
+
/>
|
|
49
|
+
</Center>
|
|
50
|
+
</UsageWrap>
|
|
51
|
+
|
|
52
|
+
```jsx
|
|
53
|
+
import { HighlightBanner } from '@utilitywarehouse/hearth-react-native';
|
|
54
|
+
|
|
55
|
+
const MyComponent = () => (
|
|
56
|
+
<HighlightBanner
|
|
57
|
+
heading="Featured Content"
|
|
58
|
+
headingColor="energy"
|
|
59
|
+
image={{
|
|
60
|
+
source: {
|
|
61
|
+
uri: 'https://example.com/image.jpg',
|
|
62
|
+
},
|
|
63
|
+
}}
|
|
64
|
+
description="This is a description of the featured content."
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Props
|
|
70
|
+
|
|
71
|
+
| Property | Type | Description | Default |
|
|
72
|
+
| -------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------ |
|
|
73
|
+
| heading | `string` | The heading text displayed at the top with colored background | `-` |
|
|
74
|
+
| headingColor | `'pig' \| 'energy' \| 'broadband' \| 'mobile' \|` <br />`'insurance' \| 'cashback' \| 'highlight'` | The semantic color scheme for the heading background | `-` |
|
|
75
|
+
| image | `ImageProps` | React Native Image props for the featured image | `-` |
|
|
76
|
+
| imageContainerHeight | `number` | Height of the image container in pixels | `200` |
|
|
77
|
+
| description | `string` | Description text displayed below the image | `-` |
|
|
78
|
+
| link | `ReactElement` | Optional Link component displayed below description | `-` |
|
|
79
|
+
| button | `ReactElement` | Optional Button component displayed below description | `-` |
|
|
80
|
+
| variant | `'emphasis' \| 'subtle'` | Visual style variant with strong or subtle borders | `'emphasis'` |
|
|
81
|
+
|
|
82
|
+
The component also accepts all standard Card props except `noPadding`, `space`, `gap`, `rowGap`, `columnGap`, `flexDirection`, `flexWrap`, `alignItems`, and `justifyContent`.
|
|
83
|
+
|
|
84
|
+
## Variants
|
|
85
|
+
|
|
86
|
+
The HighlightBanner supports two visual variants:
|
|
87
|
+
|
|
88
|
+
- **emphasis** (default) - Strong borders for clear visual separation
|
|
89
|
+
- **subtle** - Softer borders for a more understated appearance
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
### With Button
|
|
94
|
+
|
|
95
|
+
Add a Button component to provide a clear call-to-action:
|
|
96
|
+
|
|
97
|
+
<Canvas of={Stories.WithButton} />
|
|
98
|
+
|
|
99
|
+
```jsx
|
|
100
|
+
import { HighlightBanner, Button } from '@utilitywarehouse/hearth-react-native';
|
|
101
|
+
|
|
102
|
+
const MyComponent = () => (
|
|
103
|
+
<HighlightBanner
|
|
104
|
+
heading="New Feature"
|
|
105
|
+
headingColor="energy"
|
|
106
|
+
image={{
|
|
107
|
+
source: {
|
|
108
|
+
uri: 'https://example.com/feature.jpg',
|
|
109
|
+
},
|
|
110
|
+
}}
|
|
111
|
+
description="Check out our latest feature"
|
|
112
|
+
button={<Button onPress={() => console.log('pressed')}>Get Started</Button>}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### With Link
|
|
118
|
+
|
|
119
|
+
Use a Link component for a lighter-weight action:
|
|
120
|
+
|
|
121
|
+
<Canvas of={Stories.WithLink} />
|
|
122
|
+
|
|
123
|
+
```jsx
|
|
124
|
+
import { HighlightBanner, Link } from '@utilitywarehouse/hearth-react-native';
|
|
125
|
+
|
|
126
|
+
const MyComponent = () => (
|
|
127
|
+
<HighlightBanner
|
|
128
|
+
heading="Learn More"
|
|
129
|
+
headingColor="broadband"
|
|
130
|
+
image={{
|
|
131
|
+
source: {
|
|
132
|
+
uri: 'https://example.com/info.jpg',
|
|
133
|
+
},
|
|
134
|
+
}}
|
|
135
|
+
description="Explore our documentation"
|
|
136
|
+
link={<Link onPress={() => console.log('pressed')}>Read more</Link>}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Without Image
|
|
142
|
+
|
|
143
|
+
Display the HighlightBanner without an image by omitting the `image` prop:
|
|
144
|
+
|
|
145
|
+
<Canvas of={Stories.WithoutImage} />
|
|
146
|
+
|
|
147
|
+
```jsx
|
|
148
|
+
import { HighlightBanner, Button } from '@utilitywarehouse/hearth-react-native';
|
|
149
|
+
|
|
150
|
+
const MyComponent = () => (
|
|
151
|
+
<HighlightBanner
|
|
152
|
+
heading="Content Without Image"
|
|
153
|
+
description="This HighlightBanner does not have an image, focusing solely on the text content."
|
|
154
|
+
button={<Button onPress={() => console.log('pressed')}>Discover More</Button>}
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Color Variants
|
|
160
|
+
|
|
161
|
+
The component supports seven semantic color schemes that automatically apply the appropriate subtle background colors:
|
|
162
|
+
|
|
163
|
+
<Canvas of={Stories.ColorVariants} />
|
|
164
|
+
|
|
165
|
+
```jsx
|
|
166
|
+
import { HighlightBanner } from '@utilitywarehouse/hearth-react-native';
|
|
167
|
+
|
|
168
|
+
const MyComponent = () => (
|
|
169
|
+
<>
|
|
170
|
+
{/* Energy Blue */}
|
|
171
|
+
<HighlightBanner
|
|
172
|
+
heading="Energy Services"
|
|
173
|
+
headingColor="energy"
|
|
174
|
+
image={{ source: { uri: 'https://example.com/energy.jpg' } }}
|
|
175
|
+
description="Discover our energy solutions"
|
|
176
|
+
/>
|
|
177
|
+
|
|
178
|
+
{/* Broadband Green */}
|
|
179
|
+
<HighlightBanner
|
|
180
|
+
heading="Broadband Deals"
|
|
181
|
+
headingColor="broadband"
|
|
182
|
+
image={{ source: { uri: 'https://example.com/broadband.jpg' } }}
|
|
183
|
+
description="Fast and reliable broadband"
|
|
184
|
+
/>
|
|
185
|
+
|
|
186
|
+
{/* Insurance Orange */}
|
|
187
|
+
<HighlightBanner
|
|
188
|
+
heading="Insurance Coverage"
|
|
189
|
+
headingColor="insurance"
|
|
190
|
+
image={{ source: { uri: 'https://example.com/insurance.jpg' } }}
|
|
191
|
+
description="Protect what matters most"
|
|
192
|
+
/>
|
|
193
|
+
|
|
194
|
+
{/* Mobile Rose */}
|
|
195
|
+
<HighlightBanner
|
|
196
|
+
heading="Mobile Plans"
|
|
197
|
+
headingColor="mobile"
|
|
198
|
+
image={{ source: { uri: 'https://example.com/mobile.jpg' } }}
|
|
199
|
+
description="Stay connected anywhere"
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
{/* Cashback Lilac */}
|
|
203
|
+
<HighlightBanner
|
|
204
|
+
heading="Cashback Rewards"
|
|
205
|
+
headingColor="cashback"
|
|
206
|
+
image={{ source: { uri: 'https://example.com/cashback.jpg' } }}
|
|
207
|
+
description="Earn rewards on your bills"
|
|
208
|
+
/>
|
|
209
|
+
|
|
210
|
+
{/* Pig Pink */}
|
|
211
|
+
<HighlightBanner
|
|
212
|
+
heading="Savings Account"
|
|
213
|
+
headingColor="pig"
|
|
214
|
+
image={{ source: { uri: 'https://example.com/savings.jpg' } }}
|
|
215
|
+
description="Save for your future"
|
|
216
|
+
/>
|
|
217
|
+
|
|
218
|
+
{/* Highlight Yellow */}
|
|
219
|
+
<HighlightBanner
|
|
220
|
+
heading="Special Offer"
|
|
221
|
+
headingColor="highlight"
|
|
222
|
+
image={{ source: { uri: 'https://example.com/offer.jpg' } }}
|
|
223
|
+
description="Limited time promotion"
|
|
224
|
+
/>
|
|
225
|
+
</>
|
|
226
|
+
);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Subtle Variant
|
|
230
|
+
|
|
231
|
+
Use the subtle variant for a softer, less prominent appearance:
|
|
232
|
+
|
|
233
|
+
<Canvas of={Stories.SubtleCard} />
|
|
234
|
+
|
|
235
|
+
```jsx
|
|
236
|
+
import { HighlightBanner } from '@utilitywarehouse/hearth-react-native';
|
|
237
|
+
|
|
238
|
+
const MyComponent = () => (
|
|
239
|
+
<HighlightBanner
|
|
240
|
+
variant="subtle"
|
|
241
|
+
heading="Featured Content"
|
|
242
|
+
headingColor="energy"
|
|
243
|
+
image={{
|
|
244
|
+
source: {
|
|
245
|
+
uri: 'https://example.com/image.jpg',
|
|
246
|
+
},
|
|
247
|
+
}}
|
|
248
|
+
description="This banner has a subtle appearance"
|
|
249
|
+
/>
|
|
250
|
+
);
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Different Images
|
|
254
|
+
|
|
255
|
+
The component works well with various types of imagery:
|
|
256
|
+
|
|
257
|
+
<Canvas of={Stories.DifferentImages} />
|
|
258
|
+
|
|
259
|
+
### Custom Image Height
|
|
260
|
+
|
|
261
|
+
Control the image container height to suit your content needs:
|
|
262
|
+
|
|
263
|
+
```jsx
|
|
264
|
+
import { HighlightBanner } from '@utilitywarehouse/hearth-react-native';
|
|
265
|
+
|
|
266
|
+
const MyComponent = () => (
|
|
267
|
+
<>
|
|
268
|
+
{/* Default height (200px) */}
|
|
269
|
+
<HighlightBanner
|
|
270
|
+
heading="Standard Image"
|
|
271
|
+
headingColor="energy"
|
|
272
|
+
image={{ source: { uri: 'https://example.com/image.jpg' } }}
|
|
273
|
+
description="Using default height"
|
|
274
|
+
/>
|
|
275
|
+
|
|
276
|
+
{/* Custom height */}
|
|
277
|
+
<HighlightBanner
|
|
278
|
+
heading="Tall Image"
|
|
279
|
+
headingColor="broadband"
|
|
280
|
+
image={{ source: { uri: 'https://example.com/image.jpg' } }}
|
|
281
|
+
imageContainerHeight={300}
|
|
282
|
+
description="Using custom height of 300px"
|
|
283
|
+
/>
|
|
284
|
+
</>
|
|
285
|
+
);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Best Practices
|
|
289
|
+
|
|
290
|
+
- Use the **energy**, **broadband**, **mobile**, **insurance**, **cashback**, or **pig** colors to align with specific service offerings
|
|
291
|
+
- Use **highlight** for time-sensitive promotions or special offers
|
|
292
|
+
- Keep descriptions concise and scannable
|
|
293
|
+
- Choose between link and button based on the importance of the action - use buttons for primary actions
|
|
294
|
+
- Consider using the subtle variant when displaying multiple banners to reduce visual clutter
|
|
295
|
+
- Ensure images are high quality and relevant to the content
|
|
296
|
+
- Use appropriate image heights based on the aspect ratio of your images
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { ImageProps } from 'react-native';
|
|
3
|
+
import CardProps from '../Card/Card.props';
|
|
4
|
+
|
|
5
|
+
interface HighlightBannerProps
|
|
6
|
+
extends Omit<
|
|
7
|
+
CardProps,
|
|
8
|
+
| 'noPadding'
|
|
9
|
+
| 'variant'
|
|
10
|
+
| 'space'
|
|
11
|
+
| 'gap'
|
|
12
|
+
| 'rowGap'
|
|
13
|
+
| 'columnGap'
|
|
14
|
+
| 'flexDirection'
|
|
15
|
+
| 'flexWrap'
|
|
16
|
+
| 'alignItems'
|
|
17
|
+
| 'justifyContent'
|
|
18
|
+
> {
|
|
19
|
+
heading?: string;
|
|
20
|
+
headingColor?: 'pig' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'highlight';
|
|
21
|
+
variant?: 'emphasis' | 'subtle';
|
|
22
|
+
image?: ImageProps;
|
|
23
|
+
imageContainerHeight?: number;
|
|
24
|
+
description?: string;
|
|
25
|
+
link?: ReactElement;
|
|
26
|
+
button?: ReactElement;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default HighlightBannerProps;
|