@agentconsent/react 0.1.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,2243 @@
1
+ // src/action-preview/action-preview.tsx
2
+ import * as React from "react";
3
+ import * as AlertDialog from "@radix-ui/react-alert-dialog";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var ActionPreviewContext = React.createContext(null);
6
+ function useActionPreviewContext(part) {
7
+ const ctx = React.useContext(ActionPreviewContext);
8
+ if (!ctx) {
9
+ throw new Error(
10
+ `ActionPreview.${part} must be rendered inside ActionPreview.Root`
11
+ );
12
+ }
13
+ return ctx;
14
+ }
15
+ var Root2 = React.forwardRef(
16
+ function ActionPreviewRoot({
17
+ onApprove,
18
+ onReject,
19
+ consequence = "reversible",
20
+ asModal = false,
21
+ open,
22
+ onOpenChange,
23
+ children,
24
+ ...rest
25
+ }, ref) {
26
+ const titleId = React.useId();
27
+ const ctx = React.useMemo(
28
+ () => ({ consequence, onApprove, onReject, asModal, titleId }),
29
+ [consequence, onApprove, onReject, asModal, titleId]
30
+ );
31
+ if (asModal) {
32
+ return /* @__PURE__ */ jsx(ActionPreviewContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(AlertDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(AlertDialog.Portal, { children: [
33
+ /* @__PURE__ */ jsx(AlertDialog.Overlay, { "data-acp": "overlay" }),
34
+ /* @__PURE__ */ jsx(
35
+ AlertDialog.Content,
36
+ {
37
+ ref,
38
+ "data-acp": "root",
39
+ "data-modal": "",
40
+ "data-consequence": consequence,
41
+ "aria-describedby": void 0,
42
+ onEscapeKeyDown: onReject,
43
+ ...rest,
44
+ children
45
+ }
46
+ )
47
+ ] }) }) });
48
+ }
49
+ return /* @__PURE__ */ jsx(ActionPreviewContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(
50
+ "section",
51
+ {
52
+ ref,
53
+ role: "group",
54
+ "aria-labelledby": titleId,
55
+ "data-acp": "root",
56
+ "data-consequence": consequence,
57
+ ...rest,
58
+ children
59
+ }
60
+ ) });
61
+ }
62
+ );
63
+ function Header(props) {
64
+ useActionPreviewContext("Header");
65
+ return /* @__PURE__ */ jsx("div", { "data-acp": "header", ...props });
66
+ }
67
+ function Icon(props) {
68
+ useActionPreviewContext("Icon");
69
+ return /* @__PURE__ */ jsx("span", { "aria-hidden": true, "data-acp": "icon", ...props });
70
+ }
71
+ function Title2(props) {
72
+ const { asModal, titleId } = useActionPreviewContext("Title");
73
+ if (asModal) {
74
+ return /* @__PURE__ */ jsx(AlertDialog.Title, { "data-acp": "title", ...props });
75
+ }
76
+ return /* @__PURE__ */ jsx("h2", { id: titleId, "data-acp": "title", ...props });
77
+ }
78
+ function Fields(props) {
79
+ useActionPreviewContext("Fields");
80
+ return /* @__PURE__ */ jsx("dl", { "data-acp": "fields", ...props });
81
+ }
82
+ function Field({ label, children, ...rest }) {
83
+ useActionPreviewContext("Field");
84
+ return /* @__PURE__ */ jsxs("div", { "data-acp": "field", ...rest, children: [
85
+ /* @__PURE__ */ jsx("dt", { "data-acp": "field-label", children: label }),
86
+ /* @__PURE__ */ jsx("dd", { "data-acp": "field-value", children })
87
+ ] });
88
+ }
89
+ function Content2({
90
+ label,
91
+ defaultExpanded = false,
92
+ children,
93
+ ...rest
94
+ }) {
95
+ useActionPreviewContext("Content");
96
+ const [expanded, setExpanded] = React.useState(defaultExpanded);
97
+ const bodyId = React.useId();
98
+ return /* @__PURE__ */ jsxs("div", { "data-acp": "content", "data-expanded": expanded ? "" : void 0, ...rest, children: [
99
+ /* @__PURE__ */ jsx(
100
+ "button",
101
+ {
102
+ type: "button",
103
+ "data-acp": "content-toggle",
104
+ "aria-expanded": expanded,
105
+ "aria-controls": bodyId,
106
+ onClick: () => setExpanded((v) => !v),
107
+ children: label
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsx("div", { id: bodyId, "data-acp": "content-body", hidden: !expanded, children })
111
+ ] });
112
+ }
113
+ function Source({ agent, authority, children, ...rest }) {
114
+ useActionPreviewContext("Source");
115
+ return /* @__PURE__ */ jsxs("div", { "data-acp": "source", ...rest, children: [
116
+ /* @__PURE__ */ jsx("span", { "data-acp": "source-agent", children: agent }),
117
+ authority != null && /* @__PURE__ */ jsx("span", { "data-acp": "source-authority", children: authority }),
118
+ children
119
+ ] });
120
+ }
121
+ function Actions(props) {
122
+ useActionPreviewContext("Actions");
123
+ return /* @__PURE__ */ jsx("div", { "data-acp": "actions", ...props });
124
+ }
125
+ var Approve = React.forwardRef(
126
+ function ActionPreviewApprove({ onClick, ...rest }, ref) {
127
+ const { onApprove, asModal, consequence } = useActionPreviewContext("Approve");
128
+ const handleClick = (event) => {
129
+ onClick?.(event);
130
+ if (!event.defaultPrevented) onApprove();
131
+ };
132
+ const button = /* @__PURE__ */ jsx(
133
+ "button",
134
+ {
135
+ ref,
136
+ type: "button",
137
+ "data-acp": "approve",
138
+ "data-consequence": consequence,
139
+ onClick: handleClick,
140
+ ...rest
141
+ }
142
+ );
143
+ return asModal ? /* @__PURE__ */ jsx(AlertDialog.Action, { asChild: true, children: button }) : button;
144
+ }
145
+ );
146
+ var Reject = React.forwardRef(
147
+ function ActionPreviewReject({ onClick, ...rest }, ref) {
148
+ const { onReject, asModal } = useActionPreviewContext("Reject");
149
+ const handleClick = (event) => {
150
+ onClick?.(event);
151
+ if (!event.defaultPrevented) onReject();
152
+ };
153
+ const button = /* @__PURE__ */ jsx(
154
+ "button",
155
+ {
156
+ ref,
157
+ type: "button",
158
+ "data-acp": "reject",
159
+ onClick: handleClick,
160
+ ...rest
161
+ }
162
+ );
163
+ return asModal ? /* @__PURE__ */ jsx(AlertDialog.Cancel, { asChild: true, children: button }) : button;
164
+ }
165
+ );
166
+ var ActionPreview = {
167
+ Root: Root2,
168
+ Header,
169
+ Icon,
170
+ Title: Title2,
171
+ Fields,
172
+ Field,
173
+ Content: Content2,
174
+ Source,
175
+ Actions,
176
+ Approve,
177
+ Reject
178
+ };
179
+
180
+ // src/irreversibility-gate/irreversibility-gate.tsx
181
+ import * as React2 from "react";
182
+ import * as AlertDialog2 from "@radix-ui/react-alert-dialog";
183
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
184
+ var IrreversibilityGateContext = React2.createContext(null);
185
+ function useGateContext(part) {
186
+ const ctx = React2.useContext(IrreversibilityGateContext);
187
+ if (!ctx) {
188
+ throw new Error(
189
+ `IrreversibilityGate.${part} must be rendered inside IrreversibilityGate.Root`
190
+ );
191
+ }
192
+ return ctx;
193
+ }
194
+ var Root4 = React2.forwardRef(
195
+ function IrreversibilityGateRoot({
196
+ onConfirm,
197
+ onCancel,
198
+ severity = "irreversible",
199
+ confirmPhrase,
200
+ asModal = false,
201
+ open,
202
+ onOpenChange,
203
+ children,
204
+ ...rest
205
+ }, ref) {
206
+ const titleId = React2.useId();
207
+ const descId = React2.useId();
208
+ const fieldId = React2.useId();
209
+ const [typed, setTyped] = React2.useState("");
210
+ const requirePhrase = severity === "irreversible" && confirmPhrase ? confirmPhrase : null;
211
+ const canConfirm = requirePhrase === null || typed.trim() === requirePhrase;
212
+ const [prevOpen, setPrevOpen] = React2.useState(open);
213
+ if (asModal && open !== prevOpen) {
214
+ setPrevOpen(open);
215
+ if (open === false && typed !== "") setTyped("");
216
+ }
217
+ const ctx = React2.useMemo(
218
+ () => ({
219
+ severity,
220
+ onConfirm,
221
+ onCancel,
222
+ asModal,
223
+ titleId,
224
+ descId,
225
+ fieldId,
226
+ requirePhrase,
227
+ typed,
228
+ setTyped,
229
+ canConfirm
230
+ }),
231
+ [
232
+ severity,
233
+ onConfirm,
234
+ onCancel,
235
+ asModal,
236
+ titleId,
237
+ descId,
238
+ fieldId,
239
+ requirePhrase,
240
+ typed,
241
+ canConfirm
242
+ ]
243
+ );
244
+ if (asModal) {
245
+ return /* @__PURE__ */ jsx2(IrreversibilityGateContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx2(AlertDialog2.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs2(AlertDialog2.Portal, { children: [
246
+ /* @__PURE__ */ jsx2(AlertDialog2.Overlay, { "data-acp": "overlay" }),
247
+ /* @__PURE__ */ jsx2(
248
+ AlertDialog2.Content,
249
+ {
250
+ ref,
251
+ "data-acp": "root",
252
+ "data-gate": "",
253
+ "data-modal": "",
254
+ "data-severity": severity,
255
+ "aria-describedby": void 0,
256
+ onEscapeKeyDown: onCancel,
257
+ ...rest,
258
+ children
259
+ }
260
+ )
261
+ ] }) }) });
262
+ }
263
+ return /* @__PURE__ */ jsx2(IrreversibilityGateContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx2(
264
+ "section",
265
+ {
266
+ ref,
267
+ role: "group",
268
+ "aria-labelledby": titleId,
269
+ "data-acp": "root",
270
+ "data-gate": "",
271
+ "data-severity": severity,
272
+ ...rest,
273
+ children
274
+ }
275
+ ) });
276
+ }
277
+ );
278
+ function Header2(props) {
279
+ useGateContext("Header");
280
+ return /* @__PURE__ */ jsx2("div", { "data-acp": "header", ...props });
281
+ }
282
+ function Icon2(props) {
283
+ const { severity } = useGateContext("Icon");
284
+ return /* @__PURE__ */ jsx2("span", { "aria-hidden": true, "data-acp": "gate-icon", "data-severity": severity, ...props });
285
+ }
286
+ function Title4(props) {
287
+ const { asModal, titleId } = useGateContext("Title");
288
+ if (asModal) {
289
+ return /* @__PURE__ */ jsx2(AlertDialog2.Title, { "data-acp": "title", ...props });
290
+ }
291
+ return /* @__PURE__ */ jsx2("h2", { id: titleId, "data-acp": "title", ...props });
292
+ }
293
+ function Description(props) {
294
+ const { descId } = useGateContext("Description");
295
+ return /* @__PURE__ */ jsx2("p", { id: descId, "data-acp": "gate-description", ...props });
296
+ }
297
+ function Consequences(props) {
298
+ useGateContext("Consequences");
299
+ return /* @__PURE__ */ jsx2("ul", { "data-acp": "gate-consequences", ...props });
300
+ }
301
+ function Consequence({ children, ...rest }) {
302
+ useGateContext("Consequence");
303
+ return /* @__PURE__ */ jsxs2("li", { "data-acp": "gate-consequence", ...rest, children: [
304
+ /* @__PURE__ */ jsx2("span", { "aria-hidden": true, "data-acp": "gate-consequence-marker" }),
305
+ /* @__PURE__ */ jsx2("span", { "data-acp": "gate-consequence-text", children })
306
+ ] });
307
+ }
308
+ function ConfirmField({
309
+ children,
310
+ ...rest
311
+ }) {
312
+ const { requirePhrase, typed, setTyped, fieldId } = useGateContext("ConfirmField");
313
+ if (requirePhrase === null) return null;
314
+ return /* @__PURE__ */ jsxs2("div", { "data-acp": "confirm-field", children: [
315
+ /* @__PURE__ */ jsx2("label", { htmlFor: fieldId, "data-acp": "confirm-field-label", children: children ?? /* @__PURE__ */ jsxs2(Fragment, { children: [
316
+ "Type ",
317
+ /* @__PURE__ */ jsx2("code", { "data-acp": "confirm-field-phrase", children: requirePhrase }),
318
+ " to confirm"
319
+ ] }) }),
320
+ /* @__PURE__ */ jsx2(
321
+ "input",
322
+ {
323
+ id: fieldId,
324
+ "data-acp": "confirm-field-input",
325
+ type: "text",
326
+ autoComplete: "off",
327
+ autoCapitalize: "off",
328
+ autoCorrect: "off",
329
+ spellCheck: false,
330
+ value: typed,
331
+ onChange: (event) => setTyped(event.target.value),
332
+ ...rest
333
+ }
334
+ )
335
+ ] });
336
+ }
337
+ function Actions2(props) {
338
+ useGateContext("Actions");
339
+ return /* @__PURE__ */ jsx2("div", { "data-acp": "actions", ...props });
340
+ }
341
+ var Confirm = React2.forwardRef(function IrreversibilityGateConfirm({ onClick, disabled, ...rest }, ref) {
342
+ const { onConfirm, asModal, severity, canConfirm } = useGateContext("Confirm");
343
+ const isDisabled = disabled || !canConfirm;
344
+ const handleClick = (event) => {
345
+ onClick?.(event);
346
+ if (!event.defaultPrevented) onConfirm();
347
+ };
348
+ const button = /* @__PURE__ */ jsx2(
349
+ "button",
350
+ {
351
+ ref,
352
+ type: "button",
353
+ "data-acp": "confirm",
354
+ "data-severity": severity,
355
+ disabled: isDisabled,
356
+ "aria-disabled": isDisabled || void 0,
357
+ onClick: handleClick,
358
+ ...rest
359
+ }
360
+ );
361
+ return asModal ? /* @__PURE__ */ jsx2(AlertDialog2.Action, { asChild: true, children: button }) : button;
362
+ });
363
+ var Cancel3 = React2.forwardRef(function IrreversibilityGateCancel({ onClick, ...rest }, ref) {
364
+ const { onCancel, asModal } = useGateContext("Cancel");
365
+ const handleClick = (event) => {
366
+ onClick?.(event);
367
+ if (!event.defaultPrevented) onCancel();
368
+ };
369
+ const button = /* @__PURE__ */ jsx2(
370
+ "button",
371
+ {
372
+ ref,
373
+ type: "button",
374
+ "data-acp": "cancel",
375
+ onClick: handleClick,
376
+ ...rest
377
+ }
378
+ );
379
+ return asModal ? /* @__PURE__ */ jsx2(AlertDialog2.Cancel, { asChild: true, children: button }) : button;
380
+ });
381
+ var IrreversibilityGate = {
382
+ Root: Root4,
383
+ Header: Header2,
384
+ Icon: Icon2,
385
+ Title: Title4,
386
+ Description,
387
+ Consequences,
388
+ Consequence,
389
+ ConfirmField,
390
+ Actions: Actions2,
391
+ Confirm,
392
+ Cancel: Cancel3
393
+ };
394
+
395
+ // src/scoped-grant/scoped-grant.tsx
396
+ import * as React3 from "react";
397
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
398
+ var ScopedGrantContext = React3.createContext(null);
399
+ function useScopedGrantContext(part) {
400
+ const ctx = React3.useContext(ScopedGrantContext);
401
+ if (!ctx) {
402
+ throw new Error(
403
+ `ScopedGrant.${part} must be rendered inside ScopedGrant.Root`
404
+ );
405
+ }
406
+ return ctx;
407
+ }
408
+ function useGrantedSet(value, defaultValue, onValueChange) {
409
+ const isControlled = value !== void 0;
410
+ const [internal, setInternal] = React3.useState(
411
+ () => new Set(defaultValue ?? [])
412
+ );
413
+ const current = React3.useMemo(
414
+ () => isControlled ? new Set(value) : internal,
415
+ [isControlled, value, internal]
416
+ );
417
+ const setValue = React3.useCallback(
418
+ (updater) => {
419
+ const next = updater(current);
420
+ if (!isControlled) setInternal(next);
421
+ onValueChange?.([...next]);
422
+ },
423
+ [current, isControlled, onValueChange]
424
+ );
425
+ return [current, setValue];
426
+ }
427
+ var Root5 = React3.forwardRef(
428
+ function ScopedGrantRoot({
429
+ value,
430
+ defaultValue,
431
+ onValueChange,
432
+ requiredScopes,
433
+ onGrant,
434
+ onCancel,
435
+ children,
436
+ ...rest
437
+ }, ref) {
438
+ const titleId = React3.useId();
439
+ const [selected, setSelected] = useGrantedSet(
440
+ value,
441
+ defaultValue,
442
+ onValueChange
443
+ );
444
+ const requiredSet = React3.useMemo(
445
+ () => new Set(requiredScopes ?? []),
446
+ [requiredScopes]
447
+ );
448
+ const granted = React3.useMemo(() => {
449
+ const set = new Set(selected);
450
+ for (const id of requiredSet) set.add(id);
451
+ return [...set];
452
+ }, [selected, requiredSet]);
453
+ const ctx = React3.useMemo(() => {
454
+ const grantedSet = new Set(granted);
455
+ return {
456
+ isGranted: (id) => grantedSet.has(id),
457
+ isRequired: (id) => requiredSet.has(id),
458
+ toggle: (id) => {
459
+ if (requiredSet.has(id)) return;
460
+ setSelected((prev) => {
461
+ const next = new Set(prev);
462
+ if (next.has(id)) next.delete(id);
463
+ else next.add(id);
464
+ return next;
465
+ });
466
+ },
467
+ granted,
468
+ count: grantedSet.size,
469
+ onGrant,
470
+ onCancel,
471
+ titleId
472
+ };
473
+ }, [granted, requiredSet, setSelected, onGrant, onCancel, titleId]);
474
+ return /* @__PURE__ */ jsx3(ScopedGrantContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx3(
475
+ "form",
476
+ {
477
+ ref,
478
+ "data-acp": "root",
479
+ "data-grant": "",
480
+ "aria-labelledby": titleId,
481
+ onSubmit: (event) => {
482
+ event.preventDefault();
483
+ onGrant(granted);
484
+ },
485
+ ...rest,
486
+ children
487
+ }
488
+ ) });
489
+ }
490
+ );
491
+ function Header3(props) {
492
+ useScopedGrantContext("Header");
493
+ return /* @__PURE__ */ jsx3("div", { "data-acp": "header", ...props });
494
+ }
495
+ function Icon3(props) {
496
+ useScopedGrantContext("Icon");
497
+ return /* @__PURE__ */ jsx3("span", { "aria-hidden": true, "data-acp": "icon", ...props });
498
+ }
499
+ function Title5(props) {
500
+ const { titleId } = useScopedGrantContext("Title");
501
+ return /* @__PURE__ */ jsx3("h2", { id: titleId, "data-acp": "title", ...props });
502
+ }
503
+ function Description2(props) {
504
+ useScopedGrantContext("Description");
505
+ return /* @__PURE__ */ jsx3("p", { "data-acp": "grant-description", ...props });
506
+ }
507
+ function Group({ label, resource, children, ...rest }) {
508
+ useScopedGrantContext("Group");
509
+ return /* @__PURE__ */ jsxs3("fieldset", { "data-acp": "grant-group", ...rest, children: [
510
+ /* @__PURE__ */ jsxs3("legend", { "data-acp": "grant-group-legend", children: [
511
+ /* @__PURE__ */ jsx3("span", { "data-acp": "grant-group-label", children: label }),
512
+ resource != null && /* @__PURE__ */ jsx3("span", { "data-acp": "grant-group-resource", children: resource })
513
+ ] }),
514
+ children
515
+ ] });
516
+ }
517
+ var ACCESS_LABEL = {
518
+ read: "Read",
519
+ write: "Write",
520
+ delete: "Delete"
521
+ };
522
+ function Scope({
523
+ id,
524
+ access,
525
+ label,
526
+ description,
527
+ ...rest
528
+ }) {
529
+ const { isGranted, isRequired, toggle } = useScopedGrantContext("Scope");
530
+ const inputId = React3.useId();
531
+ const descId = React3.useId();
532
+ const granted = isGranted(id);
533
+ const required = isRequired(id);
534
+ return /* @__PURE__ */ jsxs3(
535
+ "div",
536
+ {
537
+ "data-acp": "scope",
538
+ "data-access": access,
539
+ "data-granted": granted ? "" : void 0,
540
+ "data-required": required ? "" : void 0,
541
+ ...rest,
542
+ children: [
543
+ /* @__PURE__ */ jsx3(
544
+ "input",
545
+ {
546
+ type: "checkbox",
547
+ id: inputId,
548
+ "data-acp": "scope-checkbox",
549
+ checked: granted,
550
+ disabled: required,
551
+ "aria-describedby": description != null ? descId : void 0,
552
+ onChange: () => toggle(id)
553
+ }
554
+ ),
555
+ /* @__PURE__ */ jsxs3("div", { "data-acp": "scope-body", children: [
556
+ /* @__PURE__ */ jsxs3("label", { htmlFor: inputId, "data-acp": "scope-label", children: [
557
+ /* @__PURE__ */ jsx3("span", { "data-acp": "scope-access", "data-access": access, children: ACCESS_LABEL[access] }),
558
+ /* @__PURE__ */ jsx3("span", { "data-acp": "scope-name", children: label }),
559
+ required && /* @__PURE__ */ jsx3("span", { "data-acp": "scope-required-tag", children: " \xB7 required" })
560
+ ] }),
561
+ description != null && /* @__PURE__ */ jsx3("p", { id: descId, "data-acp": "scope-description", children: description })
562
+ ] })
563
+ ]
564
+ }
565
+ );
566
+ }
567
+ function Actions3(props) {
568
+ useScopedGrantContext("Actions");
569
+ return /* @__PURE__ */ jsx3("div", { "data-acp": "actions", ...props });
570
+ }
571
+ var Grant = React3.forwardRef(
572
+ function ScopedGrantGrant({ children, ...rest }, ref) {
573
+ const { count } = useScopedGrantContext("Grant");
574
+ return /* @__PURE__ */ jsx3("button", { ref, type: "submit", "data-acp": "grant", ...rest, children: typeof children === "function" ? children({ count }) : children });
575
+ }
576
+ );
577
+ var Cancel4 = React3.forwardRef(
578
+ function ScopedGrantCancel({ onClick, ...rest }, ref) {
579
+ const { onCancel } = useScopedGrantContext("Cancel");
580
+ const handleClick = (event) => {
581
+ onClick?.(event);
582
+ if (!event.defaultPrevented) onCancel?.();
583
+ };
584
+ return /* @__PURE__ */ jsx3(
585
+ "button",
586
+ {
587
+ ref,
588
+ type: "button",
589
+ "data-acp": "cancel",
590
+ onClick: handleClick,
591
+ ...rest
592
+ }
593
+ );
594
+ }
595
+ );
596
+ var ScopedGrant = {
597
+ Root: Root5,
598
+ Header: Header3,
599
+ Icon: Icon3,
600
+ Title: Title5,
601
+ Description: Description2,
602
+ Group,
603
+ Scope,
604
+ Actions: Actions3,
605
+ Grant,
606
+ Cancel: Cancel4
607
+ };
608
+
609
+ // src/progressive-scope/progressive-scope.tsx
610
+ import * as React4 from "react";
611
+ import * as AlertDialog3 from "@radix-ui/react-alert-dialog";
612
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
613
+ var ProgressiveScopeContext = React4.createContext(null);
614
+ function useProgressiveScopeContext(part) {
615
+ const ctx = React4.useContext(ProgressiveScopeContext);
616
+ if (!ctx) {
617
+ throw new Error(
618
+ `ProgressiveScope.${part} must be rendered inside ProgressiveScope.Root`
619
+ );
620
+ }
621
+ return ctx;
622
+ }
623
+ var Root7 = React4.forwardRef(
624
+ function ProgressiveScopeRoot({
625
+ access = "read",
626
+ onAllowOnce,
627
+ onAllowAlways,
628
+ onDeny,
629
+ asModal = false,
630
+ open,
631
+ onOpenChange,
632
+ children,
633
+ ...rest
634
+ }, ref) {
635
+ const titleId = React4.useId();
636
+ const ctx = React4.useMemo(
637
+ () => ({
638
+ access,
639
+ onAllowOnce,
640
+ onAllowAlways,
641
+ onDeny,
642
+ asModal,
643
+ titleId
644
+ }),
645
+ [access, onAllowOnce, onAllowAlways, onDeny, asModal, titleId]
646
+ );
647
+ if (asModal) {
648
+ return /* @__PURE__ */ jsx4(ProgressiveScopeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx4(AlertDialog3.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs4(AlertDialog3.Portal, { children: [
649
+ /* @__PURE__ */ jsx4(AlertDialog3.Overlay, { "data-acp": "overlay" }),
650
+ /* @__PURE__ */ jsx4(
651
+ AlertDialog3.Content,
652
+ {
653
+ ref,
654
+ "data-acp": "root",
655
+ "data-escalation": "",
656
+ "data-modal": "",
657
+ "data-access": access,
658
+ "aria-describedby": void 0,
659
+ onEscapeKeyDown: onDeny,
660
+ ...rest,
661
+ children
662
+ }
663
+ )
664
+ ] }) }) });
665
+ }
666
+ return /* @__PURE__ */ jsx4(ProgressiveScopeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx4(
667
+ "section",
668
+ {
669
+ ref,
670
+ role: "group",
671
+ "aria-labelledby": titleId,
672
+ "data-acp": "root",
673
+ "data-escalation": "",
674
+ "data-access": access,
675
+ ...rest,
676
+ children
677
+ }
678
+ ) });
679
+ }
680
+ );
681
+ function Header4(props) {
682
+ useProgressiveScopeContext("Header");
683
+ return /* @__PURE__ */ jsx4("div", { "data-acp": "header", ...props });
684
+ }
685
+ function Icon4(props) {
686
+ useProgressiveScopeContext("Icon");
687
+ return /* @__PURE__ */ jsx4("span", { "aria-hidden": true, "data-acp": "icon", ...props });
688
+ }
689
+ function Title7(props) {
690
+ const { asModal, titleId } = useProgressiveScopeContext("Title");
691
+ if (asModal) {
692
+ return /* @__PURE__ */ jsx4(AlertDialog3.Title, { "data-acp": "title", ...props });
693
+ }
694
+ return /* @__PURE__ */ jsx4("h2", { id: titleId, "data-acp": "title", ...props });
695
+ }
696
+ function Reason(props) {
697
+ useProgressiveScopeContext("Reason");
698
+ return /* @__PURE__ */ jsx4("p", { "data-acp": "escalation-reason", ...props });
699
+ }
700
+ var ACCESS_LABEL2 = {
701
+ read: "Read",
702
+ write: "Write",
703
+ delete: "Delete"
704
+ };
705
+ function Request({ label, description, ...rest }) {
706
+ const { access } = useProgressiveScopeContext("Request");
707
+ return /* @__PURE__ */ jsxs4("div", { "data-acp": "request", "data-access": access, ...rest, children: [
708
+ /* @__PURE__ */ jsxs4("div", { "data-acp": "request-head", children: [
709
+ /* @__PURE__ */ jsx4("span", { "data-acp": "request-access", "data-access": access, children: ACCESS_LABEL2[access] }),
710
+ /* @__PURE__ */ jsx4("span", { "data-acp": "request-name", children: label })
711
+ ] }),
712
+ description != null && /* @__PURE__ */ jsx4("p", { "data-acp": "request-description", children: description })
713
+ ] });
714
+ }
715
+ function Current({ children, ...rest }) {
716
+ useProgressiveScopeContext("Current");
717
+ return /* @__PURE__ */ jsxs4("div", { "data-acp": "escalation-current", ...rest, children: [
718
+ /* @__PURE__ */ jsx4("span", { "aria-hidden": true, "data-acp": "escalation-current-marker" }),
719
+ /* @__PURE__ */ jsx4("span", { children })
720
+ ] });
721
+ }
722
+ function Actions4(props) {
723
+ useProgressiveScopeContext("Actions");
724
+ return /* @__PURE__ */ jsx4("div", { "data-acp": "actions", "data-escalation-actions": "", ...props });
725
+ }
726
+ function makeAllowButton(displayName, hook, pick) {
727
+ const Component = React4.forwardRef(function AllowButton({ onClick, ...rest }, ref) {
728
+ const ctx = useProgressiveScopeContext(displayName);
729
+ const action = pick(ctx);
730
+ const handleClick = (event) => {
731
+ onClick?.(event);
732
+ if (!event.defaultPrevented) action();
733
+ };
734
+ const button = /* @__PURE__ */ jsx4(
735
+ "button",
736
+ {
737
+ ref,
738
+ type: "button",
739
+ "data-acp": hook,
740
+ onClick: handleClick,
741
+ ...rest
742
+ }
743
+ );
744
+ return ctx.asModal ? /* @__PURE__ */ jsx4(AlertDialog3.Action, { asChild: true, children: button }) : button;
745
+ });
746
+ Component.displayName = displayName;
747
+ return Component;
748
+ }
749
+ var AllowOnce = makeAllowButton(
750
+ "ProgressiveScopeAllowOnce",
751
+ "allow-once",
752
+ (ctx) => ctx.onAllowOnce
753
+ );
754
+ var AllowAlways = makeAllowButton(
755
+ "ProgressiveScopeAllowAlways",
756
+ "allow-always",
757
+ (ctx) => ctx.onAllowAlways
758
+ );
759
+ var Deny = React4.forwardRef(
760
+ function ProgressiveScopeDeny({ onClick, ...rest }, ref) {
761
+ const { onDeny, asModal } = useProgressiveScopeContext("Deny");
762
+ const handleClick = (event) => {
763
+ onClick?.(event);
764
+ if (!event.defaultPrevented) onDeny();
765
+ };
766
+ const button = /* @__PURE__ */ jsx4(
767
+ "button",
768
+ {
769
+ ref,
770
+ type: "button",
771
+ "data-acp": "deny",
772
+ onClick: handleClick,
773
+ ...rest
774
+ }
775
+ );
776
+ return asModal ? /* @__PURE__ */ jsx4(AlertDialog3.Cancel, { asChild: true, children: button }) : button;
777
+ }
778
+ );
779
+ var ProgressiveScope = {
780
+ Root: Root7,
781
+ Header: Header4,
782
+ Icon: Icon4,
783
+ Title: Title7,
784
+ Reason,
785
+ Request,
786
+ Current,
787
+ Actions: Actions4,
788
+ AllowOnce,
789
+ AllowAlways,
790
+ Deny
791
+ };
792
+
793
+ // src/batch-approval/batch-approval.tsx
794
+ import * as React5 from "react";
795
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
796
+ var BatchApprovalContext = React5.createContext(null);
797
+ function useBatchApprovalContext(part) {
798
+ const ctx = React5.useContext(BatchApprovalContext);
799
+ if (!ctx) {
800
+ throw new Error(
801
+ `BatchApproval.${part} must be rendered inside BatchApproval.Root`
802
+ );
803
+ }
804
+ return ctx;
805
+ }
806
+ var BatchApprovalItemContext = React5.createContext(
807
+ null
808
+ );
809
+ function useItemId(part) {
810
+ const ctx = React5.useContext(BatchApprovalItemContext);
811
+ if (!ctx) {
812
+ throw new Error(
813
+ `BatchApproval.${part} must be rendered inside BatchApproval.Item`
814
+ );
815
+ }
816
+ return ctx.id;
817
+ }
818
+ function useSelectedSet(value, defaultValue, onValueChange) {
819
+ const isControlled = value !== void 0;
820
+ const [internal, setInternal] = React5.useState(
821
+ () => new Set(defaultValue ?? [])
822
+ );
823
+ const current = React5.useMemo(
824
+ () => isControlled ? new Set(value) : internal,
825
+ [isControlled, value, internal]
826
+ );
827
+ const setValue = React5.useCallback(
828
+ (updater) => {
829
+ const next = updater(current);
830
+ if (!isControlled) setInternal(next);
831
+ onValueChange?.([...next]);
832
+ },
833
+ [current, isControlled, onValueChange]
834
+ );
835
+ return [current, setValue];
836
+ }
837
+ var Root8 = React5.forwardRef(
838
+ function BatchApprovalRoot({
839
+ items,
840
+ value,
841
+ defaultValue,
842
+ onValueChange,
843
+ onApprove,
844
+ onReject,
845
+ children,
846
+ ...rest
847
+ }, ref) {
848
+ const titleId = React5.useId();
849
+ const [selected, setSelected] = useSelectedSet(
850
+ value,
851
+ defaultValue,
852
+ onValueChange
853
+ );
854
+ const reviewSet = React5.useMemo(
855
+ () => new Set(items.filter((i) => i.requiresReview).map((i) => i.id)),
856
+ [items]
857
+ );
858
+ const selectableIds = React5.useMemo(
859
+ () => items.filter((i) => !i.requiresReview).map((i) => i.id),
860
+ [items]
861
+ );
862
+ const ctx = React5.useMemo(() => {
863
+ const selectedSelectable = selectableIds.filter(
864
+ (id) => selected.has(id)
865
+ );
866
+ const selectedCount = selectedSelectable.length;
867
+ const selectableCount = selectableIds.length;
868
+ const clearFrom = (prev, ids) => {
869
+ const next = new Set(prev);
870
+ for (const id of ids) next.delete(id);
871
+ return next;
872
+ };
873
+ return {
874
+ isSelected: (id) => selected.has(id),
875
+ toggle: (id) => {
876
+ if (reviewSet.has(id)) return;
877
+ setSelected((prev) => {
878
+ const next = new Set(prev);
879
+ if (next.has(id)) next.delete(id);
880
+ else next.add(id);
881
+ return next;
882
+ });
883
+ },
884
+ requiresReview: (id) => reviewSet.has(id),
885
+ selectableIds,
886
+ selectedIds: selectedSelectable,
887
+ selectedCount,
888
+ selectableCount,
889
+ allSelected: selectableCount > 0 && selectedCount === selectableCount,
890
+ someSelected: selectedCount > 0 && selectedCount < selectableCount,
891
+ setAllSelected: (checked) => {
892
+ setSelected((prev) => {
893
+ if (!checked) return clearFrom(prev, selectableIds);
894
+ const next = new Set(prev);
895
+ for (const id of selectableIds) next.add(id);
896
+ return next;
897
+ });
898
+ },
899
+ approve: (ids) => {
900
+ onApprove(ids);
901
+ setSelected((prev) => clearFrom(prev, ids));
902
+ },
903
+ reject: (ids) => {
904
+ onReject(ids);
905
+ setSelected((prev) => clearFrom(prev, ids));
906
+ },
907
+ titleId
908
+ };
909
+ }, [
910
+ selected,
911
+ selectableIds,
912
+ reviewSet,
913
+ setSelected,
914
+ onApprove,
915
+ onReject,
916
+ titleId
917
+ ]);
918
+ return /* @__PURE__ */ jsx5(BatchApprovalContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx5(
919
+ "section",
920
+ {
921
+ ref,
922
+ role: "group",
923
+ "aria-labelledby": titleId,
924
+ "data-acp": "root",
925
+ "data-batch": "",
926
+ ...rest,
927
+ children
928
+ }
929
+ ) });
930
+ }
931
+ );
932
+ function Header5(props) {
933
+ useBatchApprovalContext("Header");
934
+ return /* @__PURE__ */ jsx5("div", { "data-acp": "header", ...props });
935
+ }
936
+ function Icon5(props) {
937
+ useBatchApprovalContext("Icon");
938
+ return /* @__PURE__ */ jsx5("span", { "aria-hidden": true, "data-acp": "icon", ...props });
939
+ }
940
+ function Title8(props) {
941
+ const { titleId } = useBatchApprovalContext("Title");
942
+ return /* @__PURE__ */ jsx5("h2", { id: titleId, "data-acp": "title", ...props });
943
+ }
944
+ function Description3(props) {
945
+ useBatchApprovalContext("Description");
946
+ return /* @__PURE__ */ jsx5("p", { "data-acp": "batch-description", ...props });
947
+ }
948
+ function Toolbar(props) {
949
+ useBatchApprovalContext("Toolbar");
950
+ return /* @__PURE__ */ jsx5("div", { "data-acp": "batch-toolbar", role: "group", ...props });
951
+ }
952
+ function SelectAll({ children, ...rest }) {
953
+ const { allSelected, someSelected, setAllSelected, selectableCount } = useBatchApprovalContext("SelectAll");
954
+ const inputRef = React5.useRef(null);
955
+ const inputId = React5.useId();
956
+ React5.useEffect(() => {
957
+ if (inputRef.current) inputRef.current.indeterminate = someSelected;
958
+ }, [someSelected]);
959
+ return /* @__PURE__ */ jsxs5("div", { "data-acp": "batch-select-all", ...rest, children: [
960
+ /* @__PURE__ */ jsx5(
961
+ "input",
962
+ {
963
+ ref: inputRef,
964
+ id: inputId,
965
+ type: "checkbox",
966
+ "data-acp": "batch-select-all-checkbox",
967
+ checked: allSelected,
968
+ disabled: selectableCount === 0,
969
+ onChange: (event) => setAllSelected(event.target.checked)
970
+ }
971
+ ),
972
+ /* @__PURE__ */ jsx5("label", { htmlFor: inputId, "data-acp": "batch-select-all-label", children: children ?? "Select all reviewable" })
973
+ ] });
974
+ }
975
+ function SelectionCount({ children, ...rest }) {
976
+ const { selectedCount, selectableCount } = useBatchApprovalContext("SelectionCount");
977
+ return /* @__PURE__ */ jsx5("span", { "data-acp": "batch-selection-count", "aria-live": "polite", ...rest, children: children ? children({ selectedCount, selectableCount }) : `${selectedCount} selected` });
978
+ }
979
+ var BatchApprove = React5.forwardRef(function BatchApprovalBatchApprove({ onClick, disabled, ...rest }, ref) {
980
+ const { approve, selectedIds, selectedCount } = useBatchApprovalContext("BatchApprove");
981
+ const isDisabled = disabled || selectedCount === 0;
982
+ return /* @__PURE__ */ jsx5(
983
+ "button",
984
+ {
985
+ ref,
986
+ type: "button",
987
+ "data-acp": "approve",
988
+ "data-batch-action": "approve",
989
+ disabled: isDisabled,
990
+ "aria-disabled": isDisabled || void 0,
991
+ onClick: (event) => {
992
+ onClick?.(event);
993
+ if (!event.defaultPrevented) approve(selectedIds);
994
+ },
995
+ ...rest
996
+ }
997
+ );
998
+ });
999
+ var BatchReject = React5.forwardRef(function BatchApprovalBatchReject({ onClick, disabled, ...rest }, ref) {
1000
+ const { reject, selectedIds, selectedCount } = useBatchApprovalContext("BatchReject");
1001
+ const isDisabled = disabled || selectedCount === 0;
1002
+ return /* @__PURE__ */ jsx5(
1003
+ "button",
1004
+ {
1005
+ ref,
1006
+ type: "button",
1007
+ "data-acp": "reject",
1008
+ "data-batch-action": "reject",
1009
+ disabled: isDisabled,
1010
+ "aria-disabled": isDisabled || void 0,
1011
+ onClick: (event) => {
1012
+ onClick?.(event);
1013
+ if (!event.defaultPrevented) reject(selectedIds);
1014
+ },
1015
+ ...rest
1016
+ }
1017
+ );
1018
+ });
1019
+ function List(props) {
1020
+ useBatchApprovalContext("List");
1021
+ return /* @__PURE__ */ jsx5("ul", { "data-acp": "batch-list", ...props });
1022
+ }
1023
+ function Item({ id, title, detail, children, ...rest }) {
1024
+ const { isSelected, toggle, requiresReview } = useBatchApprovalContext("Item");
1025
+ const inputId = React5.useId();
1026
+ const detailId = React5.useId();
1027
+ const selected = isSelected(id);
1028
+ const review = requiresReview(id);
1029
+ const itemCtx = React5.useMemo(() => ({ id }), [id]);
1030
+ return /* @__PURE__ */ jsx5(BatchApprovalItemContext.Provider, { value: itemCtx, children: /* @__PURE__ */ jsxs5(
1031
+ "li",
1032
+ {
1033
+ "data-acp": "batch-item",
1034
+ "data-selected": selected ? "" : void 0,
1035
+ "data-review": review ? "" : void 0,
1036
+ ...rest,
1037
+ children: [
1038
+ /* @__PURE__ */ jsx5("div", { "data-acp": "batch-item-select", children: review ? /* @__PURE__ */ jsx5("span", { "data-acp": "batch-item-flag", children: "Review individually" }) : /* @__PURE__ */ jsx5(
1039
+ "input",
1040
+ {
1041
+ id: inputId,
1042
+ type: "checkbox",
1043
+ "data-acp": "batch-item-checkbox",
1044
+ checked: selected,
1045
+ "aria-describedby": detail != null ? detailId : void 0,
1046
+ onChange: () => toggle(id)
1047
+ }
1048
+ ) }),
1049
+ /* @__PURE__ */ jsxs5("div", { "data-acp": "batch-item-body", children: [
1050
+ review ? /* @__PURE__ */ jsx5("span", { "data-acp": "batch-item-title", children: title }) : /* @__PURE__ */ jsx5("label", { htmlFor: inputId, "data-acp": "batch-item-title", children: title }),
1051
+ detail != null && /* @__PURE__ */ jsx5("p", { id: detailId, "data-acp": "batch-item-detail", children: detail })
1052
+ ] }),
1053
+ children != null && /* @__PURE__ */ jsx5("div", { "data-acp": "batch-item-actions", children })
1054
+ ]
1055
+ }
1056
+ ) });
1057
+ }
1058
+ var ItemApprove = React5.forwardRef(function BatchApprovalItemApprove({ onClick, ...rest }, ref) {
1059
+ const { approve } = useBatchApprovalContext("Item.Approve");
1060
+ const id = useItemId("Item.Approve");
1061
+ return /* @__PURE__ */ jsx5(
1062
+ "button",
1063
+ {
1064
+ ref,
1065
+ type: "button",
1066
+ "data-acp": "batch-item-approve",
1067
+ onClick: (event) => {
1068
+ onClick?.(event);
1069
+ if (!event.defaultPrevented) approve([id]);
1070
+ },
1071
+ ...rest
1072
+ }
1073
+ );
1074
+ });
1075
+ var ItemReject = React5.forwardRef(function BatchApprovalItemReject({ onClick, ...rest }, ref) {
1076
+ const { reject } = useBatchApprovalContext("Item.Reject");
1077
+ const id = useItemId("Item.Reject");
1078
+ return /* @__PURE__ */ jsx5(
1079
+ "button",
1080
+ {
1081
+ ref,
1082
+ type: "button",
1083
+ "data-acp": "batch-item-reject",
1084
+ onClick: (event) => {
1085
+ onClick?.(event);
1086
+ if (!event.defaultPrevented) reject([id]);
1087
+ },
1088
+ ...rest
1089
+ }
1090
+ );
1091
+ });
1092
+ var BatchApproval = {
1093
+ Root: Root8,
1094
+ Header: Header5,
1095
+ Icon: Icon5,
1096
+ Title: Title8,
1097
+ Description: Description3,
1098
+ Toolbar,
1099
+ SelectAll,
1100
+ SelectionCount,
1101
+ BatchApprove,
1102
+ BatchReject,
1103
+ List,
1104
+ Item,
1105
+ ItemApprove,
1106
+ ItemReject
1107
+ };
1108
+
1109
+ // src/consent-memory/consent-memory.tsx
1110
+ import * as React6 from "react";
1111
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1112
+ var ConsentMemoryContext = React6.createContext(null);
1113
+ function useConsentMemoryContext(part) {
1114
+ const ctx = React6.useContext(ConsentMemoryContext);
1115
+ if (!ctx) {
1116
+ throw new Error(
1117
+ `ConsentMemory.${part} must be rendered inside ConsentMemory.Root`
1118
+ );
1119
+ }
1120
+ return ctx;
1121
+ }
1122
+ function useControllableValue(value, defaultValue, onValueChange) {
1123
+ const isControlled = value !== void 0;
1124
+ const [internal, setInternal] = React6.useState(defaultValue);
1125
+ const current = isControlled ? value : internal;
1126
+ const setValue = React6.useCallback(
1127
+ (next) => {
1128
+ if (!isControlled) setInternal(next);
1129
+ onValueChange?.(next);
1130
+ },
1131
+ [isControlled, onValueChange]
1132
+ );
1133
+ return [current, setValue];
1134
+ }
1135
+ var Root9 = React6.forwardRef(
1136
+ function ConsentMemoryRoot({ value, defaultValue, onValueChange, onAllow, onDeny, children, ...rest }, ref) {
1137
+ const titleId = React6.useId();
1138
+ const name = React6.useId();
1139
+ const [selected, setSelected] = useControllableValue(
1140
+ value,
1141
+ defaultValue,
1142
+ onValueChange
1143
+ );
1144
+ const durabilityRef = React6.useRef(
1145
+ /* @__PURE__ */ new Map()
1146
+ );
1147
+ const ctx = React6.useMemo(
1148
+ () => ({
1149
+ value: selected ?? null,
1150
+ register: (next, durability) => {
1151
+ durabilityRef.current.set(next, durability);
1152
+ },
1153
+ getDurability: () => selected != null ? durabilityRef.current.get(selected) ?? null : null,
1154
+ select: setSelected,
1155
+ name,
1156
+ onAllow,
1157
+ onDeny,
1158
+ titleId
1159
+ }),
1160
+ [selected, setSelected, name, onAllow, onDeny, titleId]
1161
+ );
1162
+ return /* @__PURE__ */ jsx6(ConsentMemoryContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx6(
1163
+ "form",
1164
+ {
1165
+ ref,
1166
+ "data-acp": "root",
1167
+ "data-memory": "",
1168
+ "aria-labelledby": titleId,
1169
+ onSubmit: (event) => {
1170
+ event.preventDefault();
1171
+ if (selected != null) onAllow(selected);
1172
+ },
1173
+ ...rest,
1174
+ children
1175
+ }
1176
+ ) });
1177
+ }
1178
+ );
1179
+ function Header6(props) {
1180
+ useConsentMemoryContext("Header");
1181
+ return /* @__PURE__ */ jsx6("div", { "data-acp": "header", ...props });
1182
+ }
1183
+ function Icon6(props) {
1184
+ useConsentMemoryContext("Icon");
1185
+ return /* @__PURE__ */ jsx6("span", { "aria-hidden": true, "data-acp": "icon", ...props });
1186
+ }
1187
+ function Title9(props) {
1188
+ const { titleId } = useConsentMemoryContext("Title");
1189
+ return /* @__PURE__ */ jsx6("h2", { id: titleId, "data-acp": "title", ...props });
1190
+ }
1191
+ function Description4(props) {
1192
+ useConsentMemoryContext("Description");
1193
+ return /* @__PURE__ */ jsx6("p", { "data-acp": "memory-description", ...props });
1194
+ }
1195
+ function Options({ legend, children, ...rest }) {
1196
+ useConsentMemoryContext("Options");
1197
+ return /* @__PURE__ */ jsxs6("fieldset", { "data-acp": "memory-options", ...rest, children: [
1198
+ /* @__PURE__ */ jsx6("legend", { "data-acp": "memory-options-legend", children: legend ?? "Apply this decision:" }),
1199
+ children
1200
+ ] });
1201
+ }
1202
+ var DURABILITY_HINT = {
1203
+ once: "This time",
1204
+ session: "This session",
1205
+ scoped: "Standing \xB7 scoped",
1206
+ always: "Standing \xB7 always"
1207
+ };
1208
+ function Option({
1209
+ value,
1210
+ durability,
1211
+ label,
1212
+ consequence,
1213
+ ...rest
1214
+ }) {
1215
+ const { value: selected, select, register, name } = useConsentMemoryContext("Option");
1216
+ register(value, durability);
1217
+ const inputId = React6.useId();
1218
+ const consequenceId = React6.useId();
1219
+ const checked = selected === value;
1220
+ return /* @__PURE__ */ jsxs6(
1221
+ "div",
1222
+ {
1223
+ "data-acp": "memory-option",
1224
+ "data-durability": durability,
1225
+ "data-selected": checked ? "" : void 0,
1226
+ ...rest,
1227
+ children: [
1228
+ /* @__PURE__ */ jsx6(
1229
+ "input",
1230
+ {
1231
+ id: inputId,
1232
+ type: "radio",
1233
+ name,
1234
+ value,
1235
+ "data-acp": "memory-option-radio",
1236
+ checked,
1237
+ "aria-describedby": consequenceId,
1238
+ onChange: () => select(value)
1239
+ }
1240
+ ),
1241
+ /* @__PURE__ */ jsxs6("div", { "data-acp": "memory-option-body", children: [
1242
+ /* @__PURE__ */ jsxs6("label", { htmlFor: inputId, "data-acp": "memory-option-label", children: [
1243
+ /* @__PURE__ */ jsx6("span", { "data-acp": "memory-option-name", children: label }),
1244
+ /* @__PURE__ */ jsx6("span", { "data-acp": "memory-option-hint", "data-durability": durability, children: DURABILITY_HINT[durability] })
1245
+ ] }),
1246
+ /* @__PURE__ */ jsx6("p", { id: consequenceId, "data-acp": "memory-option-consequence", children: consequence })
1247
+ ] })
1248
+ ]
1249
+ }
1250
+ );
1251
+ }
1252
+ function Actions5(props) {
1253
+ useConsentMemoryContext("Actions");
1254
+ return /* @__PURE__ */ jsx6("div", { "data-acp": "actions", ...props });
1255
+ }
1256
+ var Allow = React6.forwardRef(
1257
+ function ConsentMemoryAllow({ children, ...rest }, ref) {
1258
+ const { getDurability } = useConsentMemoryContext("Allow");
1259
+ const durability = getDurability();
1260
+ return /* @__PURE__ */ jsx6(
1261
+ "button",
1262
+ {
1263
+ ref,
1264
+ type: "submit",
1265
+ "data-acp": "allow-once",
1266
+ "data-memory-allow": "",
1267
+ "data-durability": durability ?? void 0,
1268
+ ...rest,
1269
+ children: typeof children === "function" ? children({ durability }) : children
1270
+ }
1271
+ );
1272
+ }
1273
+ );
1274
+ var Deny2 = React6.forwardRef(
1275
+ function ConsentMemoryDeny({ onClick, ...rest }, ref) {
1276
+ const { onDeny } = useConsentMemoryContext("Deny");
1277
+ return /* @__PURE__ */ jsx6(
1278
+ "button",
1279
+ {
1280
+ ref,
1281
+ type: "button",
1282
+ "data-acp": "deny",
1283
+ onClick: (event) => {
1284
+ onClick?.(event);
1285
+ if (!event.defaultPrevented) onDeny();
1286
+ },
1287
+ ...rest
1288
+ }
1289
+ );
1290
+ }
1291
+ );
1292
+ var ConsentMemory = {
1293
+ Root: Root9,
1294
+ Header: Header6,
1295
+ Icon: Icon6,
1296
+ Title: Title9,
1297
+ Description: Description4,
1298
+ Options,
1299
+ Option,
1300
+ Actions: Actions5,
1301
+ Allow,
1302
+ Deny: Deny2
1303
+ };
1304
+
1305
+ // src/authority-boundary/authority-boundary.tsx
1306
+ import * as React7 from "react";
1307
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1308
+ var AUTHORITY_LEVELS = ["auto", "ask", "never"];
1309
+ var LEVEL_LABEL = {
1310
+ auto: "Automatic",
1311
+ ask: "Ask first",
1312
+ never: "Never"
1313
+ };
1314
+ var AuthorityBoundaryContext = React7.createContext(null);
1315
+ function useAuthorityBoundaryContext(part) {
1316
+ const ctx = React7.useContext(AuthorityBoundaryContext);
1317
+ if (!ctx) {
1318
+ throw new Error(
1319
+ `AuthorityBoundary.${part} must be rendered inside AuthorityBoundary.Root`
1320
+ );
1321
+ }
1322
+ return ctx;
1323
+ }
1324
+ function useControllableMap(value, defaultValue, onValueChange) {
1325
+ const isControlled = value !== void 0;
1326
+ const [internal, setInternal] = React7.useState(() => defaultValue ?? {});
1327
+ const current = isControlled ? value : internal;
1328
+ const setLevel = React7.useCallback(
1329
+ (id, level) => {
1330
+ const next = { ...current, [id]: level };
1331
+ if (!isControlled) setInternal(next);
1332
+ onValueChange?.(next);
1333
+ },
1334
+ [current, isControlled, onValueChange]
1335
+ );
1336
+ return [current, setLevel];
1337
+ }
1338
+ var Root10 = React7.forwardRef(
1339
+ function AuthorityBoundaryRoot({ value, defaultValue, onValueChange, children, ...rest }, ref) {
1340
+ const titleId = React7.useId();
1341
+ const [levels, setLevel] = useControllableMap(
1342
+ value,
1343
+ defaultValue,
1344
+ onValueChange
1345
+ );
1346
+ const ctx = React7.useMemo(() => {
1347
+ const counts = {
1348
+ auto: 0,
1349
+ ask: 0,
1350
+ never: 0
1351
+ };
1352
+ for (const level of Object.values(levels)) counts[level] += 1;
1353
+ return {
1354
+ getLevel: (id) => levels[id] ?? "ask",
1355
+ setLevel,
1356
+ counts,
1357
+ titleId
1358
+ };
1359
+ }, [levels, setLevel, titleId]);
1360
+ return /* @__PURE__ */ jsx7(AuthorityBoundaryContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx7(
1361
+ "section",
1362
+ {
1363
+ ref,
1364
+ role: "group",
1365
+ "aria-labelledby": titleId,
1366
+ "data-acp": "root",
1367
+ "data-authority": "",
1368
+ ...rest,
1369
+ children
1370
+ }
1371
+ ) });
1372
+ }
1373
+ );
1374
+ function Header7(props) {
1375
+ useAuthorityBoundaryContext("Header");
1376
+ return /* @__PURE__ */ jsx7("div", { "data-acp": "header", ...props });
1377
+ }
1378
+ function Icon7(props) {
1379
+ useAuthorityBoundaryContext("Icon");
1380
+ return /* @__PURE__ */ jsx7("span", { "aria-hidden": true, "data-acp": "icon", ...props });
1381
+ }
1382
+ function Title10(props) {
1383
+ const { titleId } = useAuthorityBoundaryContext("Title");
1384
+ return /* @__PURE__ */ jsx7("h2", { id: titleId, "data-acp": "title", ...props });
1385
+ }
1386
+ function Description5(props) {
1387
+ useAuthorityBoundaryContext("Description");
1388
+ return /* @__PURE__ */ jsx7("p", { "data-acp": "authority-description", ...props });
1389
+ }
1390
+ function Summary({ children, ...rest }) {
1391
+ const { counts } = useAuthorityBoundaryContext("Summary");
1392
+ return /* @__PURE__ */ jsx7("p", { "data-acp": "authority-summary", "aria-live": "polite", ...rest, children: children(counts) });
1393
+ }
1394
+ function List2(props) {
1395
+ useAuthorityBoundaryContext("List");
1396
+ return /* @__PURE__ */ jsx7("ul", { "data-acp": "authority-list", ...props });
1397
+ }
1398
+ var ACCESS_LABEL3 = {
1399
+ read: "Read",
1400
+ write: "Write",
1401
+ delete: "Delete"
1402
+ };
1403
+ function Capability({
1404
+ id,
1405
+ access,
1406
+ label,
1407
+ description,
1408
+ disallow,
1409
+ ...rest
1410
+ }) {
1411
+ const { getLevel, setLevel } = useAuthorityBoundaryContext("Capability");
1412
+ const name = React7.useId();
1413
+ const descId = React7.useId();
1414
+ const level = getLevel(id);
1415
+ const disallowed = new Set(disallow ?? []);
1416
+ return /* @__PURE__ */ jsxs7(
1417
+ "li",
1418
+ {
1419
+ "data-acp": "authority-capability",
1420
+ "data-access": access,
1421
+ "data-level": level,
1422
+ ...rest,
1423
+ children: [
1424
+ /* @__PURE__ */ jsxs7("div", { "data-acp": "authority-capability-body", children: [
1425
+ /* @__PURE__ */ jsxs7("span", { "data-acp": "authority-capability-head", children: [
1426
+ /* @__PURE__ */ jsx7("span", { "data-acp": "authority-access", "data-access": access, children: ACCESS_LABEL3[access] }),
1427
+ /* @__PURE__ */ jsx7("span", { "data-acp": "authority-capability-name", children: label })
1428
+ ] }),
1429
+ description != null && /* @__PURE__ */ jsx7("p", { id: descId, "data-acp": "authority-capability-description", children: description })
1430
+ ] }),
1431
+ /* @__PURE__ */ jsxs7(
1432
+ "fieldset",
1433
+ {
1434
+ "data-acp": "authority-control",
1435
+ "aria-describedby": description != null ? descId : void 0,
1436
+ children: [
1437
+ /* @__PURE__ */ jsxs7("legend", { "data-acp": "authority-control-legend", children: [
1438
+ "Authority for ",
1439
+ typeof label === "string" ? label : "this capability"
1440
+ ] }),
1441
+ AUTHORITY_LEVELS.map((option) => {
1442
+ const optionId = `${name}-${option}`;
1443
+ const blocked = disallowed.has(option);
1444
+ return /* @__PURE__ */ jsxs7(React7.Fragment, { children: [
1445
+ /* @__PURE__ */ jsx7(
1446
+ "input",
1447
+ {
1448
+ id: optionId,
1449
+ type: "radio",
1450
+ name,
1451
+ value: option,
1452
+ "data-acp": "authority-radio",
1453
+ "data-level": option,
1454
+ checked: level === option,
1455
+ disabled: blocked,
1456
+ onChange: () => setLevel(id, option)
1457
+ }
1458
+ ),
1459
+ /* @__PURE__ */ jsx7(
1460
+ "label",
1461
+ {
1462
+ htmlFor: optionId,
1463
+ "data-acp": "authority-level-label",
1464
+ "data-level": option,
1465
+ children: LEVEL_LABEL[option]
1466
+ }
1467
+ )
1468
+ ] }, option);
1469
+ })
1470
+ ]
1471
+ }
1472
+ )
1473
+ ]
1474
+ }
1475
+ );
1476
+ }
1477
+ var AuthorityBoundary = {
1478
+ Root: Root10,
1479
+ Header: Header7,
1480
+ Icon: Icon7,
1481
+ Title: Title10,
1482
+ Description: Description5,
1483
+ Summary,
1484
+ List: List2,
1485
+ Capability
1486
+ };
1487
+
1488
+ // src/spend-limits/spend-limits.tsx
1489
+ import * as React8 from "react";
1490
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1491
+ var SpendLimitsContext = React8.createContext(null);
1492
+ function useSpendLimitsContext(part) {
1493
+ const ctx = React8.useContext(SpendLimitsContext);
1494
+ if (!ctx) {
1495
+ throw new Error(
1496
+ `SpendLimits.${part} must be rendered inside SpendLimits.Root`
1497
+ );
1498
+ }
1499
+ return ctx;
1500
+ }
1501
+ function useControllableMap2(value, defaultValue, onValueChange) {
1502
+ const isControlled = value !== void 0;
1503
+ const [internal, setInternal] = React8.useState(
1504
+ () => defaultValue ?? {}
1505
+ );
1506
+ const current = isControlled ? value : internal;
1507
+ const setCap = React8.useCallback(
1508
+ (id, cap) => {
1509
+ const next = { ...current, [id]: cap };
1510
+ if (!isControlled) setInternal(next);
1511
+ onValueChange?.(next);
1512
+ },
1513
+ [current, isControlled, onValueChange]
1514
+ );
1515
+ return [current, setCap];
1516
+ }
1517
+ var WARNING_RATIO = 0.8;
1518
+ function stateFor(used, cap) {
1519
+ if (cap == null) return "none";
1520
+ if (used >= cap) return "reached";
1521
+ if (used / cap >= WARNING_RATIO) return "warning";
1522
+ return "ok";
1523
+ }
1524
+ var Root11 = React8.forwardRef(
1525
+ function SpendLimitsRoot({ limits, value, defaultValue, onValueChange, children, ...rest }, ref) {
1526
+ const titleId = React8.useId();
1527
+ const [caps, setCap] = useControllableMap2(
1528
+ value,
1529
+ defaultValue,
1530
+ onValueChange
1531
+ );
1532
+ const ctx = React8.useMemo(() => {
1533
+ const usage = new Map(limits.map((l) => [l.id, l.used]));
1534
+ const getUsed = (id) => usage.get(id) ?? 0;
1535
+ const getCap = (id) => Object.prototype.hasOwnProperty.call(caps, id) ? caps[id] : null;
1536
+ const summary = {
1537
+ total: limits.length,
1538
+ ok: 0,
1539
+ warning: 0,
1540
+ reached: 0
1541
+ };
1542
+ for (const limit of limits) {
1543
+ const state = stateFor(limit.used, getCap(limit.id));
1544
+ if (state === "ok") summary.ok += 1;
1545
+ else if (state === "warning") summary.warning += 1;
1546
+ else if (state === "reached") summary.reached += 1;
1547
+ }
1548
+ return {
1549
+ getUsed,
1550
+ getCap,
1551
+ setCap,
1552
+ getState: (id) => stateFor(getUsed(id), getCap(id)),
1553
+ summary,
1554
+ titleId
1555
+ };
1556
+ }, [limits, caps, setCap, titleId]);
1557
+ return /* @__PURE__ */ jsx8(SpendLimitsContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx8(
1558
+ "section",
1559
+ {
1560
+ ref,
1561
+ role: "group",
1562
+ "aria-labelledby": titleId,
1563
+ "data-acp": "root",
1564
+ "data-limits": "",
1565
+ ...rest,
1566
+ children
1567
+ }
1568
+ ) });
1569
+ }
1570
+ );
1571
+ function Header8(props) {
1572
+ useSpendLimitsContext("Header");
1573
+ return /* @__PURE__ */ jsx8("div", { "data-acp": "header", ...props });
1574
+ }
1575
+ function Icon8(props) {
1576
+ useSpendLimitsContext("Icon");
1577
+ return /* @__PURE__ */ jsx8("span", { "aria-hidden": true, "data-acp": "icon", ...props });
1578
+ }
1579
+ function Title11(props) {
1580
+ const { titleId } = useSpendLimitsContext("Title");
1581
+ return /* @__PURE__ */ jsx8("h2", { id: titleId, "data-acp": "title", ...props });
1582
+ }
1583
+ function Description6(props) {
1584
+ useSpendLimitsContext("Description");
1585
+ return /* @__PURE__ */ jsx8("p", { "data-acp": "limits-description", ...props });
1586
+ }
1587
+ function Summary2({ children, ...rest }) {
1588
+ const { summary } = useSpendLimitsContext("Summary");
1589
+ return /* @__PURE__ */ jsx8("p", { "data-acp": "limits-summary", "aria-live": "polite", ...rest, children: children(summary) });
1590
+ }
1591
+ function List3(props) {
1592
+ useSpendLimitsContext("List");
1593
+ return /* @__PURE__ */ jsx8("ul", { "data-acp": "limits-list", ...props });
1594
+ }
1595
+ var KIND_LABEL = {
1596
+ spend: "Budget",
1597
+ rate: "Rate"
1598
+ };
1599
+ var STATE_NOTE = {
1600
+ none: null,
1601
+ ok: null,
1602
+ warning: "Near cap",
1603
+ reached: "Cap reached \u2014 agent will ask before doing more"
1604
+ };
1605
+ var PERIOD_PHRASE = {
1606
+ day: "today",
1607
+ week: "this week",
1608
+ month: "this month"
1609
+ };
1610
+ function formatAmount(kind, unit, n) {
1611
+ return kind === "spend" ? `${unit}${n.toLocaleString()}` : `${n.toLocaleString()} ${unit}`;
1612
+ }
1613
+ function formatRange(kind, unit, used, cap) {
1614
+ return kind === "spend" ? `${unit}${used.toLocaleString()} of ${unit}${cap.toLocaleString()}` : `${used.toLocaleString()} of ${cap.toLocaleString()} ${unit}`;
1615
+ }
1616
+ function Limit({
1617
+ id,
1618
+ kind,
1619
+ unit,
1620
+ period,
1621
+ label,
1622
+ description,
1623
+ ...rest
1624
+ }) {
1625
+ const { getUsed, getCap, setCap, getState } = useSpendLimitsContext("Limit");
1626
+ const descId = React8.useId();
1627
+ const capId = React8.useId();
1628
+ const readoutId = React8.useId();
1629
+ const used = getUsed(id);
1630
+ const cap = getCap(id);
1631
+ const state = getState(id);
1632
+ const pct = cap == null ? 0 : cap > 0 ? Math.min(100, used / cap * 100) : 100;
1633
+ const readout = cap != null ? `${formatRange(kind, unit, used, cap)} ${PERIOD_PHRASE[period]}` : `${formatAmount(kind, unit, used)} used \xB7 no limit set`;
1634
+ const note = STATE_NOTE[state];
1635
+ const labelText = typeof label === "string" ? label : "this limit";
1636
+ return /* @__PURE__ */ jsxs8(
1637
+ "li",
1638
+ {
1639
+ "data-acp": "limits-limit",
1640
+ "data-kind": kind,
1641
+ "data-state": state,
1642
+ ...rest,
1643
+ children: [
1644
+ /* @__PURE__ */ jsxs8("div", { "data-acp": "limits-limit-body", children: [
1645
+ /* @__PURE__ */ jsxs8("span", { "data-acp": "limits-limit-head", children: [
1646
+ /* @__PURE__ */ jsx8("span", { "data-acp": "limits-kind", "data-kind": kind, children: KIND_LABEL[kind] }),
1647
+ /* @__PURE__ */ jsx8("span", { "data-acp": "limits-limit-name", children: label })
1648
+ ] }),
1649
+ description != null && /* @__PURE__ */ jsx8("p", { id: descId, "data-acp": "limits-limit-description", children: description }),
1650
+ /* @__PURE__ */ jsxs8("div", { "data-acp": "limits-meter", "data-state": state, children: [
1651
+ /* @__PURE__ */ jsx8("span", { "data-acp": "limits-meter-track", "aria-hidden": "true", children: /* @__PURE__ */ jsx8(
1652
+ "span",
1653
+ {
1654
+ "data-acp": "limits-meter-fill",
1655
+ "data-state": state,
1656
+ style: { width: `${pct}%` }
1657
+ }
1658
+ ) }),
1659
+ /* @__PURE__ */ jsx8("span", { id: readoutId, "data-acp": "limits-meter-readout", children: readout })
1660
+ ] }),
1661
+ note != null && /* @__PURE__ */ jsx8("p", { "data-acp": "limits-status", "data-state": state, children: note })
1662
+ ] }),
1663
+ /* @__PURE__ */ jsxs8("div", { "data-acp": "limits-cap", children: [
1664
+ /* @__PURE__ */ jsx8("label", { htmlFor: capId, "data-acp": "limits-cap-label", children: "Cap" }),
1665
+ /* @__PURE__ */ jsxs8("span", { "data-acp": "limits-cap-field", children: [
1666
+ kind === "spend" && /* @__PURE__ */ jsx8("span", { "data-acp": "limits-cap-unit", "aria-hidden": "true", children: unit }),
1667
+ /* @__PURE__ */ jsx8(
1668
+ "input",
1669
+ {
1670
+ id: capId,
1671
+ type: "number",
1672
+ min: 0,
1673
+ inputMode: "numeric",
1674
+ "data-acp": "limits-cap-input",
1675
+ "aria-label": `${labelText} cap, per ${period}`,
1676
+ "aria-describedby": description != null ? descId : void 0,
1677
+ value: cap ?? "",
1678
+ onChange: (event) => {
1679
+ const next = event.target.valueAsNumber;
1680
+ setCap(id, Number.isNaN(next) ? 0 : Math.max(0, next));
1681
+ }
1682
+ }
1683
+ ),
1684
+ kind === "rate" && /* @__PURE__ */ jsx8("span", { "data-acp": "limits-cap-unit", children: unit }),
1685
+ /* @__PURE__ */ jsxs8("span", { "data-acp": "limits-cap-period", children: [
1686
+ "per ",
1687
+ period
1688
+ ] })
1689
+ ] })
1690
+ ] })
1691
+ ]
1692
+ }
1693
+ );
1694
+ }
1695
+ var SpendLimits = {
1696
+ Root: Root11,
1697
+ Header: Header8,
1698
+ Icon: Icon8,
1699
+ Title: Title11,
1700
+ Description: Description6,
1701
+ Summary: Summary2,
1702
+ List: List3,
1703
+ Limit
1704
+ };
1705
+
1706
+ // src/credential-handoff/credential-handoff.tsx
1707
+ import * as React9 from "react";
1708
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1709
+ var CredentialHandoffContext = React9.createContext(null);
1710
+ function useCredentialHandoffContext(part) {
1711
+ const ctx = React9.useContext(CredentialHandoffContext);
1712
+ if (!ctx) {
1713
+ throw new Error(
1714
+ `CredentialHandoff.${part} must be rendered inside CredentialHandoff.Root`
1715
+ );
1716
+ }
1717
+ return ctx;
1718
+ }
1719
+ var Root12 = React9.forwardRef(
1720
+ function CredentialHandoffRoot({ onHandoff, onCancel, children, ...rest }, ref) {
1721
+ const titleId = React9.useId();
1722
+ const ctx = React9.useMemo(
1723
+ () => ({ onHandoff, onCancel, titleId }),
1724
+ [onHandoff, onCancel, titleId]
1725
+ );
1726
+ return /* @__PURE__ */ jsx9(CredentialHandoffContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx9(
1727
+ "section",
1728
+ {
1729
+ ref,
1730
+ role: "group",
1731
+ "aria-labelledby": titleId,
1732
+ "data-acp": "root",
1733
+ "data-handoff": "",
1734
+ ...rest,
1735
+ children
1736
+ }
1737
+ ) });
1738
+ }
1739
+ );
1740
+ function Header9(props) {
1741
+ useCredentialHandoffContext("Header");
1742
+ return /* @__PURE__ */ jsx9("div", { "data-acp": "header", ...props });
1743
+ }
1744
+ function Icon9(props) {
1745
+ useCredentialHandoffContext("Icon");
1746
+ return /* @__PURE__ */ jsx9("span", { "aria-hidden": true, "data-acp": "icon", ...props });
1747
+ }
1748
+ function Title12(props) {
1749
+ const { titleId } = useCredentialHandoffContext("Title");
1750
+ return /* @__PURE__ */ jsx9("h2", { id: titleId, "data-acp": "title", ...props });
1751
+ }
1752
+ function Description7(props) {
1753
+ useCredentialHandoffContext("Description");
1754
+ return /* @__PURE__ */ jsx9("p", { "data-acp": "handoff-description", ...props });
1755
+ }
1756
+ var HANDLER_LABEL = {
1757
+ "password-manager": "Password manager",
1758
+ passkey: "Passkey",
1759
+ payment: "Payment",
1760
+ provider: "Provider"
1761
+ };
1762
+ function Handler({ kind, name, children, ...rest }) {
1763
+ useCredentialHandoffContext("Handler");
1764
+ return /* @__PURE__ */ jsxs9("div", { "data-acp": "handoff-handler", "data-kind": kind, ...rest, children: [
1765
+ /* @__PURE__ */ jsx9("span", { "data-acp": "handoff-handler-kind", "data-kind": kind, children: HANDLER_LABEL[kind] }),
1766
+ /* @__PURE__ */ jsx9("span", { "data-acp": "handoff-handler-name", children: name }),
1767
+ children
1768
+ ] });
1769
+ }
1770
+ function Boundary(props) {
1771
+ useCredentialHandoffContext("Boundary");
1772
+ return /* @__PURE__ */ jsx9("div", { role: "note", "data-acp": "handoff-boundary", ...props });
1773
+ }
1774
+ function Returns({ legend, children, ...rest }) {
1775
+ useCredentialHandoffContext("Returns");
1776
+ const labelId = React9.useId();
1777
+ return /* @__PURE__ */ jsxs9("div", { "data-acp": "handoff-returns", children: [
1778
+ /* @__PURE__ */ jsx9("p", { id: labelId, "data-acp": "handoff-returns-legend", children: legend ?? "The agent receives:" }),
1779
+ /* @__PURE__ */ jsx9("ul", { "aria-labelledby": labelId, "data-acp": "handoff-returns-list", ...rest, children })
1780
+ ] });
1781
+ }
1782
+ function Return(props) {
1783
+ useCredentialHandoffContext("Return");
1784
+ return /* @__PURE__ */ jsx9("li", { "data-acp": "handoff-return", ...props });
1785
+ }
1786
+ function Actions6(props) {
1787
+ useCredentialHandoffContext("Actions");
1788
+ return /* @__PURE__ */ jsx9("div", { "data-acp": "actions", ...props });
1789
+ }
1790
+ var Handoff = React9.forwardRef(function CredentialHandoffHandoff({ onClick, ...rest }, ref) {
1791
+ const { onHandoff } = useCredentialHandoffContext("Handoff");
1792
+ return /* @__PURE__ */ jsx9(
1793
+ "button",
1794
+ {
1795
+ ref,
1796
+ type: "button",
1797
+ "data-acp": "handoff-continue",
1798
+ onClick: (event) => {
1799
+ onClick?.(event);
1800
+ if (!event.defaultPrevented) onHandoff();
1801
+ },
1802
+ ...rest
1803
+ }
1804
+ );
1805
+ });
1806
+ var Cancel6 = React9.forwardRef(function CredentialHandoffCancel({ onClick, ...rest }, ref) {
1807
+ const { onCancel } = useCredentialHandoffContext("Cancel");
1808
+ return /* @__PURE__ */ jsx9(
1809
+ "button",
1810
+ {
1811
+ ref,
1812
+ type: "button",
1813
+ "data-acp": "handoff-cancel",
1814
+ onClick: (event) => {
1815
+ onClick?.(event);
1816
+ if (!event.defaultPrevented) onCancel();
1817
+ },
1818
+ ...rest
1819
+ }
1820
+ );
1821
+ });
1822
+ var CredentialHandoff = {
1823
+ Root: Root12,
1824
+ Header: Header9,
1825
+ Icon: Icon9,
1826
+ Title: Title12,
1827
+ Description: Description7,
1828
+ Handler,
1829
+ Boundary,
1830
+ Returns,
1831
+ Return,
1832
+ Actions: Actions6,
1833
+ Handoff,
1834
+ Cancel: Cancel6
1835
+ };
1836
+
1837
+ // src/action-receipt/action-receipt.tsx
1838
+ import * as React10 from "react";
1839
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1840
+ var ActionReceiptContext = React10.createContext(null);
1841
+ function useActionReceiptContext(part) {
1842
+ const ctx = React10.useContext(ActionReceiptContext);
1843
+ if (!ctx) {
1844
+ throw new Error(
1845
+ `ActionReceipt.${part} must be rendered inside ActionReceipt.Root`
1846
+ );
1847
+ }
1848
+ return ctx;
1849
+ }
1850
+ var Root13 = React10.forwardRef(
1851
+ function ActionReceiptRoot({ outcome = "completed", reversibility = "reversible", children, ...rest }, ref) {
1852
+ const titleId = React10.useId();
1853
+ const ctx = React10.useMemo(
1854
+ () => ({ outcome, reversibility, titleId }),
1855
+ [outcome, reversibility, titleId]
1856
+ );
1857
+ return /* @__PURE__ */ jsx10(ActionReceiptContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx10(
1858
+ "article",
1859
+ {
1860
+ ref,
1861
+ "aria-labelledby": titleId,
1862
+ "data-acp": "root",
1863
+ "data-receipt": "",
1864
+ "data-outcome": outcome,
1865
+ ...rest,
1866
+ children
1867
+ }
1868
+ ) });
1869
+ }
1870
+ );
1871
+ function Header10(props) {
1872
+ useActionReceiptContext("Header");
1873
+ return /* @__PURE__ */ jsx10("div", { "data-acp": "header", "data-receipt-header": "", ...props });
1874
+ }
1875
+ function Icon10(props) {
1876
+ useActionReceiptContext("Icon");
1877
+ return /* @__PURE__ */ jsx10("span", { "aria-hidden": true, "data-acp": "icon", ...props });
1878
+ }
1879
+ function Title13(props) {
1880
+ const { titleId } = useActionReceiptContext("Title");
1881
+ return /* @__PURE__ */ jsx10("div", { id: titleId, "data-acp": "title", ...props });
1882
+ }
1883
+ var OUTCOME_LABEL = {
1884
+ completed: "Completed",
1885
+ undone: "Undone",
1886
+ failed: "Failed"
1887
+ };
1888
+ function Outcome({ children, ...rest }) {
1889
+ const { outcome } = useActionReceiptContext("Outcome");
1890
+ return /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-outcome", "data-outcome": outcome, ...rest, children: children ?? OUTCOME_LABEL[outcome] });
1891
+ }
1892
+ function Details(props) {
1893
+ useActionReceiptContext("Details");
1894
+ return /* @__PURE__ */ jsx10("dl", { "data-acp": "receipt-details", ...props });
1895
+ }
1896
+ function Detail({ label, children, ...rest }) {
1897
+ useActionReceiptContext("Detail");
1898
+ return /* @__PURE__ */ jsxs10("div", { "data-acp": "receipt-detail", ...rest, children: [
1899
+ /* @__PURE__ */ jsx10("dt", { "data-acp": "receipt-detail-label", children: label }),
1900
+ /* @__PURE__ */ jsx10("dd", { "data-acp": "receipt-detail-value", children })
1901
+ ] });
1902
+ }
1903
+ function Authority({ grant, via, children, ...rest }) {
1904
+ useActionReceiptContext("Authority");
1905
+ return /* @__PURE__ */ jsxs10("div", { "data-acp": "receipt-authority", ...rest, children: [
1906
+ /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-authority-label", children: "Under authority" }),
1907
+ /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-authority-grant", children: grant }),
1908
+ via != null && /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-authority-via", children: via }),
1909
+ children
1910
+ ] });
1911
+ }
1912
+ function Meta(props) {
1913
+ useActionReceiptContext("Meta");
1914
+ return /* @__PURE__ */ jsx10("dl", { "data-acp": "receipt-meta", ...props });
1915
+ }
1916
+ function MetaItem({ label, children, ...rest }) {
1917
+ useActionReceiptContext("MetaItem");
1918
+ return /* @__PURE__ */ jsxs10("div", { "data-acp": "receipt-meta-item", ...rest, children: [
1919
+ /* @__PURE__ */ jsx10("dt", { "data-acp": "receipt-meta-label", children: label }),
1920
+ /* @__PURE__ */ jsx10("dd", { "data-acp": "receipt-meta-value", children })
1921
+ ] });
1922
+ }
1923
+ function Actions7(props) {
1924
+ useActionReceiptContext("Actions");
1925
+ return /* @__PURE__ */ jsx10("div", { "data-acp": "actions", "data-receipt-actions": "", ...props });
1926
+ }
1927
+ var Undo = React10.forwardRef(
1928
+ function ActionReceiptUndo({ children, irreversibleNote, undoneNote, ...rest }, ref) {
1929
+ const { outcome, reversibility } = useActionReceiptContext("Undo");
1930
+ if (outcome === "undone") {
1931
+ return /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-undo-note", "data-state": "undone", children: undoneNote ?? "Undone" });
1932
+ }
1933
+ if (reversibility === "irreversible") {
1934
+ return /* @__PURE__ */ jsx10("span", { "data-acp": "receipt-undo-note", "data-state": "permanent", children: irreversibleNote ?? "Can't be undone" });
1935
+ }
1936
+ return /* @__PURE__ */ jsx10("button", { ref, type: "button", "data-acp": "receipt-undo", ...rest, children: children ?? "Undo" });
1937
+ }
1938
+ );
1939
+ var ActionReceipt = {
1940
+ Root: Root13,
1941
+ Header: Header10,
1942
+ Icon: Icon10,
1943
+ Title: Title13,
1944
+ Outcome,
1945
+ Details,
1946
+ Detail,
1947
+ Authority,
1948
+ Meta,
1949
+ MetaItem,
1950
+ Actions: Actions7,
1951
+ Undo
1952
+ };
1953
+
1954
+ // src/injection-flag/injection-flag.tsx
1955
+ import * as React11 from "react";
1956
+ import * as AlertDialog4 from "@radix-ui/react-alert-dialog";
1957
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1958
+ var InjectionFlagContext = React11.createContext(null);
1959
+ function useInjectionFlagContext(part) {
1960
+ const ctx = React11.useContext(InjectionFlagContext);
1961
+ if (!ctx) {
1962
+ throw new Error(
1963
+ `InjectionFlag.${part} must be rendered inside InjectionFlag.Root`
1964
+ );
1965
+ }
1966
+ return ctx;
1967
+ }
1968
+ var Root15 = React11.forwardRef(
1969
+ function InjectionFlagRoot({ onProceed, onDismiss, asModal = false, open, onOpenChange, children, ...rest }, ref) {
1970
+ const titleId = React11.useId();
1971
+ const ctx = React11.useMemo(
1972
+ () => ({ onProceed, onDismiss, asModal, titleId }),
1973
+ [onProceed, onDismiss, asModal, titleId]
1974
+ );
1975
+ if (asModal) {
1976
+ return /* @__PURE__ */ jsx11(InjectionFlagContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx11(AlertDialog4.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs11(AlertDialog4.Portal, { children: [
1977
+ /* @__PURE__ */ jsx11(AlertDialog4.Overlay, { "data-acp": "overlay" }),
1978
+ /* @__PURE__ */ jsx11(
1979
+ AlertDialog4.Content,
1980
+ {
1981
+ ref,
1982
+ "data-acp": "root",
1983
+ "data-injection": "",
1984
+ "data-modal": "",
1985
+ "aria-describedby": void 0,
1986
+ onEscapeKeyDown: onDismiss,
1987
+ ...rest,
1988
+ children
1989
+ }
1990
+ )
1991
+ ] }) }) });
1992
+ }
1993
+ return /* @__PURE__ */ jsx11(InjectionFlagContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx11(
1994
+ "section",
1995
+ {
1996
+ ref,
1997
+ role: "group",
1998
+ "aria-labelledby": titleId,
1999
+ "data-acp": "root",
2000
+ "data-injection": "",
2001
+ ...rest,
2002
+ children
2003
+ }
2004
+ ) });
2005
+ }
2006
+ );
2007
+ function Header11(props) {
2008
+ useInjectionFlagContext("Header");
2009
+ return /* @__PURE__ */ jsx11("div", { "data-acp": "header", ...props });
2010
+ }
2011
+ function Icon11(props) {
2012
+ useInjectionFlagContext("Icon");
2013
+ return /* @__PURE__ */ jsx11("span", { "aria-hidden": true, "data-acp": "icon", ...props });
2014
+ }
2015
+ function Title15(props) {
2016
+ const { asModal, titleId } = useInjectionFlagContext("Title");
2017
+ if (asModal) {
2018
+ return /* @__PURE__ */ jsx11(AlertDialog4.Title, { "data-acp": "title", ...props });
2019
+ }
2020
+ return /* @__PURE__ */ jsx11("h2", { id: titleId, "data-acp": "title", ...props });
2021
+ }
2022
+ function Description8(props) {
2023
+ useInjectionFlagContext("Description");
2024
+ return /* @__PURE__ */ jsx11("p", { "data-acp": "injection-description", ...props });
2025
+ }
2026
+ function Source2({ origin, location, children, ...rest }) {
2027
+ useInjectionFlagContext("Source");
2028
+ return /* @__PURE__ */ jsxs11("div", { "data-acp": "injection-source", ...rest, children: [
2029
+ /* @__PURE__ */ jsx11("span", { "data-acp": "injection-source-label", children: "Came from" }),
2030
+ /* @__PURE__ */ jsx11("span", { "data-acp": "injection-origin", children: origin }),
2031
+ location != null && /* @__PURE__ */ jsx11("span", { "data-acp": "injection-location", children: location }),
2032
+ children
2033
+ ] });
2034
+ }
2035
+ function Quote({ label, children, ...rest }) {
2036
+ useInjectionFlagContext("Quote");
2037
+ const labelId = React11.useId();
2038
+ return /* @__PURE__ */ jsxs11("figure", { "data-acp": "injection-quote-figure", children: [
2039
+ /* @__PURE__ */ jsx11("figcaption", { id: labelId, "data-acp": "injection-quote-label", children: label ?? "The instruction reads:" }),
2040
+ /* @__PURE__ */ jsx11(
2041
+ "blockquote",
2042
+ {
2043
+ "data-acp": "injection-quote",
2044
+ "aria-labelledby": labelId,
2045
+ ...rest,
2046
+ children
2047
+ }
2048
+ )
2049
+ ] });
2050
+ }
2051
+ function Consequence2(props) {
2052
+ useInjectionFlagContext("Consequence");
2053
+ return /* @__PURE__ */ jsx11("p", { "data-acp": "injection-consequence", ...props });
2054
+ }
2055
+ function Actions8(props) {
2056
+ useInjectionFlagContext("Actions");
2057
+ return /* @__PURE__ */ jsx11("div", { "data-acp": "actions", ...props });
2058
+ }
2059
+ var Proceed = React11.forwardRef(
2060
+ function InjectionFlagProceed({ onClick, ...rest }, ref) {
2061
+ const { onProceed, asModal } = useInjectionFlagContext("Proceed");
2062
+ const handleClick = (event) => {
2063
+ onClick?.(event);
2064
+ if (!event.defaultPrevented) onProceed();
2065
+ };
2066
+ const button = /* @__PURE__ */ jsx11(
2067
+ "button",
2068
+ {
2069
+ ref,
2070
+ type: "button",
2071
+ "data-acp": "injection-proceed",
2072
+ onClick: handleClick,
2073
+ ...rest
2074
+ }
2075
+ );
2076
+ return asModal ? /* @__PURE__ */ jsx11(AlertDialog4.Action, { asChild: true, children: button }) : button;
2077
+ }
2078
+ );
2079
+ var Dismiss = React11.forwardRef(
2080
+ function InjectionFlagDismiss({ onClick, ...rest }, ref) {
2081
+ const { onDismiss, asModal } = useInjectionFlagContext("Dismiss");
2082
+ const handleClick = (event) => {
2083
+ onClick?.(event);
2084
+ if (!event.defaultPrevented) onDismiss();
2085
+ };
2086
+ const button = /* @__PURE__ */ jsx11(
2087
+ "button",
2088
+ {
2089
+ ref,
2090
+ type: "button",
2091
+ "data-acp": "injection-dismiss",
2092
+ onClick: handleClick,
2093
+ ...rest
2094
+ }
2095
+ );
2096
+ return asModal ? /* @__PURE__ */ jsx11(AlertDialog4.Cancel, { asChild: true, children: button }) : button;
2097
+ }
2098
+ );
2099
+ var InjectionFlag = {
2100
+ Root: Root15,
2101
+ Header: Header11,
2102
+ Icon: Icon11,
2103
+ Title: Title15,
2104
+ Description: Description8,
2105
+ Source: Source2,
2106
+ Quote,
2107
+ Consequence: Consequence2,
2108
+ Actions: Actions8,
2109
+ Proceed,
2110
+ Dismiss
2111
+ };
2112
+
2113
+ // src/connection-card/connection-card.tsx
2114
+ import * as React12 from "react";
2115
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2116
+ var ConnectionCardContext = React12.createContext(null);
2117
+ function useConnectionCardContext(part) {
2118
+ const ctx = React12.useContext(ConnectionCardContext);
2119
+ if (!ctx) {
2120
+ throw new Error(
2121
+ `ConnectionCard.${part} must be rendered inside ConnectionCard.Root`
2122
+ );
2123
+ }
2124
+ return ctx;
2125
+ }
2126
+ var Root16 = React12.forwardRef(
2127
+ function ConnectionCardRoot({ status = "active", children, ...rest }, ref) {
2128
+ const titleId = React12.useId();
2129
+ const ctx = React12.useMemo(
2130
+ () => ({ status, titleId }),
2131
+ [status, titleId]
2132
+ );
2133
+ return /* @__PURE__ */ jsx12(ConnectionCardContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx12(
2134
+ "article",
2135
+ {
2136
+ ref,
2137
+ "aria-labelledby": titleId,
2138
+ "data-acp": "root",
2139
+ "data-connection": "",
2140
+ "data-status": status,
2141
+ ...rest,
2142
+ children
2143
+ }
2144
+ ) });
2145
+ }
2146
+ );
2147
+ function Header12(props) {
2148
+ useConnectionCardContext("Header");
2149
+ return /* @__PURE__ */ jsx12("div", { "data-acp": "header", "data-connection-header": "", ...props });
2150
+ }
2151
+ function Icon12(props) {
2152
+ useConnectionCardContext("Icon");
2153
+ return /* @__PURE__ */ jsx12("span", { "aria-hidden": true, "data-acp": "icon", ...props });
2154
+ }
2155
+ function Title16(props) {
2156
+ const { titleId } = useConnectionCardContext("Title");
2157
+ return /* @__PURE__ */ jsx12("div", { id: titleId, "data-acp": "title", ...props });
2158
+ }
2159
+ var STATUS_LABEL = {
2160
+ active: "Active",
2161
+ paused: "Paused",
2162
+ "needs-reauth": "Needs re-auth",
2163
+ expired: "Expired"
2164
+ };
2165
+ function Status({ children, ...rest }) {
2166
+ const { status } = useConnectionCardContext("Status");
2167
+ return /* @__PURE__ */ jsx12("span", { "data-acp": "connection-status", "data-status": status, ...rest, children: children ?? STATUS_LABEL[status] });
2168
+ }
2169
+ function Scopes(props) {
2170
+ useConnectionCardContext("Scopes");
2171
+ return /* @__PURE__ */ jsx12("ul", { "data-acp": "connection-scopes", ...props });
2172
+ }
2173
+ var ACCESS_LABEL4 = {
2174
+ read: "Read",
2175
+ write: "Write",
2176
+ delete: "Delete"
2177
+ };
2178
+ function Scope2({ access, children, ...rest }) {
2179
+ useConnectionCardContext("Scope");
2180
+ return /* @__PURE__ */ jsxs12("li", { "data-acp": "connection-scope", "data-access": access, ...rest, children: [
2181
+ /* @__PURE__ */ jsx12("span", { "data-acp": "connection-access", "data-access": access, children: ACCESS_LABEL4[access] }),
2182
+ /* @__PURE__ */ jsx12("span", { "data-acp": "connection-scope-name", children })
2183
+ ] });
2184
+ }
2185
+ function Meta2(props) {
2186
+ useConnectionCardContext("Meta");
2187
+ return /* @__PURE__ */ jsx12("dl", { "data-acp": "connection-meta", ...props });
2188
+ }
2189
+ function MetaItem2({ label, children, ...rest }) {
2190
+ useConnectionCardContext("MetaItem");
2191
+ return /* @__PURE__ */ jsxs12("div", { "data-acp": "connection-meta-item", ...rest, children: [
2192
+ /* @__PURE__ */ jsx12("dt", { "data-acp": "connection-meta-label", children: label }),
2193
+ /* @__PURE__ */ jsx12("dd", { "data-acp": "connection-meta-value", children })
2194
+ ] });
2195
+ }
2196
+ function Actions9(props) {
2197
+ useConnectionCardContext("Actions");
2198
+ return /* @__PURE__ */ jsx12("div", { "data-acp": "actions", "data-connection-actions": "", ...props });
2199
+ }
2200
+ var Action5 = React12.forwardRef(
2201
+ function ConnectionCardAction({ tone = "default", type, ...rest }, ref) {
2202
+ useConnectionCardContext("Action");
2203
+ return /* @__PURE__ */ jsx12(
2204
+ "button",
2205
+ {
2206
+ ref,
2207
+ type: type ?? "button",
2208
+ "data-acp": "connection-action",
2209
+ "data-tone": tone,
2210
+ ...rest
2211
+ }
2212
+ );
2213
+ }
2214
+ );
2215
+ var ConnectionCard = {
2216
+ Root: Root16,
2217
+ Header: Header12,
2218
+ Icon: Icon12,
2219
+ Title: Title16,
2220
+ Status,
2221
+ Scopes,
2222
+ Scope: Scope2,
2223
+ Meta: Meta2,
2224
+ MetaItem: MetaItem2,
2225
+ Actions: Actions9,
2226
+ Action: Action5
2227
+ };
2228
+ export {
2229
+ AUTHORITY_LEVELS,
2230
+ ActionPreview,
2231
+ ActionReceipt,
2232
+ AuthorityBoundary,
2233
+ BatchApproval,
2234
+ ConnectionCard,
2235
+ ConsentMemory,
2236
+ CredentialHandoff,
2237
+ InjectionFlag,
2238
+ IrreversibilityGate,
2239
+ ProgressiveScope,
2240
+ ScopedGrant,
2241
+ SpendLimits
2242
+ };
2243
+ //# sourceMappingURL=index.js.map