react-dialogger 1.1.146 → 1.2.2

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
@@ -91,6 +91,129 @@ Access them using dialog.deps.*`
91
91
 
92
92
 
93
93
 
94
+ # 🌉 Context Bridge (since v1.2.0)
95
+
96
+ > Opt-in mechanism that lets dialog bodies consume React `Context` values from
97
+ > the host application's main tree — without manual `inject/deps` plumbing for
98
+ > every Context.
99
+
100
+ #### Why it exists
101
+
102
+ react-dialogger mounts each dialog into its **own** React root via `createRoot(...)`.
103
+ This is by design (a dialog's lifetime is independent from the parent component
104
+ that opened it), but the side effect is that `useContext(...)` inside a dialog
105
+ body returns the `createContext` default (typically `null`) — Providers from the
106
+ host tree do not reach across roots.
107
+
108
+ The `inject` / `deps` API already solves this for explicit values. The Context
109
+ Bridge complements it for the cases where:
110
+
111
+ - you want to use existing hook-based code unchanged (`useContext(AppContext)`,
112
+ custom hooks like `useTheme`, `useAuth`, etc.) inside dialog bodies; or
113
+ - you have many Contexts to forward and listing them in every `inject({...})`
114
+ call is noisy.
115
+
116
+ The bridge is **opt-in and orthogonal to inject/deps** — existing dialogs that
117
+ do not opt in see zero behavior change.
118
+
119
+ #### Setup — one component, one place
120
+
121
+ Mount `<DialogContextHost contexts={[...]}/>` once in your app's main tree,
122
+ **beneath** every Provider you want to bridge:
123
+
124
+ ```jsx
125
+ import { DialogContextHost } from "react-dialogger";
126
+ import { AppContext } from "./contexts/AppContext";
127
+ import { ThemeContext } from "./contexts/ThemeContext";
128
+
129
+ function App() {
130
+ return (
131
+ <AppContextProvider>
132
+ <ThemeProvider>
133
+ {/* anywhere below the Providers you want to bridge */}
134
+ <DialogContextHost contexts={[AppContext, ThemeContext]} />
135
+
136
+ <Router>{/* ...your app... */}</Router>
137
+ </ThemeProvider>
138
+ </AppContextProvider>
139
+ );
140
+ }
141
+ ```
142
+
143
+ That is the entire setup. Every dialog opened from anywhere in the app from
144
+ this point on will see the bridged Context values inside its body — no
145
+ `setBody` wrapping, no `inject` calls for these Contexts.
146
+
147
+ #### Dialog body — unchanged
148
+
149
+ ```jsx
150
+ const MyDialogBody = ({ dialog }) => {
151
+ // Works exactly as if the body were rendered inside the host tree.
152
+ const app = React.useContext(AppContext);
153
+ const theme = React.useContext(ThemeContext);
154
+
155
+ return <div>Hello {app.user.name}</div>;
156
+ };
157
+
158
+ new Dialog(null, { /* opts */ })
159
+ .setHeader(() => "Greeting")
160
+ .setBody(d => <MyDialogBody dialog={d} />)
161
+ .show();
162
+ ```
163
+
164
+ #### Rules and gotchas
165
+
166
+ 1. **Place `<DialogContextHost/>` below every Provider you list.** `useContext(X)`
167
+ returns the createContext default if no `X.Provider` ancestor exists — so the
168
+ bridge would capture (and propagate) `null`. The fix is structural: position
169
+ the Host inside the relevant Providers.
170
+
171
+ 2. **If a bridged Context's Provider is only mounted in some pages, the bridge
172
+ delivers `null` from pages where it is unmounted.** Two ways to handle this:
173
+ - Mount the Provider higher up (e.g. at app root) so it is always present.
174
+ - Or wrap the dialog body locally with that Provider: the nearest Provider
175
+ wins, so a body-local Provider overrides the bridge's `null`.
176
+ ```jsx
177
+ .setBody(d => (
178
+ <ExpenseProvider> {/* fresh, only for this dialog */}
179
+ <MyExpenseBody dialog={d} />
180
+ </ExpenseProvider>
181
+ ))
182
+ ```
183
+
184
+ 3. **The bridge is transparent when not used.** Omit `<DialogContextHost/>` and
185
+ the internal wrapper detects the empty snapshot and renders children
186
+ unchanged. Existing pre-v1.2 projects upgrade with no code changes.
187
+
188
+ 4. **`inject` / `deps` still works.** Use it for primitive values, callbacks, or
189
+ anything you do not want as a full React Context. The bridge does not
190
+ replace it.
191
+
192
+ #### Architecture (for the curious)
193
+
194
+ ```
195
+ HOST REACT ROOT DIALOG ROOT (per Dialog.show())
196
+ +-----------------------+ +------------------------------+
197
+ | <AppContextProvider> | (internal) ContextProvide |
198
+ | <ThemeProvider> | +- AppContext.Provider |
199
+ | <DialogContextHost | | +- ThemeContext.Pr. |
200
+ | contexts={[X,Y]}/>|-- channel ->| | | +- DialogBase |
201
+ | <Router> | | | +- UserBody |
202
+ | ... | | | useContext(...)
203
+ +-----------------------+ +------------------------------+
204
+ |
205
+ v
206
+ globalDialogBridge (module singleton — pub/sub)
207
+ Host writes here, every open dialog reads from here
208
+ ```
209
+
210
+ `DialogContextHost` mounts one capture slot per registered Context, each calling
211
+ `useContext` exactly once and writing the value into the singleton channel.
212
+ Internally, every dialog body is wrapped with a Provider component that reads the
213
+ channel via `useSyncExternalStore` and re-supplies each Context as a `<Ctx.Provider>`
214
+ above the body. React's "nearest Provider wins" rule then makes hook-based code
215
+ in the body work transparently.
216
+
94
217
 
95
218
  # Why react-dialogger?
96
219
  > react-dialogger is built for React applications that need dynamic, runtime-managed dialogs rather than static JSX-based modals.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * DialogContextHost (PUBLIC)
3
+ * --------------------------
4
+ * Mounted ONCE in the host application's main React tree to enable the Context
5
+ * Bridge. Reads the current value of every Context listed in the `contexts` prop
6
+ * and publishes them to the internal pub/sub channel — opt-in dialog bodies
7
+ * automatically consume these values.
8
+ *
9
+ * The host component must be placed BELOW the Providers of every Context it
10
+ * intends to bridge — `useContext(X)` returns the createContext default
11
+ * (typically null) if no `X.Provider` ancestor exists.
12
+ *
13
+ * <AppProvider>
14
+ * <ThemeProvider>
15
+ * <DialogContextHost contexts={[AppContext, ThemeContext]} />
16
+ * <Router>...</Router>
17
+ * </ThemeProvider>
18
+ * </AppProvider>
19
+ *
20
+ * Renders nothing visible. Each bridged Context gets its own `CaptureSlot`
21
+ * subcomponent — this is intentional, so React's hook order stays stable even
22
+ * when the `contexts` prop changes shape (each slot calls `useContext` exactly
23
+ * once on its own).
24
+ */
25
+ import * as React from "react";
26
+ import { BridgedContext } from "./channel";
27
+ export interface DialogContextHostProps {
28
+ /**
29
+ * Contexts to bridge into every dialog opened by this package.
30
+ *
31
+ * Each Context's Provider must be an ancestor of this `DialogContextHost`
32
+ * element; otherwise the captured value will be the createContext default
33
+ * (typically null), which is harmless but means the bridge effectively does
34
+ * nothing for that Context.
35
+ */
36
+ contexts: ReadonlyArray<BridgedContext>;
37
+ }
38
+ /**
39
+ * Mount this once in the host application's main React tree, beneath every
40
+ * Provider whose Context you want to bridge to dialog bodies.
41
+ */
42
+ export declare const DialogContextHost: React.FC<DialogContextHostProps>;
43
+ export default DialogContextHost;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DialogContextHost = void 0;
37
+ var jsx_runtime_1 = require("react/jsx-runtime");
38
+ /**
39
+ * DialogContextHost (PUBLIC)
40
+ * --------------------------
41
+ * Mounted ONCE in the host application's main React tree to enable the Context
42
+ * Bridge. Reads the current value of every Context listed in the `contexts` prop
43
+ * and publishes them to the internal pub/sub channel — opt-in dialog bodies
44
+ * automatically consume these values.
45
+ *
46
+ * The host component must be placed BELOW the Providers of every Context it
47
+ * intends to bridge — `useContext(X)` returns the createContext default
48
+ * (typically null) if no `X.Provider` ancestor exists.
49
+ *
50
+ * <AppProvider>
51
+ * <ThemeProvider>
52
+ * <DialogContextHost contexts={[AppContext, ThemeContext]} />
53
+ * <Router>...</Router>
54
+ * </ThemeProvider>
55
+ * </AppProvider>
56
+ *
57
+ * Renders nothing visible. Each bridged Context gets its own `CaptureSlot`
58
+ * subcomponent — this is intentional, so React's hook order stays stable even
59
+ * when the `contexts` prop changes shape (each slot calls `useContext` exactly
60
+ * once on its own).
61
+ */
62
+ var React = __importStar(require("react"));
63
+ var channel_1 = require("./channel");
64
+ /**
65
+ * Internal: a single capture point for ONE Context. Calls `useContext(ctx)` and
66
+ * writes the value into the channel whenever it changes.
67
+ *
68
+ * We copy-then-mutate-then-publish so concurrent slots do not clobber each
69
+ * other's entries in the shared snapshot.
70
+ */
71
+ var CaptureSlot = function (_a) {
72
+ var ctx = _a.ctx, channel = _a.channel;
73
+ var value = React.useContext(ctx);
74
+ React.useEffect(function () {
75
+ var next = new Map(channel.getSnapshot());
76
+ next.set(ctx, value);
77
+ channel.setSnapshot(next);
78
+ }, [ctx, value, channel]);
79
+ return null;
80
+ };
81
+ /**
82
+ * Mount this once in the host application's main React tree, beneath every
83
+ * Provider whose Context you want to bridge to dialog bodies.
84
+ */
85
+ var DialogContextHost = function (_a) {
86
+ var contexts = _a.contexts;
87
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: contexts.map(function (Ctx, i) { return ((0, jsx_runtime_1.jsx)(CaptureSlot, { ctx: Ctx, channel: channel_1.globalDialogBridge }, i)); }) }));
88
+ };
89
+ exports.DialogContextHost = DialogContextHost;
90
+ exports.default = exports.DialogContextHost;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * DialogContextProvide (INTERNAL)
3
+ * -------------------------------
4
+ * NOT part of the public API. The Dialog model wraps every body with this
5
+ * component automatically — host applications must not import or use it.
6
+ *
7
+ * Subscribes to `globalDialogBridge`, reads the current snapshot, and re-supplies
8
+ * every captured Context as a Provider above `children`. React's nearest-Provider
9
+ * rule means the dialog body sees these values as if it lived inside the host
10
+ * tree.
11
+ *
12
+ * If the channel snapshot is empty (no `<DialogContextHost/>` mounted, or empty
13
+ * `contexts` prop), this component is a transparent pass-through — zero
14
+ * Providers wrapped, zero behavior change. This is the backwards-compatibility
15
+ * guarantee for existing users who do not opt into the bridge.
16
+ *
17
+ * Override semantics: dialog body authors may wrap their own component in an
18
+ * additional `<X.Provider>` to override the bridged value for that Context. The
19
+ * nearest Provider wins. This is the recommended pattern when the bridged value
20
+ * is null (because the source Provider is not mounted in the host tree at the
21
+ * moment the dialog opens).
22
+ */
23
+ import * as React from "react";
24
+ interface DialogContextProvideProps {
25
+ children: React.ReactNode;
26
+ }
27
+ export declare const DialogContextProvide: React.FC<DialogContextProvideProps>;
28
+ export default DialogContextProvide;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DialogContextProvide = void 0;
37
+ var jsx_runtime_1 = require("react/jsx-runtime");
38
+ /**
39
+ * DialogContextProvide (INTERNAL)
40
+ * -------------------------------
41
+ * NOT part of the public API. The Dialog model wraps every body with this
42
+ * component automatically — host applications must not import or use it.
43
+ *
44
+ * Subscribes to `globalDialogBridge`, reads the current snapshot, and re-supplies
45
+ * every captured Context as a Provider above `children`. React's nearest-Provider
46
+ * rule means the dialog body sees these values as if it lived inside the host
47
+ * tree.
48
+ *
49
+ * If the channel snapshot is empty (no `<DialogContextHost/>` mounted, or empty
50
+ * `contexts` prop), this component is a transparent pass-through — zero
51
+ * Providers wrapped, zero behavior change. This is the backwards-compatibility
52
+ * guarantee for existing users who do not opt into the bridge.
53
+ *
54
+ * Override semantics: dialog body authors may wrap their own component in an
55
+ * additional `<X.Provider>` to override the bridged value for that Context. The
56
+ * nearest Provider wins. This is the recommended pattern when the bridged value
57
+ * is null (because the source Provider is not mounted in the host tree at the
58
+ * moment the dialog opens).
59
+ */
60
+ var React = __importStar(require("react"));
61
+ var channel_1 = require("./channel");
62
+ var DialogContextProvide = function (_a) {
63
+ var children = _a.children;
64
+ var subscribe = React.useCallback(function (cb) { return channel_1.globalDialogBridge.subscribe(cb); }, []);
65
+ var getSnapshot = React.useCallback(function () { return channel_1.globalDialogBridge.getSnapshot(); }, []);
66
+ // useSyncExternalStore is React 18+. The package's peerDependencies already
67
+ // pin `react: ^18.2.0`, so this is safe.
68
+ var snapshot = React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
69
+ // Map iteration order follows insertion order; the FIRST inserted Context
70
+ // becomes the OUTERMOST Provider, the LAST inserted is nearest to children.
71
+ // For host-body overrides (a body wrapping its own <X.Provider>), the body's
72
+ // wrap is even closer to the consumer than this layer, so it wins regardless
73
+ // of which slot inserted X here.
74
+ var node = children;
75
+ snapshot.forEach(function (value, Ctx) {
76
+ node = (0, jsx_runtime_1.jsx)(Ctx.Provider, { value: value, children: node });
77
+ });
78
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: node });
79
+ };
80
+ exports.DialogContextProvide = DialogContextProvide;
81
+ exports.default = exports.DialogContextProvide;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * DialogBridgeChannel
3
+ * -------------------
4
+ * Internal pub/sub channel used by the Context Bridge.
5
+ *
6
+ * react-dialogger mounts each dialog into its OWN React root via `createRoot(...)`,
7
+ * which makes it impossible for the dialog body to consume Context values from the
8
+ * host application's tree using `useContext(...)`.
9
+ *
10
+ * The Context Bridge solves this by:
11
+ * 1. Letting the host app declare a list of Contexts to bridge by mounting
12
+ * `<DialogContextHost contexts={[...]}/>` once in the main tree.
13
+ * 2. Capturing the value of each registered Context in the main tree and
14
+ * pushing it into this singleton channel.
15
+ * 3. Internally wrapping every dialog body with `<DialogContextProvide/>` which
16
+ * reads the channel and re-supplies each Context as a Provider in the dialog
17
+ * tree.
18
+ *
19
+ * Public API exposed via the package entry point: only `DialogContextHost`.
20
+ * This channel and `DialogContextProvide` are internal — host applications should
21
+ * never reach into them directly.
22
+ */
23
+ import * as React from "react";
24
+ /** A React Context whose value can be anything. The bridge is value-agnostic. */
25
+ export type BridgedContext = React.Context<any>;
26
+ /** A snapshot of all bridged Contexts' current values. */
27
+ export type ContextSnapshot = Map<BridgedContext, any>;
28
+ /**
29
+ * Pub/sub channel between the host capture component and per-dialog provide.
30
+ *
31
+ * One module-level singleton (`globalDialogBridge`) is shared across the entire
32
+ * application — host capture writes, every open dialog subscribes. This is safe
33
+ * because there is only ever one main React tree per application; if you have
34
+ * multiple isolated apps on a single page, they should each ship their own copy
35
+ * of this module via independent bundles.
36
+ */
37
+ export declare class DialogBridgeChannel {
38
+ private snapshot;
39
+ private listeners;
40
+ /** Replace the current snapshot and notify every subscriber. */
41
+ setSnapshot(next: ContextSnapshot): void;
42
+ /** Read the current snapshot. Safe to call from any tree. */
43
+ getSnapshot(): ContextSnapshot;
44
+ /** Subscribe to snapshot changes. Returns an unsubscribe function. */
45
+ subscribe(listener: () => void): () => void;
46
+ }
47
+ /**
48
+ * The single bridge channel. Capture (in host tree) writes; Provide (in every
49
+ * dialog tree) reads. Never re-instantiate — import this exact reference.
50
+ */
51
+ export declare const globalDialogBridge: DialogBridgeChannel;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * DialogBridgeChannel
4
+ * -------------------
5
+ * Internal pub/sub channel used by the Context Bridge.
6
+ *
7
+ * react-dialogger mounts each dialog into its OWN React root via `createRoot(...)`,
8
+ * which makes it impossible for the dialog body to consume Context values from the
9
+ * host application's tree using `useContext(...)`.
10
+ *
11
+ * The Context Bridge solves this by:
12
+ * 1. Letting the host app declare a list of Contexts to bridge by mounting
13
+ * `<DialogContextHost contexts={[...]}/>` once in the main tree.
14
+ * 2. Capturing the value of each registered Context in the main tree and
15
+ * pushing it into this singleton channel.
16
+ * 3. Internally wrapping every dialog body with `<DialogContextProvide/>` which
17
+ * reads the channel and re-supplies each Context as a Provider in the dialog
18
+ * tree.
19
+ *
20
+ * Public API exposed via the package entry point: only `DialogContextHost`.
21
+ * This channel and `DialogContextProvide` are internal — host applications should
22
+ * never reach into them directly.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.globalDialogBridge = exports.DialogBridgeChannel = void 0;
26
+ /**
27
+ * Pub/sub channel between the host capture component and per-dialog provide.
28
+ *
29
+ * One module-level singleton (`globalDialogBridge`) is shared across the entire
30
+ * application — host capture writes, every open dialog subscribes. This is safe
31
+ * because there is only ever one main React tree per application; if you have
32
+ * multiple isolated apps on a single page, they should each ship their own copy
33
+ * of this module via independent bundles.
34
+ */
35
+ var DialogBridgeChannel = /** @class */ (function () {
36
+ function DialogBridgeChannel() {
37
+ this.snapshot = new Map();
38
+ this.listeners = new Set();
39
+ }
40
+ /** Replace the current snapshot and notify every subscriber. */
41
+ DialogBridgeChannel.prototype.setSnapshot = function (next) {
42
+ this.snapshot = next;
43
+ this.listeners.forEach(function (l) { return l(); });
44
+ };
45
+ /** Read the current snapshot. Safe to call from any tree. */
46
+ DialogBridgeChannel.prototype.getSnapshot = function () {
47
+ return this.snapshot;
48
+ };
49
+ /** Subscribe to snapshot changes. Returns an unsubscribe function. */
50
+ DialogBridgeChannel.prototype.subscribe = function (listener) {
51
+ var _this = this;
52
+ this.listeners.add(listener);
53
+ return function () {
54
+ _this.listeners.delete(listener);
55
+ };
56
+ };
57
+ return DialogBridgeChannel;
58
+ }());
59
+ exports.DialogBridgeChannel = DialogBridgeChannel;
60
+ /**
61
+ * The single bridge channel. Capture (in host tree) writes; Provide (in every
62
+ * dialog tree) reads. Never re-instantiate — import this exact reference.
63
+ */
64
+ exports.globalDialogBridge = new DialogBridgeChannel();
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Bridge module — internal barrel.
3
+ *
4
+ * Only `DialogContextHost` is re-exported from the package root (`src/index.tsx`).
5
+ * `DialogContextProvide`, `globalDialogBridge`, and the channel class are
6
+ * intentionally internal — they are used by the Dialog model to wrap each
7
+ * dialog body, but host applications should never import them directly.
8
+ */
9
+ export { DialogContextHost } from "./DialogContextHost";
10
+ export type { DialogContextHostProps } from "./DialogContextHost";
11
+ export { DialogContextProvide } from "./DialogContextProvide";
12
+ export type { BridgedContext, ContextSnapshot } from "./channel";
13
+ export { DialogBridgeChannel, globalDialogBridge } from "./channel";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * Bridge module — internal barrel.
4
+ *
5
+ * Only `DialogContextHost` is re-exported from the package root (`src/index.tsx`).
6
+ * `DialogContextProvide`, `globalDialogBridge`, and the channel class are
7
+ * intentionally internal — they are used by the Dialog model to wrap each
8
+ * dialog body, but host applications should never import them directly.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.globalDialogBridge = exports.DialogBridgeChannel = exports.DialogContextProvide = exports.DialogContextHost = void 0;
12
+ var DialogContextHost_1 = require("./DialogContextHost");
13
+ Object.defineProperty(exports, "DialogContextHost", { enumerable: true, get: function () { return DialogContextHost_1.DialogContextHost; } });
14
+ // Internal — consumed by `models/Dialog.tsx` only.
15
+ var DialogContextProvide_1 = require("./DialogContextProvide");
16
+ Object.defineProperty(exports, "DialogContextProvide", { enumerable: true, get: function () { return DialogContextProvide_1.DialogContextProvide; } });
17
+ var channel_1 = require("./channel");
18
+ Object.defineProperty(exports, "DialogBridgeChannel", { enumerable: true, get: function () { return channel_1.DialogBridgeChannel; } });
19
+ Object.defineProperty(exports, "globalDialogBridge", { enumerable: true, get: function () { return channel_1.globalDialogBridge; } });
@@ -125,7 +125,9 @@ var PlaceholderWrapper = function (_a) {
125
125
  ? React.cloneElement(initialElement, __assign(__assign({}, dialog.dialogOptions.slotProps.loader), { values: dialog.values, inProcess: dialog.isInProcess() }))
126
126
  : null;
127
127
  var backgroundColor = (_c = dialogOptions.base.style.backgroundColor) !== null && _c !== void 0 ? _c : "#FFFFFF";
128
- return (0, jsx_runtime_1.jsx)("div", { className: 'dialog-content-placeholder', style: { display: inProcess.loading ? 'flex' : 'none', backgroundColor: backgroundColor }, children: LoaderSlotElement });
128
+ return (0, jsx_runtime_1.jsx)("div", { className: 'dialog-content-placeholder', style: { display: inProcess.loading ? 'flex' : 'none', backgroundColor: backgroundColor,
129
+ // @ts-ignore
130
+ zIndex: parseInt(dialog.getDom().style.zIndex) }, children: LoaderSlotElement });
129
131
  };
130
132
  // const DialogContentBody: React.FC<IContentBodyProps> = React.forwardRef(({
131
133
  // body
package/index.d.ts CHANGED
@@ -7,3 +7,5 @@ export { DialogProcessing, DialogCloseAction, DialogFullscreenAction, DialogActi
7
7
  export { DialogAction, ActionProgress, baseDialogOptions } from "./models";
8
8
  export { InitDialogMemoizeBounds } from "./helpers";
9
9
  export { IDialogApiDef, ActionApiDef } from './types';
10
+ export { DialogContextHost } from "./bridge";
11
+ export type { DialogContextHostProps } from "./bridge";
package/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InitDialogMemoizeBounds = exports.baseDialogOptions = exports.ActionProgress = exports.DialogAction = exports.DialogInfoAction = exports.DialogActionsWrapper = exports.DialogFullscreenAction = exports.DialogCloseAction = exports.DialogProcessing = exports.default = void 0;
6
+ exports.DialogContextHost = exports.InitDialogMemoizeBounds = exports.baseDialogOptions = exports.ActionProgress = exports.DialogAction = exports.DialogInfoAction = exports.DialogActionsWrapper = exports.DialogFullscreenAction = exports.DialogCloseAction = exports.DialogProcessing = exports.default = void 0;
7
7
  require("./styles/dialog.css");
8
8
  require("./styles/dialog.action.css");
9
9
  require("./styles/circular-progress.css");
@@ -24,3 +24,9 @@ Object.defineProperty(exports, "baseDialogOptions", { enumerable: true, get: fun
24
24
  // Hooks
25
25
  var helpers_1 = require("./helpers");
26
26
  Object.defineProperty(exports, "InitDialogMemoizeBounds", { enumerable: true, get: function () { return helpers_1.InitDialogMemoizeBounds; } });
27
+ // Context Bridge — opt-in mechanism that lets dialog bodies consume Contexts
28
+ // from the host application's main React tree without manual inject/deps.
29
+ // Mount <DialogContextHost contexts={[...]}/> once in the main tree; nothing
30
+ // else is needed at dialog call sites. See ./bridge/* and README for details.
31
+ var bridge_1 = require("./bridge");
32
+ Object.defineProperty(exports, "DialogContextHost", { enumerable: true, get: function () { return bridge_1.DialogContextHost; } });
package/models/Dialog.js CHANGED
@@ -51,6 +51,10 @@ var React = __importStar(require("react"));
51
51
  var DialogBase_1 = __importDefault(require("../components/DialogBase"));
52
52
  var client_1 = require("react-dom/client");
53
53
  var appLogger_1 = require("../helpers/appLogger");
54
+ // Internal Context Bridge wrapper. Wraps every dialog body so that Contexts
55
+ // registered via <DialogContextHost/> in the host tree flow into the dialog
56
+ // tree. No behavior change when no host is mounted (empty snapshot → no-op).
57
+ var bridge_1 = require("../bridge");
54
58
  var Dialog = /** @class */ (function () {
55
59
  // private _initialValues :Dialogify<V>;
56
60
  function Dialog(dialogRef, options, _initialValues, _inject) {
@@ -240,10 +244,20 @@ var Dialog = /** @class */ (function () {
240
244
  // >, props ) );
241
245
  // root.render( React.createElement( DialogBase as React.ComponentType<BaseDialogProps<Values, I>>, props ) );
242
246
  var element = React.createElement(DialogBase_1.default, props);
247
+ // Internal Context Bridge: every dialog body is wrapped so that Contexts
248
+ // registered by the host application via <DialogContextHost/> flow into
249
+ // the dialog's React root. If no host is mounted (or its contexts list
250
+ // is empty), the snapshot is empty and DialogContextProvide passes
251
+ // children through untouched — zero behavior change for existing users
252
+ // who do not opt into the bridge.
253
+ var bridged = React.createElement(bridge_1.DialogContextProvide, null, element);
243
254
  // Wrapper varsa sar, yoksa direkt render
255
+ // Sıralama: globalWrapper (kullanıcı tanımlı) en dışta, ardından bridge,
256
+ // en içte gerçek dialog ağacı. Bu sayede globalWrapper'ın eklediği
257
+ // Provider'ları bridge override edebilir (en yakın Provider kuralı).
244
258
  root.render(Dialog._globalWrapper
245
- ? React.createElement(Dialog._globalWrapper, null, element)
246
- : element);
259
+ ? React.createElement(Dialog._globalWrapper, null, bridged)
260
+ : bridged);
247
261
  };
248
262
  return Dialog;
249
263
  }());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-dialogger",
3
- "version": "1.1.146",
3
+ "version": "1.2.2",
4
4
  "description": "This package is a continuation of the react-araci package. Due to an error, react-araci was removed, and it has been decided to continue under the new package name react-dialogger",
5
5
  "main": "index.js",
6
6
  "author": "Sueleyman Topaloglu",