react-modal-sheet 1.6.3 → 1.8.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/README.md CHANGED
@@ -1,7 +1,8 @@
1
+ <p align='center'>
2
+ <img src="media/banner.jpg" alt="React Modal Sheet logo"/>
3
+ <p/>
4
+
1
5
  <div align="center" >
2
- <br/>
3
- <br/>
4
- <h1>🪐 React Modal Sheet</h1>
5
6
  &middot;
6
7
  <i>Flexible bottom sheet component for your React apps</i>
7
8
  &middot;
@@ -40,11 +41,11 @@ npm install framer-motion
40
41
  ## Usage
41
42
 
42
43
  ```jsx
43
- import React from 'react';
44
44
  import Sheet from 'react-modal-sheet';
45
+ import { useState } from 'react';
45
46
 
46
47
  function Example() {
47
- const [isOpen, setOpen] = React.useState(false);
48
+ const [isOpen, setOpen] = useState(false);
48
49
 
49
50
  return (
50
51
  <>
@@ -71,22 +72,24 @@ Also, by constructing the sheet from smaller pieces makes it easier to apply any
71
72
 
72
73
  ## Props
73
74
 
74
- | Name | Required | Default | Description |
75
- | -------------- | -------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76
- | `children` | yes | | Use `Sheet.Container/Content/Header/Backdrop` to compose your bottom sheet. |
77
- | `isOpen` | yes | | Boolean that indicates whether the sheet is open or not. |
78
- | `onClose` | yes | | Callback fn that is called when the sheet is closed by the user. |
79
- | `disableDrag` | no | false | Disable drag for the whole sheet. |
80
- | `onOpenStart` | no | | Callback fn that is called when the sheet opening animation starts. |
81
- | `onOpenEnd` | no | | Callback fn that is called when the sheet opening animation is completed. |
82
- | `onCloseStart` | no | | Callback fn that is called when the sheet closing animation starts. |
83
- | `onCloseEnd` | no | | Callback fn that is called when the sheet closing animation is completed. |
84
- | `onSnap` | no | | Callback fn that is called with the current snap point index when the sheet snaps to a new snap point. Requires `snapPoints` prop. |
85
- | `snapPoints` | no | | Eg. `[-50, 0.5, 100, 0]` - where positive values are pixels from the bottom of the screen and negative from the top. Values between 0-1 represent percentages, eg. `0.5` means 50% of window height from the bottom of the sceen. |
86
- | `initialSnap` | no | 0 | Initial snap point when sheet is opened (index from `snapPoints`). |
87
- | `rootId` | no | | The id of the element where the main app is mounted, eg. "root". Enables iOS modal effect. |
88
- | `springConfig` | no | `DEFAULT_SPRING` | Overrides the config for the [spring animation](https://www.framer.com/api/motion/types/#spring). |
89
- | `mountPoint` | no | `document.body` | HTML element that should be used as the mount point for the sheet. |
75
+ | Name | Required | Default | Description |
76
+ |------------------------|----------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
77
+ | `children` | yes | | Use `Sheet.Container/Content/Header/Backdrop` to compose your bottom sheet. |
78
+ | `isOpen` | yes | | Boolean that indicates whether the sheet is open or not. |
79
+ | `onClose` | yes | | Callback fn that is called when the sheet is closed by the user. |
80
+ | `disableDrag` | no | false | Disable drag for the whole sheet. |
81
+ | `detent` | no | `'full-height'` | The [detent](https://developer.apple.com/design/human-interface-guidelines/components/presentation/sheets#ios-ipados) in which the sheet should be in when opened. Available values: `'full-height'` or `'content-height'`. |
82
+ | `onOpenStart` | no | | Callback fn that is called when the sheet opening animation starts. |
83
+ | `onOpenEnd` | no | | Callback fn that is called when the sheet opening animation is completed. |
84
+ | `onCloseStart` | no | | Callback fn that is called when the sheet closing animation starts. |
85
+ | `onCloseEnd` | no | | Callback fn that is called when the sheet closing animation is completed. |
86
+ | `onSnap` | no | | Callback fn that is called with the current snap point index when the sheet snaps to a new snap point. Requires `snapPoints` prop. |
87
+ | `snapPoints` | no | | Eg. `[-50, 0.5, 100, 0]` - where positive values are pixels from the bottom of the screen and negative from the top. Values between 0-1 represent percentages, eg. `0.5` means 50% of window height from the bottom of the sceen. |
88
+ | `initialSnap` | no | 0 | Initial snap point when sheet is opened (index from `snapPoints`). |
89
+ | `rootId` | no | | The id of the element where the main app is mounted, eg. "root". Enables iOS modal effect. |
90
+ | `springConfig` | no | `DEFAULT_SPRING` | Overrides the config for the [spring animation](https://www.framer.com/api/motion/types/#spring). |
91
+ | `mountPoint` | no | `document.body` | HTML element that should be used as the mount point for the sheet. |
92
+ | `prefersReducedMotion` | no | false | Skip sheet animations (sheet instantly snaps to desired location). |
90
93
 
91
94
  **`DEFAULT_SPRING`**
92
95
 
@@ -107,12 +110,12 @@ Spring animation happens when the sheet is opened/closed or when it snaps to a s
107
110
  Imperative method that can be accessed via a ref for snapping to a snap point in given index.
108
111
 
109
112
  ```tsx
110
- import React from 'react';
111
113
  import Sheet, { SheetRef } from 'react-modal-sheet';
114
+ import { useState, useRef } from 'react';
112
115
 
113
116
  function Example() {
114
- const [isOpen, setOpen] = React.useState(false);
115
- const ref = React.useRef<SheetRef>();
117
+ const [isOpen, setOpen] = useState(false);
118
+ const ref = useRef<SheetRef>();
116
119
  const snapTo = (i: number) => ref.current?.snapTo(i);
117
120
 
118
121
  return (
@@ -153,12 +156,12 @@ Similarly to the `snapTo` method the `y` value can be accessed via a ref.
153
156
  The `y` value can be useful for certain situtation eg. when you want to combine snap points with scrollable sheet content and ensure that the content stays properly scrollable in any snap point. Below you can see a simplified example of this situation and for a more detailed example take a look at the [ScrollableSnapPoints](example/components/ScrollableSnapPoints.tsx) component in the example app.
154
157
 
155
158
  ```tsx
156
- import React from 'react';
157
159
  import Sheet, { SheetRef } from 'react-modal-sheet';
160
+ import { useState, useRef } from 'react';
158
161
 
159
162
  function Example() {
160
- const [isOpen, setOpen] = React.useState(false);
161
- const ref = React.useRef<SheetRef>();
163
+ const [isOpen, setOpen] = useState(false);
164
+ const ref = useRef<SheetRef>();
162
165
 
163
166
  return (
164
167
  <>
@@ -189,6 +192,36 @@ function Example() {
189
192
  }
190
193
  ```
191
194
 
195
+ ### Detents
196
+
197
+ By default the sheet will take the full height of the page minus top padding and safe area inset. If you want the sheet height to be based on it's content you can pass `detent="content-height"` prop to the `Sheet` component:
198
+
199
+ ```tsx
200
+ function Example() {
201
+ const [isOpen, setOpen] = useState(false);
202
+
203
+ return (
204
+ <Sheet
205
+ isOpen={isOpen}
206
+ onClose={() => setOpen(false)}
207
+ detent="content-height"
208
+ >
209
+ <Sheet.Container>
210
+ <Sheet.Content>
211
+ <div style={{ height: 200 }}>Some content</div>
212
+ </Sheet.Content>
213
+ </Sheet.Container>
214
+ </Sheet>
215
+ );
216
+ }
217
+ ```
218
+
219
+ If the sheet height changes dynamically the sheet will grow until it hits the maximum full height after which it becomes scrollable.
220
+
221
+ It is possible to use snap points with `detent="content-height"` **but** the snap points are restricted by the content height. For example if one of the snap points is 800px and the sheet height is only 700px then snapping to the 800px snap point would only snap to 700px since otherwise the sheet would become detached from the bottom.
222
+
223
+ > ℹ️ If you are wondering where the term `detent` comes from it's from Apple's [Human Interface Guidelines](<[detent](https://developer.apple.com/design/human-interface-guidelines/components/presentation/sheets#ios-ipados)>).
224
+
192
225
  ## Compound Components
193
226
 
194
227
  ### `Sheet.Container`
@@ -206,7 +239,7 @@ Sheet content acts as a drag target and makes sure that content which doesn't fi
206
239
  #### Content props
207
240
 
208
241
  | Name | Required | Default | Description |
209
- | ------------- | -------- | ------- | ----------------------------------- |
242
+ |---------------|----------|---------|-------------------------------------|
210
243
  | `disableDrag` | no | false | Disable drag for the sheet content. |
211
244
 
212
245
  ### `Sheet.Header`
@@ -218,7 +251,7 @@ Sheet header acts as a drag target and has a dragging direction indicator. Rende
218
251
  #### Header props
219
252
 
220
253
  | Name | Required | Default | Description |
221
- | ------------- | -------- | ------- | ---------------------------------- |
254
+ |---------------|----------|---------|------------------------------------|
222
255
  | `disableDrag` | no | false | Disable drag for the sheet header. |
223
256
 
224
257
  ### `Sheet.Backdrop`
@@ -300,9 +333,9 @@ You can add your own styles or override the default sheet styles via the exposed
300
333
  #### CSS-in-JS
301
334
 
302
335
  ```jsx
303
- import React from 'react';
304
- import styled from 'styled-components';
305
336
  import Sheet from 'react-modal-sheeet';
337
+ import styled from 'styled-components';
338
+ import { useState } from 'react';
306
339
 
307
340
  const CustomSheet = styled(Sheet)`
308
341
  .react-modal-sheet-backdrop {
@@ -323,7 +356,7 @@ const CustomSheet = styled(Sheet)`
323
356
  `;
324
357
 
325
358
  function Example() {
326
- const [isOpen, setOpen] = React.useState(false);
359
+ const [isOpen, setOpen] = useState(false);
327
360
 
328
361
  return (
329
362
  <>
@@ -351,8 +384,8 @@ The example below utilizes React Aria to achieve an accessible modal-like bottom
351
384
  > ℹ️ The example was built by following the React Aria's [useDialog](https://react-spectrum.adobe.com/react-aria/useDialog.html) documentation.
352
385
 
353
386
  ```jsx
354
- import React from 'react';
355
387
  import Sheet from 'react-modal-sheet';
388
+ import { useRef } from 'react';
356
389
  import { useOverlayTriggerState } from 'react-stately';
357
390
 
358
391
  import {
@@ -366,7 +399,7 @@ import {
366
399
 
367
400
  const A11yExample = () => {
368
401
  const sheetState = useOverlayTriggerState({});
369
- const openButtonRef = React.useRef(null);
402
+ const openButtonRef = useRef(null);
370
403
  const openButton = useButton({ onPress: sheetState.open }, openButtonRef);
371
404
 
372
405
  return (
@@ -387,14 +420,14 @@ const A11yExample = () => {
387
420
  };
388
421
 
389
422
  const SheetComp = ({ sheetState }) => {
390
- const containerRef = React.useRef(null);
423
+ const containerRef = useRef(null);
391
424
  const dialog = useDialog({}, containerRef);
392
425
  const overlay = useOverlay(
393
426
  { onClose: sheetState.close, isOpen: true, isDismissable: true },
394
427
  containerRef
395
428
  );
396
429
 
397
- const closeButtonRef = React.useRef(null);
430
+ const closeButtonRef = useRef(null);
398
431
  const closeButton = useButton(
399
432
  { onPress: sheetState.close, 'aria-label': 'Close sheet' },
400
433
  closeButtonRef
@@ -1,3 +1,3 @@
1
1
  import * as React from 'react';
2
- declare const SheetBackdrop: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "style" | "transformTemplate" | "transformValues" | "variants" | "transition" | "onViewportBoxUpdate" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onLayoutAnimationComplete" | "onUnmount" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "drag" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragConstraints" | "dragElastic" | "dragMomentum" | "dragTransition" | "dragControls" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDragStart" | "onDragEnd" | "onDrag" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "custom" | "inherit"> & React.RefAttributes<any>>;
2
+ declare const SheetBackdrop: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "style" | "transformTemplate" | "transformValues" | "variants" | "transition" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onLayoutAnimationStart" | "onLayoutAnimationComplete" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onUnmount" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "whileInView" | "onViewportEnter" | "onViewportLeave" | "viewport" | "drag" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragConstraints" | "dragElastic" | "dragMomentum" | "dragTransition" | "dragControls" | "dragSnapToOrigin" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDragStart" | "onDragEnd" | "onDrag" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "layoutDependency" | "layoutScroll" | "custom" | "inherit"> & React.RefAttributes<any>>;
3
3
  export default SheetBackdrop;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- declare const SheetContent: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "initial" | "style" | "transformTemplate" | "transformValues" | "animate" | "exit" | "variants" | "transition" | "onViewportBoxUpdate" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onLayoutAnimationComplete" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragTransition" | "dragControls" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "custom" | "inherit"> & {
2
+ declare const SheetContent: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "style" | "transformTemplate" | "transformValues" | "initial" | "animate" | "exit" | "variants" | "transition" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onLayoutAnimationStart" | "onLayoutAnimationComplete" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onUnmount" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "whileInView" | "onViewportEnter" | "onViewportLeave" | "viewport" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragTransition" | "dragControls" | "dragSnapToOrigin" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "layoutDependency" | "layoutScroll" | "custom" | "inherit"> & {
3
3
  children?: React.ReactNode;
4
4
  disableDrag?: boolean | undefined;
5
5
  } & React.RefAttributes<any>>;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- declare const SheetHeader: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "initial" | "style" | "transformTemplate" | "transformValues" | "animate" | "exit" | "variants" | "transition" | "onViewportBoxUpdate" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onLayoutAnimationComplete" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragTransition" | "dragControls" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "custom" | "inherit"> & {
2
+ declare const SheetHeader: React.ForwardRefExoticComponent<Pick<import("framer-motion").MotionProps, "style" | "transformTemplate" | "transformValues" | "initial" | "animate" | "exit" | "variants" | "transition" | "onBeforeLayoutMeasure" | "onLayoutMeasure" | "onLayoutAnimationStart" | "onLayoutAnimationComplete" | "onUpdate" | "onAnimationStart" | "onAnimationComplete" | "onUnmount" | "onPan" | "onPanStart" | "onPanSessionStart" | "onPanEnd" | "onTap" | "onTapStart" | "onTapCancel" | "whileTap" | "whileHover" | "onHoverStart" | "onHoverEnd" | "whileFocus" | "whileInView" | "onViewportEnter" | "onViewportLeave" | "viewport" | "whileDrag" | "dragDirectionLock" | "dragPropagation" | "dragTransition" | "dragControls" | "dragSnapToOrigin" | "dragListener" | "onMeasureDragConstraints" | "_dragX" | "_dragY" | "onDirectionLock" | "onDragTransitionEnd" | "layout" | "layoutId" | "layoutDependency" | "layoutScroll" | "custom" | "inherit"> & {
3
3
  children?: React.ReactNode;
4
4
  disableDrag?: boolean | undefined;
5
5
  } & React.RefAttributes<any>>;
@@ -0,0 +1,9 @@
1
+ export declare const MAX_HEIGHT = "calc(100% - env(safe-area-inset-top) - 34px)";
2
+ export declare const IS_SSR: boolean;
3
+ export declare const DEFAULT_SPRING_CONFIG: {
4
+ stiffness: number;
5
+ damping: number;
6
+ mass: number;
7
+ };
8
+ export declare const DRAG_CLOSE_THRESHOLD = 0.6;
9
+ export declare const DRAG_VELOCITY_THRESHOLD = 500;
package/dist/hooks.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { SheetEvents } from './types';
3
+ export declare const useIsomorphicLayoutEffect: typeof React.useEffect;
3
4
  export declare const useModalEffect: (isOpen: boolean, rootId?: string | undefined) => void;
4
5
  export declare const useEventCallbacks: (isOpen: boolean, callbacks: React.MutableRefObject<SheetEvents>) => {
5
6
  handleAnimationComplete: () => void;
6
7
  };
8
+ export declare function useWindowHeight(): number;
9
+ export declare function usePrevious<T>(state: T): T | undefined;
10
+ export declare function useEvent<T extends (...args: any[]) => any>(handler: T): T;