New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-hooks-use-modal

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-hooks-use-modal - npm Package Compare versions

Comparing version 3.2.0 to 3.3.0

css-modules.d.ts

29

dist/index.d.ts

@@ -1,9 +0,15 @@

import { Options as FocusTrapOptions } from 'focus-trap';
import { Options } from 'focus-trap';
import React from 'react';
export interface WrapperProps {
interface ModalProviderProps extends UseModalOptions<{}> {
children?: React.ReactNode;
}
declare const ModalProvider: React.FC<ModalProviderProps>;
interface WrapperProps {
children: React.ReactNode;
}
export interface OverlayProps {
interface OverlayProps {
}
export interface ModalProps<T extends Record<string, unknown>> {
interface ModalProps<T extends Record<string, unknown>> {
title?: React.ReactNode;

@@ -15,6 +21,6 @@ description?: React.ReactNode;

}
export interface UseModalOptions<T extends Record<string, unknown>> {
interface UseModalOptions<T extends Record<string, unknown>> {
initialValue?: boolean;
preventScroll?: boolean;
focusTrapOptions?: FocusTrapOptions;
focusTrapOptions?: Options;
components?: {

@@ -26,3 +32,3 @@ Wrapper?: React.ComponentType<WrapperProps>;

}
export interface ModalWrapperProps<T extends Record<string, unknown>> {
interface ModalWrapperProps<T extends Record<string, unknown>> {
title?: React.ReactNode;

@@ -33,3 +39,3 @@ description?: React.ReactNode;

}
export declare type UseModalResult<T extends Record<string, unknown>> = [
type UseModalResult<T extends Record<string, unknown>> = [
ModalWrapper: React.FC<ModalWrapperProps<T>>,

@@ -40,4 +46,5 @@ open: () => void,

];
export declare type UseModal<T extends Record<string, unknown>> = (elementId?: string, options?: UseModalOptions<T>) => UseModalResult<T>;
export declare const useModal: <T extends Record<string, unknown>>(elementId?: string, options?: UseModalOptions<T> | undefined) => UseModalResult<T>;
export { ModalProvider } from './components/ModalProvider';
type UseModal<T extends Record<string, unknown>> = (elementId?: string, options?: UseModalOptions<T>) => UseModalResult<T>;
declare const useModal: <T extends Record<string, unknown>>(elementId?: string, options?: UseModalOptions<T> | undefined) => UseModalResult<T>;
export { ModalProps, ModalProvider, ModalWrapperProps, OverlayProps, UseModal, UseModalOptions, UseModalResult, WrapperProps, useModal };

@@ -1,1 +0,251 @@

var e=require("react"),t=require("react-dom"),n=require("body-scroll-lock"),r=require("focus-trap");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=l(e),a={position:"fixed",top:0,left:0,bottom:0,right:0,display:"flex",justifyContent:"center",alignItems:"center",zIndex:1e3},i=function(e){return o.default.createElement("div",{style:a},e.children)},c={position:"fixed",top:0,left:0,bottom:0,right:0,backgroundColor:"rgba(0, 0, 0, 0.5)"},u=function(){return o.default.createElement("div",{style:c})},s=function(t){return o.default.createElement(e.Fragment,null,t.children)};function d(){return d=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},d.apply(this,arguments)}var f=function(l){var a=l.children,i=l.isOpen,c=l.close,u=l.elementId,s=void 0===u?"root":u,f=l.title,p=l.description,v=l.preventScroll,m=l.focusTrapOptions,h=l.components,b=l.additionalProps,y=e.useRef(null);return function(t,n,l){e.useEffect(function(){if(n&&null!==t.current){var e=r.createFocusTrap(t.current,d({fallbackFocus:t.current},l));return e.activate(),setTimeout(function(){document.activeElement===t.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(){e.deactivate()}}},[l,n,t])}(y,i,e.useMemo(function(){return d({onDeactivate:c,clickOutsideDeactivates:!0},m)},[c,m])),function(t,r,l){e.useEffect(function(){if(null!==t.current)return l?(r?n.disableBodyScroll(t.current,{reserveScrollBarGap:!0}):n.enableBodyScroll(t.current),function(){n.clearAllBodyScrollLocks()}):void 0},[r,l,t])}(y,i,v),!1===i?null:t.createPortal(o.default.createElement(h.Wrapper,null,o.default.createElement(h.Overlay,null),o.default.createElement("div",{ref:y,role:"dialog","aria-modal":"true",tabIndex:-1,style:{position:"relative"}},o.default.createElement(h.Modal,{title:f,description:p,close:c,additionalProps:b},a))),document.getElementById(s))},p=e.createContext({}),v=["children"],m={initialValue:!1,preventScroll:!1,focusTrapOptions:{},components:{}};exports.ModalProvider=function(e){var t=e.children,n=function(e,t){if(null==e)return{};var n,r,l={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(l[n]=e[n]);return l}(e,v);return o.default.createElement(p.Provider,{value:n},t)},exports.useModal=function(t,n){var r,l,a;void 0===t&&(t="root");var c=e.useContext(p),d=e.useMemo(function(){return Object.assign({},m,c,n)},[c,n]),v=d.preventScroll,h=d.focusTrapOptions,b=d.components,y=e.useState(d.initialValue),O=y[0],g=y[1],E=e.useCallback(function(){g(!0)},[g]),k=e.useCallback(function(){g(!1)},[g]),x=null!=(r=b.Wrapper)?r:i,S=null!=(l=b.Overlay)?l:u,w=null!=(a=b.Modal)?a:s;return[e.useCallback(function(e){return o.default.createElement(f,{isOpen:O,close:k,elementId:t,title:e.title,description:e.description,preventScroll:v,focusTrapOptions:h,components:{Modal:w,Overlay:S,Wrapper:x},additionalProps:e.additionalProps},e.children)},[w,S,x,k,t,h,O,v]),E,k,O]};
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.tsx
var src_exports = {};
__export(src_exports, {
ModalProvider: () => ModalProvider,
useModal: () => useModal
});
module.exports = __toCommonJS(src_exports);
var import_react7 = __toESM(require("react"));
// src/components/DefaultComponents.tsx
var import_react = __toESM(require("react"));
var wrapperStyle = {
position: "fixed",
top: 0,
left: 0,
bottom: 0,
right: 0,
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: 1e3
};
var Wrapper = ({ children }) => {
return /* @__PURE__ */ import_react.default.createElement("div", { style: wrapperStyle }, children);
};
var overlayStyle = {
position: "fixed",
top: 0,
left: 0,
bottom: 0,
right: 0,
backgroundColor: "rgba(0, 0, 0, 0.5)"
};
var Overlay = () => {
return /* @__PURE__ */ import_react.default.createElement("div", { style: overlayStyle });
};
var Modal = ({
children
}) => {
return /* @__PURE__ */ import_react.default.createElement(import_react.Fragment, null, children);
};
// src/components/Modal.tsx
var import_react4 = __toESM(require("react"));
var import_react_dom = require("react-dom");
// src/hooks/useBodyScrollLock.ts
var import_body_scroll_lock = require("body-scroll-lock");
var import_react2 = require("react");
var useBodyScrollLock = (ref, isOpen, preventScroll) => {
(0, import_react2.useEffect)(() => {
if (ref.current === null) {
return;
}
if (preventScroll) {
if (isOpen) {
(0, import_body_scroll_lock.disableBodyScroll)(ref.current, {
reserveScrollBarGap: true
});
} else {
(0, import_body_scroll_lock.enableBodyScroll)(ref.current);
}
return () => {
(0, import_body_scroll_lock.clearAllBodyScrollLocks)();
};
}
}, [isOpen, preventScroll, ref]);
};
// src/hooks/useFocusTrap.tsx
var import_focus_trap = require("focus-trap");
var import_react3 = require("react");
var useFocusTrap = (ref, isOpen, focusTrapOptions) => {
(0, import_react3.useEffect)(() => {
if (!isOpen || ref.current === null) {
return;
}
const focusTrap = (0, import_focus_trap.createFocusTrap)(ref.current, {
fallbackFocus: ref.current,
...focusTrapOptions
});
focusTrap.activate();
setTimeout(() => {
if (document.activeElement === ref.current) {
console.warn(`[react-hooks-use-modal]: Since there were no focusable elements in the modal, the initial focus was on the containing element.
WAI-ARIA 1.1 states that there should be at least one focusable element in the modal.
https://www.w3.org/TR/wai-aria-1.1/#dialog`);
}
}, 100);
return () => {
focusTrap.deactivate();
};
}, [focusTrapOptions, isOpen, ref]);
};
// src/components/Modal.tsx
var ModalWrapper = ({
children,
isOpen,
close,
elementId = "root",
title,
description,
preventScroll,
focusTrapOptions,
components,
additionalProps
}) => {
const dialogRef = (0, import_react4.useRef)(null);
const _focusTrapOptions = (0, import_react4.useMemo)(
() => ({
onDeactivate: close,
clickOutsideDeactivates: true,
...focusTrapOptions
}),
[close, focusTrapOptions]
);
useFocusTrap(dialogRef, isOpen, _focusTrapOptions);
useBodyScrollLock(dialogRef, isOpen, preventScroll);
if (isOpen === false) {
return null;
}
return (0, import_react_dom.createPortal)(
/* @__PURE__ */ import_react4.default.createElement(components.Wrapper, null, /* @__PURE__ */ import_react4.default.createElement(components.Overlay, null), /* @__PURE__ */ import_react4.default.createElement(
"div",
{
ref: dialogRef,
role: "dialog",
"aria-modal": "true",
tabIndex: -1,
style: { position: "relative" }
},
/* @__PURE__ */ import_react4.default.createElement(
components.Modal,
{
title,
description,
close,
additionalProps
},
children
)
)),
document.getElementById(elementId)
);
};
// src/hooks/useModalConfig.ts
var import_react5 = require("react");
var ModalConfigContext = (0, import_react5.createContext)({});
var useModalConfig = () => {
return (0, import_react5.useContext)(ModalConfigContext);
};
// src/components/ModalProvider.tsx
var import_react6 = __toESM(require("react"));
var ModalProvider = ({
children,
...props
}) => {
return /* @__PURE__ */ import_react6.default.createElement(ModalConfigContext.Provider, { value: props }, children);
};
// src/index.tsx
var defaultOptions = {
initialValue: false,
preventScroll: false,
focusTrapOptions: {},
components: {}
};
var useModal = (elementId = "root", options) => {
const modalConfig = useModalConfig();
const { initialValue, preventScroll, focusTrapOptions, components } = (0, import_react7.useMemo)(
() => Object.assign({}, defaultOptions, modalConfig, options),
[modalConfig, options]
);
const [isOpen, setOpen] = (0, import_react7.useState)(initialValue);
const open = (0, import_react7.useCallback)(() => {
setOpen(true);
}, [setOpen]);
const close = (0, import_react7.useCallback)(() => {
setOpen(false);
}, [setOpen]);
const Wrapper2 = components.Wrapper ?? Wrapper;
const Overlay2 = components.Overlay ?? Overlay;
const Modal2 = components.Modal ?? Modal;
const _ModalWrapper = (0, import_react7.useCallback)(
({ title, description, children, additionalProps }) => {
return /* @__PURE__ */ import_react7.default.createElement(
ModalWrapper,
{
isOpen,
close,
elementId,
title,
description,
preventScroll,
focusTrapOptions,
components: {
Modal: Modal2,
Overlay: Overlay2,
Wrapper: Wrapper2
},
additionalProps
},
children
);
},
[
Modal2,
Overlay2,
Wrapper2,
close,
elementId,
focusTrapOptions,
isOpen,
preventScroll
]
);
return [_ModalWrapper, open, close, isOpen];
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ModalProvider,
useModal
});

@@ -16,2 +16,6 @@ module.exports = [

},
{
path: '/future',
title: 'Future useModal example',
},
];
{
"name": "react-hooks-use-modal",
"version": "3.2.0",
"version": "3.3.0",
"author": "shibe97",

@@ -17,13 +17,24 @@ "description": "A react hook which can open the modal with react-portal",

"main": "dist/index.js",
"module": "dist/index.modern.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./future": {
"import": "./dist/future/index.mjs",
"require": "./dist/future/index.js"
}
},
"dependencies": {
"body-scroll-lock": "^3.1.5",
"focus-trap": "^7.0.0"
"body-scroll-lock": "^4.0.0-beta.0",
"focus-trap": "^7.2.0"
},
"devDependencies": {
"@types/body-scroll-lock": "^3.1.0",
"@types/deepmerge": "^2.2.0",
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"css-loader": "^6.7.2",
"esbuild-css-modules-plugin": "^2.6.3",
"eslint": "^8.22.0",

@@ -36,7 +47,8 @@ "eslint-config-prettier": "^8.5.0",

"lint-staged": "^13.0.3",
"microbundle": "^0.13.3",
"prettier": "^2.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"style-loader": "^3.3.1",
"ts-loader": "^8.2.0",
"tsup": "^6.5.0",
"typescript": "^4.3.5",

@@ -52,6 +64,6 @@ "webpack": "^5.50.0",

"scripts": {
"build": "microbundle --sourcemap false",
"watch": "microbundle --watch",
"start": "webpack-dev-server --mode development",
"lint": "eslint --ext .ts --ext .tsx . --cache",
"build": "tsup",
"watch": "tsup --watch",
"start:demo": "webpack-dev-server --mode development",
"build:demo": "webpack --mode production",

@@ -58,0 +70,0 @@ "deploy:demo": "gh-pages -d examples/dist",

@@ -195,3 +195,3 @@ # useModal

```
$ npm install
$ yarn
```

@@ -202,3 +202,3 @@

```
$ npm run build
$ yarn build
```

@@ -209,21 +209,15 @@

```
$ npm run watch
$ yarn watch
```
### Build examples
### Start demo
```
$ npm run build:demo
$ yarn start:demo
```
### Start examples
Then access it on http://localhost:3001/react-hooks-use-modal
```
$ npm start
```
http://localhost:3001
## License
MIT

@@ -9,5 +9,6 @@ {

"strict": true,
"allowSyntheticDefaultImports": true
"allowSyntheticDefaultImports": true,
"baseUrl": "./"
},
"include": ["src"]
"include": ["src/**/*", "css-modules.d.ts"]
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc