@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
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
AccordionItem,
|
|
22
22
|
Alert,
|
|
23
23
|
Badge,
|
|
24
|
+
Banner,
|
|
24
25
|
BodyText,
|
|
25
26
|
BottomSheet,
|
|
26
27
|
BottomSheetModal,
|
|
@@ -42,10 +43,13 @@ import {
|
|
|
42
43
|
DescriptionListItem,
|
|
43
44
|
DetailText,
|
|
44
45
|
Divider,
|
|
46
|
+
Expandable,
|
|
47
|
+
ExpandableCard,
|
|
45
48
|
Flex,
|
|
46
49
|
FormField,
|
|
47
50
|
Grid,
|
|
48
51
|
Heading,
|
|
52
|
+
HighlightBanner,
|
|
49
53
|
Icon,
|
|
50
54
|
IconButton,
|
|
51
55
|
IconContainer,
|
|
@@ -126,6 +130,7 @@ const AllComponents: React.FC = () => {
|
|
|
126
130
|
const handleModalOpenPress = useCallback(() => {
|
|
127
131
|
modalRef.current?.present();
|
|
128
132
|
}, []);
|
|
133
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
129
134
|
const [selected, setSelected] = useState<DateType>();
|
|
130
135
|
const datePickerRef = useRef<BottomSheetModal>(null);
|
|
131
136
|
const handleDatePickerOpenPress = useCallback(() => {
|
|
@@ -188,6 +193,16 @@ const AllComponents: React.FC = () => {
|
|
|
188
193
|
</View>
|
|
189
194
|
</Center>
|
|
190
195
|
</ComponentWrapper>
|
|
196
|
+
<ComponentWrapper name="Banner" link="/?path=/docs/components-banner--docs">
|
|
197
|
+
<Center flex={1} p="200">
|
|
198
|
+
<Banner
|
|
199
|
+
icon={ElectricityMediumIcon}
|
|
200
|
+
iconContainerColor="energy"
|
|
201
|
+
heading="I'm a Banner"
|
|
202
|
+
description="This is a banner description"
|
|
203
|
+
/>
|
|
204
|
+
</Center>
|
|
205
|
+
</ComponentWrapper>
|
|
191
206
|
<ComponentWrapper name="Body Text" link="/?path=/docs/typography-body-text--docs">
|
|
192
207
|
<Center flex={1}>
|
|
193
208
|
<BodyText>This is some Body Text</BodyText>
|
|
@@ -361,6 +376,44 @@ const AllComponents: React.FC = () => {
|
|
|
361
376
|
</Center>
|
|
362
377
|
</ComponentWrapper>
|
|
363
378
|
|
|
379
|
+
<ComponentWrapper
|
|
380
|
+
name="Expandable"
|
|
381
|
+
link="/?path=/docs/utility-components-expandable--docs"
|
|
382
|
+
>
|
|
383
|
+
<Center flex={1} p="200">
|
|
384
|
+
<Box width={240} gap="100">
|
|
385
|
+
<Button onPress={() => setIsExpanded(!isExpanded)}>
|
|
386
|
+
{isExpanded ? 'Collapse' : 'Expand'}
|
|
387
|
+
</Button>
|
|
388
|
+
<Expandable expanded={isExpanded} accessibilityLabel="Expandable content section">
|
|
389
|
+
<Card>
|
|
390
|
+
<BodyText>This content expands and collapses</BodyText>
|
|
391
|
+
</Card>
|
|
392
|
+
</Expandable>
|
|
393
|
+
</Box>
|
|
394
|
+
</Center>
|
|
395
|
+
</ComponentWrapper>
|
|
396
|
+
|
|
397
|
+
<ComponentWrapper
|
|
398
|
+
name="Expandable Card"
|
|
399
|
+
link="/?path=/docs/components-expandable-card--docs"
|
|
400
|
+
>
|
|
401
|
+
<Center flex={1} p="200">
|
|
402
|
+
<ExpandableCard
|
|
403
|
+
heading="This is an"
|
|
404
|
+
helperText="Expandable Card component"
|
|
405
|
+
leadingIcon={ElectricityMediumIcon}
|
|
406
|
+
expandedContent={
|
|
407
|
+
<>
|
|
408
|
+
<BodyText>I'm expanding</BodyText>
|
|
409
|
+
<BodyText>to show more content</BodyText>
|
|
410
|
+
</>
|
|
411
|
+
}
|
|
412
|
+
style={{ width: 240 }}
|
|
413
|
+
/>
|
|
414
|
+
</Center>
|
|
415
|
+
</ComponentWrapper>
|
|
416
|
+
|
|
364
417
|
<ComponentWrapper name="Flex" link="/?path=/docs/primitives-flex--docs">
|
|
365
418
|
<Center flex={1}>
|
|
366
419
|
<Flex direction="row" space="md">
|
|
@@ -400,6 +453,24 @@ const AllComponents: React.FC = () => {
|
|
|
400
453
|
<Heading>This is a Heading</Heading>
|
|
401
454
|
</Center>
|
|
402
455
|
</ComponentWrapper>
|
|
456
|
+
<ComponentWrapper
|
|
457
|
+
name="Highlight Banner"
|
|
458
|
+
link="/?path=/docs/components-highlight-banner--docs"
|
|
459
|
+
>
|
|
460
|
+
<Center flex={1} p="200">
|
|
461
|
+
<HighlightBanner
|
|
462
|
+
heading="Featured Content"
|
|
463
|
+
headingColor="energy"
|
|
464
|
+
imageContainerHeight={40}
|
|
465
|
+
image={{
|
|
466
|
+
source: {
|
|
467
|
+
uri: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=800&q=80',
|
|
468
|
+
},
|
|
469
|
+
}}
|
|
470
|
+
description="Banner description goes here."
|
|
471
|
+
/>
|
|
472
|
+
</Center>
|
|
473
|
+
</ComponentWrapper>
|
|
403
474
|
<ComponentWrapper
|
|
404
475
|
name="Indicator Icon Button"
|
|
405
476
|
link="/?path=/docs/components-indicator-icon-button--docs"
|
|
@@ -529,10 +600,10 @@ const AllComponents: React.FC = () => {
|
|
|
529
600
|
>
|
|
530
601
|
<Center flex={1} px="300">
|
|
531
602
|
<ProgressStepper>
|
|
532
|
-
<ProgressStep id="customer-data"
|
|
533
|
-
<ProgressStep id="shipping-data"
|
|
534
|
-
<ProgressStep id="payment-data"
|
|
535
|
-
<ProgressStep id="summary"
|
|
603
|
+
<ProgressStep id="customer-data" status="complete" />
|
|
604
|
+
<ProgressStep id="shipping-data" status="complete" />
|
|
605
|
+
<ProgressStep id="payment-data" status="active" />
|
|
606
|
+
<ProgressStep id="summary" status="incomplete" />
|
|
536
607
|
</ProgressStepper>
|
|
537
608
|
</Center>
|
|
538
609
|
</ComponentWrapper>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilitywarehouse/hearth-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Utility Warehouse React Native UI library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"vite": "^7.1.3",
|
|
57
57
|
"vite-plugin-svgr": "^4.5.0",
|
|
58
58
|
"vitest": "^3.2.4",
|
|
59
|
-
"@utilitywarehouse/hearth-
|
|
60
|
-
"@utilitywarehouse/hearth-react-icons": "^0.7.
|
|
61
|
-
"@utilitywarehouse/hearth-react-native-icons": "^0.7.2",
|
|
59
|
+
"@utilitywarehouse/hearth-react-icons": "^0.7.3",
|
|
60
|
+
"@utilitywarehouse/hearth-react-native-icons": "^0.7.3",
|
|
62
61
|
"@utilitywarehouse/hearth-svg-assets": "^0.2.0",
|
|
62
|
+
"@utilitywarehouse/hearth-fonts": "^0.0.4",
|
|
63
63
|
"@utilitywarehouse/hearth-tokens": "^0.1.3"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
3
|
+
import { Banner, Button, Center, Link } from '../../';
|
|
4
|
+
import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
|
|
5
|
+
import * as Stories from './Banner.stories';
|
|
6
|
+
|
|
7
|
+
<Meta title="Components / Banner" />
|
|
8
|
+
|
|
9
|
+
<BackToTopButton />
|
|
10
|
+
|
|
11
|
+
# Banner
|
|
12
|
+
|
|
13
|
+
The `Banner` component is a versatile card-based component for displaying informational content with an icon or image. It supports various layouts, interactive features like pressable states and close buttons, and optional action elements like buttons or links.
|
|
14
|
+
|
|
15
|
+
- [Playground](#playground)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Props](#props)
|
|
18
|
+
- [Layout Options](#layout-options)
|
|
19
|
+
- [Examples](#examples)
|
|
20
|
+
- [With Icon](#with-icon)
|
|
21
|
+
- [With Image](#with-image)
|
|
22
|
+
- [With Illustration](#with-illustration)
|
|
23
|
+
- [With Button](#with-button)
|
|
24
|
+
- [With Link](#with-link)
|
|
25
|
+
- [Pressable](#pressable)
|
|
26
|
+
- [With Close Button](#with-close-button)
|
|
27
|
+
- [Vertical Layout](#vertical-layout)
|
|
28
|
+
- [Color Schemes](#color-schemes)
|
|
29
|
+
- [Complex Examples](#complex-examples)
|
|
30
|
+
|
|
31
|
+
## Playground
|
|
32
|
+
|
|
33
|
+
<Canvas of={Stories.Playground} />
|
|
34
|
+
|
|
35
|
+
<Controls of={Stories.Playground} />
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
<UsageWrap>
|
|
40
|
+
<Center>
|
|
41
|
+
<Banner
|
|
42
|
+
icon={ElectricityMediumIcon}
|
|
43
|
+
iconContainerColor="energy"
|
|
44
|
+
heading="Energy Services"
|
|
45
|
+
description="Manage your energy account and view your usage."
|
|
46
|
+
/>
|
|
47
|
+
</Center>
|
|
48
|
+
</UsageWrap>
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
52
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
53
|
+
|
|
54
|
+
const MyComponent = () => (
|
|
55
|
+
<Banner
|
|
56
|
+
icon={ElectricityMediumIcon}
|
|
57
|
+
iconContainerColor="energy"
|
|
58
|
+
heading="Energy Services"
|
|
59
|
+
description="Manage your energy account and view your usage."
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Props
|
|
65
|
+
|
|
66
|
+
| Property | Type | Description | Default |
|
|
67
|
+
| -------------------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | -------------- |
|
|
68
|
+
| icon | `ComponentType` | Icon component to display (mutually exclusive with image/illustration) | `-` |
|
|
69
|
+
| iconContainerVariant | `'subtle' \| 'emphasis'` | Icon container visual style | `'subtle'` |
|
|
70
|
+
| iconContainerSize | `'sm' \| 'md' \| 'lg'` | Icon container size | `'md'` |
|
|
71
|
+
| iconContainerColor | `'pig' \| 'energy' \| 'broadband' \| 'mobile' \|` <br />`'insurance' \| 'cashback' \| 'highlight'` | Icon container color scheme | `'pig'` |
|
|
72
|
+
| illustration | `{ light: ImageSource, dark: ImageSource }` | Themed illustration object (mutually exclusive with icon/image) | `-` |
|
|
73
|
+
| image | `{ light: ImageSource, dark: ImageSource }` | Themed image object (mutually exclusive with icon/illustration) | `-` |
|
|
74
|
+
| heading | `string` | Heading text | `-` (required) |
|
|
75
|
+
| description | `string` | Description text | `-` (required) |
|
|
76
|
+
| direction | `'horizontal' \| 'vertical'` | Layout direction for icon/image and content | `'horizontal'` |
|
|
77
|
+
| link | `ReactNode` | Link element to display | `-` |
|
|
78
|
+
| button | `ReactNode` | Button element to display | `-` |
|
|
79
|
+
| onPress | `() => void` | Makes the entire banner pressable (shows chevron) | `-` |
|
|
80
|
+
| onClose | `() => void` | Shows close button with handler | `-` |
|
|
81
|
+
| variant | `'subtle' \| 'emphasis'` | Card visual style variant | `'subtle'` |
|
|
82
|
+
| colorScheme | `'pig' \| 'energy' \| 'broadband' \| 'mobile' \|` <br />`'insurance' \| 'cashback' \| 'highlight'` | Color scheme for buttons | `'pig'` |
|
|
83
|
+
|
|
84
|
+
The component also accepts all standard Card props except `noPadding`, `space`, `gap`, `rowGap`, `columnGap`, `flexDirection`, `flexWrap`, `alignItems`, and `justifyContent`.
|
|
85
|
+
|
|
86
|
+
## Layout Options
|
|
87
|
+
|
|
88
|
+
### Horizontal Layout (Default)
|
|
89
|
+
|
|
90
|
+
The default horizontal layout places the icon or image to the left of the content, creating a compact side-by-side arrangement.
|
|
91
|
+
|
|
92
|
+
```jsx
|
|
93
|
+
<Banner
|
|
94
|
+
icon={ElectricityMediumIcon}
|
|
95
|
+
heading="Horizontal Layout"
|
|
96
|
+
description="Icon appears to the left of the content."
|
|
97
|
+
direction="horizontal"
|
|
98
|
+
/>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Vertical Layout
|
|
102
|
+
|
|
103
|
+
The vertical layout stacks the icon or image above the content, useful for centered or full-width presentations.
|
|
104
|
+
|
|
105
|
+
```jsx
|
|
106
|
+
<Banner
|
|
107
|
+
icon={ElectricityMediumIcon}
|
|
108
|
+
heading="Vertical Layout"
|
|
109
|
+
description="Icon appears above the content."
|
|
110
|
+
direction="vertical"
|
|
111
|
+
/>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### With Icon
|
|
117
|
+
|
|
118
|
+
Use an icon with `IconContainer` styling options:
|
|
119
|
+
|
|
120
|
+
<Canvas of={Stories.WithIcon} />
|
|
121
|
+
|
|
122
|
+
```jsx
|
|
123
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
124
|
+
import {
|
|
125
|
+
ElectricityMediumIcon,
|
|
126
|
+
BroadbandMediumIcon,
|
|
127
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
128
|
+
|
|
129
|
+
const MyComponent = () => (
|
|
130
|
+
<>
|
|
131
|
+
<Banner
|
|
132
|
+
icon={ElectricityMediumIcon}
|
|
133
|
+
iconContainerColor="energy"
|
|
134
|
+
heading="Energy Services"
|
|
135
|
+
description="Manage your energy account and view your usage."
|
|
136
|
+
/>
|
|
137
|
+
|
|
138
|
+
<Banner
|
|
139
|
+
icon={BroadbandMediumIcon}
|
|
140
|
+
iconContainerColor="broadband"
|
|
141
|
+
iconContainerVariant="emphasis"
|
|
142
|
+
heading="Broadband Plans"
|
|
143
|
+
description="Upgrade your broadband to faster speeds."
|
|
144
|
+
/>
|
|
145
|
+
</>
|
|
146
|
+
);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### With Image
|
|
150
|
+
|
|
151
|
+
Display a themed image that automatically switches between light and dark modes:
|
|
152
|
+
|
|
153
|
+
<Canvas of={Stories.WithImage} />
|
|
154
|
+
|
|
155
|
+
```jsx
|
|
156
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
157
|
+
|
|
158
|
+
const MyComponent = () => (
|
|
159
|
+
<Banner
|
|
160
|
+
image={{
|
|
161
|
+
light: { uri: 'https://example.com/light-image.jpg' },
|
|
162
|
+
dark: { uri: 'https://example.com/dark-image.jpg' },
|
|
163
|
+
}}
|
|
164
|
+
heading="Featured Content"
|
|
165
|
+
description="Discover amazing content curated just for you."
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### With Illustration
|
|
171
|
+
|
|
172
|
+
Display a themed illustration that adapts to layout changes:
|
|
173
|
+
|
|
174
|
+
<Canvas of={Stories.WithIllustration} />
|
|
175
|
+
|
|
176
|
+
```jsx
|
|
177
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
178
|
+
import SpotBillingDark from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-dark.svg';
|
|
179
|
+
import SpotBillingLight from '@utilitywarehouse/hearth-svg-assets/lib/spot-billing-light.svg';
|
|
180
|
+
|
|
181
|
+
const MyComponent = () => (
|
|
182
|
+
<Banner
|
|
183
|
+
illustration={{
|
|
184
|
+
light: SpotBillingLight,
|
|
185
|
+
dark: SpotBillingDark,
|
|
186
|
+
width: 80,
|
|
187
|
+
height: 80,
|
|
188
|
+
}}
|
|
189
|
+
heading="Featured Content"
|
|
190
|
+
description="Discover amazing content curated just for you."
|
|
191
|
+
/>
|
|
192
|
+
);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### With Button
|
|
196
|
+
|
|
197
|
+
Add a button for clear call-to-action:
|
|
198
|
+
|
|
199
|
+
<Canvas of={Stories.WithButton} />
|
|
200
|
+
|
|
201
|
+
```jsx
|
|
202
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
203
|
+
import { InsuranceMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
204
|
+
|
|
205
|
+
const MyComponent = () => (
|
|
206
|
+
<Banner
|
|
207
|
+
icon={InsuranceMediumIcon}
|
|
208
|
+
iconContainerColor="insurance"
|
|
209
|
+
heading="Home Insurance"
|
|
210
|
+
description="Protect your home with our comprehensive insurance."
|
|
211
|
+
button={
|
|
212
|
+
<Button size="sm" onPress={() => console.log('Get Quote pressed')}>
|
|
213
|
+
Get Quote
|
|
214
|
+
</Button>
|
|
215
|
+
}
|
|
216
|
+
/>
|
|
217
|
+
);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### With Link
|
|
221
|
+
|
|
222
|
+
Use a link for lighter-weight actions:
|
|
223
|
+
|
|
224
|
+
<Canvas of={Stories.WithLink} />
|
|
225
|
+
|
|
226
|
+
```jsx
|
|
227
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
228
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
229
|
+
|
|
230
|
+
const MyComponent = () => (
|
|
231
|
+
<Banner
|
|
232
|
+
icon={ElectricityMediumIcon}
|
|
233
|
+
iconContainerColor="energy"
|
|
234
|
+
heading="Energy Saving Tips"
|
|
235
|
+
description="Learn how to reduce your energy consumption."
|
|
236
|
+
link={<Link href="#">View tips</Link>}
|
|
237
|
+
/>
|
|
238
|
+
);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Pressable
|
|
242
|
+
|
|
243
|
+
Make the entire banner pressable with a chevron indicator:
|
|
244
|
+
|
|
245
|
+
<Canvas of={Stories.Pressable} />
|
|
246
|
+
|
|
247
|
+
```jsx
|
|
248
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
249
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
250
|
+
|
|
251
|
+
const MyComponent = () => (
|
|
252
|
+
<Banner
|
|
253
|
+
icon={ElectricityMediumIcon}
|
|
254
|
+
iconContainerColor="energy"
|
|
255
|
+
heading="Energy Dashboard"
|
|
256
|
+
description="View your energy usage and bills."
|
|
257
|
+
onPress={() => console.log('Banner pressed')}
|
|
258
|
+
/>
|
|
259
|
+
);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### With Close Button
|
|
263
|
+
|
|
264
|
+
Add a close button for dismissible banners:
|
|
265
|
+
|
|
266
|
+
<Canvas of={Stories.WithClose} />
|
|
267
|
+
|
|
268
|
+
```jsx
|
|
269
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
270
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
271
|
+
|
|
272
|
+
const MyComponent = () => (
|
|
273
|
+
<Banner
|
|
274
|
+
icon={ElectricityMediumIcon}
|
|
275
|
+
iconContainerColor="energy"
|
|
276
|
+
heading="Special Announcement"
|
|
277
|
+
description="We have some exciting news to share with you."
|
|
278
|
+
onClose={() => console.log('Close pressed')}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Vertical Layout
|
|
284
|
+
|
|
285
|
+
Stack the icon or image above the content:
|
|
286
|
+
|
|
287
|
+
<Canvas of={Stories.VerticalLayout} />
|
|
288
|
+
|
|
289
|
+
```jsx
|
|
290
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
291
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
292
|
+
|
|
293
|
+
const MyComponent = () => (
|
|
294
|
+
<Banner
|
|
295
|
+
icon={ElectricityMediumIcon}
|
|
296
|
+
iconContainerColor="energy"
|
|
297
|
+
heading="Energy Services"
|
|
298
|
+
description="Manage your energy account and view your usage."
|
|
299
|
+
direction="vertical"
|
|
300
|
+
/>
|
|
301
|
+
);
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Color Schemes
|
|
305
|
+
|
|
306
|
+
The component supports semantic color schemes for buttons and theming:
|
|
307
|
+
|
|
308
|
+
<Canvas of={Stories.ColorSchemes} />
|
|
309
|
+
|
|
310
|
+
```jsx
|
|
311
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
312
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
313
|
+
|
|
314
|
+
const MyComponent = () => (
|
|
315
|
+
<>
|
|
316
|
+
<Banner
|
|
317
|
+
icon={ElectricityMediumIcon}
|
|
318
|
+
iconContainerColor="energy"
|
|
319
|
+
colorScheme="energy"
|
|
320
|
+
heading="Energy Blue"
|
|
321
|
+
description="Banner with energy color scheme."
|
|
322
|
+
button={
|
|
323
|
+
<Button size="sm" onPress={() => {}}>
|
|
324
|
+
Action
|
|
325
|
+
</Button>
|
|
326
|
+
}
|
|
327
|
+
/>
|
|
328
|
+
|
|
329
|
+
<Banner
|
|
330
|
+
icon={BroadbandMediumIcon}
|
|
331
|
+
iconContainerColor="broadband"
|
|
332
|
+
colorScheme="broadband"
|
|
333
|
+
heading="Broadband Green"
|
|
334
|
+
description="Banner with broadband color scheme."
|
|
335
|
+
button={
|
|
336
|
+
<Button size="sm" onPress={() => {}}>
|
|
337
|
+
Action
|
|
338
|
+
</Button>
|
|
339
|
+
}
|
|
340
|
+
/>
|
|
341
|
+
</>
|
|
342
|
+
);
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Complex Examples
|
|
346
|
+
|
|
347
|
+
Combine multiple features for rich interactive banners:
|
|
348
|
+
|
|
349
|
+
<Canvas of={Stories.ComplexExample} />
|
|
350
|
+
|
|
351
|
+
```jsx
|
|
352
|
+
import { Banner } from '@utilitywarehouse/hearth-react-native';
|
|
353
|
+
import { InsuranceMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
354
|
+
|
|
355
|
+
const MyComponent = () => (
|
|
356
|
+
<>
|
|
357
|
+
{/* Pressable banner with button */}
|
|
358
|
+
<Banner
|
|
359
|
+
icon={InsuranceMediumIcon}
|
|
360
|
+
iconContainerColor="insurance"
|
|
361
|
+
iconContainerVariant="emphasis"
|
|
362
|
+
colorScheme="insurance"
|
|
363
|
+
heading="Home Insurance Alert"
|
|
364
|
+
description="Your policy renewal is coming up. Review your coverage and make any necessary changes."
|
|
365
|
+
button={
|
|
366
|
+
<Button size="sm" onPress={() => console.log('Review pressed')}>
|
|
367
|
+
Review Policy
|
|
368
|
+
</Button>
|
|
369
|
+
}
|
|
370
|
+
onPress={() => console.log('Banner pressed')}
|
|
371
|
+
/>
|
|
372
|
+
|
|
373
|
+
{/* Dismissible banner with link */}
|
|
374
|
+
<Banner
|
|
375
|
+
image={{
|
|
376
|
+
light: { uri: 'https://example.com/light.jpg' },
|
|
377
|
+
dark: { uri: 'https://example.com/dark.jpg' },
|
|
378
|
+
}}
|
|
379
|
+
heading="Exclusive Member Benefit"
|
|
380
|
+
description="As a valued member, you now have access to premium features at no extra cost."
|
|
381
|
+
variant="emphasis"
|
|
382
|
+
link={<Link href="#">Explore benefits</Link>}
|
|
383
|
+
onClose={() => console.log('Close pressed')}
|
|
384
|
+
/>
|
|
385
|
+
</>
|
|
386
|
+
);
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Best Practices
|
|
390
|
+
|
|
391
|
+
- Use **icons** for service-related or informational banners
|
|
392
|
+
- Use **images** for promotional or visual content with fixed aspect ratios
|
|
393
|
+
- Use **illustrations** for decorative or branded visual content that adapts to layout
|
|
394
|
+
- Choose **horizontal layout** for compact presentations
|
|
395
|
+
- Choose **vertical layout** for more prominent or centered displays
|
|
396
|
+
- Use **pressable** (`onPress`) when the entire banner is clickable
|
|
397
|
+
- Use **buttons** for primary actions (e.g., "Get Started", "Learn More")
|
|
398
|
+
- Use **links** for secondary actions (e.g., "View details", "Read more")
|
|
399
|
+
- Add **close button** (`onClose`) for dismissible announcements or notifications
|
|
400
|
+
- Align **iconContainerColor** and **colorScheme** with your content's semantic meaning
|
|
401
|
+
- Don't combine icon, image, and illustration - they are mutually exclusive
|
|
402
|
+
- Avoid using both `onPress` and `onClose` together unless the distinction is clear to users
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ComponentType, ReactElement } from 'react';
|
|
2
|
+
import type { ImageSourcePropType } from 'react-native';
|
|
3
|
+
import type CardProps from '../Card/Card.props';
|
|
4
|
+
|
|
5
|
+
export type BannerDirection = 'horizontal' | 'vertical';
|
|
6
|
+
|
|
7
|
+
export interface BannerProps
|
|
8
|
+
extends Omit<
|
|
9
|
+
CardProps,
|
|
10
|
+
| 'noPadding'
|
|
11
|
+
| 'variant'
|
|
12
|
+
| 'colorScheme'
|
|
13
|
+
| 'space'
|
|
14
|
+
| 'gap'
|
|
15
|
+
| 'rowGap'
|
|
16
|
+
| 'columnGap'
|
|
17
|
+
| 'flexDirection'
|
|
18
|
+
| 'flexWrap'
|
|
19
|
+
| 'alignItems'
|
|
20
|
+
| 'justifyContent'
|
|
21
|
+
> {
|
|
22
|
+
/**
|
|
23
|
+
* Icon component to display in the banner
|
|
24
|
+
* Mutually exclusive with image
|
|
25
|
+
*/
|
|
26
|
+
icon?: ComponentType;
|
|
27
|
+
/**
|
|
28
|
+
* Icon container variant
|
|
29
|
+
* @default 'subtle'
|
|
30
|
+
*/
|
|
31
|
+
iconContainerVariant?: 'subtle' | 'emphasis';
|
|
32
|
+
/**
|
|
33
|
+
* Icon container size
|
|
34
|
+
* @default 'md'
|
|
35
|
+
*/
|
|
36
|
+
iconContainerSize?: 'sm' | 'md' | 'lg';
|
|
37
|
+
/**
|
|
38
|
+
* Icon container color
|
|
39
|
+
* @default 'pig'
|
|
40
|
+
*/
|
|
41
|
+
iconContainerColor?:
|
|
42
|
+
| 'pig'
|
|
43
|
+
| 'energy'
|
|
44
|
+
| 'broadband'
|
|
45
|
+
| 'mobile'
|
|
46
|
+
| 'insurance'
|
|
47
|
+
| 'cashback'
|
|
48
|
+
| 'highlight';
|
|
49
|
+
/**
|
|
50
|
+
* Illustration to display in the banner
|
|
51
|
+
* Mutually exclusive with icon and image
|
|
52
|
+
*/
|
|
53
|
+
illustration?: {
|
|
54
|
+
light: ImageSourcePropType | ReactElement | ComponentType;
|
|
55
|
+
dark: ImageSourcePropType | ReactElement | ComponentType;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Image to display in the banner
|
|
59
|
+
* Mutually exclusive with icon and illustration
|
|
60
|
+
*/
|
|
61
|
+
image?: {
|
|
62
|
+
light: ImageSourcePropType | ReactElement | ComponentType;
|
|
63
|
+
dark: ImageSourcePropType | ReactElement | ComponentType;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Heading text
|
|
67
|
+
*/
|
|
68
|
+
heading: string;
|
|
69
|
+
/**
|
|
70
|
+
* Description text
|
|
71
|
+
*/
|
|
72
|
+
description: string;
|
|
73
|
+
/**
|
|
74
|
+
* Layout direction for icon/image and content
|
|
75
|
+
* @default 'horizontal'
|
|
76
|
+
*/
|
|
77
|
+
direction?: BannerDirection;
|
|
78
|
+
/**
|
|
79
|
+
* Link element to display
|
|
80
|
+
*/
|
|
81
|
+
link?: ReactElement;
|
|
82
|
+
/**
|
|
83
|
+
* Button element to display
|
|
84
|
+
*/
|
|
85
|
+
button?: ReactElement;
|
|
86
|
+
/**
|
|
87
|
+
* Makes the entire banner pressable
|
|
88
|
+
*/
|
|
89
|
+
onPress?: () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Close button handler
|
|
92
|
+
*/
|
|
93
|
+
onClose?: () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Card variant
|
|
96
|
+
* @default 'subtle'
|
|
97
|
+
*/
|
|
98
|
+
variant?: 'subtle' | 'emphasis';
|
|
99
|
+
/**
|
|
100
|
+
* Color scheme for the banner
|
|
101
|
+
* @default 'pig'
|
|
102
|
+
*/
|
|
103
|
+
colorScheme?: 'pig' | 'energy' | 'broadband' | 'mobile' | 'insurance' | 'cashback' | 'highlight';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export default BannerProps;
|