|
| 1 | +import { Required } from '@site/src/components'; |
| 2 | + |
| 3 | +# BottomSheet |
| 4 | + |
| 5 | +AMA Provides an accessible bottom sheet built on top |
| 6 | +of [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) |
| 7 | +and [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler). |
| 8 | + |
| 9 | +## Example |
| 10 | + |
| 11 | +```jsx |
| 12 | +import { BottomSheet } from '@react-native-ama/extras |
| 13 | +
|
| 14 | +const Component = () => ( |
| 15 | + <BottomSheet |
| 16 | + visible={modalVisible} |
| 17 | + onRequestClose={() => { |
| 18 | + setModalVisible(!modalVisible); |
| 19 | + }} |
| 20 | + closeActionAccessibilityLabel="close bottomsheet" |
| 21 | + bottomSheetStyle={styles.modalView} |
| 22 | + headerComponent={ |
| 23 | + <View style={{ paddingHorizontal: theme.padding.big }}> |
| 24 | + <Header title="This is the bottom sheet" /> |
| 25 | + </View> |
| 26 | + } |
| 27 | + scrollViewStyle={styles.modalViewContent}> |
| 28 | + <Pressable |
| 29 | + onPress={() => setModalVisible(!modalVisible)} |
| 30 | + accessibilityRole="button"> |
| 31 | + <Text>Close bottom sheet</Text> |
| 32 | + </Pressable> |
| 33 | + </BottomSheet> |
| 34 | +); |
| 35 | +``` |
| 36 | +
|
| 37 | +## Accessibility |
| 38 | +
|
| 39 | +- Checks that the `closeActionAccessibilityLabel` is a valid [accessibilityLabel](./guidelines/accessibility-label) |
| 40 | +- Provides a way [to close the bottom sheet](../guidelines/bottomsheet#2-can-be-dismissed) when the user taps on the overlay |
| 41 | +- Makes sure that the overlay is announced as "button" |
| 42 | +- Uses slide-in and slide-out animation **only** if the [Reduce Motion] (https://reactnative.dev/docs/accessibilityinfo) preference is turned off |
| 43 | +- Prevents the focus from [escaping the bottom sheet](../guidelines/bottomsheet#3-the-focus-stays-inside-it) |
| 44 | +- Provides a draggable area respecting the [minimum size](../guidelines/minimum-size) |
| 45 | +
|
| 46 | +## Props |
| 47 | +
|
| 48 | +### `animationDuration` |
| 49 | +
|
| 50 | +The duration in milliseconds of the slide in/out animation. |
| 51 | +
|
| 52 | +| Type | Default | |
| 53 | +| ------ | ------- | |
| 54 | +| number | 300 | |
| 55 | +
|
| 56 | +### `autoCloseDelay` |
| 57 | +
|
| 58 | +The duration in milliseconds before auto-closing the bottom sheet |
| 59 | +
|
| 60 | +| Type | Default | |
| 61 | +| ------ | --------- | |
| 62 | +| number | undefined | |
| 63 | +
|
| 64 | +:::tip |
| 65 | +
|
| 66 | +The auto-close will respect the user [Timed action](./guidelines/timed-actions) preference. |
| 67 | +
|
| 68 | +::: |
| 69 | +
|
| 70 | +### `bottomSheetStyle` |
| 71 | +
|
| 72 | +The style to use for the bottom sheet panel |
| 73 | +
|
| 74 | +| Type | Default | |
| 75 | +| --------- | -------------------------------------------- | |
| 76 | +| ViewStyle | `{ width: '100%', backgroundColor: '#fff' }` | |
| 77 | +
|
| 78 | +### <Required /> `closeActionAccessibilityLabel` |
| 79 | +
|
| 80 | +The accessibility label to use for the overlay button. |
| 81 | +
|
| 82 | +| Type | |
| 83 | +| ------ | |
| 84 | +| string | |
| 85 | +
|
| 86 | +### `closeDistance` |
| 87 | +
|
| 88 | +A decimal fraction percentage of the content height which represents the minimum distance to swipe before the `onClose` function is run. For example, 0.3 represents 30% of the content height needing to be gesture swiped away before the `BottomSheet` will close and the `onClose` function will run. |
| 89 | +
|
| 90 | +| Type | Default | |
| 91 | +| ------ | ------- | |
| 92 | +| number | 0.3 | |
| 93 | +
|
| 94 | +### `footerComponent` |
| 95 | +
|
| 96 | +The bottom sheet footer component. |
| 97 | +
|
| 98 | +| Type | |
| 99 | +| ----------- | |
| 100 | +| JSX.Element | |
| 101 | +
|
| 102 | +### `handleComponent` |
| 103 | +
|
| 104 | +It can be used to either disable the default handle "line" or replace it with a custom component. |
| 105 | +
|
| 106 | +| Type | |
| 107 | +| ----------------------- | |
| 108 | +| JSX.Element \| `'none'` | |
| 109 | +
|
| 110 | +### `handleStyle` |
| 111 | +
|
| 112 | +The style for the draggable line |
| 113 | +
|
| 114 | +| Type | Default | |
| 115 | +| --------- | -------------------------------------------------------------------------------------------------------------------------- | |
| 116 | +| ViewStyle | `{ width: 48, height: 4, backgroundColor: 'grey', alignSelf: 'center', marginBottom: 24, borderRadius: 2, marginTop: 12 }` | |
| 117 | +
|
| 118 | +### `headerComponent` |
| 119 | +
|
| 120 | +The bottom sheet header component. |
| 121 | +
|
| 122 | +| Type | |
| 123 | +| ----------- | |
| 124 | +| JSX.Element | |
| 125 | +
|
| 126 | +### `maxHeight` |
| 127 | +
|
| 128 | +The maximum height of the bottom sheet. |
| 129 | +
|
| 130 | +| Type | Default | |
| 131 | +| ------ | ------------------------ | |
| 132 | +| number | 90% of the screen height | |
| 133 | +
|
| 134 | +### `minVelocityToClose` |
| 135 | +
|
| 136 | +The minimum velocity needed by quickly swiping down to close the bottom sheet. |
| 137 | +
|
| 138 | +| Type | Default | |
| 139 | +| ------ | ------------------------ | |
| 140 | +| number | 90% of the screen height | |
| 141 | +
|
| 142 | +### `onBottomSheetHidden` |
| 143 | +
|
| 144 | +The callback to triggered after animations when the BottomSheet is hidden |
| 145 | +
|
| 146 | +| Type | |
| 147 | +| ---------- | |
| 148 | +| () => void | |
| 149 | +
|
| 150 | +### <Required /> `onClose` |
| 151 | +
|
| 152 | +The callback to trigger when the BottomSheet is dismissed |
| 153 | +
|
| 154 | +| Type | |
| 155 | +| ---------- | |
| 156 | +| () => void | |
| 157 | +
|
| 158 | +### `overlayOpacity` |
| 159 | +
|
| 160 | +The opacity of the overlay. |
| 161 | +
|
| 162 | +| Type | Default | |
| 163 | +| ------ | ------- | |
| 164 | +| number | 1 | |
| 165 | +
|
| 166 | +### `overlayStyle` |
| 167 | +
|
| 168 | +The style to use for the overlay |
| 169 | +
|
| 170 | +| Type | Default | |
| 171 | +| --------- | ---------------------------------------------------- | |
| 172 | +| ViewStyle | `{ backgroundColor: 'rgba(0, 0, 0, 0.5)', flex: 1 }` | |
| 173 | +
|
| 174 | +### `panGestureEnabled` |
| 175 | +
|
| 176 | +Enable or disable the dragging gesture. |
| 177 | +
|
| 178 | +| Type | Default | |
| 179 | +| ------- | ------- | |
| 180 | +| boolean | true | |
| 181 | +
|
| 182 | +### `persistent` |
| 183 | +
|
| 184 | +If true, the bottom sheet will not be closed when the user taps on the overlay; the dragging gesture is also disabled. |
| 185 | +
|
| 186 | +| Type | Default | |
| 187 | +| ------- | ------- | |
| 188 | +| boolean | true | |
| 189 | +
|
| 190 | +### `hasScrollableContent` |
| 191 | +
|
| 192 | +If true, `children` of `BottomSheet` are wrapped in a [`<ScrollView />`](https://reactnative.dev/docs/scrollview) |
| 193 | +
|
| 194 | +| Type | Default | |
| 195 | +| ------- | ------- | |
| 196 | +| boolean | true | |
| 197 | +
|
| 198 | +### `scrollViewProps` |
| 199 | +
|
| 200 | +The props to use for the [`<ScrollView />`](https://reactnative.dev/docs/scrollview) that wraps the BottomSheet content |
| 201 | +
|
| 202 | +| Type | Default | |
| 203 | +| --------------- | --------- | |
| 204 | +| scrollViewProps | undefined | |
| 205 | +
|
| 206 | +### `shouldHandleKeyboardEvents` |
| 207 | +
|
| 208 | +If true, keyboard events are handled internally by the `BottomSheet` allowing for scrolling and animations to run smoothly |
| 209 | +
|
| 210 | +| Type | Default | |
| 211 | +| ------- | ------- | |
| 212 | +| boolean | true | |
| 213 | +
|
| 214 | +### `testID` |
| 215 | +
|
| 216 | +A testID to be used by the BottomSheet. The `Modal` component within the `BottomSheet` will receive this base `testID` and other internal components will receive abstractions of the base `testID`. It is best to view the source code to understand the hierarchy of these components and what testID's they will receive. |
| 217 | + |
| 218 | +| Type | |
| 219 | +| ------ | |
| 220 | +| string | |
| 221 | + |
| 222 | +### <Required /> `topInset` |
| 223 | + |
| 224 | +The value is used to calculate the correct max ScrollView height. |
| 225 | + |
| 226 | +| Type | Default | |
| 227 | +| ------ | ------- | |
| 228 | +| number | 0 | |
| 229 | + |
| 230 | +### <Required /> `visible` |
| 231 | + |
| 232 | +The BottomSheet visibility |
| 233 | + |
| 234 | +| Type | |
| 235 | +| ------- | |
| 236 | +| boolean | |
| 237 | + |
| 238 | +### `ref` |
| 239 | + |
| 240 | +A `ref` object used to call `close` and `isVisible` functions on the bottomSheet |
| 241 | + |
| 242 | +| Type | |
| 243 | +| ----------------------------------------------------------- | |
| 244 | +| `{ close: () => Promise<void>; isVisible: () => boolean; }` | |
| 245 | + |
| 246 | +## Known issues |
| 247 | + |
| 248 | +If the app crashes with the following error: |
| 249 | + |
| 250 | +> Unsupported top level event type "onGestureHandlerStateChange" dispatched |
| 251 | + |
| 252 | +Add the following import at the top of your `App.tsx|jsx` file: |
| 253 | + |
| 254 | +```js |
| 255 | +// https://github.com/software-mansion/react-native-gesture-handler/issues/320 |
| 256 | +import 'react-native-gesture-handler'; |
| 257 | +``` |
| 258 | + |
| 259 | +## Related guidelines |
| 260 | + |
| 261 | +- [BottomSheet](../guidelines/bottomsheet) |
| 262 | +- [Focus](../guidelines/focus) |
0 commit comments