@djangocfg/ui-core 2.1.415 → 2.1.416

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-core",
3
- "version": "2.1.415",
3
+ "version": "2.1.416",
4
4
  "description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -95,7 +95,7 @@
95
95
  "check": "tsc --noEmit"
96
96
  },
97
97
  "peerDependencies": {
98
- "@djangocfg/i18n": "^2.1.415",
98
+ "@djangocfg/i18n": "^2.1.416",
99
99
  "consola": "^3.4.2",
100
100
  "lucide-react": "^0.545.0",
101
101
  "moment": "^2.30.1",
@@ -166,8 +166,8 @@
166
166
  "vaul": "1.1.2"
167
167
  },
168
168
  "devDependencies": {
169
- "@djangocfg/i18n": "^2.1.415",
170
- "@djangocfg/typescript-config": "^2.1.415",
169
+ "@djangocfg/i18n": "^2.1.416",
170
+ "@djangocfg/typescript-config": "^2.1.416",
171
171
  "@types/node": "^25.2.3",
172
172
  "@types/react": "^19.2.15",
173
173
  "@types/react-dom": "^19.2.3",
@@ -0,0 +1,59 @@
1
+ 'use client';
2
+
3
+ import type { DialogAPI } from './types';
4
+
5
+ /**
6
+ * Lazy accessor for the global `window.dialog` API installed by
7
+ * `<DialogProvider />`. Use this in any library code that needs to call
8
+ * `dialog.confirm` / `dialog.alert` / `dialog.prompt` from a non-React
9
+ * context (e.g. event handlers in `ui-tools` tools).
10
+ *
11
+ * Returns `null` (and warns once in dev) when:
12
+ * - we're rendering on the server (`typeof window === 'undefined'`)
13
+ * - the host app has not mounted `<DialogProvider />`, so `window.dialog`
14
+ * is missing.
15
+ *
16
+ * The caller must handle the `null` case — usually by bailing out of the
17
+ * action with a console warning. Library code must never throw if the
18
+ * provider is missing; consumers without it should still be able to
19
+ * import / render the component (just without CRUD flows).
20
+ *
21
+ * @example
22
+ * const dialog = getDialog();
23
+ * if (!dialog) return;
24
+ * const ok = await dialog.confirm({ title: 'Delete?', message: '…', variant: 'destructive' });
25
+ * if (ok) await onDelete();
26
+ */
27
+ export function getDialog(): DialogAPI | null {
28
+ if (typeof window === 'undefined') return null;
29
+ const api = (window as Window & { dialog?: DialogAPI }).dialog;
30
+ if (!api) {
31
+ if (process.env.NODE_ENV !== 'production' && !warnedMissing) {
32
+ warnedMissing = true;
33
+ // eslint-disable-next-line no-console
34
+ console.warn(
35
+ '[getDialog] window.dialog is not available — mount <DialogProvider /> at the app root.',
36
+ );
37
+ }
38
+ return null;
39
+ }
40
+ return api;
41
+ }
42
+
43
+ let warnedMissing = false;
44
+
45
+ /**
46
+ * Like `getDialog()` but throws when unavailable. Use sparingly — only in
47
+ * code paths where missing `window.dialog` is a developer error (e.g. an
48
+ * action explicitly triggered by user interaction in a feature that
49
+ * unconditionally requires dialogs).
50
+ */
51
+ export function requireDialog(): DialogAPI {
52
+ const api = getDialog();
53
+ if (!api) {
54
+ throw new Error(
55
+ 'requireDialog(): window.dialog is not available. Mount <DialogProvider /> at the app root.',
56
+ );
57
+ }
58
+ return api;
59
+ }
@@ -10,6 +10,9 @@ export type {
10
10
  // Store
11
11
  export { dialogStore, useDialogStore, initDialogAPI, showDialog } from './store';
12
12
 
13
+ // Imperative accessors for non-React code (library helpers, event handlers).
14
+ export { getDialog, requireDialog } from './getDialog';
15
+
13
16
  // Provider
14
17
  export { DialogProvider } from './DialogProvider';
15
18