modal-system 1.0.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/dist/index.js ADDED
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ ModalProvider: () => ModalProvider,
24
+ createModalHook: () => createModalHook,
25
+ defineModals: () => defineModals
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+
29
+ // src/core/provider.tsx
30
+ var import_react2 = require("react");
31
+
32
+ // src/core/context.ts
33
+ var import_react = require("react");
34
+ var ModalContext = (0, import_react.createContext)(null);
35
+ function useModalContext() {
36
+ const ctx = (0, import_react.useContext)(ModalContext);
37
+ if (!ctx) {
38
+ throw new Error(
39
+ "[modal-system] useModal must be called inside <ModalProvider>. Make sure you wrapped your app with <ModalProvider modals={MODALS}>."
40
+ );
41
+ }
42
+ return ctx;
43
+ }
44
+
45
+ // src/core/provider.tsx
46
+ var import_jsx_runtime = require("react/jsx-runtime");
47
+ var INITIAL_STATE = {
48
+ isOpen: false,
49
+ activeModal: void 0,
50
+ data: void 0
51
+ };
52
+ function ModalProvider({
53
+ modals,
54
+ children
55
+ }) {
56
+ const [state, setState] = (0, import_react2.useState)(INITIAL_STATE);
57
+ function _openModal(name, data) {
58
+ setState({ isOpen: true, activeModal: name, data });
59
+ }
60
+ function _closeModal() {
61
+ setState(INITIAL_STATE);
62
+ }
63
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ModalContext.Provider, { value: { ...state, _openModal, _closeModal }, children: [
64
+ children,
65
+ Object.entries(modals).map(([id, Component]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
66
+ Component,
67
+ {
68
+ isOpen: state.isOpen && state.activeModal === id,
69
+ onClose: _closeModal,
70
+ data: state.activeModal === id ? state.data : void 0
71
+ },
72
+ id
73
+ ))
74
+ ] });
75
+ }
76
+
77
+ // src/core/hook.ts
78
+ function createModalHook(_modals) {
79
+ return function useModal() {
80
+ const { _openModal, _closeModal } = useModalContext();
81
+ return {
82
+ /**
83
+ * Open a modal by name. The second argument must match the data
84
+ * interface of the registered component.
85
+ */
86
+ openModal: (name, data) => {
87
+ _openModal(name, data);
88
+ },
89
+ closeModal: _closeModal
90
+ };
91
+ };
92
+ }
93
+
94
+ // src/index.ts
95
+ function defineModals(modals) {
96
+ return modals;
97
+ }
98
+ // Annotate the CommonJS export names for ESM import in node:
99
+ 0 && (module.exports = {
100
+ ModalProvider,
101
+ createModalHook,
102
+ defineModals
103
+ });
104
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/provider.tsx","../src/core/context.ts","../src/core/hook.ts"],"sourcesContent":["// ─── Public API ────────────────────────────────────────────────────────────────\n\nexport { ModalProvider } from \"./core/provider\";\nexport { createModalHook } from \"./core/hook\";\n\n// Types\nexport type { BaseModalProps, ModalRegistry, ModalDataMap } from \"./core/types\";\n\n/**\n * Helper that returns its argument unchanged but enforces the ModalRegistry constraint.\n * Use this when defining your MODALS object to get inference + type checking.\n *\n * @example\n * export const MODALS = defineModals({\n * confirm: ConfirmModal,\n * upload: UploadModal,\n * })\n */\nexport function defineModals<T extends import(\"./core/types\").ModalRegistry>(modals: T): T {\n return modals;\n}\n","import React, { useState } from \"react\";\nimport { ModalContext } from \"./context\";\nimport type { ModalRegistry, ModalState } from \"./types\";\n\ninterface ModalProviderProps<T extends ModalRegistry> {\n modals: T;\n children: React.ReactNode;\n}\n\nconst INITIAL_STATE: ModalState = {\n isOpen: false,\n activeModal: undefined,\n data: undefined,\n};\n\n/**\n * Wrap your application root with this provider.\n *\n * @example\n * import { ModalProvider } from \"modal-system\"\n * import { MODALS } from \"./modals\"\n *\n * <ModalProvider modals={MODALS}>\n * <App />\n * </ModalProvider>\n */\nexport function ModalProvider<T extends ModalRegistry>({\n modals,\n children,\n}: ModalProviderProps<T>) {\n const [state, setState] = useState<ModalState>(INITIAL_STATE);\n\n function _openModal(name: string, data?: unknown) {\n setState({ isOpen: true, activeModal: name, data });\n }\n\n function _closeModal() {\n setState(INITIAL_STATE);\n }\n\n return (\n <ModalContext.Provider value={{ ...state, _openModal, _closeModal }}>\n {children}\n\n {Object.entries(modals).map(([id, Component]) => (\n <Component\n key={id}\n isOpen={state.isOpen && state.activeModal === id}\n onClose={_closeModal}\n data={state.activeModal === id ? state.data : undefined}\n />\n ))}\n </ModalContext.Provider>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { ModalContextValue } from \"./types\";\n\nexport const ModalContext = createContext<ModalContextValue | null>(null);\n\nexport function useModalContext(): ModalContextValue {\n const ctx = useContext(ModalContext);\n if (!ctx) {\n throw new Error(\n \"[modal-system] useModal must be called inside <ModalProvider>. \" +\n \"Make sure you wrapped your app with <ModalProvider modals={MODALS}>.\"\n );\n }\n return ctx;\n}\n","import { useModalContext } from \"./context\";\nimport type { ModalRegistry, ModalDataMap } from \"./types\";\n\n/**\n * Factory that creates a fully type-safe `useModal` hook bound to your modals registry.\n *\n * @example\n * // modals/index.ts\n * export const MODALS = defineModals({ confirm: ConfirmModal })\n * export const useModal = createModalHook(MODALS)\n *\n * // SomeComponent.tsx\n * const { openModal, closeModal } = useModal()\n * openModal(\"confirm\", { title: \"Delete?\" }) // ← autocomplete on name + data shape\n */\nexport function createModalHook<T extends ModalRegistry>(_modals: T) {\n type DataMap = ModalDataMap<T>;\n\n return function useModal() {\n const { _openModal, _closeModal } = useModalContext();\n\n return {\n /**\n * Open a modal by name. The second argument must match the data\n * interface of the registered component.\n */\n openModal: <K extends keyof T & string>(\n name: K,\n data?: DataMap[K]\n ) => {\n _openModal(name, data);\n },\n\n closeModal: _closeModal,\n };\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAAgC;;;ACAhC,mBAA0C;AAGnC,IAAM,mBAAe,4BAAwC,IAAI;AAEjE,SAAS,kBAAqC;AACnD,QAAM,UAAM,yBAAW,YAAY;AACnC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AD2BI;AAhCJ,IAAM,gBAA4B;AAAA,EAChC,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AACR;AAaO,SAAS,cAAuC;AAAA,EACrD;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAqB,aAAa;AAE5D,WAAS,WAAW,MAAc,MAAgB;AAChD,aAAS,EAAE,QAAQ,MAAM,aAAa,MAAM,KAAK,CAAC;AAAA,EACpD;AAEA,WAAS,cAAc;AACrB,aAAS,aAAa;AAAA,EACxB;AAEA,SACE,6CAAC,aAAa,UAAb,EAAsB,OAAO,EAAE,GAAG,OAAO,YAAY,YAAY,GAC/D;AAAA;AAAA,IAEA,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS,MACzC;AAAA,MAAC;AAAA;AAAA,QAEC,QAAQ,MAAM,UAAU,MAAM,gBAAgB;AAAA,QAC9C,SAAS;AAAA,QACT,MAAM,MAAM,gBAAgB,KAAK,MAAM,OAAO;AAAA;AAAA,MAHzC;AAAA,IAIP,CACD;AAAA,KACH;AAEJ;;;AEvCO,SAAS,gBAAyC,SAAY;AAGnE,SAAO,SAAS,WAAW;AACzB,UAAM,EAAE,YAAY,YAAY,IAAI,gBAAgB;AAEpD,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,WAAW,CACT,MACA,SACG;AACH,mBAAW,MAAM,IAAI;AAAA,MACvB;AAAA,MAEA,YAAY;AAAA,IACd;AAAA,EACF;AACF;;;AHlBO,SAAS,aAA6D,QAAc;AACzF,SAAO;AACT;","names":["import_react"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,75 @@
1
+ // src/core/provider.tsx
2
+ import { useState } from "react";
3
+
4
+ // src/core/context.ts
5
+ import { createContext, useContext } from "react";
6
+ var ModalContext = createContext(null);
7
+ function useModalContext() {
8
+ const ctx = useContext(ModalContext);
9
+ if (!ctx) {
10
+ throw new Error(
11
+ "[modal-system] useModal must be called inside <ModalProvider>. Make sure you wrapped your app with <ModalProvider modals={MODALS}>."
12
+ );
13
+ }
14
+ return ctx;
15
+ }
16
+
17
+ // src/core/provider.tsx
18
+ import { jsx, jsxs } from "react/jsx-runtime";
19
+ var INITIAL_STATE = {
20
+ isOpen: false,
21
+ activeModal: void 0,
22
+ data: void 0
23
+ };
24
+ function ModalProvider({
25
+ modals,
26
+ children
27
+ }) {
28
+ const [state, setState] = useState(INITIAL_STATE);
29
+ function _openModal(name, data) {
30
+ setState({ isOpen: true, activeModal: name, data });
31
+ }
32
+ function _closeModal() {
33
+ setState(INITIAL_STATE);
34
+ }
35
+ return /* @__PURE__ */ jsxs(ModalContext.Provider, { value: { ...state, _openModal, _closeModal }, children: [
36
+ children,
37
+ Object.entries(modals).map(([id, Component]) => /* @__PURE__ */ jsx(
38
+ Component,
39
+ {
40
+ isOpen: state.isOpen && state.activeModal === id,
41
+ onClose: _closeModal,
42
+ data: state.activeModal === id ? state.data : void 0
43
+ },
44
+ id
45
+ ))
46
+ ] });
47
+ }
48
+
49
+ // src/core/hook.ts
50
+ function createModalHook(_modals) {
51
+ return function useModal() {
52
+ const { _openModal, _closeModal } = useModalContext();
53
+ return {
54
+ /**
55
+ * Open a modal by name. The second argument must match the data
56
+ * interface of the registered component.
57
+ */
58
+ openModal: (name, data) => {
59
+ _openModal(name, data);
60
+ },
61
+ closeModal: _closeModal
62
+ };
63
+ };
64
+ }
65
+
66
+ // src/index.ts
67
+ function defineModals(modals) {
68
+ return modals;
69
+ }
70
+ export {
71
+ ModalProvider,
72
+ createModalHook,
73
+ defineModals
74
+ };
75
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/provider.tsx","../src/core/context.ts","../src/core/hook.ts","../src/index.ts"],"sourcesContent":["import React, { useState } from \"react\";\nimport { ModalContext } from \"./context\";\nimport type { ModalRegistry, ModalState } from \"./types\";\n\ninterface ModalProviderProps<T extends ModalRegistry> {\n modals: T;\n children: React.ReactNode;\n}\n\nconst INITIAL_STATE: ModalState = {\n isOpen: false,\n activeModal: undefined,\n data: undefined,\n};\n\n/**\n * Wrap your application root with this provider.\n *\n * @example\n * import { ModalProvider } from \"modal-system\"\n * import { MODALS } from \"./modals\"\n *\n * <ModalProvider modals={MODALS}>\n * <App />\n * </ModalProvider>\n */\nexport function ModalProvider<T extends ModalRegistry>({\n modals,\n children,\n}: ModalProviderProps<T>) {\n const [state, setState] = useState<ModalState>(INITIAL_STATE);\n\n function _openModal(name: string, data?: unknown) {\n setState({ isOpen: true, activeModal: name, data });\n }\n\n function _closeModal() {\n setState(INITIAL_STATE);\n }\n\n return (\n <ModalContext.Provider value={{ ...state, _openModal, _closeModal }}>\n {children}\n\n {Object.entries(modals).map(([id, Component]) => (\n <Component\n key={id}\n isOpen={state.isOpen && state.activeModal === id}\n onClose={_closeModal}\n data={state.activeModal === id ? state.data : undefined}\n />\n ))}\n </ModalContext.Provider>\n );\n}\n","import { createContext, useContext } from \"react\";\nimport type { ModalContextValue } from \"./types\";\n\nexport const ModalContext = createContext<ModalContextValue | null>(null);\n\nexport function useModalContext(): ModalContextValue {\n const ctx = useContext(ModalContext);\n if (!ctx) {\n throw new Error(\n \"[modal-system] useModal must be called inside <ModalProvider>. \" +\n \"Make sure you wrapped your app with <ModalProvider modals={MODALS}>.\"\n );\n }\n return ctx;\n}\n","import { useModalContext } from \"./context\";\nimport type { ModalRegistry, ModalDataMap } from \"./types\";\n\n/**\n * Factory that creates a fully type-safe `useModal` hook bound to your modals registry.\n *\n * @example\n * // modals/index.ts\n * export const MODALS = defineModals({ confirm: ConfirmModal })\n * export const useModal = createModalHook(MODALS)\n *\n * // SomeComponent.tsx\n * const { openModal, closeModal } = useModal()\n * openModal(\"confirm\", { title: \"Delete?\" }) // ← autocomplete on name + data shape\n */\nexport function createModalHook<T extends ModalRegistry>(_modals: T) {\n type DataMap = ModalDataMap<T>;\n\n return function useModal() {\n const { _openModal, _closeModal } = useModalContext();\n\n return {\n /**\n * Open a modal by name. The second argument must match the data\n * interface of the registered component.\n */\n openModal: <K extends keyof T & string>(\n name: K,\n data?: DataMap[K]\n ) => {\n _openModal(name, data);\n },\n\n closeModal: _closeModal,\n };\n };\n}\n","// ─── Public API ────────────────────────────────────────────────────────────────\n\nexport { ModalProvider } from \"./core/provider\";\nexport { createModalHook } from \"./core/hook\";\n\n// Types\nexport type { BaseModalProps, ModalRegistry, ModalDataMap } from \"./core/types\";\n\n/**\n * Helper that returns its argument unchanged but enforces the ModalRegistry constraint.\n * Use this when defining your MODALS object to get inference + type checking.\n *\n * @example\n * export const MODALS = defineModals({\n * confirm: ConfirmModal,\n * upload: UploadModal,\n * })\n */\nexport function defineModals<T extends import(\"./core/types\").ModalRegistry>(modals: T): T {\n return modals;\n}\n"],"mappings":";AAAA,SAAgB,gBAAgB;;;ACAhC,SAAS,eAAe,kBAAkB;AAGnC,IAAM,eAAe,cAAwC,IAAI;AAEjE,SAAS,kBAAqC;AACnD,QAAM,MAAM,WAAW,YAAY;AACnC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AD2BI,SAII,KAJJ;AAhCJ,IAAM,gBAA4B;AAAA,EAChC,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AACR;AAaO,SAAS,cAAuC;AAAA,EACrD;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAqB,aAAa;AAE5D,WAAS,WAAW,MAAc,MAAgB;AAChD,aAAS,EAAE,QAAQ,MAAM,aAAa,MAAM,KAAK,CAAC;AAAA,EACpD;AAEA,WAAS,cAAc;AACrB,aAAS,aAAa;AAAA,EACxB;AAEA,SACE,qBAAC,aAAa,UAAb,EAAsB,OAAO,EAAE,GAAG,OAAO,YAAY,YAAY,GAC/D;AAAA;AAAA,IAEA,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS,MACzC;AAAA,MAAC;AAAA;AAAA,QAEC,QAAQ,MAAM,UAAU,MAAM,gBAAgB;AAAA,QAC9C,SAAS;AAAA,QACT,MAAM,MAAM,gBAAgB,KAAK,MAAM,OAAO;AAAA;AAAA,MAHzC;AAAA,IAIP,CACD;AAAA,KACH;AAEJ;;;AEvCO,SAAS,gBAAyC,SAAY;AAGnE,SAAO,SAAS,WAAW;AACzB,UAAM,EAAE,YAAY,YAAY,IAAI,gBAAgB;AAEpD,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,WAAW,CACT,MACA,SACG;AACH,mBAAW,MAAM,IAAI;AAAA,MACvB;AAAA,MAEA,YAAY;AAAA,IACd;AAAA,EACF;AACF;;;AClBO,SAAS,aAA6D,QAAc;AACzF,SAAO;AACT;","names":[]}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "modal-system",
3
+ "version": "1.0.0",
4
+ "description": "Type-safe modal management system for React with DaisyUI and shadcn/ui support",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "bin": {
16
+ "modal-system": "dist/cli/index.js"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "peerDependencies": {
27
+ "react": ">=18",
28
+ "react-dom": ">=18"
29
+ },
30
+ "dependencies": {
31
+ "@clack/prompts": "^0.7.0",
32
+ "picocolors": "^1.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.19.39",
36
+ "@types/react": "^18.0.0",
37
+ "@types/react-dom": "^18.0.0",
38
+ "tsup": "^8.0.0",
39
+ "typescript": "^5.0.0"
40
+ }
41
+ }