@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.
Files changed (258) hide show
  1. package/.storybook/main.ts +12 -6
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/CHANGELOG.md +18 -0
  5. package/build/components/Banner/Banner.d.ts +6 -0
  6. package/build/components/Banner/Banner.js +161 -0
  7. package/build/components/Banner/Banner.props.d.ts +82 -0
  8. package/build/components/Banner/Banner.props.js +1 -0
  9. package/build/components/Banner/index.d.ts +2 -0
  10. package/build/components/Banner/index.js +1 -0
  11. package/build/components/BottomSheet/BottomSheetBackdrop.js +1 -5
  12. package/build/components/BottomSheet/BottomSheetFlatList.js +1 -5
  13. package/build/components/BottomSheet/BottomSheetHandle.js +1 -5
  14. package/build/components/BottomSheet/useBottomSheetLogic.d.ts +1 -1
  15. package/build/components/Button/ButtonIcon.js +2 -1
  16. package/build/components/Button/ButtonRoot.js +2 -6
  17. package/build/components/Button/ButtonText.js +4 -1
  18. package/build/components/Card/Card.context.d.ts +7 -0
  19. package/build/components/Card/CardAction/CardAction.context.d.ts +9 -0
  20. package/build/components/Card/{CardAction.context.js → CardAction/CardAction.context.js} +7 -1
  21. package/build/components/Card/CardAction/CardAction.d.ts +18 -0
  22. package/build/components/Card/CardAction/CardAction.js +7 -0
  23. package/build/components/Card/CardAction/CardAction.props.d.ts +63 -0
  24. package/build/components/Card/CardAction/CardAction.props.js +1 -0
  25. package/build/components/Card/CardAction/CardActionContent.d.ts +6 -0
  26. package/build/components/Card/CardAction/CardActionContent.js +13 -0
  27. package/build/components/Card/CardAction/CardActionHelperText.d.ts +6 -0
  28. package/build/components/Card/CardAction/CardActionHelperText.js +13 -0
  29. package/build/components/Card/CardAction/CardActionIcon.d.ts +9 -0
  30. package/build/components/Card/CardAction/CardActionIcon.js +19 -0
  31. package/build/components/Card/CardAction/CardActionLeadingContent.d.ts +6 -0
  32. package/build/components/Card/CardAction/CardActionLeadingContent.js +5 -0
  33. package/build/components/Card/CardAction/CardActionRoot.d.ts +12 -0
  34. package/build/components/Card/CardAction/CardActionRoot.js +155 -0
  35. package/build/components/Card/CardAction/CardActionText.d.ts +6 -0
  36. package/build/components/Card/CardAction/CardActionText.js +9 -0
  37. package/build/components/Card/CardAction/CardActionTrailingContent.d.ts +6 -0
  38. package/build/components/Card/CardAction/CardActionTrailingContent.js +5 -0
  39. package/build/components/Card/CardAction/CardActionTrailingIcon.d.ts +9 -0
  40. package/build/components/Card/CardAction/CardActionTrailingIcon.js +19 -0
  41. package/build/components/Card/CardAction/index.d.ts +10 -0
  42. package/build/components/Card/CardAction/index.js +9 -0
  43. package/build/components/Card/CardContent.d.ts +6 -0
  44. package/build/components/Card/CardContent.js +33 -0
  45. package/build/components/Card/CardPressHandler.context.d.ts +6 -0
  46. package/build/components/Card/CardPressHandler.context.js +6 -0
  47. package/build/components/Card/{CardAction.d.ts → CardPressHandler.d.ts} +3 -3
  48. package/build/components/Card/CardPressHandler.js +13 -0
  49. package/build/components/Card/CardRoot.js +103 -11
  50. package/build/components/Card/index.d.ts +3 -2
  51. package/build/components/Card/index.js +3 -2
  52. package/build/components/Checkbox/CheckboxIcon.js +2 -1
  53. package/build/components/Container/Container.js +3 -3
  54. package/build/components/CurrencyInput/CurrencyInput.js +1 -1
  55. package/build/components/Expandable/Expandable.d.ts +6 -0
  56. package/build/components/Expandable/Expandable.js +44 -0
  57. package/build/components/Expandable/Expandable.props.d.ts +38 -0
  58. package/build/components/Expandable/Expandable.props.js +1 -0
  59. package/build/components/Expandable/index.d.ts +2 -0
  60. package/build/components/Expandable/index.js +1 -0
  61. package/build/components/ExpandableCard/ExpandableCard.d.ts +6 -0
  62. package/build/components/ExpandableCard/ExpandableCard.js +23 -0
  63. package/build/components/ExpandableCard/ExpandableCard.props.d.ts +69 -0
  64. package/build/components/ExpandableCard/ExpandableCard.props.js +1 -0
  65. package/build/components/ExpandableCard/ExpandableCardContent.d.ts +6 -0
  66. package/build/components/ExpandableCard/ExpandableCardContent.js +14 -0
  67. package/build/components/ExpandableCard/ExpandableCardExpandedContent.d.ts +11 -0
  68. package/build/components/ExpandableCard/ExpandableCardExpandedContent.js +18 -0
  69. package/build/components/ExpandableCard/ExpandableCardGroup.d.ts +6 -0
  70. package/build/components/ExpandableCard/ExpandableCardGroup.js +17 -0
  71. package/build/components/ExpandableCard/ExpandableCardGroup.props.d.ts +25 -0
  72. package/build/components/ExpandableCard/ExpandableCardGroup.props.js +1 -0
  73. package/build/components/ExpandableCard/ExpandableCardHelperText.d.ts +6 -0
  74. package/build/components/ExpandableCard/ExpandableCardHelperText.js +13 -0
  75. package/build/components/ExpandableCard/ExpandableCardIcon.d.ts +9 -0
  76. package/build/components/ExpandableCard/ExpandableCardIcon.js +19 -0
  77. package/build/components/ExpandableCard/ExpandableCardLeadingContent.d.ts +6 -0
  78. package/build/components/ExpandableCard/ExpandableCardLeadingContent.js +5 -0
  79. package/build/components/ExpandableCard/ExpandableCardText.d.ts +6 -0
  80. package/build/components/ExpandableCard/ExpandableCardText.js +7 -0
  81. package/build/components/ExpandableCard/ExpandableCardTrailingContent.d.ts +6 -0
  82. package/build/components/ExpandableCard/ExpandableCardTrailingContent.js +5 -0
  83. package/build/components/ExpandableCard/ExpandableCardTrailingIcon.d.ts +9 -0
  84. package/build/components/ExpandableCard/ExpandableCardTrailingIcon.js +17 -0
  85. package/build/components/ExpandableCard/ExpandableCardTrigger.d.ts +17 -0
  86. package/build/components/ExpandableCard/ExpandableCardTrigger.js +7 -0
  87. package/build/components/ExpandableCard/ExpandableCardTrigger.props.d.ts +44 -0
  88. package/build/components/ExpandableCard/ExpandableCardTrigger.props.js +1 -0
  89. package/build/components/ExpandableCard/ExpandableCardTriggerRoot.d.ts +11 -0
  90. package/build/components/ExpandableCard/ExpandableCardTriggerRoot.js +91 -0
  91. package/build/components/ExpandableCard/index.d.ts +14 -0
  92. package/build/components/ExpandableCard/index.js +11 -0
  93. package/build/components/Helper/HelperIcon.js +2 -1
  94. package/build/components/HighlightBanner/HighlightBanner.d.ts +6 -0
  95. package/build/components/HighlightBanner/HighlightBanner.js +86 -0
  96. package/build/components/HighlightBanner/HighlightBanner.props.d.ts +14 -0
  97. package/build/components/HighlightBanner/HighlightBanner.props.js +1 -0
  98. package/build/components/HighlightBanner/index.d.ts +2 -0
  99. package/build/components/HighlightBanner/index.js +1 -0
  100. package/build/components/Icon/Icon.d.ts +2 -6
  101. package/build/components/IconButton/IconButtonIcon.js +2 -1
  102. package/build/components/IconContainer/IconContainer.d.ts +4 -3
  103. package/build/components/IconContainer/IconContainer.js +3 -3
  104. package/build/components/Input/InputField.js +4 -2
  105. package/build/components/Input/InputIcon.js +2 -1
  106. package/build/components/Link/LinkIcon.js +3 -2
  107. package/build/components/List/ListAction/ListActionTrailingIcon.js +2 -1
  108. package/build/components/List/ListItem/ListItemIcon.js +2 -1
  109. package/build/components/List/ListItem/ListItemTrailingIcon.js +2 -3
  110. package/build/components/Radio/RadioIcon.js +7 -2
  111. package/build/components/RadioCard/RadioCardIcon.js +3 -2
  112. package/build/components/Spinner/Spinner.web.d.ts +2 -1
  113. package/build/components/Switch/Switch.js +5 -3
  114. package/build/components/Textarea/TextareaField.js +1 -1
  115. package/build/components/ToggleButton/ToggleButtonIcon.js +2 -1
  116. package/build/components/ToggleButton/ToggleButtonRoot.js +2 -2
  117. package/build/components/UnstyledIconButton/UnstyledIconButtonIcon.js +2 -1
  118. package/build/components/index.d.ts +5 -1
  119. package/build/components/index.js +5 -1
  120. package/build/core/index.d.ts +3 -3
  121. package/build/core/index.js +3 -3
  122. package/build/core/themes.d.ts +24 -12
  123. package/build/hooks/useColorMode.d.ts +1 -1
  124. package/build/hooks/useColorMode.js +7 -8
  125. package/build/tokens/components/dark/banner.d.ts +19 -0
  126. package/build/tokens/components/dark/banner.js +19 -0
  127. package/build/tokens/components/dark/card-action.d.ts +11 -0
  128. package/build/tokens/components/dark/card-action.js +10 -0
  129. package/build/tokens/components/dark/card-content.d.ts +25 -0
  130. package/build/tokens/components/dark/card-content.js +24 -0
  131. package/build/tokens/components/dark/drawer.d.ts +29 -0
  132. package/build/tokens/components/dark/drawer.js +28 -0
  133. package/build/tokens/components/dark/illustrations.d.ts +0 -1
  134. package/build/tokens/components/dark/illustrations.js +0 -1
  135. package/build/tokens/components/dark/index.d.ts +3 -0
  136. package/build/tokens/components/dark/index.js +3 -0
  137. package/build/tokens/components/light/banner.d.ts +19 -0
  138. package/build/tokens/components/light/banner.js +19 -0
  139. package/build/tokens/components/light/card-action.d.ts +11 -0
  140. package/build/tokens/components/light/card-action.js +10 -0
  141. package/build/tokens/components/light/card-content.d.ts +25 -0
  142. package/build/tokens/components/light/card-content.js +24 -0
  143. package/build/tokens/components/light/drawer.d.ts +29 -0
  144. package/build/tokens/components/light/drawer.js +28 -0
  145. package/build/tokens/components/light/illustrations.d.ts +0 -1
  146. package/build/tokens/components/light/illustrations.js +0 -1
  147. package/build/tokens/components/light/index.d.ts +3 -0
  148. package/build/tokens/components/light/index.js +3 -0
  149. package/build/tokens/layout.d.ts +6 -6
  150. package/build/tokens/layout.js +3 -3
  151. package/build/tokens/typography.d.ts +6 -0
  152. package/build/tokens/typography.js +3 -0
  153. package/docs/components/AllComponents.web.tsx +75 -4
  154. package/docs/components/NextPrevPage.tsx +5 -5
  155. package/docs/components/VariantTitle.tsx +17 -7
  156. package/package.json +16 -14
  157. package/src/components/Banner/Banner.docs.mdx +402 -0
  158. package/src/components/Banner/Banner.props.ts +106 -0
  159. package/src/components/Banner/Banner.stories.tsx +494 -0
  160. package/src/components/Banner/Banner.tsx +264 -0
  161. package/src/components/Banner/index.ts +2 -0
  162. package/src/components/BottomSheet/BottomSheetBackdrop.tsx +1 -2
  163. package/src/components/BottomSheet/BottomSheetFlatList.tsx +1 -3
  164. package/src/components/BottomSheet/BottomSheetHandle.tsx +0 -1
  165. package/src/components/Button/ButtonIcon.tsx +2 -1
  166. package/src/components/Button/ButtonRoot.tsx +2 -6
  167. package/src/components/Button/ButtonText.tsx +4 -1
  168. package/src/components/Card/Card.context.ts +7 -0
  169. package/src/components/Card/Card.docs.mdx +221 -15
  170. package/src/components/Card/Card.stories.tsx +50 -3
  171. package/src/components/Card/CardAction/CardAction.context.ts +22 -0
  172. package/src/components/Card/CardAction/CardAction.props.ts +87 -0
  173. package/src/components/Card/CardAction/CardAction.stories.tsx +265 -0
  174. package/src/components/Card/CardAction/CardAction.tsx +10 -0
  175. package/src/components/Card/CardAction/CardActionContent.tsx +20 -0
  176. package/src/components/Card/CardAction/CardActionHelperText.tsx +21 -0
  177. package/src/components/Card/CardAction/CardActionIcon.tsx +32 -0
  178. package/src/components/Card/CardAction/CardActionLeadingContent.tsx +9 -0
  179. package/src/components/Card/CardAction/CardActionRoot.tsx +258 -0
  180. package/src/components/Card/CardAction/CardActionText.tsx +17 -0
  181. package/src/components/Card/CardAction/CardActionTrailingContent.tsx +9 -0
  182. package/src/components/Card/CardAction/CardActionTrailingIcon.tsx +32 -0
  183. package/src/components/Card/CardAction/index.ts +10 -0
  184. package/src/components/Card/CardContent.tsx +40 -0
  185. package/src/components/Card/CardPressHandler.context.ts +12 -0
  186. package/src/components/Card/CardPressHandler.tsx +20 -0
  187. package/src/components/Card/CardRoot.tsx +128 -13
  188. package/src/components/Card/index.ts +3 -2
  189. package/src/components/Checkbox/CheckboxIcon.tsx +2 -1
  190. package/src/components/Container/Container.tsx +3 -3
  191. package/src/components/CurrencyInput/CurrencyInput.tsx +1 -1
  192. package/src/components/Expandable/Expandable.docs.mdx +201 -0
  193. package/src/components/Expandable/Expandable.props.ts +46 -0
  194. package/src/components/Expandable/Expandable.stories.tsx +284 -0
  195. package/src/components/Expandable/Expandable.tsx +92 -0
  196. package/src/components/Expandable/index.ts +2 -0
  197. package/src/components/ExpandableCard/ExpandableCard.docs.mdx +312 -0
  198. package/src/components/ExpandableCard/ExpandableCard.props.ts +85 -0
  199. package/src/components/ExpandableCard/ExpandableCard.stories.tsx +326 -0
  200. package/src/components/ExpandableCard/ExpandableCard.tsx +76 -0
  201. package/src/components/ExpandableCard/ExpandableCardContent.tsx +21 -0
  202. package/src/components/ExpandableCard/ExpandableCardExpandedContent.tsx +42 -0
  203. package/src/components/ExpandableCard/ExpandableCardGroup.props.ts +31 -0
  204. package/src/components/ExpandableCard/ExpandableCardGroup.tsx +40 -0
  205. package/src/components/ExpandableCard/ExpandableCardHelperText.tsx +21 -0
  206. package/src/components/ExpandableCard/ExpandableCardIcon.tsx +32 -0
  207. package/src/components/ExpandableCard/ExpandableCardLeadingContent.tsx +9 -0
  208. package/src/components/ExpandableCard/ExpandableCardText.tsx +14 -0
  209. package/src/components/ExpandableCard/ExpandableCardTrailingContent.tsx +9 -0
  210. package/src/components/ExpandableCard/ExpandableCardTrailingIcon.tsx +30 -0
  211. package/src/components/ExpandableCard/ExpandableCardTrigger.props.ts +47 -0
  212. package/src/components/ExpandableCard/ExpandableCardTrigger.tsx +10 -0
  213. package/src/components/ExpandableCard/ExpandableCardTriggerRoot.tsx +154 -0
  214. package/src/components/ExpandableCard/index.ts +14 -0
  215. package/src/components/Helper/HelperIcon.tsx +2 -1
  216. package/src/components/HighlightBanner/HighlightBanner.docs.mdx +277 -0
  217. package/src/components/HighlightBanner/HighlightBanner.props.ts +29 -0
  218. package/src/components/HighlightBanner/HighlightBanner.stories.tsx +259 -0
  219. package/src/components/HighlightBanner/HighlightBanner.tsx +122 -0
  220. package/src/components/HighlightBanner/index.ts +2 -0
  221. package/src/components/Icon/Icon.tsx +4 -3
  222. package/src/components/IconButton/IconButtonIcon.tsx +2 -1
  223. package/src/components/IconContainer/IconContainer.tsx +17 -19
  224. package/src/components/Input/InputField.tsx +2 -1
  225. package/src/components/Input/InputIcon.tsx +2 -1
  226. package/src/components/Link/LinkIcon.tsx +3 -2
  227. package/src/components/List/ListAction/ListActionTrailingIcon.tsx +2 -1
  228. package/src/components/List/ListItem/ListItemIcon.tsx +2 -1
  229. package/src/components/List/ListItem/ListItemTrailingIcon.tsx +2 -3
  230. package/src/components/Radio/RadioIcon.tsx +8 -3
  231. package/src/components/RadioCard/RadioCardIcon.tsx +4 -3
  232. package/src/components/Switch/Switch.tsx +10 -5
  233. package/src/components/Switch/Switch.web.tsx +1 -0
  234. package/src/components/Textarea/TextareaField.tsx +1 -1
  235. package/src/components/ToggleButton/ToggleButtonIcon.tsx +2 -1
  236. package/src/components/ToggleButton/ToggleButtonRoot.tsx +2 -2
  237. package/src/components/UnstyledIconButton/UnstyledIconButtonIcon.tsx +2 -1
  238. package/src/components/index.ts +5 -9
  239. package/src/core/index.ts +14 -11
  240. package/src/hooks/useColorMode.ts +9 -12
  241. package/src/tokens/components/dark/banner.ts +19 -0
  242. package/src/tokens/components/dark/card-action.ts +11 -0
  243. package/src/tokens/components/dark/card-content.ts +25 -0
  244. package/src/tokens/components/dark/drawer.ts +29 -0
  245. package/src/tokens/components/dark/illustrations.ts +0 -1
  246. package/src/tokens/components/dark/index.ts +3 -0
  247. package/src/tokens/components/light/banner.ts +19 -0
  248. package/src/tokens/components/light/card-action.ts +11 -0
  249. package/src/tokens/components/light/card-content.ts +25 -0
  250. package/src/tokens/components/light/drawer.ts +29 -0
  251. package/src/tokens/components/light/illustrations.ts +0 -1
  252. package/src/tokens/components/light/index.ts +3 -0
  253. package/src/tokens/layout.ts +3 -3
  254. package/src/tokens/typography.ts +3 -0
  255. package/build/components/Card/CardAction.context.d.ts +0 -6
  256. package/build/components/Card/CardAction.js +0 -13
  257. package/src/components/Card/CardAction.context.ts +0 -12
  258. 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;