UNPKG

@acrool/react-modal

Version:
827 lines (826 loc) 24.5 kB
var Ie = Object.defineProperty; var $e = (e, t, r) => t in e ? Ie(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r; var _ = (e, t, r) => $e(e, typeof t != "symbol" ? t + "" : t, r); import Y, { useState as ue, useEffect as $, createContext as de, useContext as fe, useId as Ye, useRef as Oe, useCallback as We } from "react"; import me from "react-dom"; import { AnimatePresence as pe, useIsPresent as De, motion as ne } from "framer-motion"; var C = { exports: {} }, R = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var oe; function Xe() { if (oe) return R; oe = 1; var e = Symbol.for("react.transitional.element"), t = Symbol.for("react.fragment"); function r(o, a, s) { var u = null; if (s !== void 0 && (u = "" + s), a.key !== void 0 && (u = "" + a.key), "key" in a) { s = {}; for (var c in a) c !== "key" && (s[c] = a[c]); } else s = a; return a = s.ref, { $$typeof: e, type: o, key: u, ref: a !== void 0 ? a : null, props: s }; } return R.Fragment = t, R.jsx = r, R.jsxs = r, R; } var P = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ae; function Fe() { return ae || (ae = 1, process.env.NODE_ENV !== "production" && function() { function e(n) { if (n == null) return null; if (typeof n == "function") return n.$$typeof === Ne ? null : n.displayName || n.name || null; if (typeof n == "string") return n; switch (n) { case D: return "Fragment"; case ge: return "Profiler"; case ve: return "StrictMode"; case ke: return "Suspense"; case je: return "SuspenseList"; case Te: return "Activity"; } if (typeof n == "object") switch (typeof n.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), n.$$typeof) { case W: return "Portal"; case Pe: return (n.displayName || "Context") + ".Provider"; case Re: return (n._context.displayName || "Context") + ".Consumer"; case Se: var i = n.render; return n = n.displayName, n || (n = i.displayName || i.name || "", n = n !== "" ? "ForwardRef(" + n + ")" : "ForwardRef"), n; case Ae: return i = n.displayName || null, i !== null ? i : e(n.type) || "Memo"; case K: i = n._payload, n = n._init; try { return e(n(i)); } catch { } } return null; } function t(n) { return "" + n; } function r(n) { try { t(n); var i = !1; } catch { i = !0; } if (i) { i = console; var l = i.error, d = typeof Symbol == "function" && Symbol.toStringTag && n[Symbol.toStringTag] || n.constructor.name || "Object"; return l.call( i, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", d ), t(n); } } function o(n) { if (n === D) return "<>"; if (typeof n == "object" && n !== null && n.$$typeof === K) return "<...>"; try { var i = e(n); return i ? "<" + i + ">" : "<...>"; } catch { return "<...>"; } } function a() { var n = X.A; return n === null ? null : n.getOwner(); } function s() { return Error("react-stack-top-frame"); } function u(n) { if (z.call(n, "key")) { var i = Object.getOwnPropertyDescriptor(n, "key").get; if (i && i.isReactWarning) return !1; } return n.key !== void 0; } function c(n, i) { function l() { J || (J = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", i )); } l.isReactWarning = !0, Object.defineProperty(n, "key", { get: l, configurable: !0 }); } function m() { var n = e(this.type); return Q[n] || (Q[n] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), n = this.props.ref, n !== void 0 ? n : null; } function b(n, i, l, d, x, y, L, H) { return l = y.ref, n = { $$typeof: N, type: n, key: i, props: y, _owner: x }, (l !== void 0 ? l : null) !== null ? Object.defineProperty(n, "ref", { enumerable: !1, get: m }) : Object.defineProperty(n, "ref", { enumerable: !1, value: null }), n._store = {}, Object.defineProperty(n._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(n, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(n, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: L }), Object.defineProperty(n, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: H }), Object.freeze && (Object.freeze(n.props), Object.freeze(n)), n; } function h(n, i, l, d, x, y, L, H) { var f = i.children; if (f !== void 0) if (d) if (Ce(f)) { for (d = 0; d < f.length; d++) w(f[d]); Object.freeze && Object.freeze(f); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else w(f); if (z.call(i, "key")) { f = e(n); var g = Object.keys(i).filter(function(Me) { return Me !== "key"; }); d = 0 < g.length ? "{key: someKey, " + g.join(": ..., ") + ": ...}" : "{key: someKey}", re[f + d] || (g = 0 < g.length ? "{" + g.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, d, f, g, f ), re[f + d] = !0); } if (f = null, l !== void 0 && (r(l), f = "" + l), u(i) && (r(i.key), f = "" + i.key), "key" in i) { l = {}; for (var B in i) B !== "key" && (l[B] = i[B]); } else l = i; return f && c( l, typeof n == "function" ? n.displayName || n.name || "Unknown" : n ), b( n, f, y, x, a(), l, L, H ); } function w(n) { typeof n == "object" && n !== null && n.$$typeof === N && n._store && (n._store.validated = 1); } var v = Y, N = Symbol.for("react.transitional.element"), W = Symbol.for("react.portal"), D = Symbol.for("react.fragment"), ve = Symbol.for("react.strict_mode"), ge = Symbol.for("react.profiler"), Re = Symbol.for("react.consumer"), Pe = Symbol.for("react.context"), Se = Symbol.for("react.forward_ref"), ke = Symbol.for("react.suspense"), je = Symbol.for("react.suspense_list"), Ae = Symbol.for("react.memo"), K = Symbol.for("react.lazy"), Te = Symbol.for("react.activity"), Ne = Symbol.for("react.client.reference"), X = v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, z = Object.prototype.hasOwnProperty, Ce = Array.isArray, F = console.createTask ? console.createTask : function() { return null; }; v = { "react-stack-bottom-frame": function(n) { return n(); } }; var J, Q = {}, ee = v["react-stack-bottom-frame"].bind( v, s )(), te = F(o(s)), re = {}; P.Fragment = D, P.jsx = function(n, i, l, d, x) { var y = 1e4 > X.recentlyCreatedOwnerStacks++; return h( n, i, l, !1, d, x, y ? Error("react-stack-top-frame") : ee, y ? F(o(n)) : te ); }, P.jsxs = function(n, i, l, d, x) { var y = 1e4 > X.recentlyCreatedOwnerStacks++; return h( n, i, l, !0, d, x, y ? Error("react-stack-top-frame") : ee, y ? F(o(n)) : te ); }; }()), P; } var ie; function Le() { return ie || (ie = 1, process.env.NODE_ENV === "production" ? C.exports = Xe() : C.exports = Fe()), C.exports; } var p = Le(), He = Object.defineProperty, Be = (e, t, r) => t in e ? He(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, Z = (e, t, r) => Be(e, typeof t != "symbol" ? t + "" : t, r); function Ue(e) { return Object.keys(e); } function se(e) { const t = document.createElement("div"); return t.id = e.id, e.className && (t.className = e.className), e.style && Ue(e.style).forEach((r) => { var o; t.style[r] = (o = e.style) == null ? void 0 : o[r]; }), t; } class he extends Y.Component { constructor(t) { super(t), Z(this, "_el", null), Z(this, "renderPortal", () => this._el ? me.createPortal( this.props.children, this._el ) : null), !(typeof window > "u") && (this._el = se(t)); } get typeProps() { return this.props; } componentDidMount() { this._el = this._el ? this._el : se(this.props); const t = this.typeProps.containerSelector(); t == null || t.appendChild(this._el); } componentWillUnmount() { if (!this._el) return; const t = this.typeProps.containerSelector(); t == null || t.removeChild(this._el); } render() { return this.renderPortal(); } } Z(he, "defaultProps", { containerSelector: () => document.body }); const Ze = ({ children: e, containerSelector: t = () => document.body }) => { const [r, o] = ue(!1); return $(() => { o(!0); }, []), (() => { const a = t(); return r && a ? me.createPortal(e, a) : null; })(); }, ye = "acrool-react-modal", j = [ "color: #fff", "display: inline-block", "font-size: 11px", "line-height: 20px", "padding-right: 8px", "border-radius: 4px" ], A = { primary: "#0055a9", success: "#009422", info: "#17a2b8", warning: "#d7a000", danger: "#ec2127" }; function T(e, t, ...r) { console.log(`%c ${e}`, t, ...r); } function qe(e, ...t) { const r = j.concat([ `background-color: ${A.primary}` ]).join(";"); T(e, r, ...t); } function Ge(e, ...t) { const r = j.concat([ `background-color: ${A.success}` ]).join(";"); T(e, r, ...t); } function Ve(e, ...t) { const r = j.concat([ `background-color: ${A.info}` ]).join(";"); T(e, r, ...t); } function Ke(e, ...t) { const r = j.concat([ `background-color: ${A.warning}` ]).join(";"); T(e, r, ...t); } function ze(e, ...t) { const r = j.concat([ `background-color: ${A.danger}` ]).join(";"); T(e, r, ...t); } const q = { primary: qe, success: Ge, info: Ve, warning: Ke, danger: ze }, be = de({ hide: () => q.warning("No GlobalModal/hide method detected, did you embed your app with Acrool/ModalPortal?"), hideAll: () => q.warning("No GlobalModal/hideAll method detected, did you embed your app with Acrool/ModalPortal?") }), $t = () => fe(be), Je = "acrool-react-modal__root", Qe = { root: Je }, O = de({ hide: async () => q.warning("No Modal/hide method detected, did you embed your app with Acrool/ModalPortal?") }); O.Consumer; const et = () => fe(O); function I(e) { const t = new Error(e); return t.source = "ulid", t; } const G = "0123456789ABCDEFGHJKMNPQRSTVWXYZ", k = G.length, ce = Math.pow(2, 48) - 1, tt = 10, rt = 16; function nt(e) { let t = Math.floor(e() * k); return t === k && (t = k - 1), G.charAt(t); } function ot(e, t) { if (isNaN(e)) throw new Error(e + " must be a number"); if (e > ce) throw I("cannot encode time greater than " + ce); if (e < 0) throw I("time must be positive"); if (Number.isInteger(Number(e)) === !1) throw I("time must be an integer"); let r, o = ""; for (; t > 0; t--) r = e % k, o = G.charAt(r) + o, e = (e - r) / k; return o; } function at(e, t) { let r = ""; for (; e > 0; e--) r = nt(t) + r; return r; } function it(e = !1, t) { t || (t = typeof window < "u" ? window : null); const r = t && (t.crypto || t.msCrypto); if (r) return () => { const o = new Uint8Array(1); return r.getRandomValues(o), o[0] / 255; }; try { const o = require("crypto"); return () => o.randomBytes(1).readUInt8() / 255; } catch { } if (e) { try { console.error("secure crypto unusable, falling back to insecure Math.random()!"); } catch { } return () => Math.random(); } throw I("secure crypto unusable, insecure Math.random not allowed"); } function st(e) { return e || (e = it()), function(r) { return isNaN(r) && (r = Date.now()), ot(r, tt) + at(rt, e); }; } const ct = st(); function lt(e, t) { return t === -1 || t > e.length - 1 ? e : [...e.slice(0, t), ...e.slice(t + 1)]; } function ut(e, t) { return !!e.className.match(new RegExp(`(\\s|^)${t}(\\s|$)`)); } function dt(e, t) { ut(e, t) || e.classList.add(t); } function ft(e, t) { e.classList.remove(t); } function V() { return ct().toLowerCase(); } function mt(e, t) { return e == null || e === !1 || e === "false" || e === 0 || e === "0" || !(e instanceof Date) && typeof e == "object" && Object.keys(e).length === 0 || typeof e == "string" && e.trim().length === 0; } let S; class pt extends Y.Component { constructor(r) { super(r); _(this, "state", { rows: [] }); /** * 顯示 Modal * (自動 QueueKey) * @param ModalComponent * @param args * @param onHide */ _(this, "show", (r, o, a) => { const s = V(); this.showWithKey(r, s, o, a); }); /** * 顯示 Modal * (手動 QueueKey) * @param ModalComponent * @param queueKey * @param args * @param onHide */ _(this, "showWithKey", (r, o, a, s) => { this.setState((u) => { this.typeProps.onShow && this.typeProps.onShow(o); const c = u.rows.findIndex((b) => b.queueKey === o); if (c === -1) return { rows: [...u.rows, { queueKey: o, ModalComponent: r, args: a, onHide: s }] }; const m = [...u.rows]; return m[c] = { queueKey: o, ModalComponent: r, args: a }, { rows: m }; }); }); /** * 隱藏 Modal * @param queueKey */ _(this, "hide", (r) => { this.setState((o) => { const a = o.rows.findIndex((u) => u.queueKey === r); if (a === -1) return o; const s = o.rows[a]; return s != null && s.onHide && s.onHide(r), { rows: lt(o.rows, a) }; }), this.typeProps.onHide && this.typeProps.onHide(r); }); /** * 隱藏所有 Modal */ _(this, "hideAll", (r) => { this.setState((o) => ({ rows: o.rows.filter((s) => r == null ? void 0 : r.includes(s.queueKey)) })); }); S = { show: this.show, showWithKey: this.showWithKey, hide: this.hide, hideAll: this.hideAll }; } get typeProps() { return this.props; } /** * 渲染項目 */ renderItems() { const { rows: r } = this.state; return r.map((o) => /* @__PURE__ */ p.jsx( O.Provider, { value: { queueKey: o.queueKey, hide: async () => { this.hide(o.queueKey); } }, children: /* @__PURE__ */ p.jsx( o.ModalComponent, { ...o.args }, o.queueKey ) }, o.queueKey )); } render() { return /* @__PURE__ */ p.jsxs( be.Provider, { value: { hide: this.hide, hideAll: this.hideAll }, children: [ this.props.children, /* @__PURE__ */ p.jsx( he, { id: this.typeProps.id, className: Qe.root, containerSelector: this.typeProps.containerSelector, children: /* @__PURE__ */ p.jsx(pe, { mode: this.typeProps.animatePresenceMode, children: this.renderItems() }) } ) ] } ); } } _(pt, "defaultProps", { id: ye }); const we = "acrool__modal-open", xe = "acrool__modal-open-fixed"; function ht(e, t = !1) { dt(document.body, t ? `${xe}__${e}` : `${we}__${e}`); } function yt(e, t = !1) { ft(document.body, t ? `${xe}__${e}` : `${we}__${e}`); } const U = { disableBodyScroll: ht, enableBodyScroll: yt }; function Ee(e) { var t, r, o = ""; if (typeof e == "string" || typeof e == "number") o += e; else if (typeof e == "object") if (Array.isArray(e)) { var a = e.length; for (t = 0; t < a; t++) e[t] && (r = Ee(e[t])) && (o && (o += " "), o += r); } else for (r in e) e[r] && (o && (o += " "), o += r); return o; } function le() { for (var e, t, r = 0, o = "", a = arguments.length; r < a; r++) (e = arguments[r]) && (t = Ee(e)) && (o && (o += " "), o += t); return o; } const bt = "acrool-react-modal__motion-drawer", wt = "acrool-react-modal__fixedDisabled", xt = "acrool-react-modal__motion-mask-wrapper", Et = "acrool-react-modal__motion-animation-wrapper", M = { motionDrawer: bt, fixedDisabled: wt, motionMaskWrapper: xt, motionAnimationWrapper: Et }, _t = { animation: { variants: { initial: { opacity: 0, transition: { type: "spring" } }, animate: { opacity: 1 }, exit: { opacity: 0 } }, transition: { duration: 0.2 } } }, vt = ({ modalOptions: e, children: t }, r) => { const { style: o, className: a, isMaskHidden: s, isHideWithMaskClick: u, isBodyScrollEnable: c, isFixedDisabled: m, animation: b } = e ?? { className: "" }, h = Ye(), w = De(), { hide: v } = et(); $(() => { c || (w ? U.disableBodyScroll(h) : U.enableBodyScroll(h)); }, [w]), $(() => () => { c || U.enableBodyScroll(h); }, []); const N = () => mt(b) ? t : /* @__PURE__ */ p.jsx( ne.div, { transition: { type: "spring", duration: 0.2 }, className: le(M.motionAnimationWrapper, a), style: o, ...b, initial: "initial", animate: "animate", exit: "exit", children: t } ), W = () => { if (!s) return /* @__PURE__ */ p.jsx( ne.div, { className: M.motionMaskWrapper, ..._t.animation, initial: "initial", animate: "animate", exit: "exit", "data-enable-click": u, onClick: u ? v : void 0 } ); }; return /* @__PURE__ */ p.jsxs("div", { className: le(M.motionDrawer, { [M.fixedDisabled]: m }), ref: r, children: [ W(), N() ] }); }, _e = Y.forwardRef(vt); function Yt(e, t) { return (o) => { const [a, s] = ue(!0), u = Oe(null), c = (t == null ? void 0 : t.queueKey) ?? V(); $(() => { var h; return (h = t == null ? void 0 : t._effect) != null && h.onShow && t._effect.onShow(c), () => { var w; (w = t == null ? void 0 : t._effect) != null && w.onHide && t._effect.onHide(c); }; }, []); const m = () => { u.current && u.current(); }, b = We(async () => new Promise((h) => { u.current = h, s(!1); }), []); return /* @__PURE__ */ p.jsx( O.Provider, { value: { hide: b, queueKey: c }, children: /* @__PURE__ */ p.jsx( Ze, { containerSelector: () => document.getElementById(ye), children: /* @__PURE__ */ p.jsx( pe, { mode: t == null ? void 0 : t.animatePresenceMode, onExitComplete: m, children: a && /* @__PURE__ */ p.jsx(_e, { modalOptions: t, children: /* @__PURE__ */ p.jsx(e, { ...o }) }) } ) } ) } ); }; } function Ot(e, t) { const { _effect: r, ...o } = t ?? {}, a = (c) => /* @__PURE__ */ p.jsx(_e, { modalOptions: o, children: /* @__PURE__ */ p.jsx(e, { ...c }) }); function s(c) { const m = V(); c ? S.showWithKey(a, m, c, r == null ? void 0 : r.onHide) : S.showWithKey(a, m, void 0, r == null ? void 0 : r.onHide), r != null && r.onShow && r.onShow(m); } function u(c, m) { m ? S.showWithKey(a, c, m, r == null ? void 0 : r.onHide) : S.showWithKey(a, c, void 0, r == null ? void 0 : r.onHide), r != null && r.onShow && r.onShow(c); } return a.show = s, a.showWithKey = u, a; } const E = { initial: "initial", animate: "animate", exit: "exit" }, gt = (e = 20, t = "calc(40px + env(safe-area-inset-top))") => ({ ...E, variants: { initial: { position: "absolute", left: "50%", opacity: 0, x: "-50%", y: e }, animate: { opacity: 1, y: t, transition: { type: "just", duration: 0.2 } }, exit: { opacity: 0, y: e } } }), Rt = (e = 20) => ({ ...E, variants: { initial: { position: "absolute", left: "50%", top: "50%", opacity: 0, x: "-50%", y: `calc(-50% - ${e}px)` }, animate: { opacity: 1, y: "-50%", transition: { type: "just", duration: 0.2 } }, exit: { opacity: 0, y: "-50%" } } }), Pt = { ...E, variants: { initial: { scaleX: 0.5, scaleY: 0.5, scaleZ: 0.8, translateX: 0, translateY: 20, translateZ: 0, opacity: 0 }, animate: { scaleX: 1, scaleY: 1, scaleZ: 1, translateX: 0, translateY: 40, translateZ: 0, opacity: 1, transition: { type: "just", duration: 0.2 } }, exit: { scaleX: 0.8, scaleY: 0.8, scaleZ: 0.8, translateX: 0, translateY: 20, translateZ: 0, opacity: 0, transition: { type: "spring" } } } }, St = { ...E, variants: { initial: { position: "absolute", top: "50%", left: "50%", scaleX: 0.5, scaleY: 0.5, scaleZ: 0.8, translateX: "-50%", translateY: "-50%", translateZ: 0, opacity: 0 }, animate: { scaleX: 1, scaleY: 1, scaleZ: 1, translateZ: 0, opacity: 1, transition: { type: "spring", duration: 0.4 } }, exit: { scaleX: 0.8, scaleY: 0.8, scaleZ: 0.8, translateZ: 0, opacity: 0 } }, transition: { damping: 0, duration: 0.2 } }, kt = { ...E, variants: { initial: { position: "fixed", top: 0, bottom: 0, right: 0, translateX: "100%", opacity: 0.9 }, animate: { translateX: 0, opacity: 1 }, exit: { translateX: "100%", opacity: 0.9 } }, transition: { damping: 0 } }, jt = { ...E, variants: { initial: { position: "fixed", top: 0, bottom: 0, left: 0, translateX: "-100%", opacity: 0.9 }, animate: { translateX: 0, opacity: 1 }, exit: { translateX: "-100%", opacity: 0.9 } }, transition: { damping: 0 } }, At = { ...E, variants: { initial: { position: "fixed", bottom: 0, left: 0, right: 0, translateY: "100%", opacity: 0.9 }, animate: { translateY: 0, opacity: 1 }, exit: { translateY: "100%", opacity: 0.9 } }, transition: { damping: 0, duration: 0.2 } }, Tt = { ...E, variants: { initial: { position: "fixed", top: "100%", left: 0, right: 0, opacity: 0.9 }, animate: { top: 0, opacity: 1, transition: { type: "just" } }, exit: { top: "100%", opacity: 0.9 } }, transition: { damping: 0 } }, Wt = { zoomInDown: Pt, zoomInCenter: St, generateFadeInFromTop: gt, generateFadeInFromTopCentered: Rt, slideRightInLeft: jt, slideLeftInRight: kt, slideUpInBottom: At, slideUpEndInBottom: Tt }; export { U as BodyScroll, pt as ModalProvider, Wt as animation, Ot as createModal, Yt as createStateModal, S as modal, $t as useGlobalModal, et as useModal };