@utilitywarehouse/hearth-react-native 0.28.2 → 0.28.3

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.28.2 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.28.3 build /home/runner/work/hearth/hearth/packages/react-native
3
3
  > tsc
4
4
 
@@ -1,5 +1,5 @@
1
1
 
2
- > @utilitywarehouse/hearth-react-native@0.28.2 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.28.3 lint /home/runner/work/hearth/hearth/packages/react-native
3
3
  > TIMING=1 eslint .
4
4
 
5
5
 
@@ -56,13 +56,13 @@
56
56
 
57
57
  Rule | Time (ms) | Relative
58
58
  :-----------------------------------------|----------:|--------:
59
- @typescript-eslint/no-unused-vars | 1611.506 | 62.8%
60
- react-hooks/exhaustive-deps | 121.253 | 4.7%
61
- react-hooks/rules-of-hooks | 88.872 | 3.5%
62
- no-global-assign | 73.109 | 2.8%
63
- no-misleading-character-class | 41.972 | 1.6%
64
- no-unexpected-multiline | 39.944 | 1.6%
65
- no-regex-spaces | 37.157 | 1.4%
66
- @typescript-eslint/ban-ts-comment | 31.755 | 1.2%
67
- no-useless-escape | 28.823 | 1.1%
68
- @typescript-eslint/triple-slash-reference | 28.052 | 1.1%
59
+ @typescript-eslint/no-unused-vars | 1554.353 | 59.2%
60
+ react-hooks/exhaustive-deps | 144.027 | 5.5%
61
+ no-global-assign | 113.457 | 4.3%
62
+ react-hooks/rules-of-hooks | 91.927 | 3.5%
63
+ @typescript-eslint/ban-ts-comment | 60.650 | 2.3%
64
+ no-fallthrough | 48.638 | 1.9%
65
+ no-unexpected-multiline | 47.691 | 1.8%
66
+ no-misleading-character-class | 45.726 | 1.7%
67
+ @typescript-eslint/no-unused-expressions | 29.696 | 1.1%
68
+ @typescript-eslint/triple-slash-reference | 29.272 | 1.1%
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.28.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1028](https://github.com/utilitywarehouse/hearth/pull/1028) [`dccffe1`](https://github.com/utilitywarehouse/hearth/commit/dccffe16342b22e58078dfc0aadfe9a482bfcc74) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: The `Combobox` trigger outline so it is only shown when the control is focused.
8
+
3
9
  ## 0.28.2
4
10
 
5
11
  ### Patch Changes
@@ -10,10 +10,10 @@ import { DetailText } from '../DetailText';
10
10
  import { FormField, useFormFieldContext } from '../FormField';
11
11
  import { Icon } from '../Icon';
12
12
  import { Input } from '../Input';
13
+ import { SafeAreaView } from '../SafeAreaView';
13
14
  import { Spinner } from '../Spinner';
14
15
  import { UnstyledIconButton } from '../UnstyledIconButton';
15
16
  import { ComboboxContext } from './Combobox.context';
16
- import { SafeAreaView } from '../SafeAreaView';
17
17
  import ComboboxOption from './ComboboxOption';
18
18
  const DEFAULT_SNAP_POINTS = ['25%', '40%', '80%'];
19
19
  const Combobox = ({ options = [], value, onValueChange, inputValue, onInputValueChange, label, labelVariant = 'body', placeholder = 'Search', searchPlaceholder = 'Search', disabled = false, validationStatus = 'initial', helperText, helperIcon, invalidText, validText, required = true, children, bottomSheetProps, menuHeading, noOptionsFoundText = 'No options found', listProps, loading = false, readonly = false, getValueLabel, filterOption, ...rest }) => {
@@ -178,9 +178,6 @@ const styles = StyleSheet.create(theme => ({
178
178
  borderRadius: theme.components.input.borderRadius,
179
179
  paddingHorizontal: theme.components.input.paddingHorizontal,
180
180
  gap: theme.components.input.gap,
181
- outlineStyle: 'solid',
182
- outlineWidth: theme.components.input.borderWidth,
183
- outlineColor: theme.color.border.strong,
184
181
  variants: {
185
182
  disabled: {
186
183
  true: {
@@ -206,7 +203,9 @@ const styles = StyleSheet.create(theme => ({
206
203
  },
207
204
  },
208
205
  triggerFocused: {
209
- outlineWidth: theme.components.input.borderWidthFocused,
206
+ outlineStyle: 'solid',
207
+ outlineWidth: theme.components.input.borderWidth,
208
+ outlineColor: theme.color.border.strong,
210
209
  },
211
210
  leadingIconContainer: {
212
211
  alignItems: 'center',
@@ -1,5 +1,6 @@
1
1
  import { Meta } from '@storybook/addon-docs/blocks';
2
- import { BackToTopButton, NextPrevPage } from './components';
2
+ import { BodyText, Box, Card, Center, Heading } from '../src';
3
+ import { BackToTopButton, InputShadowExample, NextPrevPage, UsageWrap } from './components';
3
4
 
4
5
  <Meta title="Guides / Adding Shadows" />
5
6
  <BackToTopButton />
@@ -15,9 +16,16 @@ You can add shadows to your components in Hearth React Native using the Unistyle
15
16
 
16
17
  Hearth provides a set of predefined shadow styles that you can easily apply to your components. These shadows are defined in the theme and can be accessed via the `theme.helpers.shadow` object.
17
18
 
19
+ <UsageWrap>
20
+ <Center>
21
+ <InputShadowExample />
22
+ </Center>
23
+ </UsageWrap>
24
+
18
25
  ```tsx
19
26
  import { View } from 'react-native';
20
27
  import { StyleSheet, Input } from '@utilitywarehouse/hearth-react-native';
28
+ import { SearchMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
21
29
 
22
30
  const styles = StyleSheet.create(theme => ({
23
31
  input: {
@@ -27,13 +35,22 @@ const styles = StyleSheet.create(theme => ({
27
35
 
28
36
  const MyComponent = () => (
29
37
  <View>
30
- <Input placeholder="Input with shadow" style={styles.input} />
38
+ <Input placeholder="Input with shadow" style={styles.input} leadingIcon={SearchMediumIcon} />
31
39
  </View>
32
40
  );
33
41
  ```
34
42
 
35
43
  ## Components with Shadow Props
36
44
 
45
+ <UsageWrap>
46
+ <Center>
47
+ <Card shadowColor="brand" spacing="md">
48
+ <Heading size="md">Card with Shadow</Heading>
49
+ <BodyText>This card has a shadow color set to the brand color.</BodyText>
50
+ </Card>
51
+ </Center>
52
+ </UsageWrap>
53
+
37
54
  Some Hearth components, like `Card`, allow you to specify shadow colors directly via props. You can use the `shadowColor` prop to set the shadow color based on the theme.
38
55
 
39
56
  ```tsx
@@ -41,3 +58,10 @@ import { Card } from '@utilitywarehouse/hearth-react-native';
41
58
 
42
59
  const MyComponent = () => <Card shadowColor="brand">{/* Card content */}</Card>;
43
60
  ```
61
+
62
+ <NextPrevPage
63
+ prevLink="all-components"
64
+ prevTitle="All Components"
65
+ nextLink="primitives-box"
66
+ nextTitle="Box"
67
+ />
@@ -14,6 +14,6 @@ This page showcases all the components available in the Hearth React Native libr
14
14
  <NextPrevPage
15
15
  prevLink="layout-components"
16
16
  prevTitle="Layout Components"
17
- nextLink="components-accordion"
18
- nextTitle="Accordion"
17
+ nextLink="guides-adding-shadows"
18
+ nextTitle="Adding Shadows"
19
19
  />
@@ -9,6 +9,12 @@ 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.28.2
13
+
14
+ ### Patch Changes
15
+
16
+ - [#1024](https://github.com/utilitywarehouse/hearth/pull/1024) [`23b6767`](https://github.com/utilitywarehouse/hearth/commit/23b67672b89198a483ddcef88f9c6207b684c4d9) Thanks [@fillyD](https://github.com/fillyD)! - 🐛 [FIX]: Adds missing `testID` to `Select` component
17
+
12
18
  ## 0.28.1
13
19
 
14
20
  ### Patch Changes
@@ -0,0 +1,19 @@
1
+ import { SearchMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
2
+ import { StyleSheet } from 'react-native-unistyles';
3
+ import { Box, Input } from '../../src';
4
+
5
+ const InputShadowExample = () => {
6
+ return (
7
+ <Box padding="md">
8
+ <Input placeholder="Input with shadow" style={styles.input} leadingIcon={SearchMediumIcon} />
9
+ </Box>
10
+ );
11
+ };
12
+
13
+ const styles = StyleSheet.create(theme => ({
14
+ input: {
15
+ boxShadow: theme.helpers.shadow.functional,
16
+ },
17
+ }));
18
+
19
+ export default InputShadowExample;
@@ -3,6 +3,7 @@ export { default as AdvancedInputExample } from './AdvancedInputExample';
3
3
  export { default as BackToTopButton } from './BackToTopButton';
4
4
  export { default as BadgeList } from './BadgeList';
5
5
  export { default as DocComponentWrap } from './DocComponentWrap';
6
+ export { default as InputShadowExample } from './InputShadowExample';
6
7
  export { default as NextPrevPage } from './NextPrevPage';
7
8
  export { default as SwitchExample } from './SwitchExample';
8
9
  export { default as SwitchList } from './SwitchList';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.28.2",
3
+ "version": "0.28.3",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -9,6 +9,7 @@ import {
9
9
  CheckboxLabel,
10
10
  CheckboxTile,
11
11
  FormField,
12
+ Grid,
12
13
  } from '../../';
13
14
  import StorybookLink from '../../../../../shared/storybook/StorybookLink';
14
15
  import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
@@ -38,6 +39,7 @@ Whether you're building a simple form or a complex data collection system, the C
38
39
  - [Variants](#variants)
39
40
  - [Advanced Usage](#advanced-usage)
40
41
  - [Examples](#examples)
42
+ - [Grid Layout With Tiles](#grid-layout-with-tiles)
41
43
  - [`CheckboxTile` component](#checkboxtile-component)
42
44
  - [`CheckboxImage` component](#checkboximage-component)
43
45
  - [`CheckboxGroup` component](#checkboxgroup-component)
@@ -313,6 +315,44 @@ const MyComponent = () => {
313
315
 
314
316
  ## Examples
315
317
 
318
+ ### Grid Layout With Tiles
319
+
320
+ Wrap tile checkboxes in a `Grid` when you want a multi-column layout inside a `CheckboxGroup`.
321
+
322
+ <UsageWrap>
323
+ <Center>
324
+ <Box minWidth={400}>
325
+ <CheckboxGroup label="Which options helped?" type="tile">
326
+ <Grid columns={2} spacing="md">
327
+ <Checkbox label="Fast response" value="fast-response" />
328
+ <Checkbox label="Clear steps" value="clear-steps" />
329
+ <Checkbox label="Useful example" value="useful-example" />
330
+ <Checkbox label="Still investigating" value="still-investigating" />
331
+ </Grid>
332
+ </CheckboxGroup>
333
+ </Box>
334
+ </Center>
335
+ </UsageWrap>
336
+
337
+ ```tsx
338
+ import { Checkbox, CheckboxGroup, Grid } from '@utilitywarehouse/hearth-react-native';
339
+
340
+ const MyComponent = () => {
341
+ const [value, setValue] = React.useState(['fast-response']);
342
+
343
+ return (
344
+ <CheckboxGroup label="Which options helped?" type="tile" value={value} onChange={setValue}>
345
+ <Grid columns={2} spacing="md">
346
+ <Checkbox label="Fast response" value="fast-response" />
347
+ <Checkbox label="Clear steps" value="clear-steps" />
348
+ <Checkbox label="Useful example" value="useful-example" />
349
+ <Checkbox label="Still investigating" value="still-investigating" />
350
+ </Grid>
351
+ </CheckboxGroup>
352
+ );
353
+ };
354
+ ```
355
+
316
356
  ### `CheckboxTile` component
317
357
 
318
358
  The `CheckboxTile` component is a variant of the `Checkbox` component that displays the radio button as a card.
@@ -9,15 +9,14 @@ import { DetailText } from '../DetailText';
9
9
  import { FormField, useFormFieldContext } from '../FormField';
10
10
  import { Icon } from '../Icon';
11
11
  import { Input } from '../Input';
12
+ import { SafeAreaView } from '../SafeAreaView';
12
13
  import { Spinner } from '../Spinner';
13
14
  import { UnstyledIconButton } from '../UnstyledIconButton';
14
- import { ComboboxContext } from './Combobox.context';
15
- import { ComboboxSelection } from './Combobox.context';
15
+ import { ComboboxContext, ComboboxSelection } from './Combobox.context';
16
16
  import ComboboxProps, {
17
17
  ComboboxOptionItemProps,
18
18
  ComboboxRenderContentProps,
19
19
  } from './Combobox.props';
20
- import { SafeAreaView } from '../SafeAreaView';
21
20
  import ComboboxOption from './ComboboxOption';
22
21
 
23
22
  const DEFAULT_SNAP_POINTS = ['25%', '40%', '80%'];
@@ -376,9 +375,6 @@ const styles = StyleSheet.create(theme => ({
376
375
  borderRadius: theme.components.input.borderRadius,
377
376
  paddingHorizontal: theme.components.input.paddingHorizontal,
378
377
  gap: theme.components.input.gap,
379
- outlineStyle: 'solid',
380
- outlineWidth: theme.components.input.borderWidth,
381
- outlineColor: theme.color.border.strong,
382
378
  variants: {
383
379
  disabled: {
384
380
  true: {
@@ -404,7 +400,9 @@ const styles = StyleSheet.create(theme => ({
404
400
  },
405
401
  },
406
402
  triggerFocused: {
407
- outlineWidth: theme.components.input.borderWidthFocused,
403
+ outlineStyle: 'solid',
404
+ outlineWidth: theme.components.input.borderWidth,
405
+ outlineColor: theme.color.border.strong,
408
406
  },
409
407
  leadingIconContainer: {
410
408
  alignItems: 'center',
@@ -478,36 +478,57 @@ import { useCallback, useEffect, useRef } from 'react';
478
478
  import { Platform, StyleSheet, View } from 'react-native';
479
479
 
480
480
  import { BodyText, Heading, InlineLink, Modal } from '@utilitywarehouse/hearth-react-native';
481
+ import type { NavigationAction } from '@react-navigation/native';
481
482
 
482
- export default function ModalScreen() {
483
+ export default function ModalScreen({ onClose }: { onClose?: () => void }) {
483
484
  const modalRef = useRef<Modal>(null);
484
485
  const navigation = useNavigation();
485
486
  const isClosingRef = useRef(false);
486
487
 
487
- const handleClose = useCallback(() => {
488
- if (Platform.OS === 'ios') {
489
- navigation.goBack();
490
- return;
491
- }
492
- if (isClosingRef.current) return;
493
-
494
- isClosingRef.current = true;
495
- // Trigger our custom animation first
496
- modalRef.current?.triggerCloseAnimation?.();
488
+ const handleClose = useCallback(
489
+ (action?: NavigationAction) => {
490
+ if (Platform.OS === 'ios') {
491
+ if (onClose) {
492
+ onClose();
493
+ } else {
494
+ navigation.goBack();
495
+ }
497
496
 
498
- // Delay the actual navigation to allow our animation to play
499
- setTimeout(() => {
500
- navigation.goBack();
501
- }, 100); // Match Modal animation duration
502
- }, [navigation]);
497
+ return;
498
+ }
499
+
500
+ if (isClosingRef.current) {
501
+ return;
502
+ }
503
+
504
+ isClosingRef.current = true;
505
+ // Trigger our custom animation first
506
+ modalRef.current?.triggerCloseAnimation?.();
507
+
508
+ // Delay the actual navigation to allow our animation to play
509
+ setTimeout(() => {
510
+ if (onClose) {
511
+ onClose();
512
+ } else if (action) {
513
+ // Dispatch the original action (e.g. popToTop, replace, reset)
514
+ // so we don't override the caller's intended navigation behaviour
515
+ navigation.dispatch(action);
516
+ } else {
517
+ navigation.goBack();
518
+ }
519
+ }, 100); // Match Modal animation duration
520
+ },
521
+ [navigation, onClose]
522
+ );
503
523
 
504
524
  useEffect(() => {
505
525
  if (Platform.OS === 'android') {
506
526
  const unsubscribe = navigation.addListener('beforeRemove', e => {
507
527
  if (!isClosingRef.current) {
508
- // Prevent default behavior
528
+ // Prevent default behavior of the navigation action so we can
529
+ // play the close animation before letting navigation proceed
509
530
  e.preventDefault();
510
- handleClose();
531
+ handleClose(e.data.action);
511
532
  }
512
533
  });
513
534
 
@@ -3,6 +3,7 @@ import { TickSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
3
3
  import {
4
4
  Box,
5
5
  Center,
6
+ Grid,
6
7
  Radio,
7
8
  RadioGroup,
8
9
  RadioIcon,
@@ -41,6 +42,7 @@ The Radio component presents users with predefined choices and enables them to s
41
42
  - [Variants](#variants)
42
43
  - [Advanced Usage](#advanced-usage)
43
44
  - [Examples](#examples)
45
+ - [Grid Layout With Tiles](#grid-layout-with-tiles)
44
46
  - [`RadioTile` component](#radiotile-component)
45
47
  - [`RadioImage` component](#radioimage-component)
46
48
  - [`RadioGroup` component](#radiogroup-component)
@@ -238,6 +240,44 @@ const AdvancedExample = () => {
238
240
 
239
241
  ## Examples
240
242
 
243
+ ### Grid Layout With Tiles
244
+
245
+ Wrap tile radios in a `Grid` when you want a multi-column layout while keeping the `RadioGroup` label, helper text and validation messaging.
246
+
247
+ <UsageWrap>
248
+ <Center>
249
+ <RadioGroup label="Did this solve your problem?" type="tile">
250
+ <Box minWidth={300}>
251
+ <Grid columns={2} spacing="md">
252
+ <Radio label="Yes" value="yes" />
253
+ <Radio label="No" value="no" />
254
+ <Radio label="Partly" value="partly" />
255
+ <Radio label="Not yet" value="not-yet" />
256
+ </Grid>
257
+ </Box>
258
+ </RadioGroup>
259
+ </Center>
260
+ </UsageWrap>
261
+
262
+ ```tsx
263
+ import { Grid, Radio, RadioGroup } from '@utilitywarehouse/hearth-react-native';
264
+
265
+ const MyComponent = () => {
266
+ const [value, setValue] = React.useState('yes');
267
+
268
+ return (
269
+ <RadioGroup label="Did this solve your problem?" type="tile" value={value} onChange={setValue}>
270
+ <Grid columns={2} spacing="md">
271
+ <Radio label="Yes" value="yes" />
272
+ <Radio label="No" value="no" />
273
+ <Radio label="Partly" value="partly" />
274
+ <Radio label="Not yet" value="not-yet" />
275
+ </Grid>
276
+ </RadioGroup>
277
+ );
278
+ };
279
+ ```
280
+
241
281
  ### `RadioTile` component
242
282
 
243
283
  The `RadioTile` component is a variant of the `Radio` component that displays the radio button as a card.