@utilitywarehouse/hearth-react-native 0.30.4 → 0.31.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 +15 -18
- package/CHANGELOG.md +165 -0
- package/build/components/Badge/Badge.js +2 -2
- package/build/components/Badge/Badge.props.d.ts +1 -0
- package/build/components/Badge/BadgeText.d.ts +1 -1
- package/build/components/Badge/BadgeText.js +2 -2
- package/build/components/Container/Container.props.d.ts +2 -2
- package/build/components/ExpandableCard/ExpandableCard.d.ts +1 -1
- package/build/components/ExpandableCard/ExpandableCard.js +13 -2
- package/build/components/ExpandableCard/ExpandableCard.props.d.ts +43 -23
- package/build/components/ExpandableCard/ExpandableCardText.js +1 -1
- package/build/components/ExpandableCard/ExpandableCardTrigger.d.ts +3 -3
- package/build/components/ExpandableCard/ExpandableCardTrigger.props.d.ts +31 -6
- package/build/components/ExpandableCard/ExpandableCardTriggerRoot.d.ts +1 -1
- package/build/components/ExpandableCard/ExpandableCardTriggerRoot.js +13 -2
- package/build/components/Flex/Flex.props.d.ts +2 -2
- package/build/components/FormField/FormField.d.ts +5 -5
- package/build/components/FormField/FormField.js +3 -2
- package/build/components/Modal/Modal.d.ts +1 -1
- package/build/components/Modal/Modal.js +33 -39
- package/build/components/Modal/Modal.props.d.ts +8 -3
- package/build/components/Modal/Modal.shared.types.d.ts +19 -4
- package/build/components/Modal/Modal.web.d.ts +1 -1
- package/build/components/Modal/Modal.web.js +6 -3
- package/build/components/NavModal/NavModal.d.ts +1 -1
- package/build/components/NavModal/NavModal.js +10 -7
- package/build/components/NavModal/NavModal.props.d.ts +4 -3
- package/build/components/Table/TableHeaderCell.js +10 -1
- package/build/components/Textarea/Textarea.d.ts +1 -1
- package/build/components/Textarea/Textarea.js +64 -5
- package/build/components/Textarea/Textarea.props.d.ts +10 -0
- package/build/components/Textarea/TextareaRoot.js +4 -1
- package/build/core/themes.d.ts +92 -88
- package/build/tokens/color.d.ts +82 -80
- package/build/tokens/color.js +41 -40
- package/build/tokens/components/dark/alert.d.ts +6 -6
- package/build/tokens/components/dark/alert.js +6 -6
- package/build/tokens/components/dark/bottom-navigation.d.ts +2 -2
- package/build/tokens/components/dark/bottom-navigation.js +2 -2
- package/build/tokens/components/dark/checkbox.d.ts +1 -1
- package/build/tokens/components/dark/checkbox.js +1 -1
- package/build/tokens/components/dark/icon-button.d.ts +3 -3
- package/build/tokens/components/dark/icon-button.js +3 -3
- package/build/tokens/components/dark/inline-link.d.ts +1 -1
- package/build/tokens/components/dark/inline-link.js +1 -1
- package/build/tokens/components/dark/link.d.ts +3 -3
- package/build/tokens/components/dark/link.js +3 -3
- package/build/tokens/components/dark/navigation.d.ts +2 -2
- package/build/tokens/components/dark/navigation.js +2 -2
- package/build/tokens/components/dark/parts.d.ts +2 -2
- package/build/tokens/components/dark/parts.js +2 -2
- package/build/tokens/components/dark/progress-bar.d.ts +3 -3
- package/build/tokens/components/dark/progress-bar.js +3 -3
- package/build/tokens/components/dark/progress-stepper.d.ts +1 -1
- package/build/tokens/components/dark/progress-stepper.js +1 -1
- package/build/tokens/components/dark/spinner.d.ts +1 -1
- package/build/tokens/components/dark/spinner.js +1 -1
- package/build/tokens/components/dark/table.d.ts +2 -0
- package/build/tokens/components/dark/table.js +2 -0
- package/build/tokens/components/dark/time-picker.d.ts +1 -0
- package/build/tokens/components/dark/time-picker.js +1 -0
- package/build/tokens/components/light/parts.d.ts +3 -3
- package/build/tokens/components/light/parts.js +3 -3
- package/build/tokens/components/light/table.d.ts +2 -0
- package/build/tokens/components/light/table.js +2 -0
- package/build/tokens/components/light/time-picker.d.ts +1 -0
- package/build/tokens/components/light/time-picker.js +1 -0
- package/build/tokens/semantic-dark.d.ts +40 -40
- package/build/tokens/semantic-dark.js +40 -40
- package/docs/changelog.mdx +170 -0
- package/package.json +3 -3
- package/src/components/Badge/Badge.props.ts +1 -0
- package/src/components/Badge/Badge.tsx +6 -1
- package/src/components/Badge/BadgeText.tsx +8 -2
- package/src/components/Container/Container.props.ts +10 -1
- package/src/components/ExpandableCard/ExpandableCard.docs.mdx +89 -37
- package/src/components/ExpandableCard/ExpandableCard.props.ts +51 -27
- package/src/components/ExpandableCard/ExpandableCard.stories.tsx +67 -17
- package/src/components/ExpandableCard/ExpandableCard.tsx +15 -7
- package/src/components/ExpandableCard/ExpandableCardText.tsx +1 -1
- package/src/components/ExpandableCard/ExpandableCardTrigger.props.ts +37 -7
- package/src/components/ExpandableCard/ExpandableCardTriggerRoot.tsx +36 -2
- package/src/components/Flex/Flex.props.ts +16 -2
- package/src/components/FormField/FormField.tsx +2 -1
- package/src/components/List/List.stories.tsx +35 -0
- package/src/components/Modal/Modal.docs.mdx +52 -1
- package/src/components/Modal/Modal.props.ts +21 -6
- package/src/components/Modal/Modal.shared.types.ts +23 -4
- package/src/components/Modal/Modal.stories.tsx +165 -1
- package/src/components/Modal/Modal.tsx +101 -81
- package/src/components/Modal/Modal.web.tsx +29 -23
- package/src/components/NavModal/NavModal.docs.mdx +29 -0
- package/src/components/NavModal/NavModal.props.ts +11 -3
- package/src/components/NavModal/NavModal.stories.tsx +29 -0
- package/src/components/NavModal/NavModal.tsx +39 -33
- package/src/components/Table/TableHeaderCell.tsx +10 -1
- package/src/components/Textarea/Textarea.docs.mdx +33 -1
- package/src/components/Textarea/Textarea.props.ts +11 -2
- package/src/components/Textarea/Textarea.stories.tsx +21 -1
- package/src/components/Textarea/Textarea.tsx +107 -3
- package/src/components/Textarea/TextareaRoot.tsx +6 -2
- package/src/tokens/color.ts +41 -40
- package/src/tokens/components/dark/alert.ts +6 -6
- package/src/tokens/components/dark/bottom-navigation.ts +2 -2
- package/src/tokens/components/dark/checkbox.ts +1 -1
- package/src/tokens/components/dark/icon-button.ts +3 -3
- package/src/tokens/components/dark/inline-link.ts +1 -1
- package/src/tokens/components/dark/link.ts +3 -3
- package/src/tokens/components/dark/navigation.ts +2 -2
- package/src/tokens/components/dark/parts.ts +2 -2
- package/src/tokens/components/dark/progress-bar.ts +3 -3
- package/src/tokens/components/dark/progress-stepper.ts +1 -1
- package/src/tokens/components/dark/spinner.ts +1 -1
- package/src/tokens/components/dark/table.ts +2 -0
- package/src/tokens/components/dark/time-picker.ts +1 -0
- package/src/tokens/components/light/parts.ts +3 -3
- package/src/tokens/components/light/table.ts +2 -0
- package/src/tokens/components/light/time-picker.ts +1 -0
- package/src/tokens/semantic-dark.ts +40 -40
- package/vercel.json +0 -21
package/docs/changelog.mdx
CHANGED
|
@@ -9,6 +9,176 @@ import { BackToTopButton, NextPrevPage } from './components';
|
|
|
9
9
|
The changelog for the Hearth React Native library. Here you can find all the changes, improvements, and bug fixes for each version.
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
## 0.31.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- [#1108](https://github.com/utilitywarehouse/hearth/pull/1108) [`8c2f3b5`](https://github.com/utilitywarehouse/hearth/commit/8c2f3b5334de83a7dd799b857394a34209b748e7) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add margin, padding, and layout utility props to `Flex`.
|
|
17
|
+
|
|
18
|
+
`Flex` now exposes the shared margin and padding utility props, along with the existing layout utility prop surface, so it can be used more like other layout primitives such as `Card`.
|
|
19
|
+
|
|
20
|
+
**Component affected**:
|
|
21
|
+
- `Flex`
|
|
22
|
+
|
|
23
|
+
**Developer changes**:
|
|
24
|
+
|
|
25
|
+
You can now apply spacing and layout utility props directly on `Flex`:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
<Flex direction="row" spacing="md" padding="300" marginTop="200" flex={1}>
|
|
29
|
+
<Button>Back</Button>
|
|
30
|
+
<Button>Continue</Button>
|
|
31
|
+
</Flex>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- [#1104](https://github.com/utilitywarehouse/hearth/pull/1104) [`91feeab`](https://github.com/utilitywarehouse/hearth/commit/91feeab091ae6bf80e543f9196214066ce8b29b0) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add custom trigger content options to `ExpandableCard`.
|
|
35
|
+
|
|
36
|
+
`ExpandableCard` now supports a `triggerContent` prop for replacing the default trigger layout while keeping the chevron. `ExpandableCardTrigger` also now supports `children` with an optional `showChevron` prop, so you can fully compose the trigger content yourself and still opt in to the built-in expand/collapse chevron.
|
|
37
|
+
|
|
38
|
+
**Components affected**:
|
|
39
|
+
- `ExpandableCard`
|
|
40
|
+
- `ExpandableCardTrigger`
|
|
41
|
+
|
|
42
|
+
**Developer changes**:
|
|
43
|
+
|
|
44
|
+
Use `triggerContent` when you want a single prop on `ExpandableCard` to replace the standard trigger content:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<ExpandableCard
|
|
48
|
+
triggerContent={<BodyText weight="semibold">March bill ready</BodyText>}
|
|
49
|
+
expandedContent={<BodyText>Balance: £89.50</BodyText>}
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use `ExpandableCardTrigger` children when you want full control over the trigger structure. Add `showChevron` if you still want the built-in chevron:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<ExpandableCardTrigger isExpanded={expanded} onPress={toggleExpanded} showChevron>
|
|
57
|
+
<ExpandableCardContent>
|
|
58
|
+
<ExpandableCardText>Custom trigger</ExpandableCardText>
|
|
59
|
+
</ExpandableCardContent>
|
|
60
|
+
</ExpandableCardTrigger>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- [#1109](https://github.com/utilitywarehouse/hearth/pull/1109) [`8215550`](https://github.com/utilitywarehouse/hearth/commit/8215550745d08a8b4c18a6902e39d3199018092a) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add `numberOfLines` support to `Badge` text.
|
|
64
|
+
|
|
65
|
+
`Badge` now renders its text content on a single line by default and supports a new `numberOfLines` prop when you want to allow more lines.
|
|
66
|
+
|
|
67
|
+
**Components affected**:
|
|
68
|
+
- `Badge`
|
|
69
|
+
|
|
70
|
+
**Developer changes**:
|
|
71
|
+
|
|
72
|
+
No changes are required unless you want a `Badge` to wrap onto more than one line. To opt in, pass `numberOfLines`:
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<Badge numberOfLines={2} text="Long badge text that can wrap onto a second line" />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- [#1108](https://github.com/utilitywarehouse/hearth/pull/1108) [`8c2f3b5`](https://github.com/utilitywarehouse/hearth/commit/8c2f3b5334de83a7dd799b857394a34209b748e7) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add custom footer support to `Modal` and `NavModal`.
|
|
79
|
+
|
|
80
|
+
`Modal` and `NavModal` now support a `footer` prop for replacing the built-in primary and secondary action buttons with custom content, plus a `footerStyle` prop for styling the footer container. When `footer` is provided, the button props are now disallowed at the type level.
|
|
81
|
+
|
|
82
|
+
**Components affected**:
|
|
83
|
+
- `Modal`
|
|
84
|
+
- `NavModal`
|
|
85
|
+
|
|
86
|
+
**Developer changes**:
|
|
87
|
+
|
|
88
|
+
Use `footer` when you need a custom footer layout, such as horizontal actions or extra decoration:
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
<Modal
|
|
92
|
+
heading="Update billing details"
|
|
93
|
+
footer={
|
|
94
|
+
<Flex direction="row" spacing="md" pt="250">
|
|
95
|
+
<Button variant="outline" colorScheme="functional" style={{ flex: 1 }}>
|
|
96
|
+
Cancel
|
|
97
|
+
</Button>
|
|
98
|
+
<Button style={{ flex: 1 }}>Save changes</Button>
|
|
99
|
+
</Flex>
|
|
100
|
+
}
|
|
101
|
+
footerStyle={{
|
|
102
|
+
boxShadow: '0px -6px 12px rgba(16, 24, 40, 0.12)',
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- [#1103](https://github.com/utilitywarehouse/hearth/pull/1103) [`e375a44`](https://github.com/utilitywarehouse/hearth/commit/e375a442c507da1807e49f4d78e44edfff51d245) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add optional vertical resizing to `Textarea`.
|
|
108
|
+
|
|
109
|
+
`Textarea` now supports a new `resizable` prop that adds a bottom-right drag handle so people can increase the field height when they need more space for longer content.
|
|
110
|
+
|
|
111
|
+
**Components affected**:
|
|
112
|
+
- `Textarea`
|
|
113
|
+
|
|
114
|
+
**Developer changes**:
|
|
115
|
+
|
|
116
|
+
No changes are required unless you want to enable resizing for a textarea. To opt in, pass the new `resizable` prop:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<Textarea
|
|
120
|
+
label="Additional notes"
|
|
121
|
+
helperText="Drag the corner handle to resize"
|
|
122
|
+
placeholder="Enter your text here..."
|
|
123
|
+
resizable
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- [#1108](https://github.com/utilitywarehouse/hearth/pull/1108) [`8c2f3b5`](https://github.com/utilitywarehouse/hearth/commit/8c2f3b5334de83a7dd799b857394a34209b748e7) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add flex utility props to `Container`.
|
|
128
|
+
|
|
129
|
+
`Container` now exposes shared flex layout utility props, allowing layout properties such as `flex`, `alignItems`, `justifyContent`, and `flexDirection` to be applied directly through its public prop API.
|
|
130
|
+
|
|
131
|
+
**Component affected**:
|
|
132
|
+
- `Container`
|
|
133
|
+
|
|
134
|
+
**Developer changes**:
|
|
135
|
+
|
|
136
|
+
You can now combine `Container`'s existing spacing props with flex layout props:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<Container flex={1} justifyContent="center" alignItems="stretch" gap="200">
|
|
140
|
+
<BodyText>Content</BodyText>
|
|
141
|
+
</Container>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Patch Changes
|
|
145
|
+
|
|
146
|
+
- [#1103](https://github.com/utilitywarehouse/hearth/pull/1103) [`e375a44`](https://github.com/utilitywarehouse/hearth/commit/e375a442c507da1807e49f4d78e44edfff51d245) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Render FormField optional text with regular weight instead of inheriting the label weight.
|
|
147
|
+
|
|
148
|
+
This fixes FormField labels that append `(Optional)` so the optional text no longer inherits the main label weight.
|
|
149
|
+
|
|
150
|
+
**Components affected**:
|
|
151
|
+
- `FormField`
|
|
152
|
+
- `Textarea`
|
|
153
|
+
- `Input`
|
|
154
|
+
|
|
155
|
+
**Developer changes**:
|
|
156
|
+
|
|
157
|
+
No changes are required.
|
|
158
|
+
|
|
159
|
+
- [#1104](https://github.com/utilitywarehouse/hearth/pull/1104) [`91feeab`](https://github.com/utilitywarehouse/hearth/commit/91feeab091ae6bf80e543f9196214066ce8b29b0) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: `ExpandableCard` heading font size and weight
|
|
160
|
+
|
|
161
|
+
## 0.30.4
|
|
162
|
+
|
|
163
|
+
### Patch Changes
|
|
164
|
+
|
|
165
|
+
- [#1096](https://github.com/utilitywarehouse/hearth/pull/1096) [`6fd9021`](https://github.com/utilitywarehouse/hearth/commit/6fd9021a91ef38b56b78755965515a0807b34fa1) Thanks [@fillyD](https://github.com/fillyD)! - 🐛 [FIX]: Restore visibility of bottom sheet content in iOS accessibility tree, enabling automated tests to interact with `Select` options
|
|
166
|
+
|
|
167
|
+
## 0.30.3
|
|
168
|
+
|
|
169
|
+
### Patch Changes
|
|
170
|
+
|
|
171
|
+
- [#1094](https://github.com/utilitywarehouse/hearth/pull/1094) [`a9d8e66`](https://github.com/utilitywarehouse/hearth/commit/a9d8e660b7efa23c7a573af2658fc10ab6c043b9) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Make horizontal pressable `Banner` content flex correctly on native and web.
|
|
172
|
+
|
|
173
|
+
This fixes horizontal pressable `Banner` layouts where the content area did not expand consistently, which could misplace the chevron and action content.
|
|
174
|
+
|
|
175
|
+
**Components affected**:
|
|
176
|
+
- `Banner`
|
|
177
|
+
|
|
178
|
+
**Developer changes**:
|
|
179
|
+
|
|
180
|
+
No changes are required.
|
|
181
|
+
|
|
12
182
|
## 0.30.2
|
|
13
183
|
|
|
14
184
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilitywarehouse/hearth-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"description": "Utility Warehouse React Native UI library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"vite-plugin-svgr": "^4.5.0",
|
|
59
59
|
"vitest": "^3.2.4",
|
|
60
60
|
"@utilitywarehouse/hearth-fonts": "^0.0.4",
|
|
61
|
-
"@utilitywarehouse/hearth-react-icons": "^0.8.0",
|
|
62
61
|
"@utilitywarehouse/hearth-react-native-icons": "^0.8.0",
|
|
63
62
|
"@utilitywarehouse/hearth-svg-assets": "^0.6.0",
|
|
64
|
-
"@utilitywarehouse/hearth-tokens": "^0.2.4"
|
|
63
|
+
"@utilitywarehouse/hearth-tokens": "^0.2.4",
|
|
64
|
+
"@utilitywarehouse/hearth-react-icons": "^0.8.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@gorhom/bottom-sheet": ">=5.0.0",
|
|
@@ -15,6 +15,7 @@ const Badge = ({ children, ...props }: BadgeProps) => {
|
|
|
15
15
|
size = 'sm',
|
|
16
16
|
style,
|
|
17
17
|
text,
|
|
18
|
+
numberOfLines,
|
|
18
19
|
...rest
|
|
19
20
|
} = props;
|
|
20
21
|
|
|
@@ -31,7 +32,11 @@ const Badge = ({ children, ...props }: BadgeProps) => {
|
|
|
31
32
|
<BadgeContext.Provider value={value}>
|
|
32
33
|
<View {...rest} style={[styles.container, style]}>
|
|
33
34
|
{!!icon && <BadgeIcon as={icon} />}
|
|
34
|
-
{childIsText ?
|
|
35
|
+
{childIsText ? (
|
|
36
|
+
<BadgeText numberOfLines={numberOfLines}>{text ?? children}</BadgeText>
|
|
37
|
+
) : (
|
|
38
|
+
children
|
|
39
|
+
)}
|
|
35
40
|
</View>
|
|
36
41
|
</BadgeContext.Provider>
|
|
37
42
|
);
|
|
@@ -3,11 +3,17 @@ import { StyleSheet } from 'react-native-unistyles';
|
|
|
3
3
|
import { BodyText } from '../BodyText';
|
|
4
4
|
import { useBadgeContext } from './Badge.context';
|
|
5
5
|
|
|
6
|
-
const BadgeText = ({ children, style, ...props }: TextProps) => {
|
|
6
|
+
const BadgeText = ({ children, style, numberOfLines = 1, ...props }: TextProps) => {
|
|
7
7
|
const { variant, colorScheme, size } = useBadgeContext();
|
|
8
8
|
styles.useVariants({ variant, colorScheme });
|
|
9
9
|
return (
|
|
10
|
-
<BodyText
|
|
10
|
+
<BodyText
|
|
11
|
+
{...props}
|
|
12
|
+
numberOfLines={numberOfLines}
|
|
13
|
+
size={size}
|
|
14
|
+
weight="semibold"
|
|
15
|
+
style={[styles.text, style]}
|
|
16
|
+
>
|
|
11
17
|
{children}
|
|
12
18
|
</BodyText>
|
|
13
19
|
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ViewProps } from 'react-native';
|
|
2
2
|
import type {
|
|
3
3
|
BackgroundColorProps,
|
|
4
|
+
DisplayProps,
|
|
5
|
+
FlexLayoutProps,
|
|
4
6
|
GapProps,
|
|
5
7
|
MarginProps,
|
|
6
8
|
PaddingProps,
|
|
@@ -8,7 +10,14 @@ import type {
|
|
|
8
10
|
} from '../../types';
|
|
9
11
|
|
|
10
12
|
interface ContainerProps
|
|
11
|
-
extends
|
|
13
|
+
extends
|
|
14
|
+
ViewProps,
|
|
15
|
+
MarginProps,
|
|
16
|
+
PaddingProps,
|
|
17
|
+
GapProps,
|
|
18
|
+
BackgroundColorProps,
|
|
19
|
+
FlexLayoutProps,
|
|
20
|
+
DisplayProps {
|
|
12
21
|
/**
|
|
13
22
|
* The spacing between child elements (gap).
|
|
14
23
|
*/
|
|
@@ -22,6 +22,7 @@ The `ExpandableCard` component is an interactive card that expands to reveal add
|
|
|
22
22
|
- [With Leading Icon](#with-leading-icon)
|
|
23
23
|
- [With `Badge`](#with-badge)
|
|
24
24
|
- [With Numeric Value](#with-numeric-value)
|
|
25
|
+
- [With Custom Trigger Content](#with-custom-trigger-content)
|
|
25
26
|
- [`CardGroup`](#cardgroup)
|
|
26
27
|
- [Advanced Usage](#advanced-usage)
|
|
27
28
|
- [Accessibility](#accessibility)
|
|
@@ -58,24 +59,27 @@ const MyComponent = () => (
|
|
|
58
59
|
|
|
59
60
|
### `ExpandableCard`
|
|
60
61
|
|
|
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` | `ReactNode` | - | Badge to display
|
|
68
|
-
| `badgePosition` | `'top' \| 'bottom'` | `'bottom'` | Badge position
|
|
69
|
-
| `numericValue` | `string \| number` | - | Numeric value to display on the right
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
62
|
+
| Prop | Type | Default | Description |
|
|
63
|
+
| ------------------ | ----------------------------- | ------------------- | -------------------------------------------------------------- |
|
|
64
|
+
| `heading` | `string` | - | The heading text displayed in the trigger |
|
|
65
|
+
| `helperText` | `string` | - | Optional helper text displayed below the heading |
|
|
66
|
+
| `leadingIcon` | `ComponentType` | - | Leading icon component (automatically wrapped) |
|
|
67
|
+
| `leadingContent` | `ReactNode` | - | Leading content (icon or custom element) |
|
|
68
|
+
| `badge` | `ReactNode` | - | Badge to display |
|
|
69
|
+
| `badgePosition` | `'top' \| 'bottom'` | `'bottom'` | Badge position |
|
|
70
|
+
| `numericValue` | `string \| number` | - | Numeric value to display on the right |
|
|
71
|
+
| `triggerContent` | `ReactNode` | - | Replaces the default trigger content while keeping the chevron |
|
|
72
|
+
| `expandedContent` | `ReactNode` | - | The content to show when expanded |
|
|
73
|
+
| `expanded` | `boolean` | - | Whether the card is expanded (controlled) |
|
|
74
|
+
| `onExpandedChange` | `(expanded: boolean) => void` | - | Callback when expanded state changes |
|
|
75
|
+
| `duration` | `number` | `200` | Duration of expansion animation in milliseconds |
|
|
76
|
+
| `animateOpacity` | `boolean` | `true` | Whether to animate opacity during expansion |
|
|
77
|
+
| `disabled` | `boolean` | `false` | Whether the card is disabled |
|
|
78
|
+
| `colorScheme` | `CardColorScheme` | - | Color scheme (inherits from Card component) |
|
|
79
|
+
| `variant` | `CardVariant` | - | Variant (inherits from Card component) |
|
|
80
|
+
| `testID` | `string` | `'expandable-card'` | Test ID for testing |
|
|
81
|
+
|
|
82
|
+
When `triggerContent` is provided, the default trigger props such as `heading`, `helperText`, `leadingIcon`, `leadingContent`, `badge`, `badgePosition`, and `numericValue` are not available.
|
|
79
83
|
|
|
80
84
|
### `ExpandableCardGroup`
|
|
81
85
|
|
|
@@ -175,6 +179,34 @@ const MyComponent = () => (
|
|
|
175
179
|
/>
|
|
176
180
|
```
|
|
177
181
|
|
|
182
|
+
### With Custom Trigger Content
|
|
183
|
+
|
|
184
|
+
Use `triggerContent` when you need to replace the standard trigger layout entirely while keeping the expandable chevron.
|
|
185
|
+
|
|
186
|
+
<Canvas of={Stories.WithCustomTriggerContent} />
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { ExpandableCard, BodyText } from '@utilitywarehouse/hearth-react-native';
|
|
190
|
+
import { View } from 'react-native';
|
|
191
|
+
|
|
192
|
+
const MyComponent = () => (
|
|
193
|
+
<ExpandableCard
|
|
194
|
+
triggerContent={
|
|
195
|
+
<View style={{ flex: 1, gap: 4 }}>
|
|
196
|
+
<BodyText weight="semibold">March bill ready</BodyText>
|
|
197
|
+
<BodyText color="secondary">Due on 18 April 2026</BodyText>
|
|
198
|
+
</View>
|
|
199
|
+
}
|
|
200
|
+
expandedContent={
|
|
201
|
+
<>
|
|
202
|
+
<BodyText>Balance: £89.50</BodyText>
|
|
203
|
+
<BodyText>Payment method: Direct Debit</BodyText>
|
|
204
|
+
</>
|
|
205
|
+
}
|
|
206
|
+
/>
|
|
207
|
+
);
|
|
208
|
+
```
|
|
209
|
+
|
|
178
210
|
### `CardGroup`
|
|
179
211
|
|
|
180
212
|
Use `ExpandableCardGroup` to group multiple expandable cards with an optional header.
|
|
@@ -239,34 +271,52 @@ import {
|
|
|
239
271
|
ExpandableCardTrigger,
|
|
240
272
|
ExpandableCardExpandedContent,
|
|
241
273
|
ExpandableCardContent,
|
|
242
|
-
|
|
274
|
+
ExpandableCardHelperText,
|
|
275
|
+
ExpandableCardText,
|
|
243
276
|
BodyText,
|
|
244
277
|
} from '@utilitywarehouse/hearth-react-native';
|
|
245
|
-
import { BillMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
246
278
|
import { useState } from 'react';
|
|
279
|
+
import { View } from 'react-native';
|
|
247
280
|
|
|
248
281
|
const MyComponent = () => {
|
|
249
|
-
const [
|
|
282
|
+
const [triggerContentExpanded, setTriggerContentExpanded] = useState(false);
|
|
283
|
+
const [customChildrenExpanded, setCustomChildrenExpanded] = useState(false);
|
|
250
284
|
|
|
251
285
|
return (
|
|
252
|
-
|
|
253
|
-
<
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
<
|
|
286
|
+
<>
|
|
287
|
+
<ExpandableCard
|
|
288
|
+
expanded={triggerContentExpanded}
|
|
289
|
+
onExpandedChange={setTriggerContentExpanded}
|
|
290
|
+
expandedContent={<BodyText>Use `triggerContent` for a full replacement.</BodyText>}
|
|
291
|
+
triggerContent={
|
|
292
|
+
<View style={{ flex: 1, gap: 4 }}>
|
|
293
|
+
<BodyText weight="semibold">Use `triggerContent`</BodyText>
|
|
294
|
+
<BodyText color="secondary">Replace the built-in trigger layout</BodyText>
|
|
295
|
+
</View>
|
|
259
296
|
}
|
|
260
|
-
numericValue="£123.45"
|
|
261
|
-
isExpanded={expanded}
|
|
262
297
|
/>
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
298
|
+
|
|
299
|
+
<ExpandableCard
|
|
300
|
+
expanded={customChildrenExpanded}
|
|
301
|
+
onExpandedChange={setCustomChildrenExpanded}
|
|
302
|
+
>
|
|
303
|
+
<ExpandableCardTrigger
|
|
304
|
+
onPress={() => setCustomChildrenExpanded(!customChildrenExpanded)}
|
|
305
|
+
isExpanded={customChildrenExpanded}
|
|
306
|
+
showChevron
|
|
307
|
+
>
|
|
308
|
+
<ExpandableCardContent>
|
|
309
|
+
<ExpandableCardText>Use `children` + `showChevron`</ExpandableCardText>
|
|
310
|
+
<ExpandableCardHelperText>
|
|
311
|
+
Build the trigger yourself and keep the chevron
|
|
312
|
+
</ExpandableCardHelperText>
|
|
313
|
+
</ExpandableCardContent>
|
|
314
|
+
</ExpandableCardTrigger>
|
|
315
|
+
<ExpandableCardExpandedContent isExpanded={customChildrenExpanded}>
|
|
316
|
+
<BodyText>Use `children` when you want full trigger composition control.</BodyText>
|
|
317
|
+
</ExpandableCardExpandedContent>
|
|
318
|
+
</ExpandableCard>
|
|
319
|
+
</>
|
|
270
320
|
);
|
|
271
321
|
};
|
|
272
322
|
```
|
|
@@ -285,6 +335,8 @@ When using advanced composition, you have access to these components:
|
|
|
285
335
|
- **`ExpandableCardTrailingContent`**: Container for trailing content
|
|
286
336
|
- **`ExpandableCardTrailingIcon`**: Styled icon for trailing position
|
|
287
337
|
|
|
338
|
+
Use `triggerContent` when you want a simpler one-prop replacement on `ExpandableCard`. Use `ExpandableCardTrigger` children when you want to compose the trigger structure yourself. The built-in chevron is shown by default, and you can set `showChevron={false}` if you want to hide it.
|
|
339
|
+
|
|
288
340
|
## Accessibility
|
|
289
341
|
|
|
290
342
|
The ExpandableCard component includes built-in accessibility support:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ComponentType, ReactNode } from 'react';
|
|
2
2
|
import type CardProps from '../Card/Card.props';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
interface ExpandableCardSharedProps extends Omit<CardProps, 'children'> {
|
|
5
5
|
/**
|
|
6
6
|
* Whether the card is expanded
|
|
7
7
|
*/
|
|
@@ -12,6 +12,40 @@ export interface ExpandableCardProps extends Omit<CardProps, 'children'> {
|
|
|
12
12
|
*/
|
|
13
13
|
onExpandedChange?: (expanded: boolean) => void;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* The heading text displayed in the trigger
|
|
17
|
+
*/
|
|
18
|
+
expandedContent?: ReactNode;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Duration of the expansion animation in milliseconds
|
|
22
|
+
* @default 200
|
|
23
|
+
*/
|
|
24
|
+
duration?: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Whether to animate opacity during expansion
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
animateOpacity?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Whether the card is disabled
|
|
34
|
+
*/
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Test ID for testing
|
|
39
|
+
*/
|
|
40
|
+
testID?: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Custom children for advanced composition
|
|
44
|
+
*/
|
|
45
|
+
children?: ReactNode;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface ExpandableCardDefaultTriggerProps {
|
|
15
49
|
/**
|
|
16
50
|
* The heading text displayed in the trigger
|
|
17
51
|
*/
|
|
@@ -49,36 +83,26 @@ export interface ExpandableCardProps extends Omit<CardProps, 'children'> {
|
|
|
49
83
|
numericValue?: string | number;
|
|
50
84
|
|
|
51
85
|
/**
|
|
52
|
-
*
|
|
53
|
-
*/
|
|
54
|
-
expandedContent?: ReactNode;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Duration of the expansion animation in milliseconds
|
|
58
|
-
* @default 200
|
|
59
|
-
*/
|
|
60
|
-
duration?: number;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Whether to animate opacity during expansion
|
|
64
|
-
* @default true
|
|
65
|
-
*/
|
|
66
|
-
animateOpacity?: boolean;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Whether the card is disabled
|
|
86
|
+
* Custom trigger content that replaces the default trigger layout.
|
|
70
87
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Test ID for testing
|
|
75
|
-
*/
|
|
76
|
-
testID?: string;
|
|
88
|
+
triggerContent?: never;
|
|
89
|
+
}
|
|
77
90
|
|
|
91
|
+
interface ExpandableCardCustomTriggerProps {
|
|
78
92
|
/**
|
|
79
|
-
* Custom
|
|
93
|
+
* Custom trigger content that replaces the default trigger layout.
|
|
80
94
|
*/
|
|
81
|
-
|
|
95
|
+
triggerContent: ReactNode;
|
|
96
|
+
heading?: never;
|
|
97
|
+
helperText?: never;
|
|
98
|
+
leadingIcon?: never;
|
|
99
|
+
leadingContent?: never;
|
|
100
|
+
badge?: never;
|
|
101
|
+
badgePosition?: never;
|
|
102
|
+
numericValue?: never;
|
|
82
103
|
}
|
|
83
104
|
|
|
105
|
+
type ExpandableCardProps = ExpandableCardSharedProps &
|
|
106
|
+
(ExpandableCardDefaultTriggerProps | ExpandableCardCustomTriggerProps);
|
|
107
|
+
|
|
84
108
|
export default ExpandableCardProps;
|
|
@@ -7,11 +7,15 @@ import {
|
|
|
7
7
|
SettingsMediumIcon,
|
|
8
8
|
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
9
9
|
import React from 'react';
|
|
10
|
+
import { View } from 'react-native';
|
|
10
11
|
import { Badge, BodyText, IconContainer, Link } from '../../components';
|
|
11
12
|
import ExpandableCard from './ExpandableCard';
|
|
13
|
+
import ExpandableCardContent from './ExpandableCardContent';
|
|
12
14
|
import ExpandableCardExpandedContent from './ExpandableCardExpandedContent';
|
|
13
15
|
import ExpandableCardGroup from './ExpandableCardGroup';
|
|
16
|
+
import ExpandableCardHelperText from './ExpandableCardHelperText';
|
|
14
17
|
import ExpandableCardIcon from './ExpandableCardIcon';
|
|
18
|
+
import ExpandableCardText from './ExpandableCardText';
|
|
15
19
|
import ExpandableCardTrigger from './ExpandableCardTrigger';
|
|
16
20
|
|
|
17
21
|
const meta = {
|
|
@@ -161,6 +165,26 @@ export const WithNumericValue: Story = {
|
|
|
161
165
|
),
|
|
162
166
|
};
|
|
163
167
|
|
|
168
|
+
export const WithCustomTriggerContent: Story = {
|
|
169
|
+
render: () => (
|
|
170
|
+
<ExpandableCard
|
|
171
|
+
triggerContent={
|
|
172
|
+
<View style={{ flex: 1, gap: 4 }}>
|
|
173
|
+
<BodyText weight="semibold">March bill ready</BodyText>
|
|
174
|
+
<BodyText color="secondary">Due on 18 April 2026</BodyText>
|
|
175
|
+
</View>
|
|
176
|
+
}
|
|
177
|
+
expandedContent={
|
|
178
|
+
<>
|
|
179
|
+
<BodyText>Balance: £89.50</BodyText>
|
|
180
|
+
<BodyText>Payment method: Direct Debit</BodyText>
|
|
181
|
+
</>
|
|
182
|
+
}
|
|
183
|
+
style={{ width: 350 }}
|
|
184
|
+
/>
|
|
185
|
+
),
|
|
186
|
+
};
|
|
187
|
+
|
|
164
188
|
export const Disabled: Story = {
|
|
165
189
|
render: () => (
|
|
166
190
|
<ExpandableCard
|
|
@@ -300,27 +324,53 @@ export const ColorSchemes: Story = {
|
|
|
300
324
|
|
|
301
325
|
export const AdvancedComposition: Story = {
|
|
302
326
|
render: () => {
|
|
303
|
-
const [
|
|
327
|
+
const [triggerContentExpanded, setTriggerContentExpanded] = React.useState(false);
|
|
328
|
+
const [customChildrenExpanded, setCustomChildrenExpanded] = React.useState(false);
|
|
304
329
|
|
|
305
330
|
return (
|
|
306
|
-
<
|
|
307
|
-
<
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
331
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, width: 350 }}>
|
|
332
|
+
<ExpandableCard
|
|
333
|
+
expanded={triggerContentExpanded}
|
|
334
|
+
onExpandedChange={setTriggerContentExpanded}
|
|
335
|
+
expandedContent={
|
|
336
|
+
<>
|
|
337
|
+
<BodyText>Account Number: 1234567890</BodyText>
|
|
338
|
+
<BodyText>Sort Code: 12-34-56</BodyText>
|
|
339
|
+
<BodyText>Balance: £123.45</BodyText>
|
|
340
|
+
</>
|
|
341
|
+
}
|
|
342
|
+
triggerContent={
|
|
343
|
+
<View style={{ flex: 1, gap: 4 }}>
|
|
344
|
+
<BodyText weight="semibold">Use `triggerContent`</BodyText>
|
|
345
|
+
<BodyText color="secondary">Replace the built-in trigger layout</BodyText>
|
|
346
|
+
</View>
|
|
313
347
|
}
|
|
314
|
-
numericValue="£123.45"
|
|
315
|
-
isExpanded={expanded}
|
|
316
348
|
/>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
349
|
+
|
|
350
|
+
<ExpandableCard
|
|
351
|
+
expanded={customChildrenExpanded}
|
|
352
|
+
onExpandedChange={setCustomChildrenExpanded}
|
|
353
|
+
>
|
|
354
|
+
<ExpandableCardTrigger
|
|
355
|
+
onPress={() => setCustomChildrenExpanded(!customChildrenExpanded)}
|
|
356
|
+
isExpanded={customChildrenExpanded}
|
|
357
|
+
showChevron
|
|
358
|
+
>
|
|
359
|
+
<ExpandableCardContent>
|
|
360
|
+
<ExpandableCardText>Use `children` + `showChevron`</ExpandableCardText>
|
|
361
|
+
<ExpandableCardHelperText>
|
|
362
|
+
Build the trigger yourself and keep the chevron
|
|
363
|
+
</ExpandableCardHelperText>
|
|
364
|
+
</ExpandableCardContent>
|
|
365
|
+
</ExpandableCardTrigger>
|
|
366
|
+
<ExpandableCardExpandedContent isExpanded={customChildrenExpanded}>
|
|
367
|
+
<BodyText>Account Number: 1234567890</BodyText>
|
|
368
|
+
<BodyText>Sort Code: 12-34-56</BodyText>
|
|
369
|
+
<BodyText>Balance: £123.45</BodyText>
|
|
370
|
+
<BodyText>Last Updated: 12/11/25</BodyText>
|
|
371
|
+
</ExpandableCardExpandedContent>
|
|
372
|
+
</ExpandableCard>
|
|
373
|
+
</div>
|
|
324
374
|
);
|
|
325
375
|
},
|
|
326
376
|
};
|