@utilitywarehouse/hearth-react-native 0.16.2 → 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.
Files changed (75) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +14 -14
  3. package/CHANGELOG.md +174 -0
  4. package/build/components/BodyText/BodyText.js +2 -2
  5. package/build/components/Card/CardAction/CardActionRoot.js +12 -2
  6. package/build/components/Card/CardActions.context.d.ts +6 -0
  7. package/build/components/Card/CardActions.context.js +5 -0
  8. package/build/components/Card/CardActions.d.ts +7 -0
  9. package/build/components/Card/CardActions.js +29 -0
  10. package/build/components/Card/CardRoot.js +16 -104
  11. package/build/components/Card/helpers.d.ts +8 -0
  12. package/build/components/Card/helpers.js +146 -0
  13. package/build/components/Card/index.d.ts +2 -0
  14. package/build/components/Card/index.js +2 -0
  15. package/build/components/ExpandableCard/ExpandableCardGroup.d.ts +1 -1
  16. package/build/components/ExpandableCard/ExpandableCardGroup.js +2 -2
  17. package/build/components/ExpandableCard/ExpandableCardGroup.props.d.ts +4 -0
  18. package/build/components/IconButton/IconButton.props.d.ts +19 -0
  19. package/build/components/IconButton/IconButtonRoot.d.ts +1 -1
  20. package/build/components/IconButton/IconButtonRoot.js +43 -2
  21. package/build/components/Input/Input.js +4 -3
  22. package/build/components/Input/Input.props.d.ts +9 -0
  23. package/build/components/List/List.context.d.ts +4 -2
  24. package/build/components/List/List.context.js +0 -2
  25. package/build/components/List/List.d.ts +1 -1
  26. package/build/components/List/List.js +25 -38
  27. package/build/components/List/List.props.d.ts +1 -0
  28. package/build/components/List/ListAction/ListAction.js +24 -7
  29. package/build/components/List/ListAction/ListAction.props.d.ts +1 -0
  30. package/build/components/List/ListItem/ListItemHelperText.d.ts +1 -1
  31. package/build/components/List/ListItem/ListItemHelperText.js +2 -2
  32. package/build/components/List/ListItem/ListItemRoot.js +12 -4
  33. package/build/utils/isThemedImageProps.d.ts +1 -1
  34. package/package.json +2 -2
  35. package/src/components/BodyText/BodyText.tsx +2 -2
  36. package/src/components/Card/Card.docs.mdx +224 -66
  37. package/src/components/Card/Card.stories.tsx +29 -25
  38. package/src/components/Card/CardAction/CardAction.stories.tsx +239 -93
  39. package/src/components/Card/CardAction/CardActionRoot.tsx +15 -2
  40. package/src/components/Card/CardActions.context.ts +12 -0
  41. package/src/components/Card/CardActions.tsx +40 -0
  42. package/src/components/Card/CardRoot.tsx +27 -132
  43. package/src/components/Card/helpers.tsx +195 -0
  44. package/src/components/Card/index.ts +2 -0
  45. package/src/components/ExpandableCard/ExpandableCard.figma.tsx +33 -38
  46. package/src/components/ExpandableCard/ExpandableCardGroup.figma.tsx +34 -17
  47. package/src/components/ExpandableCard/ExpandableCardGroup.props.ts +5 -0
  48. package/src/components/ExpandableCard/ExpandableCardGroup.tsx +2 -0
  49. package/src/components/HighlightBanner/HighlightBanner.figma.tsx +46 -0
  50. package/src/components/IconButton/IconButton.docs.mdx +91 -9
  51. package/src/components/IconButton/IconButton.figma.tsx +20 -30
  52. package/src/components/IconButton/IconButton.props.ts +19 -0
  53. package/src/components/IconButton/IconButton.stories.tsx +56 -0
  54. package/src/components/IconButton/IconButtonRoot.tsx +54 -1
  55. package/src/components/IconContainer/IconContainer.figma.tsx +7 -13
  56. package/src/components/IndicatorIconButton/IndicatorIconButton.figma.tsx +16 -0
  57. package/src/components/Input/Input.docs.mdx +55 -15
  58. package/src/components/Input/Input.figma.tsx +106 -40
  59. package/src/components/Input/Input.props.ts +9 -0
  60. package/src/components/Input/Input.tsx +21 -0
  61. package/src/components/Link/Link.figma.tsx +31 -38
  62. package/src/components/List/List.context.ts +2 -4
  63. package/src/components/List/List.docs.mdx +10 -5
  64. package/src/components/List/List.figma.tsx +42 -28
  65. package/src/components/List/List.props.ts +1 -0
  66. package/src/components/List/List.stories.tsx +43 -0
  67. package/src/components/List/List.tsx +38 -51
  68. package/src/components/List/ListAction/ListAction.figma.tsx +5 -13
  69. package/src/components/List/ListAction/ListAction.props.ts +1 -0
  70. package/src/components/List/ListAction/ListAction.tsx +40 -10
  71. package/src/components/List/ListItem/ListItem.figma.tsx +43 -27
  72. package/src/components/List/ListItem/ListItemHelperText.tsx +2 -2
  73. package/src/components/List/ListItem/ListItemRoot.tsx +15 -4
  74. package/src/utils/isThemedImageProps.ts +1 -1
  75. package/src/components/InlineLink/InlineLink.figma.tsx +0 -33
@@ -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 | Type | Description | Default |
67
- | ------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------- | ----------- |
68
- | `onPress` | `() => void` | Callback function to be called when the button is pressed. | - |
69
- | `variant` | `'emphasis' \| 'solid' \| 'outline' \| 'ghost'` | The variant of the button. | 'solid' |
70
- | `size` | `'xs' \| 'md' ` | The size of the button. | 'md' |
71
- | `colorScheme` | `'highlight' \| 'affirmative \| 'destructive' \| 'functional' \| 'gold'` | The colour scheme of the button. | 'highlight' |
72
- | `loading` | `boolean` | Changes the button to a loading state. | `false` |
73
- | `disabled` | `boolean` | Disables the button. | `false` |
74
- | `pressed` | `boolean` | Changes the button to a pressed state. | `false` |
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,16 +1,8 @@
1
1
  import figma from '@figma/code-connect';
2
- import IconButton from './IconButton';
3
-
4
- /**
5
- * -- This file was auto-generated by Code Connect --
6
- * `props` includes a mapping from your code props to Figma properties.
7
- * You should check this is correct, and update the `example` function
8
- * to return the code example you'd like to see in Figma
9
- */
2
+ import { IconButton } from '../';
10
3
 
11
4
  figma.connect(IconButton, 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR?node-id=90%3A1455', {
12
5
  props: {
13
- // These props were automatically mapped based on your linked code:
14
6
  disabled: figma.enum('State', {
15
7
  Disabled: true,
16
8
  }),
@@ -18,38 +10,36 @@ figma.connect(IconButton, 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR?n
18
10
  'SM-32': 'sm',
19
11
  'MD-48': 'md',
20
12
  }),
13
+ colorScheme: figma.enum('Color Scheme', {
14
+ Affirmative: 'affirmative',
15
+ Destructive: 'destructive',
16
+ Functional: 'functional',
17
+ Highlight: 'highlight',
18
+ }),
21
19
  loading: figma.enum('State', {
22
20
  Loading: true,
23
21
  }),
24
- focusable: figma.enum('State', {
25
- Focus: true,
26
- }),
27
- 'aria-disabled': figma.enum('State', {
28
- Disabled: true,
22
+ icon: figma.enum('Size', {
23
+ 'SM-32': figma.instance('Icon-20'),
24
+ 'MD-48': figma.instance('Icon-24'),
29
25
  }),
30
- colorScheme: figma.enum('Color Scheme', {
31
- Affirmative: 'affirmative',
32
- Destructive: 'destructive',
26
+ variant: figma.enum('Variant', {
27
+ Emphasis: 'emphasis',
28
+ Solid: 'solid',
29
+ Outline: 'outline',
30
+ Ghost: 'ghost',
33
31
  }),
34
- // No matching props could be found for these Figma properties:
35
- // "icon24": figma.instance('Icon-24'),
36
- // "icon20": figma.instance('Icon-20'),
37
- // "variant": figma.enum('Variant', {
38
- // "Emphasis": "emphasis",
39
- // "Solid": "solid",
40
- // "Outline": "outline",
41
- // "Ghost": "ghost"
42
- // }),
43
- // "inverted": figma.boolean('Inverted?')
32
+ inverted: figma.boolean('Inverted?'),
44
33
  },
45
34
  example: props => (
46
35
  <IconButton
47
36
  disabled={props.disabled}
48
37
  size={props.size}
49
- icon={null}
50
- loading={props.loading}
51
- focusable={props.focusable}
38
+ variant={props.variant}
39
+ inverted={props.inverted}
52
40
  colorScheme={props.colorScheme}
41
+ loading={props.loading}
42
+ icon={props.icon}
53
43
  />
54
44
  ),
55
45
  });
@@ -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 {...props} style={[styles.container, props.style as ViewStyle]}>
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,19 +1,11 @@
1
1
  import figma from '@figma/code-connect';
2
- import IconContainer from './IconContainer';
3
-
4
- /**
5
- * -- This file was auto-generated by Code Connect --
6
- * `props` includes a mapping from your code props to Figma properties.
7
- * You should check this is correct, and update the `example` function
8
- * to return the code example you'd like to see in Figma
9
- */
2
+ import { IconContainer } from '../';
10
3
 
11
4
  figma.connect(
12
5
  IconContainer,
13
6
  'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR?node-id=5462%3A9728',
14
7
  {
15
8
  props: {
16
- // These props were automatically mapped based on your linked code:
17
9
  size: figma.enum('Size', {
18
10
  'SM-32': 'sm',
19
11
  'MD-48': 'md',
@@ -33,13 +25,15 @@ figma.connect(
33
25
  Cashback: 'cashback',
34
26
  Highlight: 'highlight',
35
27
  }),
36
- // No matching props could be found for these Figma properties:
37
- // "icon20": figma.instance('Icon-20'),
38
- // "icon24": figma.instance('Icon-24')
28
+ icon: figma.enum('Size', {
29
+ 'SM-32': figma.instance('Icon-20'),
30
+ 'MD-48': figma.instance('Icon-24'),
31
+ 'LG-64': figma.instance('Icon-24'),
32
+ }),
39
33
  },
40
34
  example: props => (
41
35
  <IconContainer
42
- icon={null}
36
+ icon={props.icon}
43
37
  size={props.size}
44
38
  radiusNone={props.radiusNone}
45
39
  variant={props.variant}
@@ -0,0 +1,16 @@
1
+ import figma from '@figma/code-connect';
2
+ import { IndicatorIconButton } from '..';
3
+
4
+ figma.connect(
5
+ IndicatorIconButton,
6
+ 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=6778-10672&t=3uUSBVdxldgG5uz3-4',
7
+ {
8
+ props: {
9
+ indicator: figma.boolean('Indicator?'),
10
+ icon: figma.nestedProps('Icon Button/Unstyled', {
11
+ icon: figma.instance('Icon-24'),
12
+ }),
13
+ },
14
+ example: props => <IndicatorIconButton icon={props.icon.icon} indicator={props.indicator} />,
15
+ }
16
+ );
@@ -29,6 +29,8 @@ The input component is a text field that allows users to enter text, numbers, or
29
29
  - [Advanced Usage](#advanced-usage)
30
30
  - [Variants](#variants)
31
31
  - [Examples](#examples)
32
+ - [With Label and Helper Text](#with-label-and-helper-text)
33
+ - [With `prefix` and `suffix`](#with-prefix-and-suffix)
32
34
  - [With `FormField`](#with-formfield)
33
35
  - [Accessibility](#accessibility)
34
36
 
@@ -46,7 +48,7 @@ The input component is a text field that allows users to enter text, numbers, or
46
48
  <InputSlot>
47
49
  <InputIcon as={EmailMediumIcon} />
48
50
  </InputSlot>
49
- <InputField placeholder="Placeholder" onChange={() => console.log('###')} />
51
+ <InputField placeholder="Placeholder" onChangeText={() => console.log('###')} />
50
52
  </Input>
51
53
  </Center>
52
54
  </UsageWrap>
@@ -95,8 +97,10 @@ all of the React Native [`View` props](https://reactnative.dev/docs/view).
95
97
  | required | `boolean` | `true` | Indicates that the input is required. **(Only to be used if the input has no children)** |
96
98
  | leadingIcon | `React.ComponentType` | `-` | The leading icon of the input. **(Only to be used if the input has no children)** |
97
99
  | trailingIcon | `React.ComponentType` | `-` | The trailing icon of the input. **(Only to be used if the input has no children)** |
100
+ | prefix | `string \| React.ReactNode` | `-` | Content to display before the input field. **(Only to be used if the input has no children)** |
101
+ | suffix | `string \| React.ReactNode` | `-` | Content to display after the input field. **(Only to be used if the input has no children)** |
98
102
  | value | `string` | `-` | The value of the input. **(Only to be used if the input has no children)** |
99
- | onChange | `function` | `-` | Callback function that is triggered when the input value changes. **(Only to be used if the input has no children)** **(Only to be used if the input has no children)** |
103
+ | onChangeText | `function` | `-` | Callback function that is triggered when the input value changes. **(Only to be used if the input has no children)** **(Only to be used if the input has no children)** |
100
104
  | onBlur | `function` | `-` | Callback function that is triggered when the input loses focus. **(Only to be used if the input has no children)** |
101
105
  | onFocus | `function` | `-` | Callback function that is triggered when the input gains focus. **(Only to be used if the input has no children)** |
102
106
  | placeholder | `string` | `-` | The placeholder text for the input. **(Only to be used if the input has no children)** |
@@ -113,7 +117,7 @@ The `InputField` inherits all of the React Native [`TextInput` props](https://re
113
117
  | ------------- | ---------------------- | -------- | ----------------------------------------------------------------- |
114
118
  | type | `'text' \| 'password'` | `'text'` | The type of the input. |
115
119
  | value | `string` | `-` | The value of the input. |
116
- | onChange | `function` | `-` | Callback function that is triggered when the input value changes. |
120
+ | onChangeText | `function` | `-` | Callback function that is triggered when the input value changes. |
117
121
  | onBlur | `function` | `-` | Callback function that is triggered when the input loses focus. |
118
122
  | onFocus | `function` | `-` | Callback function that is triggered when the input gains focus. |
119
123
  | placeholder | `string` | `-` | The placeholder text for the input. |
@@ -156,13 +160,12 @@ import {
156
160
  EyeOffMediumIcon,
157
161
  } from '@utilitywarehouse/hearth-react-native-icons';
158
162
  import { useState } from 'react';
159
- import { NativeSyntheticEvent, TextInputChangeEventData } from 'react-native';
160
163
 
161
164
  const AdvancedExample = () => {
162
165
  const [value, setValue] = useState<string>('');
163
166
  const [fieldType, setFieldType] = useState<'password' | 'text'>('password');
164
- const handleChange = (e: NativeSyntheticEvent<TextInputChangeEventData>) => {
165
- setValue(e.nativeEvent.text);
167
+ const handleChange = (text: string) => {
168
+ setValue(text);
166
169
  };
167
170
  const handleToggleFieldType = () => {
168
171
  setFieldType(fieldType === 'password' ? 'text' : 'password');
@@ -173,7 +176,7 @@ const AdvancedExample = () => {
173
176
  <InputIcon as={EmailMediumIcon} />
174
177
  </InputSlot>
175
178
  <InputField
176
- onChange={handleChange}
179
+ onChangeText={handleChange}
177
180
  type={fieldType}
178
181
  value={value}
179
182
  placeholder="Secret email address"
@@ -207,7 +210,7 @@ The `Input` component can be used with a label and helper text by passing the `l
207
210
  <Input
208
211
  label="Label"
209
212
  helperText="Helper text"
210
- onChange={() => console.log('###')}
213
+ onChangeText={() => console.log('###')}
211
214
  placeholder="Placeholder"
212
215
  />
213
216
  </Center>
@@ -218,14 +221,14 @@ import { Input } from '@utilitywarehouse/hearth-react-native';
218
221
 
219
222
  const MyComponent = () => {
220
223
  const [value, setValue] = useState('');
221
- const handleChange = e => {
222
- setValue(e.target.value);
224
+ const handleChange = text => {
225
+ setValue(text);
223
226
  };
224
227
  return (
225
228
  <Input
226
229
  label="Label"
227
230
  helperText="Helper text"
228
- onChange={handleChange}
231
+ onChangeText={handleChange}
229
232
  value={value}
230
233
  placeholder="Placeholder"
231
234
  />
@@ -233,6 +236,43 @@ const MyComponent = () => {
233
236
  };
234
237
  ```
235
238
 
239
+ ## With `prefix` and `suffix`
240
+
241
+ The `Input` component can be customised with `prefix` and `suffix` props to add content before or after the input field.
242
+
243
+ <UsageWrap>
244
+ <Center>
245
+ <Input
246
+ label="Amount"
247
+ prefix="£"
248
+ suffix="GBP"
249
+ onChangeText={() => console.log('###')}
250
+ placeholder="0.00"
251
+ />
252
+ </Center>
253
+ </UsageWrap>
254
+
255
+ ```tsx
256
+ import { Input } from '@utilitywarehouse/hearth-react-native';
257
+
258
+ const MyComponent = () => {
259
+ const [value, setValue] = useState('');
260
+ const handleChange = text => {
261
+ setValue(text);
262
+ };
263
+ return (
264
+ <Input
265
+ label="Amount"
266
+ prefix="£"
267
+ suffix="GBP"
268
+ onChangeText={handleChange}
269
+ value={value}
270
+ placeholder="0.00"
271
+ />
272
+ );
273
+ };
274
+ ```
275
+
236
276
  ### With `FormField`
237
277
 
238
278
  The `Input` component can be used with the `FormField` component to create a custom input field.
@@ -241,7 +281,7 @@ For more information on the `FormField` componment view the [docs here](/docs/co
241
281
  <UsageWrap>
242
282
  <Center>
243
283
  <FormField label="Label" helperText="Helper text" helperPosition="bottom">
244
- <Input onChange={() => console.log('###')} placeholder="Placeholder" />
284
+ <Input onChangeText={() => console.log('###')} placeholder="Placeholder" />
245
285
  </FormField>
246
286
  </Center>
247
287
  </UsageWrap>
@@ -251,12 +291,12 @@ import { FormField, Input } from '@utilitywarehouse/hearth-react-native';
251
291
 
252
292
  const MyComponent = () => {
253
293
  const [value, setValue] = useState('');
254
- const handleChange = e => {
255
- setValue(e.target.value);
294
+ const handleChange = text => {
295
+ setValue(text);
256
296
  };
257
297
  return (
258
298
  <FormField label="Label" helperText="Helper text" helperPosition="bottom">
259
- <Input onChange={handleChange} value={value} placeholder="Placeholder" />
299
+ <Input onChangeText={handleChange} value={value} placeholder="Placeholder" />
260
300
  </FormField>
261
301
  );
262
302
  };