@ikonai/sdk-react-ui 1.10.0 → 1.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/account/use-account-removal.d.ts +37 -0
  2. package/account/use-account-removal.d.ts.map +1 -0
  3. package/app/boot-snapshot-variant.d.ts +2 -1
  4. package/app/boot-snapshot-variant.d.ts.map +1 -0
  5. package/app/connection-recovery.d.ts +1 -0
  6. package/app/connection-recovery.d.ts.map +1 -0
  7. package/app/connection-state-renderer.d.ts +2 -1
  8. package/app/connection-state-renderer.d.ts.map +1 -0
  9. package/app/feedback/feedback-controls.d.ts +24 -0
  10. package/app/feedback/feedback-controls.d.ts.map +1 -0
  11. package/app/feedback/feedback-form.d.ts +26 -0
  12. package/app/feedback/feedback-form.d.ts.map +1 -0
  13. package/app/feedback/platform-layer.d.ts +32 -0
  14. package/app/feedback/platform-layer.d.ts.map +1 -0
  15. package/app/feedback/use-ikon-feedback.d.ts +13 -0
  16. package/app/feedback/use-ikon-feedback.d.ts.map +1 -0
  17. package/app/ikon-app.d.ts +1 -0
  18. package/app/ikon-app.d.ts.map +1 -0
  19. package/app/index.d.ts +2 -0
  20. package/app/index.d.ts.map +1 -0
  21. package/app/use-ikon-app.d.ts +29 -1
  22. package/app/use-ikon-app.d.ts.map +1 -0
  23. package/app/use-ikon-debug.d.ts +2 -1
  24. package/app/use-ikon-debug.d.ts.map +1 -0
  25. package/auth/auth-context.d.ts +2 -1
  26. package/auth/auth-context.d.ts.map +1 -0
  27. package/auth/auth-service.d.ts +39 -6
  28. package/auth/auth-service.d.ts.map +1 -0
  29. package/auth/index.d.ts +4 -2
  30. package/auth/index.d.ts.map +1 -0
  31. package/auth/oauth-continuation.d.ts +1 -0
  32. package/auth/oauth-continuation.d.ts.map +1 -0
  33. package/auth/storage.d.ts +2 -1
  34. package/auth/storage.d.ts.map +1 -0
  35. package/auth/types.d.ts +22 -7
  36. package/auth/types.d.ts.map +1 -0
  37. package/auth/use-auth-guard.d.ts +1 -0
  38. package/auth/use-auth-guard.d.ts.map +1 -0
  39. package/auth/use-sso-sign-in.d.ts +18 -0
  40. package/auth/use-sso-sign-in.d.ts.map +1 -0
  41. package/base/base-div.d.ts +1 -0
  42. package/base/base-div.d.ts.map +1 -0
  43. package/base/base-module.d.ts +1 -0
  44. package/base/base-module.d.ts.map +1 -0
  45. package/base/focus-hint-dispatch.d.ts +41 -0
  46. package/base/focus-hint-dispatch.d.ts.map +1 -0
  47. package/consent/use-consent.d.ts +35 -0
  48. package/consent/use-consent.d.ts.map +1 -0
  49. package/debug/debug-overlay.d.ts +2 -1
  50. package/debug/debug-overlay.d.ts.map +1 -0
  51. package/feedback-form-BSy2olwD.js +511 -0
  52. package/hooks/index.d.ts +1 -0
  53. package/hooks/index.d.ts.map +1 -0
  54. package/hooks/use-ikon-reactive.d.ts +2 -1
  55. package/hooks/use-ikon-reactive.d.ts.map +1 -0
  56. package/hooks/use-reactive.d.ts +2 -1
  57. package/hooks/use-reactive.d.ts.map +1 -0
  58. package/hooks/use-toasts.d.ts +1 -0
  59. package/hooks/use-toasts.d.ts.map +1 -0
  60. package/i18n/i18n.d.ts +2 -1
  61. package/i18n/i18n.d.ts.map +1 -0
  62. package/i18n/index.d.ts +1 -0
  63. package/i18n/index.d.ts.map +1 -0
  64. package/ikon-ui-registry.d.ts +1 -0
  65. package/ikon-ui-registry.d.ts.map +1 -0
  66. package/ikon-ui.d.ts +3 -2
  67. package/ikon-ui.d.ts.map +1 -0
  68. package/index.d.ts +9 -6
  69. package/index.d.ts.map +1 -0
  70. package/index.js +2279 -1931
  71. package/inspect/inspect-overlay.d.ts +1 -0
  72. package/inspect/inspect-overlay.d.ts.map +1 -0
  73. package/media/audio-player.d.ts +1 -0
  74. package/media/audio-player.d.ts.map +1 -0
  75. package/media/media-module.d.ts +1 -0
  76. package/media/media-module.d.ts.map +1 -0
  77. package/media/use-media-capture.d.ts +2 -1
  78. package/media/use-media-capture.d.ts.map +1 -0
  79. package/media/use-sibling-client.d.ts +2 -1
  80. package/media/use-sibling-client.d.ts.map +1 -0
  81. package/media/video-canvas.d.ts +1 -0
  82. package/media/video-canvas.d.ts.map +1 -0
  83. package/media/video-stream-view.d.ts +4 -2
  84. package/media/video-stream-view.d.ts.map +1 -0
  85. package/motion/motion-controller.d.ts +2 -1
  86. package/motion/motion-controller.d.ts.map +1 -0
  87. package/package.json +1 -1
  88. package/parallax-view.d.ts +3 -2
  89. package/parallax-view.d.ts.map +1 -0
  90. package/renderer/component-library.d.ts +1 -0
  91. package/renderer/component-library.d.ts.map +1 -0
  92. package/renderer/index.d.ts +2 -0
  93. package/renderer/index.d.ts.map +1 -0
  94. package/renderer/lazy-resolver.d.ts +10 -0
  95. package/renderer/lazy-resolver.d.ts.map +1 -0
  96. package/renderer/types.d.ts +5 -4
  97. package/renderer/types.d.ts.map +1 -0
  98. package/renderer/ui-renderer.d.ts +4 -3
  99. package/renderer/ui-renderer.d.ts.map +1 -0
  100. package/renderer/use-root-view.d.ts +2 -1
  101. package/renderer/use-root-view.d.ts.map +1 -0
  102. package/renderer/use-ui-node.d.ts +2 -1
  103. package/renderer/use-ui-node.d.ts.map +1 -0
  104. package/renderer/use-ui-store.d.ts +2 -1
  105. package/renderer/use-ui-store.d.ts.map +1 -0
  106. package/shadertoy/shadertoy-gl.d.ts +1 -0
  107. package/shadertoy/shadertoy-gl.d.ts.map +1 -0
  108. package/shadertoy/shadertoy-module.d.ts +4 -3
  109. package/shadertoy/shadertoy-module.d.ts.map +1 -0
  110. package/shadertoy/shadertoy-renderer.d.ts +1 -1
  111. package/shadertoy/shadertoy-renderer.d.ts.map +1 -0
  112. package/shadertoy/shadertoy-type.d.ts +2 -0
  113. package/shadertoy/shadertoy-type.d.ts.map +1 -0
  114. package/shadertoy-renderer-Cq1lOXBs.js +428 -0
  115. package/shadertoy-type-Cs2WeCWV.js +15 -0
  116. package/shared/render-motion-letters.d.ts +1 -0
  117. package/shared/render-motion-letters.d.ts.map +1 -0
  118. package/surface.d.ts +8 -5
  119. package/surface.d.ts.map +1 -0
  120. package/theme/ikon-auth.css +7 -5
  121. package/use-ikon-styles.d.ts +2 -1
  122. package/use-ikon-styles.d.ts.map +1 -0
  123. package/use-ikon-ui-stores.d.ts +2 -0
  124. package/use-ikon-ui-stores.d.ts.map +1 -0
  125. package/app/connection-state-renderer.spec.d.ts +0 -1
  126. package/app/ikon-app.spec.d.ts +0 -1
  127. package/auth/auth-context.spec.d.ts +0 -1
  128. package/base/focus-hint-scroll.spec.d.ts +0 -1
  129. package/media/use-media-capture.spec.d.ts +0 -1
  130. package/media/use-sibling-client.spec.d.ts +0 -1
  131. package/media/video-stream-view.spec.d.ts +0 -1
  132. package/renderer/unresolved-node.spec.d.ts +0 -1
  133. package/vite.config.d.ts +0 -2
@@ -1,3 +1,4 @@
1
1
  import { IkonUiComponentResolver } from '../ikon-ui-registry';
2
2
  export declare function createBaseDivResolver(): IkonUiComponentResolver;
3
3
  export declare function createBaseResolvers(): IkonUiComponentResolver[];
4
+ //# sourceMappingURL=base-div.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-div.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/base/base-div.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAocnE,wBAAgB,qBAAqB,IAAI,uBAAuB,CAmD/D;AAsDD,wBAAgB,mBAAmB,IAAI,uBAAuB,EAAE,CAO/D"}
@@ -4,3 +4,4 @@ export declare const IKON_UI_BASE_MODULE = "base";
4
4
  export declare const loadBaseModule: IkonUiModuleLoader;
5
5
  export declare function registerBaseModule(registry: IkonUiRegistry): void;
6
6
  export { createBaseResolvers };
7
+ //# sourceMappingURL=base-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-module.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/base/base-module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAE1C,eAAO,MAAM,cAAc,EAAE,kBAAsD,CAAC;AAEpF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAEjE;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Arbitrates `std.focus-hint` nodes: the ranking, cooldown and announcement half of the FocusHint
3
+ * contract. The renderer submits one hint per effect run; the dispatcher decides whether it acts,
4
+ * and when.
5
+ *
6
+ * - Hints submitted in the same tick compete. Within each scroll container only the highest
7
+ * `ranking` scrolls it, on every re-send, which is what keeps a streaming reply followed. Focus
8
+ * and the announcement go to the highest-ranked hint with something new, a hint key or region
9
+ * text its region has not acted on yet. Ties go to the one submitted last, as rendering in
10
+ * document order did before.
11
+ * - `cooldownMs` is per region, the element the hint was placed in. A hint arriving inside the
12
+ * window is held and acts when the window ends, replacing any hint already held there, so a
13
+ * churning region acts at most once per window and still lands on its latest state.
14
+ * - The announcement waits until the region's text has been still for a settle window (the longer
15
+ * of `ANNOUNCEMENT_SETTLE_MS` and the cooldown), so a streamed reply is read once it stops, not
16
+ * every time a chunk lands. It says what arrived: only the appended part when the text extends
17
+ * what that region last announced, otherwise the whole text. Past the cap the oldest part is
18
+ * dropped, so the newest content is what is read.
19
+ * - The announcement goes through one shared, visually hidden live region per politeness, so it
20
+ * reaches a screen reader whatever the hinted element's own markup is.
21
+ */
22
+ export type FocusHintPoliteness = 'polite' | 'assertive';
23
+ export interface FocusHintSubmission {
24
+ /** The element the hint was placed in: its text is announced and its cooldown is kept. */
25
+ readonly region: HTMLElement;
26
+ readonly hintKey: string | undefined;
27
+ readonly ranking: number;
28
+ readonly cooldownMs: number;
29
+ /** Null for a hint that does not scroll. */
30
+ readonly scrollGroup: object | null;
31
+ /** Null for a hint that moves focus without an announcement. */
32
+ readonly politeness: FocusHintPoliteness | null;
33
+ /** Scrolls the region into view, returning what undoes its listeners. */
34
+ scroll(): (() => void) | undefined;
35
+ focus(): void;
36
+ }
37
+ export interface FocusHintHandle {
38
+ cancel(): void;
39
+ }
40
+ export declare function submitFocusHint(submission: FocusHintSubmission): FocusHintHandle;
41
+ //# sourceMappingURL=focus-hint-dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-hint-dispatch.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/base/focus-hint-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,gEAAgE;IAChE,QAAQ,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,yEAAyE;IACzE,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,IAAI,IAAI,CAAC;CAChB;AA8CD,wBAAgB,eAAe,CAAC,UAAU,EAAE,mBAAmB,GAAG,eAAe,CAoBhF"}
@@ -0,0 +1,35 @@
1
+ import { ConsentAnswers, ConsentRecord, IkonClient } from '@ikonai/sdk';
2
+ export interface UseConsentOptions {
3
+ /** The connected client the answers are read through. Nothing is read while it is null. */
4
+ client: IkonClient | null;
5
+ /** The purposes this screen asks about. */
6
+ purposes: readonly string[];
7
+ }
8
+ export interface UseConsentResult {
9
+ /** Every answer the signed-in user has given, keyed by purpose. */
10
+ answers: ConsentAnswers;
11
+ /** True while the answers are being read. */
12
+ isLoading: boolean;
13
+ /** True while an answer is being recorded. */
14
+ isSubmitting: boolean;
15
+ /** The last failure, in the app's own words, or null. */
16
+ error: string | null;
17
+ /** The answer for one purpose; not-asked when there is none. Never granted by default. */
18
+ consentFor(purpose: string): ConsentRecord;
19
+ /** Whether one purpose is granted today. False while the answers are still loading. */
20
+ isGranted(purpose: string): boolean;
21
+ grant(purpose: string): Promise<void>;
22
+ revoke(purpose: string): Promise<void>;
23
+ reload(): Promise<void>;
24
+ }
25
+ /**
26
+ * The signed-in user's consent for the purposes this screen asks about: what they have answered, and
27
+ * the two calls that record an answer and take it back.
28
+ *
29
+ * Nothing here is granted until it has been read and the answer is a yes — while the answers are
30
+ * loading, while the client is offline, and for a visitor the app cannot name, every purpose reads
31
+ * as not granted. Gate the feature on {@link UseConsentResult.isGranted}, and say that the feature
32
+ * is off rather than letting it look as though it is running.
33
+ */
34
+ export declare function useConsent({ client, purposes }: UseConsentOptions): UseConsentResult;
35
+ //# sourceMappingURL=use-consent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-consent.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/consent/use-consent.ts"],"names":[],"mappings":"AACA,OAAO,EAA0E,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/J,MAAM,WAAW,iBAAiB;IAChC,2FAA2F;IAC3F,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,2CAA2C;IAC3C,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,OAAO,EAAE,cAAc,CAAC;IACxB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,YAAY,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0FAA0F;IAC1F,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;IAC3C,uFAAuF;IACvF,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAUD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,iBAAiB,GAAG,gBAAgB,CA2FpF"}
@@ -21,4 +21,5 @@ export interface DebugOverlayProps {
21
21
  /**
22
22
  * The overlay component. Returns null unless `?ikon-debug-overlay=true` is set or `forceVisible`.
23
23
  */
24
- export declare function DebugOverlay({ state, forceVisible }: DebugOverlayProps): import("react").JSX.Element | null;
24
+ export declare function DebugOverlay({ state, forceVisible }: DebugOverlayProps): import('react').JSX.Element | null;
25
+ //# sourceMappingURL=debug-overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-overlay.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/debug/debug-overlay.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,qBAAqB,SAM9B,CAAC;AAuGL,MAAM,WAAW,iBAAiB;IAChC;sFACkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAU,EAAE,YAAoB,EAAE,EAAE,iBAAiB,sCAkDnF"}
@@ -0,0 +1,511 @@
1
+ import { FeedbackRequestError as e, IKON_CAPTURE_EXCLUDE_ATTRIBUTE as t, collectFeedbackContext as n, randomUuid as r, submitFeedbackReport as i } from "@ikonai/sdk";
2
+ import { useEffect as a, useId as o, useMemo as s, useRef as c, useState as l } from "react";
3
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
4
+ //#region src/app/feedback/feedback-form.tsx
5
+ var f = [
6
+ {
7
+ kind: "bug",
8
+ label: "Something's wrong"
9
+ },
10
+ {
11
+ kind: "idea",
12
+ label: "Idea"
13
+ },
14
+ {
15
+ kind: "confusing",
16
+ label: "Confusing"
17
+ },
18
+ {
19
+ kind: "praise",
20
+ label: "Love this"
21
+ }
22
+ ], p = 10, m = 26214400, h = 52428800, g = 10001, _ = 1e4;
23
+ function v({ access: e, screenshot: g, appSession: v, clientSession: y, onClose: x, onDirtyChange: C }) {
24
+ let w = o(), T = o(), [E, D] = l("bug"), [O, k] = l(""), [A, j] = l([]), [M, N] = l(null), [P, F] = l(g ? { status: "pending" } : { status: "none" }), [I, L] = l({ status: "idle" }), [R, z] = l(!1), [B] = l(() => r()), V = c(null), H = c(null);
25
+ a(() => {
26
+ H.current?.focus();
27
+ }, []), a(() => {
28
+ if (!g) return;
29
+ let e = !1, t = null, n = setTimeout(() => {
30
+ e = !0, F({ status: "failed" });
31
+ }, _);
32
+ return g.then((r) => {
33
+ e || (clearTimeout(n), t = URL.createObjectURL(r.png), F({
34
+ status: "ready",
35
+ image: r,
36
+ url: t
37
+ }));
38
+ }, () => {
39
+ e || (clearTimeout(n), F({ status: "failed" }));
40
+ }), () => {
41
+ e = !0, clearTimeout(n), t && URL.revokeObjectURL(t);
42
+ };
43
+ }, [g]);
44
+ let U = P.status === "ready" ? P.image.png : null, W = O.trim().length > 0 || A.length > 0;
45
+ a(() => {
46
+ C?.(W);
47
+ }, [W, C]);
48
+ let G = (e) => {
49
+ if (e.length === 0) return;
50
+ let t = [...A], n = [], r = t.reduce((e, t) => e + t.size, 0) + (U?.size ?? 0);
51
+ for (let i of e) t.length >= p ? n.push(`${i.name} (at most ${p} files)`) : i.size > m ? n.push(`${i.name} (over 25 MB)`) : r + i.size > h ? n.push(`${i.name} (the report would pass 50 MB)`) : (t.push(i), r += i.size);
52
+ j(t), N(n.length > 0 ? `Not attached: ${n.join(", ")}` : null);
53
+ }, K = (e) => {
54
+ j((t) => t.filter((t, n) => n !== e)), N(null);
55
+ }, q = () => {
56
+ P.status === "ready" && URL.revokeObjectURL(P.url), F({ status: "none" });
57
+ }, J = I.status !== "sending" && P.status !== "pending" && (O.trim().length > 0 || A.length > 0 || U !== null), Y = async () => {
58
+ if (J) {
59
+ if (!e) {
60
+ L({
61
+ status: "failed",
62
+ message: "Feedback cannot be sent from this page because it is not signed in to the app."
63
+ });
64
+ return;
65
+ }
66
+ L({ status: "sending" });
67
+ try {
68
+ await i(e, {
69
+ kind: E,
70
+ text: O.trim(),
71
+ context: n(),
72
+ appSession: v,
73
+ clientSession: y
74
+ }, {
75
+ files: A,
76
+ screenshot: U
77
+ }, { draftId: B }), L({ status: "sent" });
78
+ } catch (e) {
79
+ L({
80
+ status: "failed",
81
+ message: ee(e)
82
+ });
83
+ }
84
+ }
85
+ }, X = c(null), Z = (e) => {
86
+ if (e.key === "Escape" && I.status !== "sending") {
87
+ e.stopPropagation(), x();
88
+ return;
89
+ }
90
+ e.key === "Tab" && b(e, X.current);
91
+ }, te = (e) => {
92
+ let t = e.key === "ArrowRight" || e.key === "ArrowDown" ? 1 : e.key === "ArrowLeft" || e.key === "ArrowUp" ? -1 : 0;
93
+ if (t === 0) return;
94
+ e.preventDefault();
95
+ let n = f[(f.findIndex((e) => e.kind === E) + t + f.length) % f.length];
96
+ D(n.kind), e.currentTarget.querySelector(`[data-kind="${n.kind}"]`)?.focus();
97
+ }, ne = (e) => {
98
+ e.preventDefault(), z(!1), G(Array.from(e.dataTransfer?.files ?? []));
99
+ }, Q = { [t]: "" }, $ = s(() => S(R), [R]);
100
+ return I.status === "sent" ? /* @__PURE__ */ u("div", {
101
+ ...Q,
102
+ style: $.scrim,
103
+ onKeyDown: Z,
104
+ children: /* @__PURE__ */ d("div", {
105
+ ref: X,
106
+ role: "dialog",
107
+ "aria-modal": "true",
108
+ "aria-labelledby": w,
109
+ style: $.panel,
110
+ children: [
111
+ /* @__PURE__ */ u("h2", {
112
+ id: w,
113
+ style: $.title,
114
+ children: "Thanks, your report was sent"
115
+ }),
116
+ /* @__PURE__ */ u("p", {
117
+ style: $.note,
118
+ children: "The people building this app will read it."
119
+ }),
120
+ /* @__PURE__ */ u("div", {
121
+ style: $.actions,
122
+ children: /* @__PURE__ */ u("button", {
123
+ type: "button",
124
+ style: $.primary,
125
+ onClick: x,
126
+ autoFocus: !0,
127
+ children: "Close"
128
+ })
129
+ })
130
+ ]
131
+ })
132
+ }) : /* @__PURE__ */ u("div", {
133
+ ...Q,
134
+ style: $.scrim,
135
+ onKeyDown: Z,
136
+ children: /* @__PURE__ */ d("div", {
137
+ ref: X,
138
+ role: "dialog",
139
+ "aria-modal": "true",
140
+ "aria-labelledby": w,
141
+ style: $.panel,
142
+ onDragOver: (e) => {
143
+ e.preventDefault(), z(!0);
144
+ },
145
+ onDragLeave: () => z(!1),
146
+ onDrop: ne,
147
+ children: [
148
+ /* @__PURE__ */ u("h2", {
149
+ id: w,
150
+ style: $.title,
151
+ children: "Send feedback"
152
+ }),
153
+ /* @__PURE__ */ u("div", {
154
+ role: "radiogroup",
155
+ "aria-label": "Kind of feedback",
156
+ style: $.kinds,
157
+ onKeyDown: te,
158
+ children: f.map((e) => /* @__PURE__ */ u("button", {
159
+ type: "button",
160
+ role: "radio",
161
+ "data-kind": e.kind,
162
+ "aria-checked": E === e.kind,
163
+ tabIndex: E === e.kind ? 0 : -1,
164
+ style: E === e.kind ? $.kindSelected : $.kind,
165
+ onClick: () => D(e.kind),
166
+ children: e.label
167
+ }, e.kind))
168
+ }),
169
+ /* @__PURE__ */ u("label", {
170
+ htmlFor: T,
171
+ style: $.label,
172
+ children: "What would you like to tell us?"
173
+ }),
174
+ /* @__PURE__ */ u("textarea", {
175
+ ref: H,
176
+ id: T,
177
+ value: O,
178
+ onChange: (e) => k(e.target.value),
179
+ rows: 5,
180
+ style: $.textarea
181
+ }),
182
+ /* @__PURE__ */ d("div", {
183
+ style: $.attachRow,
184
+ children: [
185
+ /* @__PURE__ */ u("button", {
186
+ type: "button",
187
+ style: $.secondary,
188
+ onClick: () => V.current?.click(),
189
+ children: "Attach files"
190
+ }),
191
+ /* @__PURE__ */ u("span", {
192
+ style: $.note,
193
+ children: "or drop them here"
194
+ }),
195
+ /* @__PURE__ */ u("input", {
196
+ ref: V,
197
+ type: "file",
198
+ multiple: !0,
199
+ hidden: !0,
200
+ "aria-label": "Attach files",
201
+ onChange: (e) => {
202
+ G(Array.from(e.target.files ?? [])), e.target.value = "";
203
+ }
204
+ })
205
+ ]
206
+ }),
207
+ A.length > 0 && /* @__PURE__ */ u("ul", {
208
+ "aria-label": "Attached files",
209
+ style: $.fileList,
210
+ children: A.map((e, t) => /* @__PURE__ */ d("li", {
211
+ style: $.fileItem,
212
+ children: [/* @__PURE__ */ u("span", {
213
+ style: $.fileName,
214
+ children: e.name
215
+ }), /* @__PURE__ */ u("button", {
216
+ type: "button",
217
+ style: $.link,
218
+ "aria-label": `Remove ${e.name}`,
219
+ onClick: () => K(t),
220
+ children: "Remove"
221
+ })]
222
+ }, `${e.name}-${t}`))
223
+ }),
224
+ M && /* @__PURE__ */ u("p", {
225
+ role: "status",
226
+ style: $.warning,
227
+ children: M
228
+ }),
229
+ /* @__PURE__ */ u("p", {
230
+ "aria-live": "polite",
231
+ style: P.status === "pending" ? $.note : $.hidden,
232
+ children: P.status === "pending" ? "Taking a screenshot…" : ""
233
+ }),
234
+ P.status === "failed" && /* @__PURE__ */ u("p", {
235
+ style: $.note,
236
+ children: "The screenshot could not be taken."
237
+ }),
238
+ P.status === "ready" && /* @__PURE__ */ d("figure", {
239
+ style: $.screenshot,
240
+ children: [/* @__PURE__ */ u("img", {
241
+ src: P.url,
242
+ alt: "Screenshot of the app, sent with the report",
243
+ style: $.thumbnail
244
+ }), /* @__PURE__ */ d("figcaption", {
245
+ style: $.screenshotCaption,
246
+ children: [P.image.lostContent && /* @__PURE__ */ u("span", {
247
+ style: $.note,
248
+ children: "Some content could not be captured and shows as grey."
249
+ }), /* @__PURE__ */ u("button", {
250
+ type: "button",
251
+ style: $.link,
252
+ onClick: q,
253
+ children: "Remove screenshot"
254
+ })]
255
+ })]
256
+ }),
257
+ /* @__PURE__ */ u("p", {
258
+ style: $.note,
259
+ children: "Read by the app's team and AI. Includes this screen, the page address and your device details."
260
+ }),
261
+ I.status === "failed" && /* @__PURE__ */ u("p", {
262
+ role: "alert",
263
+ style: $.error,
264
+ children: I.message
265
+ }),
266
+ /* @__PURE__ */ d("div", {
267
+ style: $.actions,
268
+ children: [/* @__PURE__ */ u("button", {
269
+ type: "button",
270
+ style: $.secondary,
271
+ onClick: x,
272
+ disabled: I.status === "sending",
273
+ children: "Cancel"
274
+ }), /* @__PURE__ */ u("button", {
275
+ type: "button",
276
+ style: J ? $.primary : $.primaryDisabled,
277
+ onClick: () => void Y(),
278
+ disabled: !J,
279
+ children: I.status === "sending" ? "Sending…" : I.status === "failed" ? "Try again" : "Send"
280
+ })]
281
+ })
282
+ ]
283
+ })
284
+ });
285
+ }
286
+ var y = "button:not([disabled]), textarea:not([disabled]), input:not([disabled]):not([type=\"hidden\"]):not([hidden]), [href], [tabindex]:not([tabindex=\"-1\"])";
287
+ function b(e, t) {
288
+ if (!t) return;
289
+ let n = Array.from(t.querySelectorAll(y));
290
+ if (n.length === 0) {
291
+ e.preventDefault();
292
+ return;
293
+ }
294
+ let r = n[0], i = n[n.length - 1], a = t.ownerDocument.activeElement;
295
+ e.shiftKey && (a === r || !t.contains(a)) ? (e.preventDefault(), i.focus()) : !e.shiftKey && (a === i || !t.contains(a)) && (e.preventDefault(), r.focus());
296
+ }
297
+ function ee(t) {
298
+ return t instanceof e ? t.status === 0 ? "Your report could not be sent: the feedback service is unreachable. Check the connection and try again." : t.status === 401 || t.status === 403 ? `Your report could not be sent: this account may not send feedback for this app (${t.message}).` : t.status === 413 ? "Your report could not be sent: the attachments are too large. Remove some and try again." : t.status === 429 ? "Your report could not be sent: too many reports in a short time. Try again later." : `Your report could not be sent: ${t.message}` : `Your report could not be sent: ${t instanceof Error ? t.message : String(t)}`;
299
+ }
300
+ var x = {
301
+ card: "var(--ikon-bg-card, #ffffff)",
302
+ subtle: "var(--ikon-bg-subtle, #f4f4f5)",
303
+ solid: "var(--ikon-bg-solid, #161618)",
304
+ onSolid: "var(--ikon-text-on-solid, #ffffff)",
305
+ text: "var(--ikon-text-primary, #161618)",
306
+ muted: "var(--ikon-text-tertiary, #6e6e74)",
307
+ border: "var(--ikon-border-primary, #d4d4d7)",
308
+ borderSoft: "var(--ikon-border-secondary, #e8e8ea)",
309
+ error: "var(--ikon-error-text, #b32218)",
310
+ errorSurface: "var(--ikon-error-surface, #fef2f1)",
311
+ warning: "var(--ikon-status-warning, #db6803)",
312
+ scrim: "var(--ikon-overlay-scrim, rgba(22, 22, 24, 0.5))",
313
+ focus: "var(--ikon-brand-500, #f5277f)"
314
+ };
315
+ function S(e) {
316
+ let t = {
317
+ minHeight: 40,
318
+ padding: "0 14px",
319
+ borderRadius: "var(--ikon-radius-md, 4px)",
320
+ font: "inherit",
321
+ fontSize: 14,
322
+ cursor: "pointer"
323
+ }, n = {
324
+ ...t,
325
+ minHeight: 36,
326
+ borderRadius: "var(--ikon-radius-full, 9999px)",
327
+ border: `1px solid ${x.border}`,
328
+ background: x.card,
329
+ color: x.text
330
+ };
331
+ return {
332
+ scrim: {
333
+ position: "fixed",
334
+ top: 0,
335
+ right: 0,
336
+ bottom: 0,
337
+ left: 0,
338
+ zIndex: g,
339
+ display: "flex",
340
+ alignItems: "center",
341
+ justifyContent: "center",
342
+ padding: 16,
343
+ background: x.scrim,
344
+ boxSizing: "border-box"
345
+ },
346
+ panel: {
347
+ boxSizing: "border-box",
348
+ width: "100%",
349
+ maxWidth: 460,
350
+ maxHeight: "100%",
351
+ overflowY: "auto",
352
+ padding: 20,
353
+ display: "flex",
354
+ flexDirection: "column",
355
+ gap: 12,
356
+ background: x.card,
357
+ color: x.text,
358
+ border: `1px ${e ? "dashed" : "solid"} ${e ? x.focus : x.borderSoft}`,
359
+ borderRadius: "var(--ikon-radius-xl, 8px)",
360
+ boxShadow: "0 12px 40px rgba(0, 0, 0, 0.25)",
361
+ font: "15px/1.45 var(--ikon-font-body, system-ui, -apple-system, \"Segoe UI\", sans-serif)"
362
+ },
363
+ title: {
364
+ margin: 0,
365
+ fontSize: 18,
366
+ fontWeight: 600
367
+ },
368
+ kinds: {
369
+ display: "flex",
370
+ flexWrap: "wrap",
371
+ gap: 8
372
+ },
373
+ kind: n,
374
+ kindSelected: {
375
+ ...n,
376
+ background: x.solid,
377
+ color: x.onSolid,
378
+ borderColor: x.solid
379
+ },
380
+ label: {
381
+ fontSize: 14,
382
+ fontWeight: 500
383
+ },
384
+ textarea: {
385
+ boxSizing: "border-box",
386
+ width: "100%",
387
+ padding: 10,
388
+ resize: "vertical",
389
+ font: "inherit",
390
+ color: x.text,
391
+ background: x.card,
392
+ border: `1px solid ${x.border}`,
393
+ borderRadius: "var(--ikon-radius-md, 4px)"
394
+ },
395
+ attachRow: {
396
+ display: "flex",
397
+ alignItems: "center",
398
+ gap: 10
399
+ },
400
+ fileList: {
401
+ margin: 0,
402
+ padding: 0,
403
+ listStyle: "none",
404
+ display: "flex",
405
+ flexDirection: "column",
406
+ gap: 4
407
+ },
408
+ fileItem: {
409
+ display: "flex",
410
+ alignItems: "center",
411
+ justifyContent: "space-between",
412
+ gap: 8,
413
+ padding: "4px 8px",
414
+ background: x.subtle,
415
+ borderRadius: "var(--ikon-radius-md, 4px)"
416
+ },
417
+ fileName: {
418
+ overflow: "hidden",
419
+ textOverflow: "ellipsis",
420
+ whiteSpace: "nowrap",
421
+ fontSize: 14
422
+ },
423
+ screenshot: {
424
+ margin: 0,
425
+ display: "flex",
426
+ gap: 10,
427
+ alignItems: "flex-start"
428
+ },
429
+ thumbnail: {
430
+ width: 120,
431
+ maxHeight: 120,
432
+ objectFit: "contain",
433
+ objectPosition: "top left",
434
+ border: `1px solid ${x.borderSoft}`,
435
+ borderRadius: "var(--ikon-radius-md, 4px)",
436
+ background: x.subtle
437
+ },
438
+ screenshotCaption: {
439
+ display: "flex",
440
+ flexDirection: "column",
441
+ alignItems: "flex-start",
442
+ gap: 4
443
+ },
444
+ note: {
445
+ margin: 0,
446
+ fontSize: 13,
447
+ color: x.muted
448
+ },
449
+ hidden: {
450
+ position: "absolute",
451
+ width: 1,
452
+ height: 1,
453
+ margin: -1,
454
+ padding: 0,
455
+ overflow: "hidden",
456
+ clip: "rect(0 0 0 0)",
457
+ border: 0
458
+ },
459
+ warning: {
460
+ margin: 0,
461
+ fontSize: 13,
462
+ color: x.warning
463
+ },
464
+ error: {
465
+ margin: 0,
466
+ padding: "8px 10px",
467
+ fontSize: 14,
468
+ color: x.error,
469
+ background: x.errorSurface,
470
+ borderRadius: "var(--ikon-radius-md, 4px)"
471
+ },
472
+ actions: {
473
+ display: "flex",
474
+ justifyContent: "flex-end",
475
+ gap: 8,
476
+ marginTop: 4
477
+ },
478
+ primary: {
479
+ ...t,
480
+ border: "1px solid transparent",
481
+ background: x.solid,
482
+ color: x.onSolid
483
+ },
484
+ primaryDisabled: {
485
+ ...t,
486
+ border: "1px solid transparent",
487
+ background: x.solid,
488
+ color: x.onSolid,
489
+ opacity: .5,
490
+ cursor: "default"
491
+ },
492
+ secondary: {
493
+ ...t,
494
+ border: `1px solid ${x.border}`,
495
+ background: x.card,
496
+ color: x.text
497
+ },
498
+ link: {
499
+ padding: 0,
500
+ border: "none",
501
+ background: "none",
502
+ color: x.text,
503
+ font: "inherit",
504
+ fontSize: 13,
505
+ textDecoration: "underline",
506
+ cursor: "pointer"
507
+ }
508
+ };
509
+ }
510
+ //#endregion
511
+ export { g as FEEDBACK_DIALOG_Z_INDEX, f as FEEDBACK_KIND_OPTIONS, v as FeedbackForm, _ as SCREENSHOT_WAIT_MS };
package/hooks/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { useToasts, type Toast } from './use-toasts';
2
2
  export { useIkonReactive } from './use-ikon-reactive';
3
3
  export { useReactive } from './use-reactive';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { IkonClient } from '../../sdk/sdk/src/index.ts';
1
+ import { IkonClient } from '@ikonai/sdk';
2
2
  /**
3
3
  * Subscribe to a server-side <c>Reactive&lt;T&gt;</c> and re-render whenever
4
4
  * the value changes. The hook returns the current value, starting from the
@@ -12,3 +12,4 @@ import { IkonClient } from '../../sdk/sdk/src/index.ts';
12
12
  * <c>useState</c> plumbing.
13
13
  */
14
14
  export declare function useIkonReactive<T>(client: IkonClient | null | undefined, stableId: string, initialValue: T): T;
15
+ //# sourceMappingURL=use-ikon-reactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-ikon-reactive.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/hooks/use-ikon-reactive.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,GACd,CAAC,CAoCH"}
@@ -1,4 +1,4 @@
1
- import { IkonClient } from '../../sdk/sdk/src/index.ts';
1
+ import { IkonClient } from '@ikonai/sdk';
2
2
  /**
3
3
  * Subscribe to a server-side <c>Reactive&lt;T&gt;</c> by the C# member name it
4
4
  * was declared with. Resolves the stable id once via the framework function
@@ -13,3 +13,4 @@ import { IkonClient } from '../../sdk/sdk/src/index.ts';
13
13
  * per-app helper RPC to fetch the hashed stable id.
14
14
  */
15
15
  export declare function useReactive<T>(client: IkonClient | null | undefined, memberName: string, initialValue: T): T;
16
+ //# sourceMappingURL=use-reactive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-reactive.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/hooks/use-reactive.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACrC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GACd,CAAC,CA2BH"}
@@ -8,3 +8,4 @@ export declare function useToasts(maxToasts?: number, autoDismissMs?: number): {
8
8
  toasts: Toast[];
9
9
  dismissToast: (id: string) => void;
10
10
  };
11
+ //# sourceMappingURL=use-toasts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-toasts.d.ts","sourceRoot":"","sources":["../../../../sdk/sdk-react-ui/src/hooks/use-toasts.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,SAAS,CAAC,SAAS,SAAI,EAAE,aAAa,SAAO;;uBAIrB,MAAM;EAqD7C"}