@utilitywarehouse/hearth-react-native 0.6.0 → 0.8.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.
- package/.storybook/main.ts +12 -6
- 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/Button/ButtonIcon.js +2 -1
- package/build/components/Button/ButtonRoot.js +2 -6
- package/build/components/Button/ButtonText.js +4 -1
- package/build/components/Card/Card.context.d.ts +7 -0
- package/build/components/Card/CardAction/CardAction.context.d.ts +9 -0
- package/build/components/Card/{CardAction.context.js → CardAction/CardAction.context.js} +7 -1
- package/build/components/Card/CardAction/CardAction.d.ts +18 -0
- package/build/components/Card/CardAction/CardAction.js +7 -0
- package/build/components/Card/CardAction/CardAction.props.d.ts +63 -0
- package/build/components/Card/CardAction/CardAction.props.js +1 -0
- package/build/components/Card/CardAction/CardActionContent.d.ts +6 -0
- package/build/components/Card/CardAction/CardActionContent.js +13 -0
- package/build/components/Card/CardAction/CardActionHelperText.d.ts +6 -0
- package/build/components/Card/CardAction/CardActionHelperText.js +13 -0
- package/build/components/Card/CardAction/CardActionIcon.d.ts +9 -0
- package/build/components/Card/CardAction/CardActionIcon.js +19 -0
- package/build/components/Card/CardAction/CardActionLeadingContent.d.ts +6 -0
- package/build/components/Card/CardAction/CardActionLeadingContent.js +5 -0
- package/build/components/Card/CardAction/CardActionRoot.d.ts +12 -0
- package/build/components/Card/CardAction/CardActionRoot.js +155 -0
- package/build/components/Card/CardAction/CardActionText.d.ts +6 -0
- package/build/components/Card/CardAction/CardActionText.js +9 -0
- package/build/components/Card/CardAction/CardActionTrailingContent.d.ts +6 -0
- package/build/components/Card/CardAction/CardActionTrailingContent.js +5 -0
- package/build/components/Card/CardAction/CardActionTrailingIcon.d.ts +9 -0
- package/build/components/Card/CardAction/CardActionTrailingIcon.js +19 -0
- package/build/components/Card/CardAction/index.d.ts +10 -0
- package/build/components/Card/CardAction/index.js +9 -0
- package/build/components/Card/CardContent.d.ts +6 -0
- package/build/components/Card/CardContent.js +33 -0
- package/build/components/Card/CardPressHandler.context.d.ts +6 -0
- package/build/components/Card/CardPressHandler.context.js +6 -0
- package/build/components/Card/{CardAction.d.ts → CardPressHandler.d.ts} +3 -3
- package/build/components/Card/CardPressHandler.js +13 -0
- package/build/components/Card/CardRoot.js +103 -11
- package/build/components/Card/index.d.ts +3 -2
- package/build/components/Card/index.js +3 -2
- package/build/components/Checkbox/CheckboxIcon.js +2 -1
- package/build/components/Container/Container.js +3 -3
- package/build/components/CurrencyInput/CurrencyInput.js +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/Helper/HelperIcon.js +2 -1
- package/build/components/HighlightBanner/HighlightBanner.d.ts +6 -0
- package/build/components/HighlightBanner/HighlightBanner.js +86 -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/Icon/Icon.d.ts +2 -6
- package/build/components/IconButton/IconButtonIcon.js +2 -1
- package/build/components/IconContainer/IconContainer.d.ts +4 -3
- package/build/components/IconContainer/IconContainer.js +3 -3
- package/build/components/Input/InputField.js +4 -2
- package/build/components/Input/InputIcon.js +2 -1
- package/build/components/Link/LinkIcon.js +3 -2
- package/build/components/List/ListAction/ListActionTrailingIcon.js +2 -1
- package/build/components/List/ListItem/ListItemIcon.js +2 -1
- package/build/components/List/ListItem/ListItemTrailingIcon.js +2 -3
- package/build/components/Radio/RadioIcon.js +7 -2
- package/build/components/RadioCard/RadioCardIcon.js +3 -2
- package/build/components/Spinner/Spinner.web.d.ts +2 -1
- package/build/components/Switch/Switch.js +5 -3
- package/build/components/Textarea/TextareaField.js +1 -1
- package/build/components/ToggleButton/ToggleButtonIcon.js +2 -1
- package/build/components/ToggleButton/ToggleButtonRoot.js +2 -2
- package/build/components/UnstyledIconButton/UnstyledIconButtonIcon.js +2 -1
- package/build/components/index.d.ts +5 -1
- package/build/components/index.js +5 -1
- package/build/core/index.d.ts +3 -3
- package/build/core/index.js +3 -3
- package/build/core/themes.d.ts +24 -12
- package/build/hooks/useColorMode.d.ts +1 -1
- package/build/hooks/useColorMode.js +7 -8
- package/build/tokens/components/dark/banner.d.ts +19 -0
- package/build/tokens/components/dark/banner.js +19 -0
- package/build/tokens/components/dark/card-action.d.ts +11 -0
- package/build/tokens/components/dark/card-action.js +10 -0
- package/build/tokens/components/dark/card-content.d.ts +25 -0
- package/build/tokens/components/dark/card-content.js +24 -0
- package/build/tokens/components/dark/drawer.d.ts +29 -0
- package/build/tokens/components/dark/drawer.js +28 -0
- package/build/tokens/components/dark/illustrations.d.ts +0 -1
- package/build/tokens/components/dark/illustrations.js +0 -1
- package/build/tokens/components/dark/index.d.ts +3 -0
- package/build/tokens/components/dark/index.js +3 -0
- package/build/tokens/components/light/banner.d.ts +19 -0
- package/build/tokens/components/light/banner.js +19 -0
- package/build/tokens/components/light/card-action.d.ts +11 -0
- package/build/tokens/components/light/card-action.js +10 -0
- package/build/tokens/components/light/card-content.d.ts +25 -0
- package/build/tokens/components/light/card-content.js +24 -0
- package/build/tokens/components/light/drawer.d.ts +29 -0
- package/build/tokens/components/light/drawer.js +28 -0
- package/build/tokens/components/light/illustrations.d.ts +0 -1
- package/build/tokens/components/light/illustrations.js +0 -1
- package/build/tokens/components/light/index.d.ts +3 -0
- package/build/tokens/components/light/index.js +3 -0
- package/build/tokens/layout.d.ts +6 -6
- package/build/tokens/layout.js +3 -3
- package/build/tokens/typography.d.ts +6 -0
- package/build/tokens/typography.js +3 -0
- package/docs/components/AllComponents.web.tsx +75 -4
- package/docs/components/NextPrevPage.tsx +5 -5
- package/docs/components/VariantTitle.tsx +17 -7
- package/package.json +16 -14
- 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 +1 -2
- package/src/components/BottomSheet/BottomSheetFlatList.tsx +1 -3
- package/src/components/BottomSheet/BottomSheetHandle.tsx +0 -1
- package/src/components/Button/ButtonIcon.tsx +2 -1
- package/src/components/Button/ButtonRoot.tsx +2 -6
- package/src/components/Button/ButtonText.tsx +4 -1
- package/src/components/Card/Card.context.ts +7 -0
- package/src/components/Card/Card.docs.mdx +221 -15
- package/src/components/Card/Card.stories.tsx +50 -3
- package/src/components/Card/CardAction/CardAction.context.ts +22 -0
- package/src/components/Card/CardAction/CardAction.props.ts +87 -0
- package/src/components/Card/CardAction/CardAction.stories.tsx +265 -0
- package/src/components/Card/CardAction/CardAction.tsx +10 -0
- package/src/components/Card/CardAction/CardActionContent.tsx +20 -0
- package/src/components/Card/CardAction/CardActionHelperText.tsx +21 -0
- package/src/components/Card/CardAction/CardActionIcon.tsx +32 -0
- package/src/components/Card/CardAction/CardActionLeadingContent.tsx +9 -0
- package/src/components/Card/CardAction/CardActionRoot.tsx +258 -0
- package/src/components/Card/CardAction/CardActionText.tsx +17 -0
- package/src/components/Card/CardAction/CardActionTrailingContent.tsx +9 -0
- package/src/components/Card/CardAction/CardActionTrailingIcon.tsx +32 -0
- package/src/components/Card/CardAction/index.ts +10 -0
- package/src/components/Card/CardContent.tsx +40 -0
- package/src/components/Card/CardPressHandler.context.ts +12 -0
- package/src/components/Card/CardPressHandler.tsx +20 -0
- package/src/components/Card/CardRoot.tsx +128 -13
- package/src/components/Card/index.ts +3 -2
- package/src/components/Checkbox/CheckboxIcon.tsx +2 -1
- package/src/components/Container/Container.tsx +3 -3
- package/src/components/CurrencyInput/CurrencyInput.tsx +1 -1
- 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/Helper/HelperIcon.tsx +2 -1
- package/src/components/HighlightBanner/HighlightBanner.docs.mdx +277 -0
- package/src/components/HighlightBanner/HighlightBanner.props.ts +29 -0
- package/src/components/HighlightBanner/HighlightBanner.stories.tsx +259 -0
- package/src/components/HighlightBanner/HighlightBanner.tsx +122 -0
- package/src/components/HighlightBanner/index.ts +2 -0
- package/src/components/Icon/Icon.tsx +4 -3
- package/src/components/IconButton/IconButtonIcon.tsx +2 -1
- package/src/components/IconContainer/IconContainer.tsx +17 -19
- package/src/components/Input/InputField.tsx +2 -1
- package/src/components/Input/InputIcon.tsx +2 -1
- package/src/components/Link/LinkIcon.tsx +3 -2
- package/src/components/List/ListAction/ListActionTrailingIcon.tsx +2 -1
- package/src/components/List/ListItem/ListItemIcon.tsx +2 -1
- package/src/components/List/ListItem/ListItemTrailingIcon.tsx +2 -3
- package/src/components/Radio/RadioIcon.tsx +8 -3
- package/src/components/RadioCard/RadioCardIcon.tsx +4 -3
- package/src/components/Switch/Switch.tsx +10 -5
- package/src/components/Switch/Switch.web.tsx +1 -0
- package/src/components/Textarea/TextareaField.tsx +1 -1
- package/src/components/ToggleButton/ToggleButtonIcon.tsx +2 -1
- package/src/components/ToggleButton/ToggleButtonRoot.tsx +2 -2
- package/src/components/UnstyledIconButton/UnstyledIconButtonIcon.tsx +2 -1
- package/src/components/index.ts +5 -9
- package/src/core/index.ts +14 -11
- package/src/hooks/useColorMode.ts +9 -12
- package/src/tokens/components/dark/banner.ts +19 -0
- package/src/tokens/components/dark/card-action.ts +11 -0
- package/src/tokens/components/dark/card-content.ts +25 -0
- package/src/tokens/components/dark/drawer.ts +29 -0
- package/src/tokens/components/dark/illustrations.ts +0 -1
- package/src/tokens/components/dark/index.ts +3 -0
- package/src/tokens/components/light/banner.ts +19 -0
- package/src/tokens/components/light/card-action.ts +11 -0
- package/src/tokens/components/light/card-content.ts +25 -0
- package/src/tokens/components/light/drawer.ts +29 -0
- package/src/tokens/components/light/illustrations.ts +0 -1
- package/src/tokens/components/light/index.ts +3 -0
- package/src/tokens/layout.ts +3 -3
- package/src/tokens/typography.ts +3 -0
- package/build/components/Card/CardAction.context.d.ts +0 -6
- package/build/components/Card/CardAction.js +0 -13
- package/src/components/Card/CardAction.context.ts +0 -12
- package/src/components/Card/CardAction.tsx +0 -18
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import { BackToTopButton, ViewFigmaButton } from '../../../docs/components';
|
|
3
|
+
import * as Stories from './ExpandableCard.stories';
|
|
4
|
+
|
|
5
|
+
<Meta title="Components / Expandable Card" />
|
|
6
|
+
|
|
7
|
+
<BackToTopButton />
|
|
8
|
+
|
|
9
|
+
<ViewFigmaButton link="https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=7222-5934" />
|
|
10
|
+
|
|
11
|
+
# Expandable Card
|
|
12
|
+
|
|
13
|
+
The `ExpandableCard` component is an interactive card that expands to reveal additional content when clicked. It's a Card component with smooth expansion animations, making it perfect for displaying collapsible information sections.
|
|
14
|
+
|
|
15
|
+
- [Playground](#playground)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Props](#props)
|
|
18
|
+
- [`ExpandableCard`](#expandablecard)
|
|
19
|
+
- [`ExpandableCardGroup`](#expandablecardgroup)
|
|
20
|
+
- [Examples](#examples)
|
|
21
|
+
- [Basic Example](#basic-example)
|
|
22
|
+
- [With Leading Icon](#with-leading-icon)
|
|
23
|
+
- [With `Badge`](#with-badge)
|
|
24
|
+
- [With Numeric Value](#with-numeric-value)
|
|
25
|
+
- [`CardGroup`](#cardgroup)
|
|
26
|
+
- [Advanced Usage](#advanced-usage)
|
|
27
|
+
- [Accessibility](#accessibility)
|
|
28
|
+
|
|
29
|
+
## Playground
|
|
30
|
+
|
|
31
|
+
<Canvas of={Stories.Playground} />
|
|
32
|
+
|
|
33
|
+
<Controls of={Stories.Playground} />
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
<Canvas of={Stories.BasicExample} />
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { ExpandableCard, BodyText } from '@utilitywarehouse/hearth-react-native';
|
|
41
|
+
|
|
42
|
+
const MyComponent = () => (
|
|
43
|
+
<ExpandableCard
|
|
44
|
+
heading="Order Details"
|
|
45
|
+
helperText="View your order information"
|
|
46
|
+
expandedContent={
|
|
47
|
+
<>
|
|
48
|
+
<BodyText>Order #12345</BodyText>
|
|
49
|
+
<BodyText>Status: Delivered</BodyText>
|
|
50
|
+
<BodyText>Date: 10 Nov 2025</BodyText>
|
|
51
|
+
</>
|
|
52
|
+
}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Props
|
|
58
|
+
|
|
59
|
+
### `ExpandableCard`
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
| ------------------ | ----------------------------- | ------------------- | ------------------------------------------------ |
|
|
63
|
+
| `heading` | `string` | - | The heading text displayed in the trigger |
|
|
64
|
+
| `helperText` | `string` | - | Optional helper text displayed below the heading |
|
|
65
|
+
| `leadingIcon` | `ComponentType` | - | Leading icon component (automatically wrapped) |
|
|
66
|
+
| `leadingContent` | `ReactNode` | - | Leading content (icon or custom element) |
|
|
67
|
+
| `badge` | `BadgeProps` | - | Badge to display |
|
|
68
|
+
| `badgePosition` | `'top' \| 'bottom'` | `'bottom'` | Badge position |
|
|
69
|
+
| `numericValue` | `string \| number` | - | Numeric value to display on the right |
|
|
70
|
+
| `expandedContent` | `ReactNode` | - | The content to show when expanded |
|
|
71
|
+
| `expanded` | `boolean` | - | Whether the card is expanded (controlled) |
|
|
72
|
+
| `onExpandedChange` | `(expanded: boolean) => void` | - | Callback when expanded state changes |
|
|
73
|
+
| `duration` | `number` | `200` | Duration of expansion animation in milliseconds |
|
|
74
|
+
| `animateOpacity` | `boolean` | `true` | Whether to animate opacity during expansion |
|
|
75
|
+
| `disabled` | `boolean` | `false` | Whether the card is disabled |
|
|
76
|
+
| `colorScheme` | `CardColorScheme` | - | Color scheme (inherits from Card component) |
|
|
77
|
+
| `variant` | `CardVariant` | - | Variant (inherits from Card component) |
|
|
78
|
+
| `testID` | `string` | `'expandable-card'` | Test ID for testing |
|
|
79
|
+
|
|
80
|
+
### `ExpandableCardGroup`
|
|
81
|
+
|
|
82
|
+
| Prop | Type | Default | Description |
|
|
83
|
+
| ----------------------- | ----------- | ------------------------- | ---------------------------------------------- |
|
|
84
|
+
| `heading` | `string` | - | Section heading |
|
|
85
|
+
| `helperText` | `string` | - | Helper text displayed below the heading |
|
|
86
|
+
| `headerTrailingContent` | `ReactNode` | - | Trailing content for the header (e.g., a link) |
|
|
87
|
+
| `children` | `ReactNode` | - | The ExpandableCard children |
|
|
88
|
+
| `testID` | `string` | `'expandable-card-group'` | Test ID for testing |
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
### Basic Example
|
|
93
|
+
|
|
94
|
+
<Canvas of={Stories.BasicExample} />
|
|
95
|
+
|
|
96
|
+
### With Leading Icon
|
|
97
|
+
|
|
98
|
+
You can add a leading icon using the `leadingIcon` prop for simple icons, or use `leadingContent` with an `IconContainer` for more customization.
|
|
99
|
+
|
|
100
|
+
<Canvas of={Stories.WithLeadingIcon} />
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { ExpandableCard, BodyText } from '@utilitywarehouse/hearth-react-native';
|
|
104
|
+
import { SettingsMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
105
|
+
|
|
106
|
+
const MyComponent = () => (
|
|
107
|
+
<ExpandableCard
|
|
108
|
+
heading="Settings"
|
|
109
|
+
helperText="Configure your preferences"
|
|
110
|
+
leadingIcon={SettingsMediumIcon}
|
|
111
|
+
expandedContent={
|
|
112
|
+
<>
|
|
113
|
+
<BodyText>• Notifications</BodyText>
|
|
114
|
+
<BodyText>• Privacy</BodyText>
|
|
115
|
+
<BodyText>• Account</BodyText>
|
|
116
|
+
</>
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Or use `leadingContent` with `IconContainer` for emphasis variants:
|
|
123
|
+
|
|
124
|
+
<Canvas of={Stories.WithIconContainer} />
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { ExpandableCard, IconContainer, BodyText } from '@utilitywarehouse/hearth-react-native';
|
|
128
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
129
|
+
|
|
130
|
+
const MyComponent = () => (
|
|
131
|
+
<ExpandableCard
|
|
132
|
+
heading="Electricity"
|
|
133
|
+
helperText="Last reading 23/03/24"
|
|
134
|
+
leadingContent={
|
|
135
|
+
<IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
|
|
136
|
+
}
|
|
137
|
+
expandedContent={
|
|
138
|
+
<>
|
|
139
|
+
<BodyText>Current Usage: 245 kWh</BodyText>
|
|
140
|
+
<BodyText>Estimated Cost: £45.50</BodyText>
|
|
141
|
+
</>
|
|
142
|
+
}
|
|
143
|
+
/>
|
|
144
|
+
);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### With `Badge`
|
|
148
|
+
|
|
149
|
+
<Canvas of={Stories.WithBadge} />
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
<ExpandableCard
|
|
153
|
+
heading="New Feature"
|
|
154
|
+
helperText="Check out what's new"
|
|
155
|
+
badge={{ text: 'New', colorScheme: 'cyan' }}
|
|
156
|
+
expandedContent={<BodyText>We've added new features to improve your experience.</BodyText>}
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### With Numeric Value
|
|
161
|
+
|
|
162
|
+
<Canvas of={Stories.WithNumericValue} />
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<ExpandableCard
|
|
166
|
+
heading="Total Balance"
|
|
167
|
+
helperText="Current account balance"
|
|
168
|
+
numericValue="£123.45"
|
|
169
|
+
expandedContent={
|
|
170
|
+
<>
|
|
171
|
+
<BodyText>Available: £100.00</BodyText>
|
|
172
|
+
<BodyText>Pending: £23.45</BodyText>
|
|
173
|
+
</>
|
|
174
|
+
}
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### `CardGroup`
|
|
179
|
+
|
|
180
|
+
Use `ExpandableCardGroup` to group multiple expandable cards with an optional header.
|
|
181
|
+
|
|
182
|
+
<Canvas of={Stories.CardGroup} />
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import {
|
|
186
|
+
ExpandableCard,
|
|
187
|
+
ExpandableCardGroup,
|
|
188
|
+
IconContainer,
|
|
189
|
+
Link,
|
|
190
|
+
BodyText,
|
|
191
|
+
} from '@utilitywarehouse/hearth-react-native';
|
|
192
|
+
import { ElectricityMediumIcon, GasMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
193
|
+
|
|
194
|
+
const MyComponent = () => (
|
|
195
|
+
<ExpandableCardGroup
|
|
196
|
+
heading="Your Services"
|
|
197
|
+
helperText="View details for each service"
|
|
198
|
+
headerTrailingContent={<Link href="#">View all</Link>}
|
|
199
|
+
>
|
|
200
|
+
<ExpandableCard
|
|
201
|
+
heading="Electricity"
|
|
202
|
+
helperText="Last reading 23/03/24"
|
|
203
|
+
leadingContent={
|
|
204
|
+
<IconContainer icon={ElectricityMediumIcon} size="md" variant="emphasis" color="energy" />
|
|
205
|
+
}
|
|
206
|
+
expandedContent={
|
|
207
|
+
<>
|
|
208
|
+
<BodyText>Current Usage: 245 kWh</BodyText>
|
|
209
|
+
<BodyText>Estimated Cost: £45.50</BodyText>
|
|
210
|
+
</>
|
|
211
|
+
}
|
|
212
|
+
/>
|
|
213
|
+
<ExpandableCard
|
|
214
|
+
heading="Gas"
|
|
215
|
+
helperText="Last reading 23/03/24"
|
|
216
|
+
leadingContent={
|
|
217
|
+
<IconContainer icon={GasMediumIcon} size="md" variant="emphasis" color="energy" />
|
|
218
|
+
}
|
|
219
|
+
expandedContent={
|
|
220
|
+
<>
|
|
221
|
+
<BodyText>Current Usage: 180 kWh</BodyText>
|
|
222
|
+
<BodyText>Estimated Cost: £32.00</BodyText>
|
|
223
|
+
</>
|
|
224
|
+
}
|
|
225
|
+
/>
|
|
226
|
+
</ExpandableCardGroup>
|
|
227
|
+
);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Advanced Usage
|
|
231
|
+
|
|
232
|
+
If you need to use the `ExpandableCard` component in a more advanced way, you can use the child components directly for full composition control.
|
|
233
|
+
|
|
234
|
+
<Canvas of={Stories.AdvancedComposition} />
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
import {
|
|
238
|
+
ExpandableCard,
|
|
239
|
+
ExpandableCardTrigger,
|
|
240
|
+
ExpandableCardExpandedContent,
|
|
241
|
+
ExpandableCardContent,
|
|
242
|
+
IconContainer,
|
|
243
|
+
BodyText,
|
|
244
|
+
} from '@utilitywarehouse/hearth-react-native';
|
|
245
|
+
import { BillMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
246
|
+
import { useState } from 'react';
|
|
247
|
+
|
|
248
|
+
const MyComponent = () => {
|
|
249
|
+
const [expanded, setExpanded] = useState(false);
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<ExpandableCard expanded={expanded} onExpandedChange={setExpanded}>
|
|
253
|
+
<ExpandableCardTrigger
|
|
254
|
+
onPress={() => setExpanded(!expanded)}
|
|
255
|
+
heading="Custom Account Details"
|
|
256
|
+
helperText="View your detailed account information"
|
|
257
|
+
leadingContent={
|
|
258
|
+
<IconContainer icon={BillMediumIcon} size="md" variant="emphasis" color="pig" />
|
|
259
|
+
}
|
|
260
|
+
numericValue="£123.45"
|
|
261
|
+
isExpanded={expanded}
|
|
262
|
+
/>
|
|
263
|
+
<ExpandableCardExpandedContent isExpanded={expanded}>
|
|
264
|
+
<BodyText>Account Number: 1234567890</BodyText>
|
|
265
|
+
<BodyText>Sort Code: 12-34-56</BodyText>
|
|
266
|
+
<BodyText>Balance: £123.45</BodyText>
|
|
267
|
+
<BodyText>Last Updated: 12/11/25</BodyText>
|
|
268
|
+
</ExpandableCardExpandedContent>
|
|
269
|
+
</ExpandableCard>
|
|
270
|
+
);
|
|
271
|
+
};
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Child Components
|
|
275
|
+
|
|
276
|
+
When using advanced composition, you have access to these components:
|
|
277
|
+
|
|
278
|
+
- **`ExpandableCardTrigger`**: The clickable header section with heading, helper text, leading/trailing content
|
|
279
|
+
- **`ExpandableCardExpandedContent`**: Wrapper for the expanded content area with animation controls
|
|
280
|
+
- **`ExpandableCardContent`**: Content container with proper spacing and gap
|
|
281
|
+
- **`ExpandableCardIcon`**: Styled icon component for leading icons
|
|
282
|
+
- **`ExpandableCardText`**: Styled text for main heading
|
|
283
|
+
- **`ExpandableCardHelperText`**: Styled text for helper/secondary text
|
|
284
|
+
- **`ExpandableCardLeadingContent`**: Container for leading content (icons, images, etc.)
|
|
285
|
+
- **`ExpandableCardTrailingContent`**: Container for trailing content
|
|
286
|
+
- **`ExpandableCardTrailingIcon`**: Styled icon for trailing position
|
|
287
|
+
|
|
288
|
+
## Accessibility
|
|
289
|
+
|
|
290
|
+
The ExpandableCard component includes built-in accessibility support:
|
|
291
|
+
|
|
292
|
+
- Uses `accessibilityRole="button"` to indicate it's interactive
|
|
293
|
+
- Sets `accessibilityState` to communicate expanded/collapsed and disabled states
|
|
294
|
+
- Provides meaningful `accessibilityLabel` combining heading and helper text
|
|
295
|
+
- Chevron icon changes direction to indicate current state
|
|
296
|
+
- Keyboard accessible when used on web
|
|
297
|
+
|
|
298
|
+
## Best Practices
|
|
299
|
+
|
|
300
|
+
1. **Use descriptive headings**: Make sure your heading clearly describes what content will be revealed.
|
|
301
|
+
|
|
302
|
+
2. **Keep expanded content concise**: While you can put any content inside, try to keep it focused and scannable.
|
|
303
|
+
|
|
304
|
+
3. **Group related cards**: Use `ExpandableCardGroup` to organize multiple related expandable cards with a common header.
|
|
305
|
+
|
|
306
|
+
4. **Consider initial state**: Most cards should start collapsed, but you can default to expanded for critical information.
|
|
307
|
+
|
|
308
|
+
5. **Provide visual context**: Use leading icons or icon containers to help users quickly identify the card's purpose.
|
|
309
|
+
|
|
310
|
+
6. **Use numeric values appropriately**: Display counts, amounts, or other quantitative data that adds quick context.
|
|
311
|
+
|
|
312
|
+
7. **Controlled vs Uncontrolled**: Use controlled state (via `expanded` and `onExpandedChange`) when you need to manage expansion state externally, otherwise let the component handle it internally.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type BadgeProps from '../Badge/Badge.props';
|
|
3
|
+
import type CardProps from '../Card/Card.props';
|
|
4
|
+
|
|
5
|
+
export interface ExpandableCardProps extends Omit<CardProps, 'children'> {
|
|
6
|
+
/**
|
|
7
|
+
* Whether the card is expanded
|
|
8
|
+
*/
|
|
9
|
+
expanded?: boolean;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Callback when expanded state changes
|
|
13
|
+
*/
|
|
14
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The heading text displayed in the trigger
|
|
18
|
+
*/
|
|
19
|
+
heading?: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Optional helper text displayed below the heading
|
|
23
|
+
*/
|
|
24
|
+
helperText?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Leading icon component
|
|
28
|
+
*/
|
|
29
|
+
leadingIcon?: ComponentType;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Leading content (icon or custom element)
|
|
33
|
+
*/
|
|
34
|
+
leadingContent?: ReactNode;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Badge to display
|
|
38
|
+
*/
|
|
39
|
+
badge?: BadgeProps;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Badge position
|
|
43
|
+
* @default 'bottom'
|
|
44
|
+
*/
|
|
45
|
+
badgePosition?: 'top' | 'bottom';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Numeric value to display on the right
|
|
49
|
+
*/
|
|
50
|
+
numericValue?: string | number;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The content to show when expanded
|
|
54
|
+
*/
|
|
55
|
+
expandedContent?: ReactNode;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Duration of the expansion animation in milliseconds
|
|
59
|
+
* @default 200
|
|
60
|
+
*/
|
|
61
|
+
duration?: number;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether to animate opacity during expansion
|
|
65
|
+
* @default true
|
|
66
|
+
*/
|
|
67
|
+
animateOpacity?: boolean;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether the card is disabled
|
|
71
|
+
*/
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Test ID for testing
|
|
76
|
+
*/
|
|
77
|
+
testID?: string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Custom children for advanced composition
|
|
81
|
+
*/
|
|
82
|
+
children?: ReactNode;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default ExpandableCardProps;
|