@utilitywarehouse/hearth-react-native 0.27.2 → 0.27.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.27.2 build /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.27.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.27.2 lint /home/runner/work/hearth/hearth/packages/react-native
2
+ > @utilitywarehouse/hearth-react-native@0.27.3 lint /home/runner/work/hearth/hearth/packages/react-native
3
3
  > TIMING=1 eslint .
4
4
 
5
5
 
@@ -31,8 +31,8 @@
31
31
  78:8 warning React Hook useEffect has a missing dependency: 'formFieldContext'. Either include it or remove the dependency array react-hooks/exhaustive-deps
32
32
 
33
33
  /home/runner/work/hearth/hearth/packages/react-native/src/components/Modal/Modal.tsx
34
- 86:6 warning React Hook useCallback has an unnecessary dependency: 'Platform.OS'. Either exclude it or remove the dependency array. Outer scope values like 'Platform.OS' aren't valid dependencies because mutating them doesn't re-render the component react-hooks/exhaustive-deps
35
- 313:5 warning React Hook useCallback has a missing dependency: 'footer'. Either include it or remove the dependency array react-hooks/exhaustive-deps
34
+ 93:6 warning React Hook useCallback has an unnecessary dependency: 'Platform.OS'. Either exclude it or remove the dependency array. Outer scope values like 'Platform.OS' aren't valid dependencies because mutating them doesn't re-render the component react-hooks/exhaustive-deps
35
+ 330:5 warning React Hook useCallback has a missing dependency: 'footer'. Either include it or remove the dependency array react-hooks/exhaustive-deps
36
36
 
37
37
  /home/runner/work/hearth/hearth/packages/react-native/src/components/Modal/Modal.web.tsx
38
38
  66:6 warning React Hook useCallback has an unnecessary dependency: 'Platform.OS'. Either exclude it or remove the dependency array. Outer scope values like 'Platform.OS' aren't valid dependencies because mutating them doesn't re-render the component react-hooks/exhaustive-deps
@@ -57,13 +57,13 @@
57
57
 
58
58
  Rule | Time (ms) | Relative
59
59
  :-----------------------------------------|----------:|--------:
60
- @typescript-eslint/no-unused-vars | 1502.050 | 59.5%
61
- react-hooks/exhaustive-deps | 121.560 | 4.8%
62
- react-hooks/rules-of-hooks | 110.933 | 4.4%
63
- no-global-assign | 82.813 | 3.3%
64
- @typescript-eslint/ban-ts-comment | 53.232 | 2.1%
65
- @typescript-eslint/triple-slash-reference | 44.665 | 1.8%
66
- no-unexpected-multiline | 38.719 | 1.5%
67
- no-misleading-character-class | 38.467 | 1.5%
68
- no-loss-of-precision | 30.881 | 1.2%
69
- no-useless-backreference | 26.745 | 1.1%
60
+ @typescript-eslint/no-unused-vars | 1647.829 | 61.5%
61
+ react-hooks/exhaustive-deps | 126.846 | 4.7%
62
+ no-global-assign | 85.087 | 3.2%
63
+ react-hooks/rules-of-hooks | 75.260 | 2.8%
64
+ no-misleading-character-class | 68.283 | 2.6%
65
+ no-unexpected-multiline | 54.599 | 2.0%
66
+ @typescript-eslint/ban-ts-comment | 52.506 | 2.0%
67
+ no-useless-escape | 31.809 | 1.2%
68
+ no-loss-of-precision | 30.517 | 1.1%
69
+ @typescript-eslint/triple-slash-reference | 29.522 | 1.1%
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @utilitywarehouse/hearth-react-native
2
2
 
3
+ ## 0.27.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1006](https://github.com/utilitywarehouse/hearth/pull/1006) [`1996112`](https://github.com/utilitywarehouse/hearth/commit/1996112864146e86972ef6b9b07a8be5a72b552f) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Make `paddingNone` remove horizontal padding for ghost buttons in `md` size
8
+
9
+ Fixed an issue where setting `paddingNone` on a ghost button did not remove horizontal padding when using `md` size. The prop now removes horizontal padding for both `sm` and `md` ghost buttons.
10
+
11
+ **Components affected**:
12
+ - `Button`
13
+
14
+ **Developer changes**:
15
+
16
+ No changes required.
17
+
18
+ - [#1012](https://github.com/utilitywarehouse/hearth/pull/1012) [`4fda116`](https://github.com/utilitywarehouse/hearth/commit/4fda116c2a1bec383df7e630180ab57166ab9da4) Thanks [@jordmccord](https://github.com/jordmccord)! - 🐛 [FIX]: Prevent outlines from being clipped for scrollable children in `Modal`
19
+
20
+ Fixed an issue in in-nav modals where child components with outlines could be visually clipped at the horizontal edges when content was scrollable.
21
+
22
+ **Components affected**:
23
+ - `Modal`
24
+
25
+ **Developer changes**:
26
+
27
+ No changes required.
28
+
29
+ - [#1012](https://github.com/utilitywarehouse/hearth/pull/1012) [`4fda116`](https://github.com/utilitywarehouse/hearth/commit/4fda116c2a1bec383df7e630180ab57166ab9da4) Thanks [@jordmccord](https://github.com/jordmccord)! - 💅 [ENHANCEMENT]: Update horizontal padding values for scrollable in-nav `Modal` content
30
+
31
+ Adjusted horizontal padding behaviour in scrollable in-nav modals to preserve child outlines while keeping visual spacing consistent.
32
+
33
+ **Components affected**:
34
+ - `Modal`
35
+
36
+ **Developer changes**:
37
+
38
+ No changes required.
39
+
40
+ - [#1009](https://github.com/utilitywarehouse/hearth/pull/1009) [`3d65ef2`](https://github.com/utilitywarehouse/hearth/commit/3d65ef2f8f7701b128a9c679f1910cd3d0f5c0c3) Thanks [@fillyD](https://github.com/fillyD)! - 🐛 [FIX]: testID for `List` component
41
+
3
42
  ## 0.27.2
4
43
 
5
44
  ### Patch Changes
@@ -108,6 +108,14 @@ const styles = StyleSheet.create(theme => ({
108
108
  paddingHorizontal: 0,
109
109
  },
110
110
  },
111
+ {
112
+ size: 'md',
113
+ paddingNone: true,
114
+ variant: 'ghost',
115
+ styles: {
116
+ paddingHorizontal: 0,
117
+ },
118
+ },
111
119
  // Variant Color Schemes
112
120
  // Emphasis
113
121
  // Emphasis Yellow
@@ -6,7 +6,7 @@ import { Card } from '../Card';
6
6
  import { SectionHeader } from '../SectionHeader';
7
7
  import { ListContext } from './List.context';
8
8
  const List = ({ children, heading, helperText, headerTrailingContent, invalidText, ...props }) => {
9
- const { loading, disabled, container = 'none' } = props;
9
+ const { loading, disabled, container = 'none', testID, style, ...rest } = props;
10
10
  const orderRef = useRef([]);
11
11
  const [firstItemId, setFirstItemId] = useState(undefined);
12
12
  const containerToCard = {
@@ -35,7 +35,7 @@ const List = ({ children, heading, helperText, headerTrailingContent, invalidTex
35
35
  registerItem,
36
36
  };
37
37
  styles.useVariants({ disabled });
38
- return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...props, style: [styles.container, props.style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent, invalidText: invalidText })) : null, container === 'none' ? (_jsx(View, { children: children })) : (React.Children.count(children) > 0 && (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, children: _jsx(_Fragment, { children: children }) })))] }) }));
38
+ return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...rest, style: [styles.container, style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent, invalidText: invalidText })) : null, container === 'none' ? (_jsx(View, { testID: testID, children: children })) : (React.Children.count(children) > 0 && (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, testID: testID, children: _jsx(_Fragment, { children: children }) })))] }) }));
39
39
  };
40
40
  List.displayName = 'List';
41
41
  const styles = StyleSheet.create(theme => ({
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { BottomSheetFooter, } from '@gorhom/bottom-sheet';
3
3
  import { CloseMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
4
4
  import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
5
- import { AccessibilityInfo, Dimensions, Platform, ScrollView, View, findNodeHandle } from 'react-native';
5
+ import { AccessibilityInfo, Dimensions, Platform, ScrollView, View, findNodeHandle, } from 'react-native';
6
6
  import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withTiming, } from 'react-native-reanimated';
7
7
  import { StyleSheet } from 'react-native-unistyles';
8
8
  import { useTheme } from '../../hooks';
@@ -120,7 +120,12 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
120
120
  });
121
121
  const footer = (_jsxs(View, { style: styles.footer, children: [onPressPrimaryButton && primaryButtonText ? (_jsx(Button, { onPress: handlePrimaryButtonPress, text: primaryButtonText, inverted: isBrandBackground && inNavModal, ...primaryButtonProps, variant: primaryButtonProps?.variant ?? 'solid', colorScheme: primaryButtonProps?.colorScheme ?? 'highlight' })) : null, onPressSecondaryButton && secondaryButtonText ? (_jsx(Button, { onPress: handleSecondaryButtonPress, text: secondaryButtonText, inverted: isBrandBackground && inNavModal, ...secondaryButtonProps, variant: secondaryButtonProps?.variant ?? 'outline', colorScheme: secondaryButtonProps?.colorScheme ?? 'functional' })) : null] }));
122
122
  const InNavModalContainer = scrollable ? ScrollView : View;
123
- const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg", color: isBrandBackground && inNavModal ? theme.color.icon.inverted : undefined }), _jsx(Heading, { size: "lg", textAlign: "center", inverted: isBrandBackground && inNavModal, children: loadingHeading })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description && !image ? (_jsx(BodyText, { accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", inverted: isBrandBackground && inNavModal, ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [image, _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] })] })) : null, inNavModal && (_jsxs(InNavModalContainer, { style: { flex: stickyFooter ? 1 : 0 }, children: [children, !stickyFooter ? _jsx(View, { style: styles.inNavModalFooterContainer, children: footer }) : null] })), !inNavModal && children, ((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons ? footer : null] })) }));
123
+ const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg", color: isBrandBackground && inNavModal ? theme.color.icon.inverted : undefined }), _jsx(Heading, { size: "lg", textAlign: "center", inverted: isBrandBackground && inNavModal, children: loadingHeading })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description && !image ? (_jsx(BodyText, { accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", inverted: isBrandBackground && inNavModal, ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [image, _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] })] })) : null, inNavModal && (_jsxs(InNavModalContainer, { style: {
124
+ flex: stickyFooter ? 1 : 0,
125
+ ...(scrollable ? { marginHorizontal: -1 } : {}),
126
+ }, ...(scrollable ? { contentContainerStyle: { paddingHorizontal: 1 } } : {}), children: [children, !stickyFooter ? (_jsx(View, { style: styles.inNavModalFooterContainer, children: footer })) : null] })), !inNavModal && children, ((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons
127
+ ? footer
128
+ : null] })) }));
124
129
  const renderFooter = useCallback((props) => (_jsx(BottomSheetFooter, { ...props, children: _jsx(View, { style: styles.footerWrap, children: footer }) })), [
125
130
  onPressPrimaryButton,
126
131
  primaryButtonText,
@@ -129,7 +134,7 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
129
134
  primaryButtonProps,
130
135
  secondaryButtonProps,
131
136
  ]);
132
- return inNavModal ? (_jsxs(View, { onLayout: (e) => {
137
+ return inNavModal ? (_jsxs(View, { onLayout: e => {
133
138
  setInNavModalHeight(e.nativeEvent.layout.height);
134
139
  }, style: {
135
140
  flex: 1,
@@ -240,7 +245,7 @@ const styles = StyleSheet.create((theme, rt) => ({
240
245
  borderTopLeftRadius: theme.components.modal.borderRadius,
241
246
  borderTopRightRadius: theme.components.modal.borderRadius,
242
247
  backgroundColor: theme.color.surface.neutral.strong,
243
- paddingBottom: theme.components.modal.padding + rt.insets.bottom,
248
+ paddingBottom: theme.components.bottomSheet.padding + rt.insets.bottom,
244
249
  variants: {
245
250
  background: {
246
251
  primary: {},
@@ -250,22 +255,22 @@ const styles = StyleSheet.create((theme, rt) => ({
250
255
  },
251
256
  fullscreen: {
252
257
  true: {
253
- padding: theme.components.modal.padding,
258
+ padding: theme.components.bottomSheet.padding,
254
259
  paddingTop: rt.insets.top,
255
260
  },
256
261
  false: {
257
- padding: theme.components.modal.padding,
258
- }
259
- }
262
+ padding: theme.components.bottomSheet.padding,
263
+ },
264
+ },
260
265
  },
261
266
  },
262
267
  inNavModalFooterContainer: {
263
- paddingTop: theme.components.modal.padding,
268
+ paddingTop: theme.components.bottomSheet.padding,
264
269
  },
265
270
  androidContainer: {
266
271
  height: rt.insets.top + 18,
267
- paddingLeft: theme.components.modal.padding,
268
- paddingRight: theme.components.modal.padding,
272
+ paddingLeft: theme.components.bottomSheet.padding,
273
+ paddingRight: theme.components.bottomSheet.padding,
269
274
  justifyContent: 'flex-end',
270
275
  },
271
276
  pretendContent: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.27.2",
3
+ "version": "0.27.3",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { Meta, StoryObj } from '@storybook/react-vite';
1
+ import { Meta, StoryObj } from '@storybook/react-native';
2
2
  import * as Icons from '@utilitywarehouse/hearth-react-native-icons';
3
3
  import { AddSmallIcon, ChevronRightSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
4
4
  import { Platform } from 'react-native';
@@ -92,7 +92,7 @@ type Story = StoryObj<typeof meta>;
92
92
 
93
93
  export const Playground: Story = {
94
94
  /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
95
- render: ({ icon: _icon, children: _, ...args }) => {
95
+ render: ({ icon: _icon, children: _, ...args }: StoryObj<typeof meta.args>) => {
96
96
  // @ts-expect-error - This is a playground
97
97
  const icon = _icon === 'none' ? undefined : Icons[_icon];
98
98
  return <Button {...args} icon={icon} />;
@@ -104,7 +104,7 @@ export const Variants: Story = {
104
104
  controls: { exclude: ['variant'] },
105
105
  },
106
106
  /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
107
- render: ({ icon: _icon, children: _, ...args }) => {
107
+ render: ({ icon: _icon, children: _, ...args }: StoryObj<typeof meta.args>) => {
108
108
  // @ts-expect-error - This is a playground
109
109
  const icon = _icon === 'none' ? undefined : Icons[_icon];
110
110
  return (
@@ -123,11 +123,9 @@ export const Variants: Story = {
123
123
  {args.colorScheme !== 'highlight' && (
124
124
  <>
125
125
  <VariantTitle title="Outline" invert={args.inverted}>
126
- {/* @ts-expect-error - story loop types don't match */}
127
126
  <Button {...args} variant="outline" icon={icon} />
128
127
  </VariantTitle>
129
128
  <VariantTitle title="Ghost" invert={args.inverted}>
130
- {/* @ts-expect-error - story loop types don't match */}
131
129
  <Button {...args} variant="ghost" icon={icon} />
132
130
  </VariantTitle>
133
131
  </>
@@ -138,6 +136,44 @@ export const Variants: Story = {
138
136
  },
139
137
  };
140
138
 
139
+ export const PaddingNone: Story = {
140
+ parameters: {
141
+ controls: {
142
+ include: ['text', 'size', 'inverted', 'icon', 'iconPosition'],
143
+ },
144
+ },
145
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
146
+ render: ({ icon: _icon, children: _, ...args }: StoryObj<typeof meta.args>) => {
147
+ // @ts-expect-error - This is a playground
148
+ const icon = _icon === 'none' ? undefined : Icons[_icon];
149
+
150
+ return (
151
+ <Flex direction="column" spacing="lg">
152
+ <VariantTitle title="Default Padding" invert={args.inverted}>
153
+ <Flex direction="row" align="center" spacing="none">
154
+ <Box backgroundColor="brand" width="100" height="100" />
155
+ <Button
156
+ {...args}
157
+ colorScheme="functional"
158
+ variant="ghost"
159
+ icon={icon}
160
+ paddingNone={false}
161
+ />
162
+ <Box backgroundColor="brand" width="100" height="100" />
163
+ </Flex>
164
+ </VariantTitle>
165
+ <VariantTitle title="No Padding (paddingNone)" invert={args.inverted}>
166
+ <Flex direction="row" align="center" spacing="none">
167
+ <Box backgroundColor="brand" width="100" height="100" />
168
+ <Button {...args} colorScheme="functional" variant="ghost" icon={icon} paddingNone />
169
+ <Box backgroundColor="brand" width="100" height="100" />
170
+ </Flex>
171
+ </VariantTitle>
172
+ </Flex>
173
+ );
174
+ },
175
+ };
176
+
141
177
  type ColorScheme = ButtonProps['colorScheme'];
142
178
  type Variant = ButtonProps['variant'];
143
179
 
@@ -145,7 +181,7 @@ export const KitchenSink: Story = {
145
181
  parameters: {
146
182
  controls: { include: ['text', 'size', 'inverted'] },
147
183
  },
148
- render: ({ text, inverted, size }) => {
184
+ render: ({ text, inverted, size }: StoryObj<typeof meta.args>) => {
149
185
  const schemes: Array<ColorScheme> = ['highlight', 'destructive', 'affirmative', 'functional'];
150
186
  const variants: Array<Variant> = ['emphasis', 'solid', 'outline', 'ghost'];
151
187
  return (
@@ -174,7 +210,7 @@ export const KitchenSink: Story = {
174
210
  .map(variant => (
175
211
  <Box key={variant} mb="100">
176
212
  <Box mb="100">
177
- <DetailText size="lg" color={inverted ? 'warmWhite50' : 'grey1000'}>
213
+ <DetailText size="lg" inverted={inverted}>
178
214
  {scheme} - {variant}
179
215
  </DetailText>
180
216
  </Box>
@@ -132,6 +132,14 @@ const styles = StyleSheet.create(theme => ({
132
132
  paddingHorizontal: 0,
133
133
  },
134
134
  },
135
+ {
136
+ size: 'md',
137
+ paddingNone: true,
138
+ variant: 'ghost',
139
+ styles: {
140
+ paddingHorizontal: 0,
141
+ },
142
+ },
135
143
  // Variant Color Schemes
136
144
  // Emphasis
137
145
  // Emphasis Yellow
@@ -14,7 +14,8 @@ const List = ({
14
14
  invalidText,
15
15
  ...props
16
16
  }: ListProps) => {
17
- const { loading, disabled, container = 'none' } = props;
17
+ const { loading, disabled, container = 'none', testID, style, ...rest } = props;
18
+
18
19
  const orderRef = useRef<string[]>([]);
19
20
  const [firstItemId, setFirstItemId] = useState<string | undefined>(undefined);
20
21
  const containerToCard: {
@@ -51,7 +52,7 @@ const List = ({
51
52
  styles.useVariants({ disabled });
52
53
  return (
53
54
  <ListContext.Provider value={value}>
54
- <View {...props} style={[styles.container, props.style]}>
55
+ <View {...rest} style={[styles.container, style]}>
55
56
  {heading ? (
56
57
  <SectionHeader
57
58
  heading={heading}
@@ -61,10 +62,10 @@ const List = ({
61
62
  />
62
63
  ) : null}
63
64
  {container === 'none' ? (
64
- <View>{children}</View>
65
+ <View testID={testID}>{children}</View>
65
66
  ) : (
66
67
  React.Children.count(children) > 0 && (
67
- <Card {...containerToCard} noPadding style={styles.card}>
68
+ <Card {...containerToCard} noPadding style={styles.card} testID={testID}>
68
69
  <>{children}</>
69
70
  </Card>
70
71
  )
@@ -7,7 +7,14 @@ import {
7
7
  import { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
8
8
  import { CloseMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
9
9
  import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
10
- import { AccessibilityInfo, Dimensions, Platform, ScrollView, View, findNodeHandle } from 'react-native';
10
+ import {
11
+ AccessibilityInfo,
12
+ Dimensions,
13
+ Platform,
14
+ ScrollView,
15
+ View,
16
+ findNodeHandle,
17
+ } from 'react-native';
11
18
  import Animated, {
12
19
  Easing,
13
20
  useAnimatedStyle,
@@ -292,13 +299,23 @@ const Modal = ({
292
299
  </View>
293
300
  ) : null}
294
301
  {inNavModal && (
295
- <InNavModalContainer style={{ flex: stickyFooter ? 1 : 0 }}>
302
+ <InNavModalContainer
303
+ style={{
304
+ flex: stickyFooter ? 1 : 0,
305
+ ...(scrollable ? { marginHorizontal: -1 } : {}),
306
+ }}
307
+ {...(scrollable ? { contentContainerStyle: { paddingHorizontal: 1 } } : {})}
308
+ >
296
309
  {children}
297
- {!stickyFooter ? <View style={styles.inNavModalFooterContainer}>{footer}</View> : null}
310
+ {!stickyFooter ? (
311
+ <View style={styles.inNavModalFooterContainer}>{footer}</View>
312
+ ) : null}
298
313
  </InNavModalContainer>
299
314
  )}
300
315
  {!inNavModal && children}
301
- {((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons ? footer : null}
316
+ {((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons
317
+ ? footer
318
+ : null}
302
319
  </View>
303
320
  )}
304
321
  </>
@@ -322,7 +339,7 @@ const Modal = ({
322
339
 
323
340
  return inNavModal ? (
324
341
  <View
325
- onLayout={(e) => {
342
+ onLayout={e => {
326
343
  setInNavModalHeight(e.nativeEvent.layout.height);
327
344
  }}
328
345
  style={{
@@ -338,9 +355,7 @@ const Modal = ({
338
355
  <Animated.View
339
356
  style={[styles.inNavModalContainer, Platform.OS === 'android' && animatedInNavModalStyle]}
340
357
  >
341
- <View style={styles.inNavModalContent}>
342
- {content}
343
- </View>
358
+ <View style={styles.inNavModalContent}>{content}</View>
344
359
  </Animated.View>
345
360
  </View>
346
361
  ) : (
@@ -471,7 +486,7 @@ const styles = StyleSheet.create((theme, rt) => ({
471
486
  borderTopLeftRadius: theme.components.modal.borderRadius,
472
487
  borderTopRightRadius: theme.components.modal.borderRadius,
473
488
  backgroundColor: theme.color.surface.neutral.strong,
474
- paddingBottom: theme.components.modal.padding + rt.insets.bottom,
489
+ paddingBottom: theme.components.bottomSheet.padding + rt.insets.bottom,
475
490
  variants: {
476
491
  background: {
477
492
  primary: {},
@@ -481,22 +496,22 @@ const styles = StyleSheet.create((theme, rt) => ({
481
496
  },
482
497
  fullscreen: {
483
498
  true: {
484
- padding: theme.components.modal.padding,
499
+ padding: theme.components.bottomSheet.padding,
485
500
  paddingTop: rt.insets.top,
486
501
  },
487
502
  false: {
488
- padding: theme.components.modal.padding,
489
- }
490
- }
503
+ padding: theme.components.bottomSheet.padding,
504
+ },
505
+ },
491
506
  },
492
507
  },
493
508
  inNavModalFooterContainer: {
494
- paddingTop: theme.components.modal.padding,
509
+ paddingTop: theme.components.bottomSheet.padding,
495
510
  },
496
511
  androidContainer: {
497
512
  height: rt.insets.top + 18,
498
- paddingLeft: theme.components.modal.padding,
499
- paddingRight: theme.components.modal.padding,
513
+ paddingLeft: theme.components.bottomSheet.padding,
514
+ paddingRight: theme.components.bottomSheet.padding,
500
515
  justifyContent: 'flex-end',
501
516
  },
502
517
  pretendContent: {