react-hooks-use-modal
Advanced tools
Comparing version 2.1.0 to 3.0.0
@@ -0,16 +1,30 @@ | ||
import { Options as FocusTrapOptions } from 'focus-trap'; | ||
import React from 'react'; | ||
export interface WrapperProps { | ||
children: React.ReactNode; | ||
} | ||
export interface OverlayProps { | ||
} | ||
export interface ModalProps { | ||
title?: React.ReactNode; | ||
description?: React.ReactNode; | ||
close: () => void; | ||
children: React.ReactNode; | ||
isOpen: boolean; | ||
onOverlayClick: React.MouseEventHandler<HTMLDivElement>; | ||
elementId: 'root' | string; | ||
} | ||
export interface ModalOptions { | ||
export interface UseModalOptions { | ||
preventScroll?: boolean; | ||
closeOnOverlayClick?: boolean; | ||
focusTrapOptions?: FocusTrapOptions; | ||
components?: { | ||
Wrapper?: React.ComponentType<WrapperProps>; | ||
Overlay?: React.ComponentType<OverlayProps>; | ||
Modal?: React.ComponentType<ModalProps>; | ||
}; | ||
} | ||
export declare type UseModal = (elementId: string, options?: ModalOptions) => [ | ||
ModalWrapper: React.FC<{ | ||
children: React.ReactNode; | ||
}>, | ||
export interface ModalWrapperProps { | ||
title?: React.ReactNode; | ||
description?: React.ReactNode; | ||
children: React.ReactNode; | ||
} | ||
export declare type UseModal = (elementId?: string, options?: UseModalOptions) => [ | ||
ModalWrapper: React.FC<ModalWrapperProps>, | ||
open: () => void, | ||
@@ -21,1 +35,2 @@ close: () => void, | ||
export declare const useModal: UseModal; | ||
export { ModalProvider } from './components/ModalProvider'; |
@@ -1,1 +0,1 @@ | ||
var e=require("react"),t=require("react-dom"),l=require("disable-scroll");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=n(e),r=n(l),i={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},a={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)",zIndex:1e5},d={position:"relative",zIndex:100001},c=function(e){var l=e.children,n=e.isOpen,r=e.elementId,c=void 0===r?"root":r;return!1===(void 0!==n&&n)?null:t.createPortal(o.default.createElement("div",{style:i},o.default.createElement("div",{style:a,onClick:e.onOverlayClick}),o.default.createElement("div",{style:d},l)),document.getElementById(c))};exports.useModal=function(t,l){void 0===t&&(t="root"),void 0===l&&(l={});var n=l.preventScroll,i=void 0!==n&&n,a=l.closeOnOverlayClick,d=void 0===a||a,u=e.useState(!1),f=u[0],s=u[1],v=e.useCallback(function(){s(!0),i&&r.default.on()},[s,i]),p=e.useCallback(function(){s(!1),i&&r.default.off()},[s,i]),m=e.useCallback(function(e){e.stopPropagation(),d&&p()},[d,p]);return[e.useCallback(function(e){return o.default.createElement(c,{isOpen:f,onOverlayClick:m,elementId:t},e.children)},[f,p,t]),v,p,f]}; | ||
var e=require("deepmerge"),t=require("react"),r=require("react-dom"),n=require("body-scroll-lock"),l=require("focus-trap");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=o(e),c=o(t),i={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},u=function(e){return c.default.createElement("div",{style:i},e.children)},d={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)"},s=function(){return c.default.createElement("div",{style:d})},f=function(e){return c.default.createElement(t.Fragment,null,e.children)};function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},p.apply(this,arguments)}var v=function(e){var o=e.children,a=e.isOpen,i=e.close,u=e.elementId,d=void 0===u?"root":u,s=e.title,f=e.description,v=e.preventScroll,m=e.focusTrapOptions,h=e.components,b=t.useRef(null);return function(e,r,n){t.useEffect(function(){if(r&&null!==e.current){var t=l.createFocusTrap(e.current,p({fallbackFocus:e.current},n));return t.activate(),setTimeout(function(){document.activeElement===e.current&&console.warn("[react-hooks-use-modal]: Since there were no focusable elements in the modal, the initial focus was on the containing element.\n WAI-ARIA 1.1 states that there should be at least one focusable element in the modal.\n https://www.w3.org/TR/wai-aria-1.1/#dialog")},100),function(){t.deactivate()}}},[n,r,e])}(b,a,p({onDeactivate:i,clickOutsideDeactivates:!0},m)),function(e,r,l){t.useEffect(function(){if(null!==e.current)return l?(r?n.disableBodyScroll(e.current,{reserveScrollBarGap:!0}):n.enableBodyScroll(e.current),function(){n.clearAllBodyScrollLocks()}):void 0},[r,l,e])}(b,a,v),!1===a?null:r.createPortal(c.default.createElement(h.Wrapper,null,c.default.createElement(h.Overlay,null),c.default.createElement("div",{ref:b,role:"dialog","aria-modal":"true",tabIndex:-1,style:{position:"relative"}},c.default.createElement(h.Modal,{title:s,description:f,close:i},o))),document.getElementById(d))},m=t.createContext({}),h=["children"];exports.ModalProvider=function(e){var t=e.children,r=function(e,t){if(null==e)return{};var r,n,l={},o=Object.keys(e);for(n=0;n<o.length;n++)t.indexOf(r=o[n])>=0||(l[r]=e[r]);return l}(e,h);return c.default.createElement(m.Provider,{value:r},t)},exports.useModal=function(e,r){var n,l,o;void 0===e&&(e="root"),void 0===r&&(r={});var i=a.default(t.useContext(m),r),d=i.preventScroll,p=void 0!==d&&d,h=i.focusTrapOptions,b=void 0===h?{}:h,y=i.components,g=void 0===y?{}:y,O=t.useState(!1),E=O[0],k=O[1],x=t.useCallback(function(){k(!0)},[k]),w=t.useCallback(function(){k(!1)},[k]),S=null!=(n=g.Wrapper)?n:u,I=null!=(l=g.Overlay)?l:s,C=null!=(o=g.Modal)?o:f;return[t.useCallback(function(t){return c.default.createElement(v,{isOpen:E,close:w,elementId:e,title:t.title,description:t.description,preventScroll:p,focusTrapOptions:b,components:{Modal:C,Overlay:I,Wrapper:S}},t.children)},[C,I,S,w,e,b,E,p]),x,w,E]}; |
@@ -1,1 +0,1 @@ | ||
import e,{useState as t,useCallback as o}from"react";import{createPortal as n}from"react-dom";import i from"disable-scroll";var r={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},l={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)",zIndex:1e5},c={position:"relative",zIndex:100001},d=function(t){var o=t.children,i=t.isOpen,d=t.elementId,a=void 0===d?"root":d;return!1===(void 0!==i&&i)?null:n(e.createElement("div",{style:r},e.createElement("div",{style:l,onClick:t.onOverlayClick}),e.createElement("div",{style:c},o)),document.getElementById(a))},a=function(n,r){void 0===n&&(n="root"),void 0===r&&(r={});var l=r.preventScroll,c=void 0!==l&&l,a=r.closeOnOverlayClick,m=void 0===a||a,f=t(!1),v=f[0],p=f[1],s=o(function(){p(!0),c&&i.on()},[p,c]),u=o(function(){p(!1),c&&i.off()},[p,c]),y=o(function(e){e.stopPropagation(),m&&u()},[m,u]);return[o(function(t){return e.createElement(d,{isOpen:v,onOverlayClick:y,elementId:n},t.children)},[v,u,n]),s,u,v]};export{a as useModal}; | ||
import e from"deepmerge";import t,{Fragment as n,useEffect as r,useRef as o,createContext as i,useContext as l,useState as c,useCallback as a}from"react";import{createPortal as u}from"react-dom";import{disableBodyScroll as s,enableBodyScroll as d,clearAllBodyScrollLocks as f}from"body-scroll-lock";import{createFocusTrap as p}from"focus-trap";var m={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},v=function(e){return t.createElement("div",{style:m},e.children)},h={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)"},g=function(){return t.createElement("div",{style:h})},y=function(e){return t.createElement(n,null,e.children)};function O(){return O=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},O.apply(this,arguments)}var b=function(e){var n=e.children,i=e.isOpen,l=e.close,c=e.elementId,a=void 0===c?"root":c,m=e.title,v=e.description,h=e.preventScroll,g=e.focusTrapOptions,y=e.components,b=o(null);return function(e,t,n){r(function(){if(t&&null!==e.current){var r=p(e.current,O({fallbackFocus:e.current},n));return r.activate(),setTimeout(function(){document.activeElement===e.current&&console.warn("[react-hooks-use-modal]: Since there were no focusable elements in the modal, the initial focus was on the containing element.\n WAI-ARIA 1.1 states that there should be at least one focusable element in the modal.\n https://www.w3.org/TR/wai-aria-1.1/#dialog")},100),function(){r.deactivate()}}},[n,t,e])}(b,i,O({onDeactivate:l,clickOutsideDeactivates:!0},g)),function(e,t,n){r(function(){if(null!==e.current)return n?(t?s(e.current,{reserveScrollBarGap:!0}):d(e.current),function(){f()}):void 0},[t,n,e])}(b,i,h),!1===i?null:u(t.createElement(y.Wrapper,null,t.createElement(y.Overlay,null),t.createElement("div",{ref:b,role:"dialog","aria-modal":"true",tabIndex:-1,style:{position:"relative"}},t.createElement(y.Modal,{title:m,description:v,close:l},n))),document.getElementById(a))},E=i({}),w=["children"],I=function(e){var n=e.children,r=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)t.indexOf(n=i[r])>=0||(o[n]=e[n]);return o}(e,w);return t.createElement(E.Provider,{value:r},n)},x=function(n,r){var o,i,u;void 0===n&&(n="root"),void 0===r&&(r={});var s=e(l(E),r),d=s.preventScroll,f=void 0!==d&&d,p=s.focusTrapOptions,m=void 0===p?{}:p,h=s.components,O=void 0===h?{}:h,w=c(!1),I=w[0],x=w[1],k=a(function(){x(!0)},[x]),S=a(function(){x(!1)},[x]),T=null!=(o=O.Wrapper)?o:v,j=null!=(i=O.Overlay)?i:g,W=null!=(u=O.Modal)?u:y;return[a(function(e){return t.createElement(b,{isOpen:I,close:S,elementId:n,title:e.title,description:e.description,preventScroll:f,focusTrapOptions:m,components:{Modal:W,Overlay:j,Wrapper:T}},e.children)},[W,j,T,S,n,m,I,f]),k,S,I]};export{I as ModalProvider,x as useModal}; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom"),require("disable-scroll")):"function"==typeof define&&define.amd?define(["exports","react","react-dom","disable-scroll"],t):t((e||self).reactHooksUseModal={},e.react,e.reactDom,e.disableScroll)}(this,function(e,t,o,l){function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=n(t),r=n(l),a={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},d={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)",zIndex:1e5},c={position:"relative",zIndex:100001},u=function(e){var t=e.children,l=e.isOpen,n=e.elementId,r=void 0===n?"root":n;return!1===(void 0!==l&&l)?null:o.createPortal(i.default.createElement("div",{style:a},i.default.createElement("div",{style:d,onClick:e.onOverlayClick}),i.default.createElement("div",{style:c},t)),document.getElementById(r))};e.useModal=function(e,o){void 0===e&&(e="root"),void 0===o&&(o={});var l=o.preventScroll,n=void 0!==l&&l,a=o.closeOnOverlayClick,d=void 0===a||a,c=t.useState(!1),f=c[0],s=c[1],p=t.useCallback(function(){s(!0),n&&r.default.on()},[s,n]),v=t.useCallback(function(){s(!1),n&&r.default.off()},[s,n]),m=t.useCallback(function(e){e.stopPropagation(),d&&v()},[d,v]);return[t.useCallback(function(t){return i.default.createElement(u,{isOpen:f,onOverlayClick:m,elementId:e},t.children)},[f,v,e]),p,v,f]}}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("deepmerge"),require("react"),require("react-dom"),require("body-scroll-lock"),require("focus-trap")):"function"==typeof define&&define.amd?define(["exports","deepmerge","react","react-dom","body-scroll-lock","focus-trap"],t):t((e||self).reactHooksUseModal={},e.deepmerge,e.react,e.reactDom,e.bodyScrollLock,e.focusTrap)}(this,function(e,t,n,r,o,l){function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c=a(t),i=a(n),u={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},d=function(e){return i.default.createElement("div",{style:u},e.children)},s={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)"},f=function(){return i.default.createElement("div",{style:s})},p=function(e){return i.default.createElement(n.Fragment,null,e.children)};function m(){return m=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},m.apply(this,arguments)}var v=function(e){var t=e.children,a=e.isOpen,c=e.close,u=e.elementId,d=void 0===u?"root":u,s=e.title,f=e.description,p=e.preventScroll,v=e.focusTrapOptions,h=e.components,b=n.useRef(null);return function(e,t,r){n.useEffect(function(){if(t&&null!==e.current){var n=l.createFocusTrap(e.current,m({fallbackFocus:e.current},r));return n.activate(),setTimeout(function(){document.activeElement===e.current&&console.warn("[react-hooks-use-modal]: Since there were no focusable elements in the modal, the initial focus was on the containing element.\n WAI-ARIA 1.1 states that there should be at least one focusable element in the modal.\n https://www.w3.org/TR/wai-aria-1.1/#dialog")},100),function(){n.deactivate()}}},[r,t,e])}(b,a,m({onDeactivate:c,clickOutsideDeactivates:!0},v)),function(e,t,r){n.useEffect(function(){if(null!==e.current)return r?(t?o.disableBodyScroll(e.current,{reserveScrollBarGap:!0}):o.enableBodyScroll(e.current),function(){o.clearAllBodyScrollLocks()}):void 0},[t,r,e])}(b,a,p),!1===a?null:r.createPortal(i.default.createElement(h.Wrapper,null,i.default.createElement(h.Overlay,null),i.default.createElement("div",{ref:b,role:"dialog","aria-modal":"true",tabIndex:-1,style:{position:"relative"}},i.default.createElement(h.Modal,{title:s,description:f,close:c},t))),document.getElementById(d))},h=n.createContext({}),b=["children"];e.ModalProvider=function(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,o={},l=Object.keys(e);for(r=0;r<l.length;r++)t.indexOf(n=l[r])>=0||(o[n]=e[n]);return o}(e,b);return i.default.createElement(h.Provider,{value:n},t)},e.useModal=function(e,t){var r,o,l;void 0===e&&(e="root"),void 0===t&&(t={});var a=c.default(n.useContext(h),t),u=a.preventScroll,s=void 0!==u&&u,m=a.focusTrapOptions,b=void 0===m?{}:m,y=a.components,g=void 0===y?{}:y,O=n.useState(!1),k=O[0],E=O[1],x=n.useCallback(function(){E(!0)},[E]),S=n.useCallback(function(){E(!1)},[E]),w=null!=(r=g.Wrapper)?r:d,T=null!=(o=g.Overlay)?o:f,I=null!=(l=g.Modal)?l:p;return[n.useCallback(function(t){return i.default.createElement(v,{isOpen:k,close:S,elementId:e,title:t.title,description:t.description,preventScroll:s,focusTrapOptions:b,components:{Modal:I,Overlay:T,Wrapper:w}},t.children)},[I,T,w,S,e,b,k,s]),x,S,k]}}); |
{ | ||
"name": "react-hooks-use-modal", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"author": "shibe97", | ||
@@ -20,9 +20,18 @@ "description": "A react hook which can open the modal with react-portal", | ||
"dependencies": { | ||
"disable-scroll": "^0.6.0" | ||
"body-scroll-lock": "^3.1.5", | ||
"deepmerge": "^4.2.2", | ||
"focus-trap": "^7.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/body-scroll-lock": "^3.1.0", | ||
"@types/deepmerge": "^2.2.0", | ||
"@types/react": "^17.0.16", | ||
"@types/react-dom": "^17.0.9", | ||
"eslint": "^8.22.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-config-react-app": "^7.0.1", | ||
"gh-pages": "^2.1.1", | ||
"html-webpack-plugin": "^5.3.2", | ||
"husky": "^8.0.1", | ||
"lint-staged": "^13.0.3", | ||
"microbundle": "^0.13.3", | ||
@@ -35,4 +44,4 @@ "prettier": "^2.3.2", | ||
"webpack": "^5.50.0", | ||
"webpack-cli": "^3.3.12", | ||
"webpack-dev-server": "^3.11.2" | ||
"webpack-cli": "^4.10.0", | ||
"webpack-dev-server": "^4.10.0" | ||
}, | ||
@@ -47,13 +56,23 @@ "peerDependencies": { | ||
"start": "webpack-dev-server --mode development", | ||
"lint": "eslint --ext .ts --ext .tsx . --cache", | ||
"build:demo": "webpack --mode production", | ||
"deploy:demo": "gh-pages -d examples/dist" | ||
"deploy:demo": "gh-pages -d examples/dist", | ||
"lint-staged": "lint-staged", | ||
"prepare": "husky install" | ||
}, | ||
"lint-staged": { | ||
"*.{js,jsx,json,css,md}": [ | ||
"prettier --write", | ||
"git add" | ||
"*.{ts,tsx}": [ | ||
"eslint", | ||
"prettier --write" | ||
] | ||
}, | ||
"eslintConfig": { | ||
"extends": "react-app" | ||
"extends": [ | ||
"react-app", | ||
"prettier" | ||
], | ||
"ignorePatterns": [ | ||
"*.config.js", | ||
"dist" | ||
] | ||
}, | ||
@@ -60,0 +79,0 @@ "prettier": { |
124
README.md
@@ -15,3 +15,5 @@ # useModal | ||
preventScroll: true, | ||
closeOnOverlayClick: false; | ||
focusTrapOptions: { | ||
clickOutsideDeactivates: false, | ||
}, | ||
}); | ||
@@ -37,6 +39,8 @@ return ( | ||
### [ModalComponent, openFunc, closeFunc, isOpenBool] = useModal(domNode?, { preventScroll?, closeOnOverlayClick? }) | ||
### [ModalComponent, openFunc, closeFunc, isOpenBool] = useModal(domNode?, { preventScroll?, focusTrapOptions?, components? }) | ||
`ModalComponent` | ||
Type: React.FC<{ title?: React.ReactNode; description?: React.ReactNode, children?: React.ReactNode }> | ||
Modal component that displays children in the screen center. | ||
If you specify `title` and `description`, you must implement custom components with the `components` option's `Modal` property and render in them. | ||
@@ -62,6 +66,116 @@ `openFunc` | ||
`closeOnOverlayClick` | ||
Optional to close modal when click the overlay. | ||
Default value is true. | ||
`focusTrapOptions` | ||
Override the focus-trap options used internally. | ||
For example, to prevent a modal from closing when a non-modal element is clicked, do the following | ||
```jsx | ||
useModal('root', { | ||
focusTrapOptions: { | ||
clickOutsideDeactivates: false, | ||
}, | ||
}); | ||
``` | ||
`components` | ||
Optional. | ||
This is an option to customize the `ModalWrapper` returned by useModal. | ||
Use as follows | ||
```jsx | ||
useModal('root', { | ||
components: { | ||
Modal: ({ title, description, children }) => { | ||
return ( | ||
<div | ||
style={{ | ||
padding: '60px 100px', | ||
backgroundColor: '#fff', | ||
borderRadius: '10px', | ||
}} | ||
> | ||
{title && <h1>{title}</h1>} | ||
{description && <p>{description}</p>} | ||
{children} | ||
</div> | ||
); | ||
}, | ||
Overlay: () => { | ||
return ( | ||
<div | ||
style={{ | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
bottom: 0, | ||
right: 0, | ||
backgroundColor: 'rgba(0, 0, 0, 0.5)', | ||
}} | ||
/> | ||
); | ||
}, | ||
Wrapper: ({ children }) => { | ||
return ( | ||
<div | ||
style={{ | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
bottom: 0, | ||
right: 0, | ||
display: 'flex', | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
zIndex: 1000, | ||
}} | ||
> | ||
{children} | ||
</div> | ||
); | ||
}, | ||
}, | ||
}); | ||
``` | ||
Combined with `ModalProvider` (described below), you can specify the default style for all `useModal` in the project. | ||
## Global Settings | ||
The `ModalProvider` component allows you to apply a common default configuration to all `useModal` hooks. | ||
```jsx | ||
<ModalProvider {...options}> | ||
<Component /> | ||
</ModalProvider> | ||
``` | ||
The following example sets all `useModal` hooks to not scroll outside the modal by default. | ||
```jsx | ||
const Component1 = () => { | ||
const [Modal] = useModal('root'); | ||
return ( | ||
<Modal> | ||
<h2>Common</h2> | ||
</Modal> | ||
); | ||
}; | ||
const Component2 = () => { | ||
const [Modal] = useModal('root', { preventScroll: false }); // override | ||
return ( | ||
<Modal> | ||
<h2>Override options</h2> | ||
</Modal> | ||
); | ||
}; | ||
const App = () => { | ||
return ( | ||
<ModalProvider preventScroll> | ||
<Component1 /> | ||
<Component2 /> | ||
</ModalProvider> | ||
); | ||
}; | ||
``` | ||
## Demo | ||
@@ -68,0 +182,0 @@ |
20062
17
138
219
5
20
+ Addedbody-scroll-lock@^3.1.5
+ Addeddeepmerge@^4.2.2
+ Addedfocus-trap@^7.0.0
+ Addedbody-scroll-lock@3.1.5(transitive)
+ Addeddeepmerge@4.3.1(transitive)
+ Addedfocus-trap@7.6.4(transitive)
+ Addedtabbable@6.2.0(transitive)
- Removeddisable-scroll@^0.6.0
- Removeddisable-scroll@0.6.0(transitive)