@utilitywarehouse/hearth-react-native 0.17.0 → 0.18.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +13 -13
- package/CHANGELOG.md +42 -0
- package/build/components/BodyText/BodyText.js +2 -2
- package/build/components/IconButton/IconButton.props.d.ts +19 -0
- package/build/components/IconButton/IconButtonRoot.d.ts +1 -1
- package/build/components/IconButton/IconButtonRoot.js +43 -2
- package/build/components/List/ListItem/ListItemHelperText.d.ts +1 -1
- package/build/components/List/ListItem/ListItemHelperText.js +2 -2
- package/package.json +2 -2
- package/src/components/BodyText/BodyText.tsx +2 -2
- package/src/components/IconButton/IconButton.docs.mdx +91 -9
- package/src/components/IconButton/IconButton.props.ts +19 -0
- package/src/components/IconButton/IconButton.stories.tsx +56 -0
- package/src/components/IconButton/IconButtonRoot.tsx +54 -1
- package/src/components/List/ListItem/ListItemHelperText.tsx +2 -2
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @utilitywarehouse/hearth-react-native@0.
|
|
2
|
+
> @utilitywarehouse/hearth-react-native@0.18.0 lint /home/runner/work/hearth/hearth/packages/react-native
|
|
3
3
|
> TIMING=1 eslint .
|
|
4
4
|
|
|
5
5
|
|
|
@@ -55,15 +55,15 @@
|
|
|
55
55
|
|
|
56
56
|
✖ 24 problems (0 errors, 24 warnings)
|
|
57
57
|
|
|
58
|
-
Rule
|
|
59
|
-
|
|
60
|
-
@typescript-eslint/no-unused-vars
|
|
61
|
-
|
|
62
|
-
react-hooks/exhaustive-deps
|
|
63
|
-
|
|
64
|
-
no-
|
|
65
|
-
|
|
66
|
-
no-
|
|
67
|
-
|
|
68
|
-
no-regex-spaces
|
|
69
|
-
|
|
58
|
+
Rule | Time (ms) | Relative
|
|
59
|
+
:---------------------------------|----------:|--------:
|
|
60
|
+
@typescript-eslint/no-unused-vars | 1538.884 | 63.7%
|
|
61
|
+
no-global-assign | 88.035 | 3.6%
|
|
62
|
+
react-hooks/exhaustive-deps | 86.501 | 3.6%
|
|
63
|
+
react-hooks/rules-of-hooks | 67.331 | 2.8%
|
|
64
|
+
no-misleading-character-class | 48.025 | 2.0%
|
|
65
|
+
no-unexpected-multiline | 45.795 | 1.9%
|
|
66
|
+
no-loss-of-precision | 34.916 | 1.4%
|
|
67
|
+
@typescript-eslint/ban-ts-comment | 33.872 | 1.4%
|
|
68
|
+
no-regex-spaces | 31.659 | 1.3%
|
|
69
|
+
no-fallthrough | 31.350 | 1.3%
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @utilitywarehouse/hearth-react-native
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#869](https://github.com/utilitywarehouse/hearth/pull/869) [`89231c8`](https://github.com/utilitywarehouse/hearth/commit/89231c818dfd694f53b50f4cc961a38d0a50999e) Thanks [@jordmccord](https://github.com/jordmccord)! - 🌟 [FEATURE]: Add color override props to `IconButton` for service-specific branding
|
|
8
|
+
|
|
9
|
+
The `IconButton` component now supports custom color overrides through three new optional props: `backgroundColor`, `activeBackgroundColor`, and `shadowColor`. These props enable service-specific branding for use cases like service buttons (Electricity, Broadband, Mobile, Insurance, Cashback Card).
|
|
10
|
+
|
|
11
|
+
⚠️ **Important**: These props should be used sparingly and only for specific use cases where brand-specific colors are required. For most use cases, continue using the standard `colorScheme` and `variant` props to maintain design system consistency.
|
|
12
|
+
|
|
13
|
+
**Components affected**:
|
|
14
|
+
- `IconButton`
|
|
15
|
+
|
|
16
|
+
**Developer changes**:
|
|
17
|
+
|
|
18
|
+
You can now customize `IconButton` colors for service-specific branding:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { IconButton } from '@utilitywarehouse/hearth-react-native';
|
|
22
|
+
import { ElectricityMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
23
|
+
|
|
24
|
+
<IconButton
|
|
25
|
+
icon={ElectricityMediumIcon}
|
|
26
|
+
backgroundColor="energyBlue200"
|
|
27
|
+
activeBackgroundColor="energyBlue300"
|
|
28
|
+
shadowColor="energyBlue300"
|
|
29
|
+
variant="emphasis"
|
|
30
|
+
onPress={handlePress}
|
|
31
|
+
/>;
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The new props are:
|
|
35
|
+
- `backgroundColor` - Sets the base background color, overriding the color scheme's default
|
|
36
|
+
- `activeBackgroundColor` - Sets the background color when pressed or in an active state
|
|
37
|
+
- `shadowColor` - Sets the shadow/elevation color
|
|
38
|
+
|
|
39
|
+
These overrides work alongside the existing `variant` and `colorScheme` props, allowing you to maintain structural styling while customizing colors for specific branding requirements.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- [#871](https://github.com/utilitywarehouse/hearth/pull/871) [`8984335`](https://github.com/utilitywarehouse/hearth/commit/89843355d268aaa184bea75784e6841568c4784f) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Fix style ordering in `BodyText` to ensure color props properly override custom styles
|
|
44
|
+
|
|
3
45
|
## 0.17.0
|
|
4
46
|
|
|
5
47
|
### Minor Changes
|
|
@@ -18,7 +18,7 @@ const BodyText = ({ children, color, size = 'md', truncated, weight = 'regular',
|
|
|
18
18
|
}
|
|
19
19
|
: {}), style: [
|
|
20
20
|
styles.text,
|
|
21
|
-
|
|
21
|
+
props.style,
|
|
22
22
|
{
|
|
23
23
|
...(textTransform && { textTransform }),
|
|
24
24
|
...(textAlign && { textAlign }),
|
|
@@ -27,7 +27,7 @@ const BodyText = ({ children, color, size = 'md', truncated, weight = 'regular',
|
|
|
27
27
|
...(userSelect && { userSelect }),
|
|
28
28
|
...(textAlignVertical && { textAlignVertical }),
|
|
29
29
|
},
|
|
30
|
-
|
|
30
|
+
styles.getColours(color, textDecorationColor),
|
|
31
31
|
], children: children }));
|
|
32
32
|
};
|
|
33
33
|
BodyText.displayName = 'BodyText';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
2
|
import type { PressableProps } from 'react-native';
|
|
3
3
|
import { ViewProps } from 'react-native-svg/lib/typescript/fabric/utils';
|
|
4
|
+
import { ColorValue } from '../../types';
|
|
4
5
|
import { ButtonVariants } from '../Button/Button.props';
|
|
5
6
|
export type IconButtonProps = {
|
|
6
7
|
disabled?: boolean;
|
|
@@ -9,4 +10,22 @@ export type IconButtonProps = {
|
|
|
9
10
|
icon: ComponentType;
|
|
10
11
|
loading?: boolean;
|
|
11
12
|
children?: ViewProps['children'];
|
|
13
|
+
/**
|
|
14
|
+
* Custom background color override.
|
|
15
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
16
|
+
* @default undefined
|
|
17
|
+
*/
|
|
18
|
+
backgroundColor?: ColorValue;
|
|
19
|
+
/**
|
|
20
|
+
* Custom active/pressed background color override.
|
|
21
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
22
|
+
* @default undefined
|
|
23
|
+
*/
|
|
24
|
+
activeBackgroundColor?: ColorValue;
|
|
25
|
+
/**
|
|
26
|
+
* Custom shadow color override.
|
|
27
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
28
|
+
* @default undefined
|
|
29
|
+
*/
|
|
30
|
+
shadowColor?: ColorValue;
|
|
12
31
|
} & Omit<PressableProps, 'children'> & ButtonVariants;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IconButtonProps } from './IconButton.props';
|
|
2
2
|
declare const IconButtonRoot: {
|
|
3
|
-
({ children, colorScheme, variant, size, inverted, states, ...props }: IconButtonProps & {
|
|
3
|
+
({ children, colorScheme, variant, size, inverted, states, backgroundColor, activeBackgroundColor, shadowColor, ...props }: IconButtonProps & {
|
|
4
4
|
states?: {
|
|
5
5
|
active?: boolean;
|
|
6
6
|
disabled?: boolean;
|
|
@@ -2,12 +2,23 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { Pressable } from 'react-native';
|
|
4
4
|
import { StyleSheet } from 'react-native-unistyles';
|
|
5
|
+
import { getFlattenedColorValue } from '../../utils';
|
|
5
6
|
import { IconButtonContext } from './IconButton.context';
|
|
6
|
-
const IconButtonRoot = ({ children, colorScheme = 'highlight', variant = 'solid', size = 'md', inverted = false, states, ...props }) => {
|
|
7
|
+
const IconButtonRoot = ({ children, colorScheme = 'highlight', variant = 'solid', size = 'md', inverted = false, states, backgroundColor, activeBackgroundColor, shadowColor, ...props }) => {
|
|
7
8
|
const { active, disabled } = states || {};
|
|
8
9
|
styles.useVariants({ colorScheme, variant, size, inverted, disabled, active });
|
|
9
10
|
const value = useMemo(() => ({ colorScheme, variant, size, inverted, disabled, active }), [colorScheme, variant, size, inverted, disabled, active]);
|
|
10
|
-
return (_jsx(IconButtonContext.Provider, { value: value, children: _jsx(Pressable, { ...props, style: [
|
|
11
|
+
return (_jsx(IconButtonContext.Provider, { value: value, children: _jsx(Pressable, { ...props, style: [
|
|
12
|
+
styles.container,
|
|
13
|
+
styles.overrides({
|
|
14
|
+
backgroundColor,
|
|
15
|
+
activeBackgroundColor,
|
|
16
|
+
shadowColor,
|
|
17
|
+
active,
|
|
18
|
+
variant,
|
|
19
|
+
}),
|
|
20
|
+
props.style,
|
|
21
|
+
], children: children }) }));
|
|
11
22
|
};
|
|
12
23
|
IconButtonRoot.displayName = 'IconButtonRoot';
|
|
13
24
|
const styles = StyleSheet.create(theme => ({
|
|
@@ -394,5 +405,35 @@ const styles = StyleSheet.create(theme => ({
|
|
|
394
405
|
},
|
|
395
406
|
],
|
|
396
407
|
},
|
|
408
|
+
overrides: ({ backgroundColor, activeBackgroundColor, shadowColor, active, variant }) => ({
|
|
409
|
+
...(backgroundColor
|
|
410
|
+
? {
|
|
411
|
+
backgroundColor: getFlattenedColorValue(backgroundColor, theme.color),
|
|
412
|
+
_web: {
|
|
413
|
+
_hover: {
|
|
414
|
+
backgroundColor: getFlattenedColorValue(activeBackgroundColor ?? backgroundColor, theme.color),
|
|
415
|
+
},
|
|
416
|
+
_active: {
|
|
417
|
+
backgroundColor: getFlattenedColorValue(activeBackgroundColor ?? backgroundColor, theme.color),
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
}
|
|
421
|
+
: {}),
|
|
422
|
+
...(active && activeBackgroundColor
|
|
423
|
+
? {
|
|
424
|
+
backgroundColor: getFlattenedColorValue(activeBackgroundColor, theme.color),
|
|
425
|
+
}
|
|
426
|
+
: {}),
|
|
427
|
+
...(shadowColor && variant === 'emphasis'
|
|
428
|
+
? {
|
|
429
|
+
boxShadow: `${theme.shadow.mobile.sm.x}px ${theme.shadow.mobile.sm.y}px ${theme.shadow.mobile.sm.spread}px ${getFlattenedColorValue(shadowColor, theme.color)}`,
|
|
430
|
+
}
|
|
431
|
+
: {}),
|
|
432
|
+
...(active && shadowColor && variant === 'emphasis'
|
|
433
|
+
? {
|
|
434
|
+
boxShadow: 'none',
|
|
435
|
+
}
|
|
436
|
+
: {}),
|
|
437
|
+
}),
|
|
397
438
|
}));
|
|
398
439
|
export default IconButtonRoot;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BodyTextProps } from '../../BodyText';
|
|
2
2
|
declare const ListItemHelperText: {
|
|
3
|
-
({ children, ...props }: BodyTextProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
({ children, style, ...props }: BodyTextProps): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
displayName: string;
|
|
5
5
|
};
|
|
6
6
|
export default ListItemHelperText;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { StyleSheet } from 'react-native-unistyles';
|
|
3
3
|
import { BodyText } from '../../BodyText';
|
|
4
|
-
const ListItemHelperText = ({ children, ...props }) => {
|
|
5
|
-
return (_jsx(BodyText, { size: "md",
|
|
4
|
+
const ListItemHelperText = ({ children, style, ...props }) => {
|
|
5
|
+
return (_jsx(BodyText, { size: "md", style: [styles.text, style], ...props, children: children }));
|
|
6
6
|
};
|
|
7
7
|
ListItemHelperText.displayName = 'ListItemHelperText';
|
|
8
8
|
const styles = StyleSheet.create(theme => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@utilitywarehouse/hearth-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Utility Warehouse React Native UI library",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"vite-plugin-svgr": "^4.5.0",
|
|
57
57
|
"vitest": "^3.2.4",
|
|
58
58
|
"@utilitywarehouse/hearth-fonts": "^0.0.4",
|
|
59
|
-
"@utilitywarehouse/hearth-react-native-icons": "^0.7.4",
|
|
60
59
|
"@utilitywarehouse/hearth-react-icons": "^0.7.4",
|
|
60
|
+
"@utilitywarehouse/hearth-react-native-icons": "^0.7.4",
|
|
61
61
|
"@utilitywarehouse/hearth-svg-assets": "^0.3.0",
|
|
62
62
|
"@utilitywarehouse/hearth-tokens": "^0.2.2"
|
|
63
63
|
},
|
|
@@ -43,7 +43,7 @@ const BodyText = ({
|
|
|
43
43
|
: {})}
|
|
44
44
|
style={[
|
|
45
45
|
styles.text,
|
|
46
|
-
|
|
46
|
+
props.style,
|
|
47
47
|
{
|
|
48
48
|
...(textTransform && { textTransform }),
|
|
49
49
|
...(textAlign && { textAlign }),
|
|
@@ -53,7 +53,7 @@ const BodyText = ({
|
|
|
53
53
|
...(userSelect && { userSelect }),
|
|
54
54
|
...(textAlignVertical && { textAlignVertical }),
|
|
55
55
|
},
|
|
56
|
-
|
|
56
|
+
styles.getColours(color, textDecorationColor),
|
|
57
57
|
]}
|
|
58
58
|
>
|
|
59
59
|
{children}
|
|
@@ -22,6 +22,7 @@ The `IconButton` component is used to trigger an action or event, such as openin
|
|
|
22
22
|
- [Usage](#usage)
|
|
23
23
|
- [Props](#props)
|
|
24
24
|
- [Variants](#variants)
|
|
25
|
+
- [Custom Color Overrides](#custom-color-overrides)
|
|
25
26
|
|
|
26
27
|
## Playground
|
|
27
28
|
|
|
@@ -63,16 +64,97 @@ const MyComponent = () => {
|
|
|
63
64
|
|
|
64
65
|
## Props
|
|
65
66
|
|
|
66
|
-
| Property
|
|
67
|
-
|
|
|
68
|
-
| `onPress`
|
|
69
|
-
| `variant`
|
|
70
|
-
| `size`
|
|
71
|
-
| `colorScheme`
|
|
72
|
-
| `loading`
|
|
73
|
-
| `disabled`
|
|
74
|
-
| `pressed`
|
|
67
|
+
| Property | Type | Description | Default |
|
|
68
|
+
| ----------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------- |
|
|
69
|
+
| `onPress` | `() => void` | Callback function to be called when the button is pressed. | - |
|
|
70
|
+
| `variant` | `'emphasis' \| 'solid' \| 'outline' \| 'ghost'` | The variant of the button. | 'solid' |
|
|
71
|
+
| `size` | `'xs' \| 'md' ` | The size of the button. | 'md' |
|
|
72
|
+
| `colorScheme` | `'highlight' \| 'affirmative \| 'destructive' \|`<br />` 'functional' \| 'gold'` | The colour scheme of the button. | 'highlight' |
|
|
73
|
+
| `loading` | `boolean` | Changes the button to a loading state. | `false` |
|
|
74
|
+
| `disabled` | `boolean` | Disables the button. | `false` |
|
|
75
|
+
| `pressed` | `boolean` | Changes the button to a pressed state. | `false` |
|
|
76
|
+
| `backgroundColor` | `ColorValue` | Custom background color override. Use sparingly for specific use cases only. | - |
|
|
77
|
+
| `activeBackgroundColor` | `ColorValue` | Custom active/pressed background color override. Use sparingly for specific use cases only. | - |
|
|
78
|
+
| `shadowColor` | `ColorValue` | Custom shadow color override. Use sparingly for specific use cases only. | - |
|
|
75
79
|
|
|
76
80
|
## Variants
|
|
77
81
|
|
|
78
82
|
<Canvas of={Stories.KitchenSink} />
|
|
83
|
+
|
|
84
|
+
## Custom Color Overrides
|
|
85
|
+
|
|
86
|
+
The `IconButton` component supports custom color overrides through the `backgroundColor`, `activeBackgroundColor`, and `shadowColor` props.
|
|
87
|
+
|
|
88
|
+
**⚠️ Important:** These props should be used **sparingly** and only for specific use cases where brand-specific colors are required, such as service buttons (Electricity, Broadband, Mobile, Insurance, Cashback Card).
|
|
89
|
+
|
|
90
|
+
For most use cases, you should use the standard `colorScheme` and `variant` props which maintain design system consistency.
|
|
91
|
+
|
|
92
|
+
### Example: Service Icon Buttons
|
|
93
|
+
|
|
94
|
+
<Canvas of={Stories.ServiceIconButtons} />
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { IconButton } from '@utilitywarehouse/hearth-react-native';
|
|
98
|
+
import {
|
|
99
|
+
ElectricityMediumIcon,
|
|
100
|
+
BroadbandMediumIcon,
|
|
101
|
+
MobileMediumIcon,
|
|
102
|
+
InsuranceMediumIcon,
|
|
103
|
+
CashbackCardMediumIcon,
|
|
104
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
105
|
+
|
|
106
|
+
const MyComponent = () => {
|
|
107
|
+
return (
|
|
108
|
+
<>
|
|
109
|
+
<IconButton
|
|
110
|
+
icon={ElectricityMediumIcon}
|
|
111
|
+
backgroundColor="energyBlue200"
|
|
112
|
+
activeBackgroundColor="energyBlue300"
|
|
113
|
+
variant="emphasis"
|
|
114
|
+
shadowColor="energyBlue300"
|
|
115
|
+
onPress={() => console.log('Pressed')}
|
|
116
|
+
/>
|
|
117
|
+
<IconButton
|
|
118
|
+
icon={BroadbandMediumIcon}
|
|
119
|
+
backgroundColor="broadbandGreen200"
|
|
120
|
+
activeBackgroundColor="broadbandGreen300"
|
|
121
|
+
variant="emphasis"
|
|
122
|
+
shadowColor="broadbandGreen300"
|
|
123
|
+
onPress={() => console.log('Pressed')}
|
|
124
|
+
/>
|
|
125
|
+
<IconButton
|
|
126
|
+
icon={MobileMediumIcon}
|
|
127
|
+
backgroundColor="mobileRose200"
|
|
128
|
+
activeBackgroundColor="mobileRose300"
|
|
129
|
+
variant="emphasis"
|
|
130
|
+
shadowColor="mobileRose400"
|
|
131
|
+
onPress={() => console.log('Pressed')}
|
|
132
|
+
/>
|
|
133
|
+
<IconButton
|
|
134
|
+
icon={InsuranceMediumIcon}
|
|
135
|
+
backgroundColor="insuranceOrange300"
|
|
136
|
+
activeBackgroundColor="insuranceOrange400"
|
|
137
|
+
variant="emphasis"
|
|
138
|
+
shadowColor="insuranceOrange400"
|
|
139
|
+
onPress={() => console.log('Pressed')}
|
|
140
|
+
/>
|
|
141
|
+
<IconButton
|
|
142
|
+
icon={CashbackCardMediumIcon}
|
|
143
|
+
backgroundColor="cashbackLilac300"
|
|
144
|
+
activeBackgroundColor="cashbackLilac400"
|
|
145
|
+
variant="emphasis"
|
|
146
|
+
shadowColor="cashbackLilac500"
|
|
147
|
+
onPress={() => console.log('Pressed')}
|
|
148
|
+
/>
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Override Props Behavior
|
|
155
|
+
|
|
156
|
+
- **`backgroundColor`**: Sets the base background color of the button, overriding the color scheme's default background
|
|
157
|
+
- **`activeBackgroundColor`**: Sets the background color when the button is pressed or in an active state
|
|
158
|
+
- **`shadowColor`**: Sets the shadow/elevation color for the button
|
|
159
|
+
|
|
160
|
+
These overrides work alongside the existing `variant` and `colorScheme` props, allowing you to maintain the structural styling while customising colors for specific branding requirements.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
2
|
import type { PressableProps } from 'react-native';
|
|
3
3
|
import { ViewProps } from 'react-native-svg/lib/typescript/fabric/utils';
|
|
4
|
+
import { ColorValue } from '../../types';
|
|
4
5
|
import { ButtonVariants } from '../Button/Button.props';
|
|
5
6
|
|
|
6
7
|
export type IconButtonProps = {
|
|
@@ -22,5 +23,23 @@ export type IconButtonProps = {
|
|
|
22
23
|
*/
|
|
23
24
|
loading?: boolean;
|
|
24
25
|
children?: ViewProps['children'];
|
|
26
|
+
/**
|
|
27
|
+
* Custom background color override.
|
|
28
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
29
|
+
* @default undefined
|
|
30
|
+
*/
|
|
31
|
+
backgroundColor?: ColorValue;
|
|
32
|
+
/**
|
|
33
|
+
* Custom active/pressed background color override.
|
|
34
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
35
|
+
* @default undefined
|
|
36
|
+
*/
|
|
37
|
+
activeBackgroundColor?: ColorValue;
|
|
38
|
+
/**
|
|
39
|
+
* Custom shadow color override.
|
|
40
|
+
* ⚠️ Use sparingly and only for specific use cases (e.g., service buttons).
|
|
41
|
+
* @default undefined
|
|
42
|
+
*/
|
|
43
|
+
shadowColor?: ColorValue;
|
|
25
44
|
} & Omit<PressableProps, 'children'> &
|
|
26
45
|
ButtonVariants;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import * as Icons from '@utilitywarehouse/hearth-react-native-icons';
|
|
3
|
+
import {
|
|
4
|
+
BroadbandMediumIcon,
|
|
5
|
+
CashbackCardMediumIcon,
|
|
6
|
+
ElectricityMediumIcon,
|
|
7
|
+
InsuranceMediumIcon,
|
|
8
|
+
MobileMediumIcon,
|
|
9
|
+
} from '@utilitywarehouse/hearth-react-native-icons';
|
|
3
10
|
import { ComponentType } from 'react';
|
|
4
11
|
import { IconButton, IconButtonProps } from '.';
|
|
5
12
|
import { VariantTitle } from '../../../docs/components';
|
|
@@ -213,3 +220,52 @@ export const KitchenSink: Story = {
|
|
|
213
220
|
);
|
|
214
221
|
},
|
|
215
222
|
};
|
|
223
|
+
|
|
224
|
+
export const ServiceIconButtons: Story = {
|
|
225
|
+
render: () => {
|
|
226
|
+
return (
|
|
227
|
+
<ButtonGroup space="md">
|
|
228
|
+
<IconButton
|
|
229
|
+
icon={ElectricityMediumIcon}
|
|
230
|
+
backgroundColor="energyBlue200"
|
|
231
|
+
activeBackgroundColor="energyBlue300"
|
|
232
|
+
variant="emphasis"
|
|
233
|
+
shadowColor="energyBlue300"
|
|
234
|
+
onPress={() => console.log('Pressed')}
|
|
235
|
+
/>
|
|
236
|
+
<IconButton
|
|
237
|
+
icon={BroadbandMediumIcon}
|
|
238
|
+
backgroundColor="broadbandGreen200"
|
|
239
|
+
activeBackgroundColor="broadbandGreen300"
|
|
240
|
+
variant="emphasis"
|
|
241
|
+
shadowColor="broadbandGreen300"
|
|
242
|
+
onPress={() => console.log('Pressed')}
|
|
243
|
+
/>
|
|
244
|
+
<IconButton
|
|
245
|
+
icon={MobileMediumIcon}
|
|
246
|
+
backgroundColor="mobileRose200"
|
|
247
|
+
activeBackgroundColor="mobileRose300"
|
|
248
|
+
variant="emphasis"
|
|
249
|
+
shadowColor="mobileRose400"
|
|
250
|
+
onPress={() => console.log('Pressed')}
|
|
251
|
+
/>
|
|
252
|
+
<IconButton
|
|
253
|
+
icon={InsuranceMediumIcon}
|
|
254
|
+
backgroundColor="insuranceOrange300"
|
|
255
|
+
activeBackgroundColor="insuranceOrange400"
|
|
256
|
+
variant="emphasis"
|
|
257
|
+
shadowColor="insuranceOrange400"
|
|
258
|
+
onPress={() => console.log('Pressed')}
|
|
259
|
+
/>
|
|
260
|
+
<IconButton
|
|
261
|
+
icon={CashbackCardMediumIcon}
|
|
262
|
+
backgroundColor="cashbackLilac300"
|
|
263
|
+
activeBackgroundColor="cashbackLilac400"
|
|
264
|
+
variant="emphasis"
|
|
265
|
+
shadowColor="cashbackLilac500"
|
|
266
|
+
onPress={() => console.log('Pressed')}
|
|
267
|
+
/>
|
|
268
|
+
</ButtonGroup>
|
|
269
|
+
);
|
|
270
|
+
},
|
|
271
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { Pressable, ViewStyle } from 'react-native';
|
|
3
3
|
import { StyleSheet } from 'react-native-unistyles';
|
|
4
|
+
import { getFlattenedColorValue } from '../../utils';
|
|
4
5
|
import { IconButtonContext } from './IconButton.context';
|
|
5
6
|
import type { IconButtonProps } from './IconButton.props';
|
|
6
7
|
|
|
@@ -11,6 +12,9 @@ const IconButtonRoot = ({
|
|
|
11
12
|
size = 'md',
|
|
12
13
|
inverted = false,
|
|
13
14
|
states,
|
|
15
|
+
backgroundColor,
|
|
16
|
+
activeBackgroundColor,
|
|
17
|
+
shadowColor,
|
|
14
18
|
...props
|
|
15
19
|
}: IconButtonProps & { states?: { active?: boolean; disabled?: boolean } }) => {
|
|
16
20
|
const { active, disabled } = states || {};
|
|
@@ -21,7 +25,20 @@ const IconButtonRoot = ({
|
|
|
21
25
|
);
|
|
22
26
|
return (
|
|
23
27
|
<IconButtonContext.Provider value={value}>
|
|
24
|
-
<Pressable
|
|
28
|
+
<Pressable
|
|
29
|
+
{...props}
|
|
30
|
+
style={[
|
|
31
|
+
styles.container,
|
|
32
|
+
styles.overrides({
|
|
33
|
+
backgroundColor,
|
|
34
|
+
activeBackgroundColor,
|
|
35
|
+
shadowColor,
|
|
36
|
+
active,
|
|
37
|
+
variant,
|
|
38
|
+
}),
|
|
39
|
+
props.style as ViewStyle,
|
|
40
|
+
]}
|
|
41
|
+
>
|
|
25
42
|
{children}
|
|
26
43
|
</Pressable>
|
|
27
44
|
</IconButtonContext.Provider>
|
|
@@ -420,6 +437,42 @@ const styles = StyleSheet.create(theme => ({
|
|
|
420
437
|
},
|
|
421
438
|
],
|
|
422
439
|
},
|
|
440
|
+
overrides: ({ backgroundColor, activeBackgroundColor, shadowColor, active, variant }) => ({
|
|
441
|
+
...(backgroundColor
|
|
442
|
+
? {
|
|
443
|
+
backgroundColor: getFlattenedColorValue(backgroundColor, theme.color),
|
|
444
|
+
_web: {
|
|
445
|
+
_hover: {
|
|
446
|
+
backgroundColor: getFlattenedColorValue(
|
|
447
|
+
activeBackgroundColor ?? backgroundColor,
|
|
448
|
+
theme.color
|
|
449
|
+
),
|
|
450
|
+
},
|
|
451
|
+
_active: {
|
|
452
|
+
backgroundColor: getFlattenedColorValue(
|
|
453
|
+
activeBackgroundColor ?? backgroundColor,
|
|
454
|
+
theme.color
|
|
455
|
+
),
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
}
|
|
459
|
+
: {}),
|
|
460
|
+
...(active && activeBackgroundColor
|
|
461
|
+
? {
|
|
462
|
+
backgroundColor: getFlattenedColorValue(activeBackgroundColor, theme.color),
|
|
463
|
+
}
|
|
464
|
+
: {}),
|
|
465
|
+
...(shadowColor && variant === 'emphasis'
|
|
466
|
+
? {
|
|
467
|
+
boxShadow: `${theme.shadow.mobile.sm.x}px ${theme.shadow.mobile.sm.y}px ${theme.shadow.mobile.sm.spread}px ${getFlattenedColorValue(shadowColor, theme.color)}`,
|
|
468
|
+
}
|
|
469
|
+
: {}),
|
|
470
|
+
...(active && shadowColor && variant === 'emphasis'
|
|
471
|
+
? {
|
|
472
|
+
boxShadow: 'none',
|
|
473
|
+
}
|
|
474
|
+
: {}),
|
|
475
|
+
}),
|
|
423
476
|
}));
|
|
424
477
|
|
|
425
478
|
export default IconButtonRoot;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { StyleSheet } from 'react-native-unistyles';
|
|
2
2
|
import { BodyText, BodyTextProps } from '../../BodyText';
|
|
3
3
|
|
|
4
|
-
const ListItemHelperText = ({ children, ...props }: BodyTextProps) => {
|
|
4
|
+
const ListItemHelperText = ({ children, style, ...props }: BodyTextProps) => {
|
|
5
5
|
return (
|
|
6
|
-
<BodyText size="md"
|
|
6
|
+
<BodyText size="md" style={[styles.text, style]} {...props}>
|
|
7
7
|
{children}
|
|
8
8
|
</BodyText>
|
|
9
9
|
);
|