@ai-matrx/kit 0.7.4 → 0.9.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/uuid.cjs ADDED
@@ -0,0 +1,35 @@
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/uuid.ts
21
+ var uuid_exports = {};
22
+ __export(uuid_exports, {
23
+ isRfc4122Uuid: () => isRfc4122Uuid,
24
+ isUuidShape: () => isUuidShape
25
+ });
26
+ module.exports = __toCommonJS(uuid_exports);
27
+ var UUID_SHAPE_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
28
+ var RFC_4122_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
29
+ function isUuidShape(value) {
30
+ return typeof value === "string" && UUID_SHAPE_RE.test(value);
31
+ }
32
+ function isRfc4122Uuid(value) {
33
+ return typeof value === "string" && RFC_4122_RE.test(value);
34
+ }
35
+ //# sourceMappingURL=uuid.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/uuid.ts"],"sourcesContent":["/**\n * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named\n * so that nobody can pick the wrong one by accident.\n *\n * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had\n * TWO different predicates both called `isUuid`, and the difference was\n * invisible at the call site:\n *\n * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).\n * Right for \"is this a database id or a slug?\", where a v7 id, a nil UUID\n * and a hand-made test fixture must all pass.\n * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally\n * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.\n * Right for a validation door on a public route, where the only ids that\n * should ever arrive are ones this system minted.\n *\n * They were never reconciled because there was no shared home; the census had\n * to allowlist two of them as \"provably a different capability\". Both now live\n * here, under names that say which is which, and `isUuid` is deliberately NOT\n * exported: a caller must choose.\n *\n * Note the strict predicate REJECTS values the lax one accepts, including the\n * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.\n * Never swap one for the other to make a test pass.\n */\n\n/** 8-4-4-4-12 hex, any version, any variant. */\nconst UUID_SHAPE_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 hex with an RFC-4122 version (1–5) and variant (8/9/a/b). */\nconst RFC_4122_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * True when `value` has UUID *shape* — the right question for \"did I get an\n * id or a slug?\". Accepts every UUID version plus the nil UUID.\n */\nexport function isUuidShape(value: unknown): value is string {\n return typeof value === \"string\" && UUID_SHAPE_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,\n * variant 8/9/a/b) — the right question for a validation door on a public\n * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.\n */\nexport function isRfc4122Uuid(value: unknown): value is string {\n return typeof value === \"string\" && RFC_4122_RE.test(value);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,IAAM,gBACJ;AAGF,IAAM,cACJ;AAMK,SAAS,YAAY,OAAiC;AAC3D,SAAO,OAAO,UAAU,YAAY,cAAc,KAAK,KAAK;AAC9D;AAOO,SAAS,cAAc,OAAiC;AAC7D,SAAO,OAAO,UAAU,YAAY,YAAY,KAAK,KAAK;AAC5D;","names":[]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named
3
+ * so that nobody can pick the wrong one by accident.
4
+ *
5
+ * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had
6
+ * TWO different predicates both called `isUuid`, and the difference was
7
+ * invisible at the call site:
8
+ *
9
+ * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).
10
+ * Right for "is this a database id or a slug?", where a v7 id, a nil UUID
11
+ * and a hand-made test fixture must all pass.
12
+ * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally
13
+ * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.
14
+ * Right for a validation door on a public route, where the only ids that
15
+ * should ever arrive are ones this system minted.
16
+ *
17
+ * They were never reconciled because there was no shared home; the census had
18
+ * to allowlist two of them as "provably a different capability". Both now live
19
+ * here, under names that say which is which, and `isUuid` is deliberately NOT
20
+ * exported: a caller must choose.
21
+ *
22
+ * Note the strict predicate REJECTS values the lax one accepts, including the
23
+ * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.
24
+ * Never swap one for the other to make a test pass.
25
+ */
26
+ /**
27
+ * True when `value` has UUID *shape* — the right question for "did I get an
28
+ * id or a slug?". Accepts every UUID version plus the nil UUID.
29
+ */
30
+ declare function isUuidShape(value: unknown): value is string;
31
+ /**
32
+ * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,
33
+ * variant 8/9/a/b) — the right question for a validation door on a public
34
+ * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.
35
+ */
36
+ declare function isRfc4122Uuid(value: unknown): value is string;
37
+
38
+ export { isRfc4122Uuid, isUuidShape };
package/dist/uuid.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named
3
+ * so that nobody can pick the wrong one by accident.
4
+ *
5
+ * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had
6
+ * TWO different predicates both called `isUuid`, and the difference was
7
+ * invisible at the call site:
8
+ *
9
+ * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).
10
+ * Right for "is this a database id or a slug?", where a v7 id, a nil UUID
11
+ * and a hand-made test fixture must all pass.
12
+ * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally
13
+ * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.
14
+ * Right for a validation door on a public route, where the only ids that
15
+ * should ever arrive are ones this system minted.
16
+ *
17
+ * They were never reconciled because there was no shared home; the census had
18
+ * to allowlist two of them as "provably a different capability". Both now live
19
+ * here, under names that say which is which, and `isUuid` is deliberately NOT
20
+ * exported: a caller must choose.
21
+ *
22
+ * Note the strict predicate REJECTS values the lax one accepts, including the
23
+ * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.
24
+ * Never swap one for the other to make a test pass.
25
+ */
26
+ /**
27
+ * True when `value` has UUID *shape* — the right question for "did I get an
28
+ * id or a slug?". Accepts every UUID version plus the nil UUID.
29
+ */
30
+ declare function isUuidShape(value: unknown): value is string;
31
+ /**
32
+ * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,
33
+ * variant 8/9/a/b) — the right question for a validation door on a public
34
+ * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.
35
+ */
36
+ declare function isRfc4122Uuid(value: unknown): value is string;
37
+
38
+ export { isRfc4122Uuid, isUuidShape };
package/dist/uuid.js ADDED
@@ -0,0 +1,14 @@
1
+ // src/uuid.ts
2
+ var UUID_SHAPE_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
3
+ var RFC_4122_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
4
+ function isUuidShape(value) {
5
+ return typeof value === "string" && UUID_SHAPE_RE.test(value);
6
+ }
7
+ function isRfc4122Uuid(value) {
8
+ return typeof value === "string" && RFC_4122_RE.test(value);
9
+ }
10
+ export {
11
+ isRfc4122Uuid,
12
+ isUuidShape
13
+ };
14
+ //# sourceMappingURL=uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/uuid.ts"],"sourcesContent":["/**\n * @ai-matrx/kit/uuid — the two UUID predicates the fleet actually uses, named\n * so that nobody can pick the wrong one by accident.\n *\n * WHY THIS FILE EXISTS (2026-09-07 duplication census, rows 6–8). The fleet had\n * TWO different predicates both called `isUuid`, and the difference was\n * invisible at the call site:\n *\n * - `@ai-matrx/associations/core`'s — a LAX shape check (8-4-4-4-12 hex).\n * Right for \"is this a database id or a slug?\", where a v7 id, a nil UUID\n * and a hand-made test fixture must all pass.\n * - Six matrx-frontend API doors' — a STRICT RFC-4122 check that additionally\n * pins the version nibble to `1-5` and the variant nibble to `8/9/a/b`.\n * Right for a validation door on a public route, where the only ids that\n * should ever arrive are ones this system minted.\n *\n * They were never reconciled because there was no shared home; the census had\n * to allowlist two of them as \"provably a different capability\". Both now live\n * here, under names that say which is which, and `isUuid` is deliberately NOT\n * exported: a caller must choose.\n *\n * Note the strict predicate REJECTS values the lax one accepts, including the\n * nil UUID `00000000-0000-0000-0000-000000000000` and every UUIDv6/v7/v8 id.\n * Never swap one for the other to make a test pass.\n */\n\n/** 8-4-4-4-12 hex, any version, any variant. */\nconst UUID_SHAPE_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** 8-4-4-4-12 hex with an RFC-4122 version (1–5) and variant (8/9/a/b). */\nconst RFC_4122_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\n/**\n * True when `value` has UUID *shape* — the right question for \"did I get an\n * id or a slug?\". Accepts every UUID version plus the nil UUID.\n */\nexport function isUuidShape(value: unknown): value is string {\n return typeof value === \"string\" && UUID_SHAPE_RE.test(value);\n}\n\n/**\n * True when `value` is a syntactically valid RFC-4122 UUID (version 1–5,\n * variant 8/9/a/b) — the right question for a validation door on a public\n * route. Stricter than {@link isUuidShape}: rejects the nil UUID and v6/v7/v8.\n */\nexport function isRfc4122Uuid(value: unknown): value is string {\n return typeof value === \"string\" && RFC_4122_RE.test(value);\n}\n"],"mappings":";AA2BA,IAAM,gBACJ;AAGF,IAAM,cACJ;AAMK,SAAS,YAAY,OAAiC;AAC3D,SAAO,OAAO,UAAU,YAAY,cAAc,KAAK,KAAK;AAC9D;AAOO,SAAS,cAAc,OAAiC;AAC7D,SAAO,OAAO,UAAU,YAAY,YAAY,KAAK,KAAK;AAC5D;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/kit",
3
- "version": "0.7.4",
3
+ "version": "0.9.0",
4
4
  "description": "The always-include AI Matrx kit: the little primitives every Matrx app speaks — autosave that never loses a keystroke, stale-response guards, clipboard with graceful fallbacks — one per subpath, tree-shaken to what you use.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -12,7 +12,6 @@
12
12
  "hooks",
13
13
  "autosave",
14
14
  "clipboard",
15
- "confirm-dialog",
16
15
  "toast",
17
16
  "ai-matrx",
18
17
  "url-state",
@@ -22,7 +21,13 @@
22
21
  "indexeddb",
23
22
  "tailwind-colors",
24
23
  "qr-code",
25
- "short-link"
24
+ "short-link",
25
+ "format",
26
+ "duration",
27
+ "file-size",
28
+ "escape-html",
29
+ "uuid",
30
+ "confirm-opener"
26
31
  ],
27
32
  "repository": {
28
33
  "type": "git",
@@ -121,16 +126,6 @@
121
126
  "default": "./dist/drafts.cjs"
122
127
  }
123
128
  },
124
- "./confirm": {
125
- "import": {
126
- "types": "./dist/confirm.d.ts",
127
- "default": "./dist/confirm.js"
128
- },
129
- "require": {
130
- "types": "./dist/confirm.d.cts",
131
- "default": "./dist/confirm.cjs"
132
- }
133
- },
134
129
  "./confirm-opener": {
135
130
  "import": {
136
131
  "types": "./dist/confirm-opener.d.ts",
@@ -260,14 +255,42 @@
260
255
  "types": "./dist/short-link-react.d.cts",
261
256
  "default": "./dist/short-link-react.cjs"
262
257
  }
258
+ },
259
+ "./format": {
260
+ "import": {
261
+ "types": "./dist/format.d.ts",
262
+ "default": "./dist/format.js"
263
+ },
264
+ "require": {
265
+ "types": "./dist/format.d.cts",
266
+ "default": "./dist/format.cjs"
267
+ }
268
+ },
269
+ "./html-escape": {
270
+ "import": {
271
+ "types": "./dist/html-escape.d.ts",
272
+ "default": "./dist/html-escape.js"
273
+ },
274
+ "require": {
275
+ "types": "./dist/html-escape.d.cts",
276
+ "default": "./dist/html-escape.cjs"
277
+ }
278
+ },
279
+ "./uuid": {
280
+ "import": {
281
+ "types": "./dist/uuid.d.ts",
282
+ "default": "./dist/uuid.js"
283
+ },
284
+ "require": {
285
+ "types": "./dist/uuid.d.cts",
286
+ "default": "./dist/uuid.cjs"
287
+ }
263
288
  }
264
289
  },
265
290
  "dependencies": {
266
- "@radix-ui/react-alert-dialog": "^1.1.23",
267
291
  "idb": "^8.0.3",
268
292
  "json5": "^2.2.3",
269
- "jsqr": "^1.4.0",
270
- "tailwind-merge": "^3.6.0"
293
+ "jsqr": "^1.4.0"
271
294
  },
272
295
  "peerDependencies": {
273
296
  "react": ">=18.0.0"
package/dist/confirm.cjs DELETED
@@ -1,353 +0,0 @@
1
- "use client";
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // src/confirm.ts
32
- var confirm_exports = {};
33
- __export(confirm_exports, {
34
- ConfirmDialog: () => ConfirmDialog,
35
- ConfirmDialogHost: () => ConfirmDialogHost,
36
- confirm: () => confirm
37
- });
38
- module.exports = __toCommonJS(confirm_exports);
39
-
40
- // src/confirm/opener.ts
41
- var STATE_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.kit.confirm-opener-state");
42
- function getState() {
43
- const holder = globalThis;
44
- let state = holder[STATE_SLOT];
45
- if (!state) {
46
- state = { host: null, queue: [] };
47
- holder[STATE_SLOT] = state;
48
- }
49
- return state;
50
- }
51
- function _registerHost(controller) {
52
- const state = getState();
53
- state.host = controller;
54
- while (state.queue.length > 0) {
55
- const next = state.queue.shift();
56
- controller.show(next.opts, next.resolve);
57
- }
58
- }
59
- function _unregisterHost(controller) {
60
- const state = getState();
61
- if (state.host === controller) state.host = null;
62
- }
63
- function confirm(opts) {
64
- return new Promise((resolve) => {
65
- const state = getState();
66
- if (state.host) {
67
- state.host.show(opts, resolve);
68
- } else {
69
- state.queue.push({ opts, resolve });
70
- }
71
- });
72
- }
73
-
74
- // src/confirm/host.tsx
75
- var React3 = __toESM(require("react"), 1);
76
-
77
- // src/confirm/cn.ts
78
- var import_tailwind_merge = require("tailwind-merge");
79
- function cn(...values) {
80
- return (0, import_tailwind_merge.twMerge)(values.filter(Boolean).join(" "));
81
- }
82
-
83
- // src/confirm/alert-dialog.tsx
84
- var React2 = __toESM(require("react"), 1);
85
- var AlertDialogPrimitive = __toESM(require("@radix-ui/react-alert-dialog"), 1);
86
-
87
- // src/react-tree.ts
88
- var React = __toESM(require("react"), 1);
89
- var REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal");
90
- function treeContainsComponent(node, Component) {
91
- if (node == null || typeof node === "boolean") return false;
92
- if (Array.isArray(node)) {
93
- return node.some((child) => treeContainsComponent(child, Component));
94
- }
95
- if (React.isValidElement(node)) {
96
- if (node.type === Component) return true;
97
- const props = node.props;
98
- return props.children != null ? treeContainsComponent(props.children, Component) : false;
99
- }
100
- if (typeof node === "string" || typeof node === "number") return false;
101
- if (typeof node === "object" && node.$$typeof === REACT_PORTAL_TYPE) {
102
- return treeContainsComponent(
103
- node.children,
104
- Component
105
- );
106
- }
107
- if (typeof node === "object" && Symbol.iterator in node) {
108
- return Array.from(node).some(
109
- (child) => treeContainsComponent(child, Component)
110
- );
111
- }
112
- const runtimeProcess = globalThis.process;
113
- if (runtimeProcess?.env?.NODE_ENV !== "production") {
114
- const keys = typeof node === "object" ? ` with keys {${Object.keys(node).join(", ")}}` : "";
115
- console.error(
116
- `[treeContainsComponent] A non-renderable value${keys} is being passed as a React child. React will throw 'Objects are not valid as a React child' at the real render site. Stringify it (e.g. JSON.stringify) before rendering.`,
117
- node
118
- );
119
- }
120
- return false;
121
- }
122
-
123
- // src/confirm/alert-dialog.tsx
124
- var import_jsx_runtime = require("react/jsx-runtime");
125
- var buttonBase = "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 h-9 px-4 py-2";
126
- var buttonDefault = "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90";
127
- var buttonOutline = "border border-border bg-card shadow-sm hover:bg-accent hover:text-accent-foreground";
128
- var AlertDialog = AlertDialogPrimitive.Root;
129
- var AlertDialogPortal = AlertDialogPrimitive.Portal;
130
- var AlertDialogOverlay = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
131
- AlertDialogPrimitive.Overlay,
132
- {
133
- className: cn(
134
- "fixed inset-0 z-[10000] bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
135
- className
136
- ),
137
- ...props,
138
- ref
139
- }
140
- ));
141
- AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
142
- var AlertDialogContentPrimitive = React2.forwardRef(({ ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogPrimitive.Content, { ...props, ref, "aria-modal": "true" }));
143
- AlertDialogContentPrimitive.displayName = "AlertDialogContentPrimitive";
144
- var AlertDialogDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
145
- AlertDialogPrimitive.Description,
146
- {
147
- ref,
148
- className: cn("text-sm text-muted-foreground", className),
149
- ...props
150
- }
151
- ));
152
- AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
153
- var AlertDialogContent = React2.forwardRef(({ className, children, container, ...props }, ref) => {
154
- const hasDescription = treeContainsComponent(children, AlertDialogDescription) || treeContainsComponent(children, AlertDialogPrimitive.Description);
155
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AlertDialogPortal, { container: container ?? void 0, children: [
156
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogOverlay, {}),
157
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
158
- AlertDialogContentPrimitive,
159
- {
160
- ref,
161
- className: cn(
162
- "fixed left-[50%] top-[50%] z-[10000] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
163
- className
164
- ),
165
- ...props,
166
- children: [
167
- !hasDescription && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AlertDialogPrimitive.Description, { className: "sr-only", children: "Please confirm the action described in this dialog." }),
168
- children
169
- ]
170
- }
171
- )
172
- ] });
173
- });
174
- AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
175
- var AlertDialogHeader = ({
176
- className,
177
- ...props
178
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
179
- "div",
180
- {
181
- className: cn(
182
- "flex flex-col space-y-2 text-center sm:text-left",
183
- className
184
- ),
185
- ...props
186
- }
187
- );
188
- AlertDialogHeader.displayName = "AlertDialogHeader";
189
- var AlertDialogFooter = ({
190
- className,
191
- ...props
192
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
193
- "div",
194
- {
195
- className: cn(
196
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
197
- className
198
- ),
199
- ...props
200
- }
201
- );
202
- AlertDialogFooter.displayName = "AlertDialogFooter";
203
- var AlertDialogTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
204
- AlertDialogPrimitive.Title,
205
- {
206
- ref,
207
- className: cn("text-lg font-semibold", className),
208
- ...props
209
- }
210
- ));
211
- AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
212
- var AlertDialogAction = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
213
- AlertDialogPrimitive.Action,
214
- {
215
- ref,
216
- className: cn(buttonBase, buttonDefault, className),
217
- ...props
218
- }
219
- ));
220
- AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
221
- var AlertDialogCancel = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
222
- AlertDialogPrimitive.Cancel,
223
- {
224
- ref,
225
- className: cn(buttonBase, buttonOutline, "mt-2 sm:mt-0", className),
226
- ...props
227
- }
228
- ));
229
- AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
230
-
231
- // src/confirm/confirm-dialog.tsx
232
- var import_jsx_runtime2 = require("react/jsx-runtime");
233
- function SpinnerIcon({ className }) {
234
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
235
- "svg",
236
- {
237
- xmlns: "http://www.w3.org/2000/svg",
238
- width: 24,
239
- height: 24,
240
- viewBox: "0 0 24 24",
241
- fill: "none",
242
- stroke: "currentColor",
243
- strokeWidth: 2,
244
- strokeLinecap: "round",
245
- strokeLinejoin: "round",
246
- "aria-hidden": "true",
247
- className,
248
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
249
- }
250
- );
251
- }
252
- function ConfirmDialog({
253
- open,
254
- onOpenChange,
255
- title,
256
- description,
257
- content,
258
- contentClassName,
259
- confirmLabel = "Confirm",
260
- cancelLabel = "Cancel",
261
- variant = "default",
262
- busy = false,
263
- confirmDisabled = false,
264
- portalContainer,
265
- onConfirm
266
- }) {
267
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
268
- AlertDialogContent,
269
- {
270
- className: contentClassName,
271
- container: portalContainer ?? void 0,
272
- children: [
273
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(AlertDialogHeader, { children: [
274
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogTitle, { children: title }),
275
- description ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogDescription, { children: description }) : null
276
- ] }),
277
- content ?? null,
278
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(AlertDialogFooter, { children: [
279
- cancelLabel === null ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AlertDialogCancel, { className: "max-lg:min-h-11", disabled: busy, children: cancelLabel }),
280
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
281
- AlertDialogAction,
282
- {
283
- disabled: busy || confirmDisabled,
284
- onClick: (event) => {
285
- event.preventDefault();
286
- void onConfirm();
287
- },
288
- className: cn(
289
- "max-lg:min-h-11",
290
- variant === "destructive" && "bg-destructive text-destructive-foreground hover:bg-destructive/90"
291
- ),
292
- children: [
293
- busy ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SpinnerIcon, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
294
- confirmLabel
295
- ]
296
- }
297
- )
298
- ] })
299
- ]
300
- }
301
- ) });
302
- }
303
-
304
- // src/confirm/host.tsx
305
- var import_jsx_runtime3 = require("react/jsx-runtime");
306
- function ConfirmDialogHost() {
307
- const [active, setActive] = React3.useState(null);
308
- const [tick, setTick] = React3.useState(0);
309
- const queueRef = React3.useRef([]);
310
- React3.useEffect(() => {
311
- const controller = {
312
- show: (opts, resolve) => {
313
- queueRef.current.push({ opts, resolve });
314
- setTick((n) => n + 1);
315
- }
316
- };
317
- _registerHost(controller);
318
- return () => _unregisterHost(controller);
319
- }, []);
320
- React3.useEffect(() => {
321
- if (active === null && queueRef.current.length > 0) {
322
- setActive(queueRef.current.shift());
323
- }
324
- }, [active, tick]);
325
- const handleConfirm = React3.useCallback(() => {
326
- if (!active) return;
327
- active.resolve(true);
328
- setActive(null);
329
- }, [active]);
330
- const handleOpenChange = React3.useCallback(
331
- (open) => {
332
- if (!open && active) {
333
- active.resolve(false);
334
- setActive(null);
335
- }
336
- },
337
- [active]
338
- );
339
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
340
- ConfirmDialog,
341
- {
342
- open: !!active,
343
- onOpenChange: handleOpenChange,
344
- title: active?.opts.title ?? "",
345
- description: active?.opts.description,
346
- confirmLabel: active?.opts.confirmLabel,
347
- cancelLabel: active?.opts.cancelLabel,
348
- variant: active?.opts.variant,
349
- onConfirm: handleConfirm
350
- }
351
- );
352
- }
353
- //# sourceMappingURL=confirm.cjs.map