react-pure-modal 3.0.2 → 3.0.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.
package/README.md CHANGED
@@ -28,6 +28,8 @@ https://memcrab.github.io/react-pure-modal/
28
28
  ## Usage
29
29
 
30
30
  ```jsx
31
+ import Modal from "react-pure-modal";
32
+
31
33
  <Modal
32
34
  isOpen={isOpen}
33
35
  onClose={onClose}
@@ -45,14 +47,61 @@ https://memcrab.github.io/react-pure-modal/
45
47
  </Modal>
46
48
  ```
47
49
 
50
+ ## Context
51
+
52
+ Use the exported context hook when you need modal state inside custom children (for example, a custom close button passed into `Modal.Close`).
53
+
54
+ ```jsx
55
+ import Modal, { useModalContext } from "react-pure-modal";
56
+
57
+ function CustomCloseContent() {
58
+ const { onClose } = useModalContext();
59
+ return (
60
+ <button type="button" onClick={() => onClose?.()}>
61
+ Save & Close
62
+ </button>
63
+ );
64
+ }
65
+
66
+ <Modal.Close>
67
+ <CustomCloseContent />
68
+ </Modal.Close>
69
+ ```
70
+
71
+ The context provides: `isOpen`, `onClose`, `closeOnBackdropClick`, and `style`.
72
+
73
+ `Modal.Close` renders the default icon button when no children are provided.
74
+
75
+ ## Portal
76
+
77
+ Render the modal into a dedicated DOM node (for example, a `#modal-root`
78
+ mounted near `body`).
79
+
80
+ ```jsx
81
+ import Modal from "react-pure-modal";
82
+
83
+ const portalRoot = document.getElementById("modal-root");
84
+
85
+ <Modal isOpen={isOpen} onClose={onClose} portal={portalRoot}>
86
+ <Modal.Close />
87
+ <Modal.Content>Portal content</Modal.Content>
88
+ </Modal>
89
+ ```
90
+
48
91
  ## Options
49
92
 
50
93
  - `isOpen` (boolean) - controls whether the modal is rendered; defaults to `false`.
51
94
  - `onClose` (VoidFunction) - called when the user clicks the close button, presses ESC, or (optionally) clicks the backdrop; set `isOpen` to `false` inside it. Any return value is ignored.
52
95
  - `closeOnBackdropClick` (boolean) - if `true`, clicking the backdrop calls `onClose` (default is `false`).
53
96
  - `style` (CSS custom properties) - inline CSS variables applied to the backdrop element; use this to set the variables listed below. TypeScript users can reference the exported `ModalCssVariable` union for autocomplete.
97
+ - `portal` (Element | DocumentFragment | null) - when provided, render the modal into the target via `createPortal`. If set during SSR (no `document`) or the node is missing, the modal returns `null`.
54
98
  - `children` - compose the modal from the provided compounds: `Modal.Close`, `Modal.Header`, `Modal.Content`, and `Modal.Footer`.
55
99
 
100
+ ## Compound component props
101
+
102
+ - `Modal.Header align` (`"start" | "center" | "end"`) - horizontal alignment for header content (default: `start`).
103
+ - `Modal.Footer align` (`"start" | "center" | "end"`) - horizontal alignment for footer content (default: `start`).
104
+
56
105
  ## CSS Variables
57
106
 
58
107
  All variables can be provided through the `style` prop (e.g. `style={{ "--radius": "16px" }}`). Close button variables apply when `Modal.Close` is rendered.
@@ -70,12 +119,14 @@ All variables can be provided through the `style` prop (e.g. `style={{ "--radius
70
119
  - `--close-button-background` - background for the close icon circle.
71
120
  - `--close-button-border` - border applied to the close icon circle (defaults to `var(--dividers-border)`).
72
121
  - `--close-button-size` - diameter of the close icon circle.
73
- - `--close-button-container-padding` - extra tap target padding around the close icon.
74
122
  - `--close-button-container-transform` - transform applied to the close button container (for positional nudges).
123
+ - `--close-button-place-self` - `place-self` value for the close button container (defaults to `start end`).
124
+ - `--close-button-grid-row` - grid row for the close button container (defaults to `1`).
75
125
  - `--close-button-hover-transform` - transform applied to the close icon on hover.
76
126
  - `--z-index` - base stacking level for the backdrop (panel uses `+1`).
77
127
  - `--top-content-padding` / `--bottom-content-padding` - vertical padding for the content area.
78
128
  - `--top-header-padding` / `--bottom-header-padding` - vertical padding for the header.
129
+ - `--header-left-padding` / `--header-right-padding` - horizontal padding for the header (defaults to `--left-padding`/`--right-padding`).
79
130
  - `--top-footer-padding` / `--bottom-footer-padding` - vertical padding for the footer.
80
131
  - `--left-padding` / `--right-padding` - horizontal padding shared across sections.
81
132
  - `--dividers-color` - border color for header/footer dividers (also used as the default close icon border).
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{createContext as o,useCallback as r,useContext as t,useEffect as n,useId as a,useLayoutEffect as d,useMemo as i,useRef as l}from"react";var s={"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/compounds/Modal.module.css":function(e,o,r){r.d(o,{A:()=>i});var t=r("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js"),n=r.n(t),a=r("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/api.js"),d=r.n(a)()(n());d.push([e.id,"body:has(.pureModalBackdrop-RW7tAF){overflow:hidden}.pureModalBackdrop-RW7tAF{--radius:12px;--aspect-ratio:auto;--backdrop-color:#0006;--box-shadow:0px 1px 2px #00000024,0px 8px 20px #0000002e,0px 20px 48px #00000038;--max-width:95vw;--max-height:90vh;--min-width:320px;--background:white;--background-panels:#ffffffe6;--top-content-padding:16px;--bottom-content-padding:16px;--top-footer-padding:16px;--bottom-footer-padding:16px;--left-padding:24px;--right-padding:24px;--calculated-right-padding:var(--right-padding);--z-index:1041;--backdrop-filter:blur(3px);--top-header-padding:16px;--bottom-header-padding:16px;--dividers-color:silver;--dividers-border:1px solid var(--dividers-color);--close-button-background:var(--background-panels,white);--close-button-size:30px;--close-button-container-padding:var(--radius);--close-button-container-transform:none;--close-button-space:var(--close-button-size);--close-button-border:var(--dividers-border);--close-button-hover-transform:scale(1.05);backdrop-filter:var(--backdrop-filter);z-index:var(--z-index);background-color:var(--backdrop-color);flex-direction:column;justify-content:center;align-items:center;animation:.26s cubic-bezier(.16,.84,.44,1) both backdropFadeSmooth-ZnEuSQ;display:flex;position:fixed;inset:0;overflow:auto}@keyframes backdropFadeSmooth-ZnEuSQ{0%{opacity:0;-webkit-backdrop-filter:blur();background-color:#0000}to{opacity:1;backdrop-filter:var(--backdrop-filter);background-color:var(--backdrop-color)}}.pureModal-Hr1gWI{z-index:calc(var(--z-index) + 1);background:var(--background);box-shadow:var(--box-shadow);border-radius:var(--radius);max-height:var(--max-height);max-width:max(320px,var(--max-width));min-width:var(--min-width);aspect-ratio:var(--aspect-ratio);grid-template-rows:auto minmax(0,1fr) minmax(0,max-content);grid-template-columns:1fr;grid-auto-flow:row;display:grid;overflow:visible;&:has(>.pureModalHeader-DahjVw)>.pureModalContent-t7nwPr{grid-row:2}animation:.24s cubic-bezier(.18,.77,.42,1) both panelSoftPop-JNSB6U}@keyframes panelSoftPop-JNSB6U{0%{opacity:0;transform:translateY(8px)scale(.97)}to{opacity:1;transform:translateY(0)scale(1)}}.pureModalHeader-DahjVw{padding:var(--top-header-padding)var(--calculated-right-padding)var(--bottom-header-padding)var(--left-padding);border-bottom:var(--dividers-border);border-radius:var(--radius)var(--radius)0 0;background:var(--background-panels);box-sizing:border-box;grid-area:1/1;align-items:center;width:100%;display:flex}.pureModalContent-t7nwPr{padding:var(--top-content-padding)var(--calculated-right-padding)var(--bottom-content-padding)var(--left-padding);box-sizing:border-box;overscroll-behavior:contain;width:100%;grid-area:1/1/2/-1;min-block-size:0;overflow:auto}.pureModalFooter-hj8jgh{padding:var(--top-footer-padding)var(--calculated-right-padding)calc(var(--bottom-footer-padding) + env(safe-area-inset-bottom))var(--left-padding);border-top:var(--dividers-border);border-radius:0 0 var(--radius)var(--radius);background:var(--background-panels);box-sizing:border-box;grid-area:3/1/auto/-1;width:100%;display:block}@media (width<=600px){.pureModalBackdrop-RW7tAF{--radius:12px 12px 0 0;justify-content:end}.pureModal-Hr1gWI{--aspect-ratio:auto;min-width:var(--max-width);animation:.28s cubic-bezier(.25,.85,.35,1) panelSheetIn-loLXeB}@keyframes panelSheetIn-loLXeB{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}}.pureModal-Hr1gWI:has(.pureCloseButton-Ac2K32) .pureModalHeader-DahjVw{--calculated-right-padding:calc(var(--right-padding) + var(--close-button-space))}.pureCloseButton-Ac2K32{padding:var(--close-button-container-padding);transform:var(--close-button-container-transform,none);z-index:3;grid-area:1/1/auto/-1;place-self:start end;align-items:center;display:flex}.pureCloseButtonIcon-m_tk65{border-radius:calc(var(--radius)*2);font-weight:700;font-size:calc(var(--close-button-size)/2);height:var(--close-button-size);color:var(--dividers-color);width:var(--close-button-size);cursor:pointer;text-align:center;line-height:calc(var(--close-button-size) - 1px);aspect-ratio:1;border:var(--close-button-border);background:var(--close-button-background);padding:0;transition:all .1s ease-in-out;&:hover{transform:var(--close-button-hover-transform)}}",""]),d.locals={pureModalBackdrop:"pureModalBackdrop-RW7tAF",backdropFadeSmooth:"backdropFadeSmooth-ZnEuSQ",pureModal:"pureModal-Hr1gWI",panelSoftPop:"panelSoftPop-JNSB6U",pureModalHeader:"pureModalHeader-DahjVw",pureModalContent:"pureModalContent-t7nwPr",pureModalFooter:"pureModalFooter-hj8jgh",panelSheetIn:"panelSheetIn-loLXeB",pureCloseButton:"pureCloseButton-Ac2K32",pureCloseButtonIcon:"pureCloseButtonIcon-m_tk65"};let i=d},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/api.js":function(e){e.exports=function(e){var o=[];return o.toString=function(){return this.map(function(o){var r="",t=void 0!==o[5];return o[4]&&(r+="@supports (".concat(o[4],") {")),o[2]&&(r+="@media ".concat(o[2]," {")),t&&(r+="@layer".concat(o[5].length>0?" ".concat(o[5]):""," {")),r+=e(o),t&&(r+="}"),o[2]&&(r+="}"),o[4]&&(r+="}"),r}).join("")},o.i=function(e,r,t,n,a){"string"==typeof e&&(e=[[null,e,void 0]]);var d={};if(t)for(var i=0;i<this.length;i++){var l=this[i][0];null!=l&&(d[l]=!0)}for(var s=0;s<e.length;s++){var c=[].concat(e[s]);t&&d[c[0]]||(void 0!==a&&(void 0===c[5]||(c[1]="@layer".concat(c[5].length>0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=a),r&&(c[2]&&(c[1]="@media ".concat(c[2]," {").concat(c[1],"}")),c[2]=r),n&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=n):c[4]="".concat(n)),o.push(c))}},o}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js":function(e){e.exports=function(e){return e[1]}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/injectStylesIntoStyleTag.js":function(e){var o=[];function r(e){for(var r=-1,t=0;t<o.length;t++)if(o[t].identifier===e){r=t;break}return r}function t(e,t){for(var n={},a=[],d=0;d<e.length;d++){var i=e[d],l=t.base?i[0]+t.base:i[0],s=n[l]||0,c="".concat(l," ").concat(s);n[l]=s+1;var u=r(c),p={css:i[1],media:i[2],sourceMap:i[3],supports:i[4],layer:i[5]};if(-1!==u)o[u].references++,o[u].updater(p);else{var m=function(e,o){var r=o.domAPI(o);return r.update(e),function(o){o?(o.css!==e.css||o.media!==e.media||o.sourceMap!==e.sourceMap||o.supports!==e.supports||o.layer!==e.layer)&&r.update(e=o):r.remove()}}(p,t);t.byIndex=d,o.splice(d,0,{identifier:c,updater:m,references:1})}a.push(c)}return a}e.exports=function(e,n){var a=t(e=e||[],n=n||{});return function(e){e=e||[];for(var d=0;d<a.length;d++){var i=r(a[d]);o[i].references--}for(var l=t(e,n),s=0;s<a.length;s++){var c=r(a[s]);0===o[c].references&&(o[c].updater(),o.splice(c,1))}a=l}}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertBySelector.js":function(e){var o={};e.exports=function(e,r){var t=function(e){if(void 0===o[e]){var r=document.querySelector(e);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(e){r=null}o[e]=r}return o[e]}(e);if(!t)throw Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");t.appendChild(r)}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertStyleElement.js":function(e){e.exports=function(e){var o=document.createElement("style");return e.setAttributes(o,e.attributes),e.insert(o,e.options),o}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/setAttributesWithoutAttributes.js":function(e,o,r){e.exports=function(e){var o=r.nc;o&&e.setAttribute("nonce",o)}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleDomAPI.js":function(e){e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var o=e.insertStyleElement(e);return{update:function(r){var t,n,a;t="",r.supports&&(t+="@supports (".concat(r.supports,") {")),r.media&&(t+="@media ".concat(r.media," {")),(n=void 0!==r.layer)&&(t+="@layer".concat(r.layer.length>0?" ".concat(r.layer):""," {")),t+=r.css,n&&(t+="}"),r.media&&(t+="}"),r.supports&&(t+="}"),(a=r.sourceMap)&&"undefined"!=typeof btoa&&(t+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(t,o,e.options)},remove:function(){var e;null===(e=o).parentNode||e.parentNode.removeChild(e)}}}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleTagTransform.js":function(e){e.exports=function(e,o){if(o.styleSheet)o.styleSheet.cssText=e;else{for(;o.firstChild;)o.removeChild(o.firstChild);o.appendChild(document.createTextNode(e))}}}},c={};function u(e){var o=c[e];if(void 0!==o)return o.exports;var r=c[e]={id:e,exports:{}};return s[e](r,r.exports,u),r.exports}u.n=e=>{var o=e&&e.__esModule?()=>e.default:()=>e;return u.d(o,{a:o}),o},u.d=(e,o)=>{for(var r in o)u.o(o,r)&&!u.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},u.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),u.nc=void 0;var p=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/injectStylesIntoStyleTag.js"),m=u.n(p),b=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleDomAPI.js"),f=u.n(b),v=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertBySelector.js"),h=u.n(v),g=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/setAttributesWithoutAttributes.js"),x=u.n(g),y=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertStyleElement.js"),k=u.n(y),w=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleTagTransform.js"),M=u.n(w),S=u("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/compounds/Modal.module.css"),_={};_.styleTagTransform=M(),_.setAttributes=x(),_.insert=h().bind(null,"head"),_.domAPI=f(),_.insertStyleElement=k(),m()(S.A,_);let j=S.A&&S.A.locals?S.A.locals:void 0,C=o(void 0);function B(e){if(!e)return -99999;let o=Number.parseInt(getComputedStyle(e).zIndex||"0",10);return Number.isNaN(o)?-99999:o}function A(e){return Math.max(Math.max(...Array.from(document.querySelectorAll(e)).map(e=>B(e))),1)}function I({children:o}){let{isOpen:a,onClose:i,style:s,closeOnBackdropClick:c}=t(C)??{},u=l(null),p=r(e=>{if(function(e){if(!e)return!1;let o=e.tagName.toLowerCase();return"input"===o||"textarea"===o||"select"===o||!!e.isContentEditable}(document.activeElement))return;let o=B(u.current),r=A(`.${j.pureModalBackdrop}`);return!!i&&"Escape"===e.key&&o===r&&(i(),!0)},[i]);return n(()=>{if(a)return document.addEventListener("keydown",p),()=>{document.removeEventListener("keydown",p)}},[a,p]),d(()=>{let e=s?.["--z-index"],o="number"==typeof e?e:"string"==typeof e?Number.parseFloat(e):NaN,r=Number.isFinite(o)?o:A(`.${j.pureModalBackdrop}`);u.current&&(u.current.style.zIndex=String(r+1))},[s?.["--z-index"]]),e("div",{ref:u,className:j.pureModalBackdrop,onMouseDown:e=>{if(c){if(e){if(!e.target.classList.contains(j.pureModalBackdrop))return;e.stopPropagation(),e.preventDefault()}i?.()}},"aria-modal":"true",role:"dialog",style:s,children:o})}function z(o){let r=a(),t=i(()=>({isOpen:!!o.isOpen,onClose:o.onClose,closeOnBackdropClick:!!o.closeOnBackdropClick,style:o.style}),[o.isOpen,o.onClose,o.closeOnBackdropClick,o.style]);return t.isOpen?e(C.Provider,{value:t,children:e(I,{children:e("div",{id:`pure-modal-${r}`,className:j.pureModal,children:o.children})})}):null}z.Footer=function({children:o}){return e("div",{className:j.pureModalFooter,children:o})},z.Header=function({children:o}){return e("div",{className:j.pureModalHeader,children:o})},z.Content=function({children:o}){return e("div",{className:j.pureModalContent,children:o})},z.Close=function({children:o}){let{onClose:r}=t(C)??{};return e("div",{className:j.pureCloseButton,children:o||e("button",{type:"button",onClick:r,className:j.pureCloseButtonIcon,children:"✕"})})};let N=z;export{N as default};
1
+ import{jsx as e}from"react/jsx-runtime";import{createContext as r,useCallback as o,useContext as t,useEffect as n,useId as a,useLayoutEffect as d,useMemo as i,useRef as l}from"react";import{createPortal as s}from"react-dom";var c={"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/compounds/Modal.module.css":function(e,r,o){o.d(r,{A:()=>i});var t=o("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js"),n=o.n(t),a=o("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/api.js"),d=o.n(a)()(n());d.push([e.id,"body:has(.pureModalBackdrop-RW7tAF){overflow:hidden}.pureModalBackdrop-RW7tAF{--radius:12px;--aspect-ratio:auto;--backdrop-color:#0006;--box-shadow:0px 1px 2px #00000024,0px 8px 20px #0000002e,0px 20px 48px #00000038;--max-width:95vw;--max-height:90vh;--min-width:320px;--background:white;--background-panels:#ffffffe6;--top-content-padding:16px;--bottom-content-padding:16px;--top-footer-padding:16px;--bottom-footer-padding:16px;--left-padding:24px;--right-padding:24px;--header-right-padding:var(--right-padding);--header-left-padding:var(--left-padding);--z-index:1041;--backdrop-filter:blur(3px);--top-header-padding:16px;--bottom-header-padding:16px;--dividers-color:silver;--dividers-border:1px solid var(--dividers-color);--close-button-background:var(--background-panels,white);--close-button-size:30px;--close-button-container-transform:translate(calc(0px - var(--radius)),var(--radius));--close-button-place-self:start end;--close-button-border:var(--dividers-border);--close-button-hover-transform:scale(1.05);--close-button-grid-row:1;backdrop-filter:var(--backdrop-filter);z-index:var(--z-index);background-color:var(--backdrop-color);flex-direction:column;justify-content:center;align-items:center;animation:.26s cubic-bezier(.16,.84,.44,1) both backdropFadeSmooth-ZnEuSQ;display:flex;position:fixed;inset:0;overflow:auto}@keyframes backdropFadeSmooth-ZnEuSQ{0%{opacity:0;-webkit-backdrop-filter:blur();background-color:#0000}to{opacity:1;backdrop-filter:var(--backdrop-filter);background-color:var(--backdrop-color)}}.pureModal-Hr1gWI{z-index:calc(var(--z-index) + 1);background:var(--background);box-shadow:var(--box-shadow);border-radius:var(--radius);max-height:var(--max-height);max-width:max(320px,var(--max-width));min-width:var(--min-width);aspect-ratio:var(--aspect-ratio);grid-template-rows:auto minmax(0,1fr) minmax(0,max-content);grid-template-columns:1fr;grid-auto-flow:row;display:grid;overflow:visible;&:has(>.pureModalHeader-DahjVw)>.pureModalContent-t7nwPr{grid-row:2}animation:.24s cubic-bezier(.18,.77,.42,1) both panelSoftPop-JNSB6U}@keyframes panelSoftPop-JNSB6U{0%{opacity:0;transform:translateY(8px)scale(.97)}to{opacity:1;transform:translateY(0)scale(1)}}.pureModalHeader-DahjVw{padding:var(--top-header-padding)var(--header-right-padding)var(--bottom-header-padding)var(--header-left-padding);border-bottom:var(--dividers-border);border-radius:var(--radius)var(--radius)0 0;background:var(--background-panels);width:100%;max-width:max(320px,var(--max-width));box-sizing:border-box;text-align:left;grid-area:1/1;justify-content:flex-start;align-items:center;display:flex}.pureModalHeader-DahjVw[data-align=center]{text-align:center;justify-content:center}.pureModalHeader-DahjVw[data-align=end]{text-align:right;justify-content:flex-end}.pureModalContent-t7nwPr{padding:var(--top-content-padding)var(--right-padding)var(--bottom-content-padding)var(--left-padding);box-sizing:border-box;overscroll-behavior:contain;width:100%;grid-area:1/1/2/-1;min-block-size:0;overflow:auto}.pureModalFooter-hj8jgh{padding:var(--top-footer-padding)var(--right-padding)calc(var(--bottom-footer-padding) + env(safe-area-inset-bottom))var(--left-padding);border-top:var(--dividers-border);border-radius:0 0 var(--radius)var(--radius);background:var(--background-panels);text-align:left;width:100%;max-width:max(320px,var(--max-width));box-sizing:border-box;grid-area:3/1/auto/-1;display:block}.pureModalFooter-hj8jgh[data-align=center]{text-align:center;justify-content:center}.pureModalFooter-hj8jgh[data-align=end]{text-align:right;justify-content:flex-end}@media (width<=600px){.pureModalBackdrop-RW7tAF{--radius:12px 12px 0 0;justify-content:end}.pureModal-Hr1gWI{--aspect-ratio:auto;min-width:var(--max-width);animation:.28s cubic-bezier(.25,.85,.35,1) panelSheetIn-loLXeB}@keyframes panelSheetIn-loLXeB{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}}.pureCloseButton-Ac2K32{grid-row:var(--close-button-grid-row,1);place-self:var(--close-button-place-self,start end);transform:var(--close-button-container-transform,none);z-index:3;grid-column:1/-1;align-items:center;display:flex}.pureCloseButtonIcon-m_tk65{border-radius:calc(var(--radius)*2);font-weight:700;font-size:calc(var(--close-button-size)/2);line-height:calc(var(--close-button-size) - 1px);height:var(--close-button-size);color:var(--dividers-color);width:var(--close-button-size);cursor:pointer;text-align:center;aspect-ratio:1;border:var(--close-button-border);background:var(--close-button-background);padding:0;transition:all .1s ease-in-out;&:hover{transform:var(--close-button-hover-transform)}}",""]),d.locals={pureModalBackdrop:"pureModalBackdrop-RW7tAF",backdropFadeSmooth:"backdropFadeSmooth-ZnEuSQ",pureModal:"pureModal-Hr1gWI",panelSoftPop:"panelSoftPop-JNSB6U",pureModalHeader:"pureModalHeader-DahjVw",pureModalContent:"pureModalContent-t7nwPr",pureModalFooter:"pureModalFooter-hj8jgh",panelSheetIn:"panelSheetIn-loLXeB",pureCloseButton:"pureCloseButton-Ac2K32",pureCloseButtonIcon:"pureCloseButtonIcon-m_tk65"};let i=d},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/api.js":function(e){e.exports=function(e){var r=[];return r.toString=function(){return this.map(function(r){var o="",t=void 0!==r[5];return r[4]&&(o+="@supports (".concat(r[4],") {")),r[2]&&(o+="@media ".concat(r[2]," {")),t&&(o+="@layer".concat(r[5].length>0?" ".concat(r[5]):""," {")),o+=e(r),t&&(o+="}"),r[2]&&(o+="}"),r[4]&&(o+="}"),o}).join("")},r.i=function(e,o,t,n,a){"string"==typeof e&&(e=[[null,e,void 0]]);var d={};if(t)for(var i=0;i<this.length;i++){var l=this[i][0];null!=l&&(d[l]=!0)}for(var s=0;s<e.length;s++){var c=[].concat(e[s]);t&&d[c[0]]||(void 0!==a&&(void 0===c[5]||(c[1]="@layer".concat(c[5].length>0?" ".concat(c[5]):""," {").concat(c[1],"}")),c[5]=a),o&&(c[2]&&(c[1]="@media ".concat(c[2]," {").concat(c[1],"}")),c[2]=o),n&&(c[4]?(c[1]="@supports (".concat(c[4],") {").concat(c[1],"}"),c[4]=n):c[4]="".concat(n)),r.push(c))}},r}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js":function(e){e.exports=function(e){return e[1]}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/injectStylesIntoStyleTag.js":function(e){var r=[];function o(e){for(var o=-1,t=0;t<r.length;t++)if(r[t].identifier===e){o=t;break}return o}function t(e,t){for(var n={},a=[],d=0;d<e.length;d++){var i=e[d],l=t.base?i[0]+t.base:i[0],s=n[l]||0,c="".concat(l," ").concat(s);n[l]=s+1;var u=o(c),p={css:i[1],media:i[2],sourceMap:i[3],supports:i[4],layer:i[5]};if(-1!==u)r[u].references++,r[u].updater(p);else{var m=function(e,r){var o=r.domAPI(r);return o.update(e),function(r){r?(r.css!==e.css||r.media!==e.media||r.sourceMap!==e.sourceMap||r.supports!==e.supports||r.layer!==e.layer)&&o.update(e=r):o.remove()}}(p,t);t.byIndex=d,r.splice(d,0,{identifier:c,updater:m,references:1})}a.push(c)}return a}e.exports=function(e,n){var a=t(e=e||[],n=n||{});return function(e){e=e||[];for(var d=0;d<a.length;d++){var i=o(a[d]);r[i].references--}for(var l=t(e,n),s=0;s<a.length;s++){var c=o(a[s]);0===r[c].references&&(r[c].updater(),r.splice(c,1))}a=l}}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertBySelector.js":function(e){var r={};e.exports=function(e,o){var t=function(e){if(void 0===r[e]){var o=document.querySelector(e);if(window.HTMLIFrameElement&&o instanceof window.HTMLIFrameElement)try{o=o.contentDocument.head}catch(e){o=null}r[e]=o}return r[e]}(e);if(!t)throw Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");t.appendChild(o)}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertStyleElement.js":function(e){e.exports=function(e){var r=document.createElement("style");return e.setAttributes(r,e.attributes),e.insert(r,e.options),r}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/setAttributesWithoutAttributes.js":function(e,r,o){e.exports=function(e){var r=o.nc;r&&e.setAttribute("nonce",r)}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleDomAPI.js":function(e){e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var r=e.insertStyleElement(e);return{update:function(o){var t,n,a;t="",o.supports&&(t+="@supports (".concat(o.supports,") {")),o.media&&(t+="@media ".concat(o.media," {")),(n=void 0!==o.layer)&&(t+="@layer".concat(o.layer.length>0?" ".concat(o.layer):""," {")),t+=o.css,n&&(t+="}"),o.media&&(t+="}"),o.supports&&(t+="}"),(a=o.sourceMap)&&"undefined"!=typeof btoa&&(t+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(t,r,e.options)},remove:function(){var e;null===(e=r).parentNode||e.parentNode.removeChild(e)}}}},"./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleTagTransform.js":function(e){e.exports=function(e,r){if(r.styleSheet)r.styleSheet.cssText=e;else{for(;r.firstChild;)r.removeChild(r.firstChild);r.appendChild(document.createTextNode(e))}}}},u={};function p(e){var r=u[e];if(void 0!==r)return r.exports;var o=u[e]={id:e,exports:{}};return c[e](o,o.exports,p),o.exports}p.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return p.d(r,{a:r}),r},p.d=(e,r)=>{for(var o in r)p.o(r,o)&&!p.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},p.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),p.nc=void 0;var m=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/injectStylesIntoStyleTag.js"),f=p.n(m),b=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleDomAPI.js"),v=p.n(b),h=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertBySelector.js"),g=p.n(h),x=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/setAttributesWithoutAttributes.js"),y=p.n(x),k=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/insertStyleElement.js"),w=p.n(k),M=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/style-loader/runtime/styleTagTransform.js"),j=p.n(M),S=p("./node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/compounds/Modal.module.css"),_={};_.styleTagTransform=j(),_.setAttributes=y(),_.insert=g().bind(null,"head"),_.domAPI=v(),_.insertStyleElement=w(),f()(S.A,_);let C=S.A&&S.A.locals?S.A.locals:void 0,B=r(void 0);function A(){return t(B)??{}}function I(e){if(!e)return -99999;let r=Number.parseInt(getComputedStyle(e).zIndex||"0",10);return Number.isNaN(r)?-99999:r}function z(e){return Math.max(Math.max(...Array.from(document.querySelectorAll(e)).map(e=>I(e))),1)}function N({children:r}){let{isOpen:t,onClose:a,style:i,closeOnBackdropClick:s}=A(),c=l(null),u=o(e=>{if(function(e){if(!e)return!1;let r=e.tagName.toLowerCase();return"input"===r||"textarea"===r||"select"===r||!!e.isContentEditable}(document.activeElement))return;let r=I(c.current),o=z(`.${C.pureModalBackdrop}`);return!!a&&"Escape"===e.key&&r===o&&(a(),!0)},[a]);return n(()=>{if(t)return document.addEventListener("keydown",u),()=>{document.removeEventListener("keydown",u)}},[t,u]),d(()=>{let e=i?.["--z-index"],r="number"==typeof e?e:"string"==typeof e?Number.parseFloat(e):NaN,o=Number.isFinite(r)?r:z(`.${C.pureModalBackdrop}`);c.current&&(c.current.style.zIndex=String(o+1))},[i?.["--z-index"]]),e("div",{ref:c,className:C.pureModalBackdrop,onMouseDown:e=>{if(s){if(e){if(!e.target.classList.contains(C.pureModalBackdrop))return;e.stopPropagation(),e.preventDefault()}a?.()}},"aria-modal":"true",role:"dialog",style:i,children:r})}function F(r){let o=a(),t=i(()=>({isOpen:!!r.isOpen,onClose:r.onClose,closeOnBackdropClick:!!r.closeOnBackdropClick,style:r.style}),[r.isOpen,r.onClose,r.closeOnBackdropClick,r.style]);if(!t.isOpen)return null;let n=e(B.Provider,{value:t,children:e(N,{children:e("div",{id:`pure-modal-${o}`,className:C.pureModal,children:r.children})})});return void 0!==r.portal?"undefined"!=typeof document&&r.portal?s(n,r.portal):null:n}F.Footer=function({align:r,children:o}){return e("div",{className:C.pureModalFooter,"data-align":r,children:o})},F.Header=function({align:r,children:o}){return e("div",{className:C.pureModalHeader,"data-align":r,children:o})},F.Content=function({children:r}){return e("div",{className:C.pureModalContent,children:r})},F.Close=function({children:r}){let{onClose:o}=A();return e("div",{className:C.pureCloseButton,children:r||e("button",{type:"button",onClick:o,className:C.pureCloseButtonIcon,children:"✕"})})};let E=F;export{B as ModalContext,E as default,A as useModalContext};
@@ -1,5 +1,7 @@
1
+ import type { ModalSectionAlign } from "./Modal.types";
1
2
  type ModalFooterProps = {
3
+ align?: ModalSectionAlign;
2
4
  children?: React.ReactNode;
3
5
  };
4
- export declare function ModalFooter({ children }: ModalFooterProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function ModalFooter({ align, children }: ModalFooterProps): import("react/jsx-runtime").JSX.Element;
5
7
  export {};
@@ -1,5 +1,7 @@
1
+ import type { ModalSectionAlign } from "./Modal.types";
1
2
  type ModalHeaderProps = {
3
+ align?: ModalSectionAlign;
2
4
  children?: React.ReactNode;
3
5
  };
4
- export declare function ModalHeader({ children }: ModalHeaderProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function ModalHeader({ align, children }: ModalHeaderProps): import("react/jsx-runtime").JSX.Element;
5
7
  export {};
@@ -6,7 +6,8 @@ import type { ModalFooter } from "./Footer";
6
6
  import type { ModalHeader } from "./Header";
7
7
  export type ModalCompoundElement = ReactElement<typeof ModalBackdrop> | ReactElement<typeof ModalClose> | ReactElement<typeof ModalHeader> | ReactElement<typeof ModalContent> | ReactElement<typeof ModalFooter>;
8
8
  export type ModalChildren = ModalCompoundElement | ModalCompoundElement[];
9
- export type ModalCssVariable = "--radius" | "--aspect-ratio" | "--backdrop-color" | "--box-shadow" | "--max-width" | "--max-height" | "--min-width" | "--background" | "--background-panels" | "--z-index" | "--top-content-padding" | "--bottom-content-padding" | "--top-header-padding" | "--bottom-header-padding" | "--top-footer-padding" | "--bottom-footer-padding" | "--left-padding" | "--right-padding" | "--close-button-background" | "--close-button-border" | "--close-button-size" | "--close-button-container-padding" | "--close-button-container-transform" | "--close-button-hover-transform" | "--dividers-color" | "--dividers-border" | "--backdrop-filter";
9
+ export type ModalSectionAlign = "start" | "center" | "end";
10
+ export type ModalCssVariable = "--radius" | "--aspect-ratio" | "--backdrop-color" | "--box-shadow" | "--max-width" | "--max-height" | "--min-width" | "--background" | "--background-panels" | "--z-index" | "--top-content-padding" | "--bottom-content-padding" | "--top-header-padding" | "--bottom-header-padding" | "--header-left-padding" | "--header-right-padding" | "--top-footer-padding" | "--bottom-footer-padding" | "--left-padding" | "--right-padding" | "--close-button-background" | "--close-button-border" | "--close-button-size" | "--close-button-container-transform" | "--close-button-place-self" | "--close-button-grid-row" | "--close-button-hover-transform" | "--dividers-color" | "--dividers-border" | "--backdrop-filter";
10
11
  export type ModalStyle = Partial<Record<ModalCssVariable, string | number>>;
11
12
  export type ModalProps = {
12
13
  children: ModalChildren;
@@ -14,4 +15,5 @@ export type ModalProps = {
14
15
  style?: ModalStyle;
15
16
  onClose?: VoidFunction;
16
17
  closeOnBackdropClick?: boolean;
18
+ portal?: Element | DocumentFragment | null;
17
19
  };
@@ -1,3 +1,6 @@
1
1
  import Modal from "./compounds/Modal";
2
+ import { ModalContext, useModalContext } from "./compounds/ModalContext";
2
3
  export default Modal;
3
- export type { ModalCompoundElement, ModalProps, ModalCssVariable, } from "./compounds/Modal.types";
4
+ export { ModalContext, useModalContext };
5
+ export type { ModalCompoundElement, ModalProps, ModalCssVariable, ModalSectionAlign, } from "./compounds/Modal.types";
6
+ export type { ModalContextType } from "./compounds/ModalContext";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-pure-modal",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "React modal",
5
5
  "type": "module",
6
6
  "exports": {