@hexclave/next 1.0.13 → 1.0.15

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 (189) hide show
  1. package/dist/clickmap/clickmap-core.d.ts +15 -0
  2. package/dist/clickmap/clickmap-core.d.ts.map +1 -0
  3. package/dist/clickmap/clickmap-core.js +1527 -0
  4. package/dist/clickmap/clickmap-core.js.map +1 -0
  5. package/dist/clickmap/clickmap-styles.d.ts +5 -0
  6. package/dist/clickmap/clickmap-styles.d.ts.map +1 -0
  7. package/dist/clickmap/clickmap-styles.js +1095 -0
  8. package/dist/clickmap/clickmap-styles.js.map +1 -0
  9. package/dist/clickmap/index.d.ts +16 -0
  10. package/dist/clickmap/index.d.ts.map +1 -0
  11. package/dist/clickmap/index.js +74 -0
  12. package/dist/clickmap/index.js.map +1 -0
  13. package/dist/components/api-key-dialogs.js +2 -2
  14. package/dist/components/credential-sign-in.js +1 -1
  15. package/dist/components/credential-sign-up.js +1 -1
  16. package/dist/components/magic-link-sign-in.js +1 -1
  17. package/dist/components/message-cards/known-error-message-card.d.ts +1 -1
  18. package/dist/components/team-switcher.js +1 -1
  19. package/dist/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
  20. package/dist/components-page/account-settings/email-and-auth/emails-section.js +1 -1
  21. package/dist/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
  22. package/dist/components-page/account-settings/email-and-auth/password-section.js +1 -1
  23. package/dist/components-page/account-settings/teams/team-creation-page.js +1 -1
  24. package/dist/components-page/account-settings/teams/team-member-invitation-section.js +1 -1
  25. package/dist/components-page/auth-page.js +1 -1
  26. package/dist/components-page/cli-auth-confirm.js +1 -1
  27. package/dist/components-page/cli-auth-confirm.test.js +1 -1
  28. package/dist/components-page/forgot-password.d.ts.map +1 -1
  29. package/dist/components-page/forgot-password.js +2 -3
  30. package/dist/components-page/forgot-password.js.map +1 -1
  31. package/dist/components-page/hexclave-handler-client.d.ts +1 -1
  32. package/dist/components-page/mfa.js +4 -19
  33. package/dist/components-page/mfa.js.map +1 -1
  34. package/dist/components-page/oauth-callback.js +1 -1
  35. package/dist/components-page/onboarding.js +1 -1
  36. package/dist/components-page/password-reset.d.ts.map +1 -1
  37. package/dist/components-page/password-reset.js +5 -7
  38. package/dist/components-page/password-reset.js.map +1 -1
  39. package/dist/components-page/team-creation.js +1 -1
  40. package/dist/dev-tool/dev-tool-core.d.ts.map +1 -1
  41. package/dist/dev-tool/dev-tool-core.js +258 -262
  42. package/dist/dev-tool/dev-tool-core.js.map +1 -1
  43. package/dist/dev-tool/dev-tool-styles.d.ts +1 -1
  44. package/dist/dev-tool/dev-tool-styles.d.ts.map +1 -1
  45. package/dist/dev-tool/dev-tool-styles.js +13 -143
  46. package/dist/dev-tool/dev-tool-styles.js.map +1 -1
  47. package/dist/dev-tool/index.d.ts.map +1 -1
  48. package/dist/dev-tool/index.js +5 -12
  49. package/dist/dev-tool/index.js.map +1 -1
  50. package/dist/esm/clickmap/clickmap-core.d.ts +15 -0
  51. package/dist/esm/clickmap/clickmap-core.d.ts.map +1 -0
  52. package/dist/esm/clickmap/clickmap-core.js +1525 -0
  53. package/dist/esm/clickmap/clickmap-core.js.map +1 -0
  54. package/dist/esm/clickmap/clickmap-styles.d.ts +5 -0
  55. package/dist/esm/clickmap/clickmap-styles.d.ts.map +1 -0
  56. package/dist/esm/clickmap/clickmap-styles.js +1093 -0
  57. package/dist/esm/clickmap/clickmap-styles.js.map +1 -0
  58. package/dist/esm/clickmap/index.d.ts +16 -0
  59. package/dist/esm/clickmap/index.d.ts.map +1 -0
  60. package/dist/esm/clickmap/index.js +72 -0
  61. package/dist/esm/clickmap/index.js.map +1 -0
  62. package/dist/esm/components/api-key-dialogs.js +2 -2
  63. package/dist/esm/components/credential-sign-in.js +1 -1
  64. package/dist/esm/components/credential-sign-up.js +1 -1
  65. package/dist/esm/components/magic-link-sign-in.js +1 -1
  66. package/dist/esm/components/team-switcher.js +1 -1
  67. package/dist/esm/components-page/account-settings/active-sessions/active-sessions-page.js +1 -1
  68. package/dist/esm/components-page/account-settings/email-and-auth/emails-section.js +1 -1
  69. package/dist/esm/components-page/account-settings/email-and-auth/mfa-section.js +1 -1
  70. package/dist/esm/components-page/account-settings/email-and-auth/password-section.js +1 -1
  71. package/dist/esm/components-page/account-settings/teams/team-creation-page.js +1 -1
  72. package/dist/esm/components-page/account-settings/teams/team-member-invitation-section.js +1 -1
  73. package/dist/esm/components-page/auth-page.js +1 -1
  74. package/dist/esm/components-page/cli-auth-confirm.js +1 -1
  75. package/dist/esm/components-page/cli-auth-confirm.test.js +1 -1
  76. package/dist/esm/components-page/forgot-password.d.ts.map +1 -1
  77. package/dist/esm/components-page/forgot-password.js +2 -3
  78. package/dist/esm/components-page/forgot-password.js.map +1 -1
  79. package/dist/esm/components-page/hexclave-handler-client.d.ts +1 -1
  80. package/dist/esm/components-page/mfa.js +4 -19
  81. package/dist/esm/components-page/mfa.js.map +1 -1
  82. package/dist/esm/components-page/oauth-callback.js +1 -1
  83. package/dist/esm/components-page/onboarding.js +1 -1
  84. package/dist/esm/components-page/password-reset.d.ts.map +1 -1
  85. package/dist/esm/components-page/password-reset.js +5 -7
  86. package/dist/esm/components-page/password-reset.js.map +1 -1
  87. package/dist/esm/components-page/team-creation.js +1 -1
  88. package/dist/esm/dev-tool/dev-tool-core.d.ts.map +1 -1
  89. package/dist/esm/dev-tool/dev-tool-core.js +35 -39
  90. package/dist/esm/dev-tool/dev-tool-core.js.map +1 -1
  91. package/dist/esm/dev-tool/dev-tool-styles.d.ts +1 -1
  92. package/dist/esm/dev-tool/dev-tool-styles.d.ts.map +1 -1
  93. package/dist/esm/dev-tool/dev-tool-styles.js +13 -143
  94. package/dist/esm/dev-tool/dev-tool-styles.js.map +1 -1
  95. package/dist/esm/dev-tool/index.d.ts.map +1 -1
  96. package/dist/esm/dev-tool/index.js +2 -9
  97. package/dist/esm/dev-tool/index.js.map +1 -1
  98. package/dist/esm/generated/global-css.d.ts +1 -1
  99. package/dist/esm/generated/global-css.js +1 -1
  100. package/dist/esm/generated/global-css.js.map +1 -1
  101. package/dist/esm/generated/quetzal-translations.d.ts +2 -2
  102. package/dist/esm/in-page-ui/base-styles.d.ts +5 -0
  103. package/dist/esm/in-page-ui/base-styles.d.ts.map +1 -0
  104. package/dist/esm/in-page-ui/base-styles.js +166 -0
  105. package/dist/esm/in-page-ui/base-styles.js.map +1 -0
  106. package/dist/esm/in-page-ui/dom.d.ts +15 -0
  107. package/dist/esm/in-page-ui/dom.d.ts.map +1 -0
  108. package/dist/esm/in-page-ui/dom.js +44 -0
  109. package/dist/esm/in-page-ui/dom.js.map +1 -0
  110. package/dist/esm/lib/auth.js +1 -1
  111. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -1
  112. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  113. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js +20 -0
  114. package/dist/esm/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  115. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  116. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js +4 -2
  117. package/dist/esm/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  118. package/dist/esm/lib/hexclave-app/apps/implementations/common.js +2 -2
  119. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts +13 -0
  120. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  121. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
  122. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  123. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
  124. package/dist/esm/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
  125. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  126. package/dist/esm/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  127. package/dist/esm/lib/hexclave-app/apps/implementations/session-replay.js +1 -1
  128. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
  129. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
  130. package/dist/esm/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
  131. package/dist/esm/providers/theme-provider.js +1 -1
  132. package/dist/generated/global-css.d.ts +1 -1
  133. package/dist/generated/global-css.js +1 -1
  134. package/dist/generated/global-css.js.map +1 -1
  135. package/dist/generated/quetzal-translations.d.ts +2 -2
  136. package/dist/in-page-ui/base-styles.d.ts +5 -0
  137. package/dist/in-page-ui/base-styles.d.ts.map +1 -0
  138. package/dist/in-page-ui/base-styles.js +168 -0
  139. package/dist/in-page-ui/base-styles.js.map +1 -0
  140. package/dist/in-page-ui/dom.d.ts +15 -0
  141. package/dist/in-page-ui/dom.d.ts.map +1 -0
  142. package/dist/in-page-ui/dom.js +51 -0
  143. package/dist/in-page-ui/dom.js.map +1 -0
  144. package/dist/index.d.ts +1 -1
  145. package/dist/integrations/convex/component/convex.config.d.ts +1 -1
  146. package/dist/lib/auth.js +1 -1
  147. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts +5 -1
  148. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.d.ts.map +1 -1
  149. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js +20 -0
  150. package/dist/lib/hexclave-app/apps/implementations/admin-app-impl.js.map +1 -1
  151. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.d.ts.map +1 -1
  152. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js +4 -2
  153. package/dist/lib/hexclave-app/apps/implementations/client-app-impl.js.map +1 -1
  154. package/dist/lib/hexclave-app/apps/implementations/common.js +2 -2
  155. package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts +13 -0
  156. package/dist/lib/hexclave-app/apps/implementations/event-tracker.d.ts.map +1 -1
  157. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js +146 -14
  158. package/dist/lib/hexclave-app/apps/implementations/event-tracker.js.map +1 -1
  159. package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js +221 -0
  160. package/dist/lib/hexclave-app/apps/implementations/event-tracker.test.js.map +1 -1
  161. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.d.ts +1 -1
  162. package/dist/lib/hexclave-app/apps/implementations/server-app-impl.js +1 -1
  163. package/dist/lib/hexclave-app/apps/implementations/session-replay.js +1 -1
  164. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts +5 -0
  165. package/dist/lib/hexclave-app/apps/interfaces/admin-app.d.ts.map +1 -1
  166. package/dist/lib/hexclave-app/apps/interfaces/admin-app.js.map +1 -1
  167. package/dist/lib/hexclave-app/apps/interfaces/server-app.d.ts +1 -1
  168. package/dist/lib/hexclave-app/common.d.ts +1 -1
  169. package/dist/providers/hexclave-provider-client.d.ts +1 -1
  170. package/dist/providers/theme-provider.js +1 -1
  171. package/dist/{storage-CKzvsBxG.d.ts → storage-ksajV_p6.d.ts} +1 -1
  172. package/dist/{storage-CKzvsBxG.d.ts.map → storage-ksajV_p6.d.ts.map} +1 -1
  173. package/package.json +4 -4
  174. package/src/clickmap/clickmap-core.ts +1997 -0
  175. package/src/clickmap/clickmap-styles.ts +1102 -0
  176. package/src/clickmap/index.ts +95 -0
  177. package/src/components-page/forgot-password.tsx +1 -2
  178. package/src/components-page/mfa.tsx +12 -21
  179. package/src/components-page/password-reset.tsx +4 -6
  180. package/src/dev-tool/dev-tool-core.ts +38 -65
  181. package/src/dev-tool/dev-tool-styles.ts +13 -142
  182. package/src/dev-tool/index.ts +1 -14
  183. package/src/in-page-ui/base-styles.ts +171 -0
  184. package/src/in-page-ui/dom.ts +80 -0
  185. package/src/lib/hexclave-app/apps/implementations/admin-app-impl.ts +23 -1
  186. package/src/lib/hexclave-app/apps/implementations/client-app-impl.ts +7 -0
  187. package/src/lib/hexclave-app/apps/implementations/event-tracker.test.ts +287 -0
  188. package/src/lib/hexclave-app/apps/implementations/event-tracker.ts +226 -16
  189. package/src/lib/hexclave-app/apps/interfaces/admin-app.ts +3 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickmap-styles.js","names":[],"sources":["../../src/clickmap/clickmap-styles.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n// CSS for the standalone clickmap overlay.\n//\n// The clickmap is fully independent from the dev tool: it ships its own\n// stylesheet and panel chrome so the dev tool (and its stylesheet) can be\n// removed without affecting the clickmap. Class names keep the shared `sdt-`\n// prefix on purpose — the analytics ingest/query layers exclude self-clicks by\n// that prefix (see @hexclave/shared/dist/utils/dev-tool).\n// Uses the .hexclave-clickmap scope to avoid conflicts with host app styles.\n// Design tokens + base reset come from the shared in-page-ui module.\n\nimport { getInPageUiBaseCSS } from \"../in-page-ui/base-styles\";\n\nexport const clickmapCSS = getInPageUiBaseCSS('.hexclave-clickmap') + `\n /* Bottom-centered floating panel (the clickmap's only chrome) */\n .hexclave-clickmap .sdt-hm-panel {\n position: fixed;\n left: 50%;\n bottom: 18px;\n z-index: 2147483647;\n width: min(680px, calc(100vw - 24px));\n max-width: calc(100vw - 24px);\n max-height: calc(100vh - 36px);\n transform: translateX(-50%);\n display: flex;\n flex-direction: column;\n overflow: visible;\n }\n\n .hexclave-clickmap .sdt-hm-panel-inner {\n display: flex;\n flex-direction: column;\n width: 100%;\n animation: sdt-hm-panel-enter 0.2s ease-out;\n }\n\n @keyframes sdt-hm-panel-enter {\n from {\n opacity: 0;\n transform: scale(0.95) translateY(8px);\n }\n to {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n }\n\n /* --- Clickmaps --- */\n\n .hexclave-clickmap .sdt-hm {\n height: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n overflow: visible;\n background: transparent;\n }\n\n /* One spacing rhythm across the pill: a tight 2px base gap so adjacent\n controls read as clusters, with the wider between-group separation\n coming only from the metrics block's own padding (and the title's\n trailing padding). Item-level whitespace inside ghost icon buttons\n already provides the rest of the breathing room. */\n .hexclave-clickmap .sdt-hm-toolbar {\n position: relative;\n z-index: 4;\n display: flex;\n align-items: center;\n gap: 2px;\n min-height: 44px;\n padding: 6px 8px;\n border: 1px solid var(--sdt-border);\n border-radius: 999px;\n background: var(--sdt-overlay-bg);\n box-shadow: 0 18px 48px rgba(0, 0, 0, 0.24);\n backdrop-filter: blur(18px);\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-title {\n flex-shrink: 0;\n padding: 0 6px 0 2px;\n font-size: 13px;\n font-weight: 650;\n color: var(--sdt-text);\n line-height: 1.1;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-filters {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-filters .sdt-hm-filter-input {\n height: 28px;\n border-radius: 999px;\n font-size: 11.5px;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-filters > .sdt-hm-filter-input {\n flex-shrink: 0;\n width: auto;\n max-width: 120px;\n padding-right: 4px;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-url {\n position: relative;\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n /* The revert/info ghost buttons hug the input they belong to. */\n gap: 2px;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-url .sdt-hm-filter-input {\n flex: 1;\n }\n\n .hexclave-clickmap .sdt-hm-mode {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 2px;\n border-radius: 999px;\n background: var(--sdt-bg-elevated);\n border: 1px solid var(--sdt-border-subtle);\n }\n\n .hexclave-clickmap .sdt-hm-mode-btn {\n min-width: 24px;\n height: 20px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 999px;\n background: transparent;\n color: var(--sdt-text-tertiary);\n padding: 0 7px;\n font: inherit;\n font-family: var(--sdt-font-mono, ui-monospace, monospace);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n }\n\n .hexclave-clickmap .sdt-hm-mode-btn:not(.sdt-hm-mode-btn-active):hover {\n color: var(--sdt-text);\n }\n\n .hexclave-clickmap .sdt-hm-mode-btn-active {\n background: var(--sdt-accent);\n color: white;\n }\n\n .hexclave-clickmap .sdt-hm-filter-input-error,\n .hexclave-clickmap .sdt-hm-filter-input-error:focus {\n border-color: var(--sdt-error);\n }\n\n .hexclave-clickmap .sdt-hm-filter-info {\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 999px;\n background: transparent;\n color: var(--sdt-text-tertiary);\n cursor: pointer;\n padding: 0;\n }\n\n .hexclave-clickmap .sdt-hm-filter-info:hover,\n .hexclave-clickmap .sdt-hm-filter-info[aria-expanded=\"true\"] {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n }\n\n .hexclave-clickmap .sdt-hm-url-help {\n display: none;\n position: absolute;\n bottom: calc(100% + 10px);\n right: 0;\n z-index: 6;\n width: 320px;\n max-width: min(320px, calc(100vw - 32px));\n box-sizing: border-box;\n padding: 14px;\n border: 1px solid var(--sdt-border);\n border-radius: var(--sdt-radius-lg);\n background: var(--sdt-bg);\n box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);\n backdrop-filter: blur(18px);\n cursor: default;\n }\n\n .hexclave-clickmap .sdt-hm-url-help-open {\n display: block;\n }\n\n .hexclave-clickmap .sdt-hm-url-help-title {\n font-size: 12px;\n font-weight: 650;\n color: var(--sdt-text);\n margin-bottom: 6px;\n }\n\n .hexclave-clickmap .sdt-hm-url-help-body {\n font-size: 11.5px;\n line-height: 1.5;\n color: var(--sdt-text-secondary);\n }\n\n .hexclave-clickmap .sdt-hm-url-help-rows {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin-top: 12px;\n padding-top: 12px;\n border-top: 1px solid var(--sdt-border-subtle);\n }\n\n .hexclave-clickmap .sdt-hm-url-help-row {\n display: flex;\n align-items: baseline;\n gap: 10px;\n }\n\n .hexclave-clickmap .sdt-hm-url-help-code {\n flex-shrink: 0;\n border-radius: var(--sdt-radius);\n background: var(--sdt-bg-elevated);\n border: 1px solid var(--sdt-border-subtle);\n padding: 1px 6px;\n font-family: var(--sdt-font-mono, ui-monospace, monospace);\n font-size: 11px;\n color: var(--sdt-text);\n white-space: nowrap;\n }\n\n .hexclave-clickmap .sdt-hm-url-help-desc {\n font-size: 11px;\n line-height: 1.4;\n color: var(--sdt-text-secondary);\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-metrics {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n /* Side padding is what separates the metrics group from the url field\n on its left and the toggle cluster on its right. */\n padding: 0 8px;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--sdt-text-secondary);\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-metric-value {\n font-size: 12px;\n font-weight: 700;\n color: var(--sdt-text);\n font-variant-numeric: tabular-nums;\n }\n\n .hexclave-clickmap .sdt-hm-toolbar-metric-icon {\n display: inline-flex;\n align-items: center;\n color: var(--sdt-text-tertiary);\n }\n\n .hexclave-clickmap .sdt-hm-icon-btn {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: 0;\n border-radius: 999px;\n background: transparent;\n color: var(--sdt-text-secondary);\n cursor: pointer;\n }\n\n .hexclave-clickmap .sdt-hm-icon-btn:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n }\n\n /* Presses must always target the button itself: the chevron svg is replaced\n when the panel toggles, and a press whose mousedown landed on a since-\n detached svg never produces a click. */\n .hexclave-clickmap .sdt-hm-icon-btn svg {\n pointer-events: none;\n }\n\n /* Styled tooltips for toolbar controls, driven by a data-sdt-tip attribute\n instead of native title so they match the overlay theme and also show on\n keyboard focus. The hover transition-delay acts as a hover-intent gate so\n tooltips don't flash while the pointer crosses the toolbar; hover-out has\n no delay, so they dismiss instantly. */\n .hexclave-clickmap [data-sdt-tip] {\n position: relative;\n }\n\n .hexclave-clickmap [data-sdt-tip]::after {\n content: attr(data-sdt-tip);\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%) translateY(2px);\n padding: 4px 8px;\n border: 1px solid var(--sdt-border);\n border-radius: var(--sdt-radius);\n background: var(--sdt-overlay-bg);\n backdrop-filter: blur(18px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.24);\n color: var(--sdt-text);\n font-size: 11px;\n font-weight: 600;\n line-height: 1.2;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.12s ease, transform 0.12s ease;\n z-index: 3;\n }\n\n .hexclave-clickmap [data-sdt-tip]:hover::after,\n .hexclave-clickmap [data-sdt-tip]:focus-visible::after {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n transition-delay: 0.35s;\n }\n\n /* The info button's tooltip would sit on top of its own help popover. */\n .hexclave-clickmap .sdt-hm-filter-info[aria-expanded=\"true\"]::after {\n opacity: 0;\n }\n\n .hexclave-clickmap .sdt-hm-details {\n display: none;\n position: relative;\n z-index: 1;\n max-height: min(460px, calc(100vh - 98px));\n overflow: hidden;\n border: 1px solid var(--sdt-border);\n border-radius: var(--sdt-radius-lg);\n background: var(--sdt-bg);\n box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22);\n }\n\n .hexclave-clickmap .sdt-hm-expanded .sdt-hm-details {\n display: flex;\n flex-direction: column;\n }\n\n .hexclave-clickmap .sdt-hm-head {\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n gap: 14px;\n padding: 16px;\n border-bottom: 1px solid var(--sdt-border-subtle);\n }\n\n .hexclave-clickmap .sdt-hm-filters {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .hexclave-clickmap .sdt-hm-filter-row {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n }\n\n .hexclave-clickmap .sdt-hm-seg {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 2px;\n height: 30px;\n padding: 3px;\n border-radius: var(--sdt-radius);\n border: 1px solid var(--sdt-border-subtle);\n background: var(--sdt-bg-elevated);\n box-sizing: border-box;\n }\n\n .hexclave-clickmap .sdt-hm-seg-thumb {\n position: absolute;\n top: 3px;\n left: 0;\n bottom: 3px;\n width: 0;\n border-radius: calc(var(--sdt-radius) - 2px);\n background: var(--sdt-bg);\n border: 1px solid var(--sdt-border);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);\n transform: translateX(0);\n transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1), width 220ms cubic-bezier(0.22, 1, 0.36, 1);\n pointer-events: none;\n }\n\n .hexclave-clickmap .sdt-hm-seg-btn {\n position: relative;\n z-index: 1;\n flex: 1 1 0;\n min-width: 0;\n border: 0;\n background: transparent;\n color: var(--sdt-text-tertiary);\n font: inherit;\n font-family: var(--sdt-font);\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n padding: 0 4px;\n border-radius: calc(var(--sdt-radius) - 2px);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: color 160ms ease;\n }\n\n .hexclave-clickmap .sdt-hm-seg-btn:hover {\n color: var(--sdt-text-secondary);\n }\n\n .hexclave-clickmap .sdt-hm-seg-btn[aria-checked=\"true\"] {\n color: var(--sdt-text);\n }\n\n .hexclave-clickmap .sdt-hm-seg-btn:focus-visible {\n outline: 2px solid var(--sdt-accent);\n outline-offset: -2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .hexclave-clickmap .sdt-hm-seg-thumb {\n transition: none;\n }\n }\n\n .hexclave-clickmap .sdt-hm-filter-field {\n display: flex;\n flex-direction: column;\n gap: 5px;\n min-width: 0;\n }\n\n .hexclave-clickmap .sdt-hm-filter-label-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 6px;\n min-height: 13px;\n }\n\n .hexclave-clickmap .sdt-hm-filter-label {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--sdt-text-tertiary);\n }\n\n .hexclave-clickmap .sdt-hm-filter-reset {\n display: none;\n flex-shrink: 0;\n width: 20px;\n height: 20px;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 999px;\n background: transparent;\n padding: 0;\n color: var(--sdt-accent);\n cursor: pointer;\n }\n\n .hexclave-clickmap .sdt-hm-filter-reset:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-accent-hover);\n }\n\n .hexclave-clickmap .sdt-hm-filter-reset-visible {\n display: inline-flex;\n }\n\n .hexclave-clickmap .sdt-hm-filter-input {\n height: 30px;\n border-radius: var(--sdt-radius);\n border: 1px solid var(--sdt-border-subtle);\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text);\n padding: 0 9px;\n font: inherit;\n font-size: 12px;\n font-family: var(--sdt-font);\n min-width: 0;\n width: 100%;\n box-sizing: border-box;\n }\n\n .hexclave-clickmap .sdt-hm-filter-input:focus {\n outline: none;\n border-color: var(--sdt-accent);\n }\n\n .hexclave-clickmap .sdt-hm-actions {\n display: flex;\n align-items: stretch;\n gap: 10px;\n }\n\n .hexclave-clickmap .sdt-hm-actions .sdt-hm-btn {\n height: auto;\n flex-shrink: 0;\n white-space: nowrap;\n padding: 0 16px;\n }\n\n .hexclave-clickmap .sdt-hm-btn {\n height: 30px;\n border-radius: var(--sdt-radius);\n border: 1px solid var(--sdt-border-subtle);\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-secondary);\n padding: 0 10px;\n font: inherit;\n font-size: 12px;\n cursor: pointer;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n }\n\n .hexclave-clickmap .sdt-hm-btn:hover {\n background: var(--sdt-bg-hover);\n color: var(--sdt-text);\n transition: none;\n }\n\n .hexclave-clickmap .sdt-hm-btn-primary {\n background: var(--sdt-accent);\n border-color: var(--sdt-accent);\n color: white;\n }\n\n .hexclave-clickmap .sdt-hm-btn-primary:hover {\n background: var(--sdt-accent);\n border-color: var(--sdt-accent);\n color: white;\n transition: none;\n }\n\n .hexclave-clickmap .sdt-hm-btn-sm {\n height: 24px;\n flex-shrink: 0;\n border-radius: 999px;\n padding: 0 10px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n }\n\n .hexclave-clickmap .sdt-hm-btn:disabled {\n opacity: 0.45;\n pointer-events: none;\n }\n\n /* Dead-clicks-only filter toggle (toolbar icon button + expanded-panel\n button). Active state borrows the error tint used by the dead chips so\n the mode reads as \"you are looking at failures\". */\n .hexclave-clickmap .sdt-hm-dead-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n }\n\n .hexclave-clickmap .sdt-hm-dead-toggle-icon {\n display: inline-flex;\n align-items: center;\n }\n\n .hexclave-clickmap .sdt-hm-dead-toggle-active,\n .hexclave-clickmap .sdt-hm-dead-toggle-active:hover {\n background: var(--sdt-error-muted);\n border-color: var(--sdt-error);\n color: var(--sdt-error);\n transition: none;\n }\n\n /* Toolbar overlay toggle while the overlay is hidden: tinted so the off\n state reads at a glance, eye-off icon carries the meaning. */\n .hexclave-clickmap .sdt-hm-overlay-mini-off,\n .hexclave-clickmap .sdt-hm-overlay-mini-off:hover {\n background: var(--sdt-accent-muted);\n color: var(--sdt-accent-hover);\n }\n\n .hexclave-clickmap .sdt-hm-stats {\n flex: 1;\n min-width: 0;\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 8px;\n }\n\n .hexclave-clickmap .sdt-hm-stat {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n border-radius: var(--sdt-radius);\n background: var(--sdt-bg-elevated);\n padding: 7px 10px;\n }\n\n .hexclave-clickmap .sdt-hm-stat-label {\n font-size: 9.5px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--sdt-text-tertiary);\n }\n\n .hexclave-clickmap .sdt-hm-stat-value {\n font-size: 15px;\n font-weight: 650;\n color: var(--sdt-text);\n font-variant-numeric: tabular-nums;\n }\n\n /* No top padding on the scroller: the sticky list header pins at top 0,\n and scroller padding reads as a see-through strip above it while the\n list scrolls (Chromium offsets sticky insets by the scroll container's\n padding). The status line below carries the 12px instead. */\n .hexclave-clickmap .sdt-hm-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 0 16px 14px;\n }\n\n .hexclave-clickmap .sdt-hm-token-status {\n color: var(--sdt-text-secondary);\n padding: 12px 2px 0;\n font-size: 11.5px;\n line-height: 1.45;\n }\n\n .hexclave-clickmap .sdt-hm-token-status-error {\n color: var(--sdt-error);\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning {\n display: none;\n gap: 8px;\n padding: 10px;\n border-radius: var(--sdt-radius);\n border: 1px solid rgba(234, 179, 8, 0.24);\n background: var(--sdt-warning-muted);\n color: var(--sdt-text);\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-visible {\n display: flex;\n flex-direction: column;\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-title {\n font-size: 12px;\n font-weight: 650;\n color: var(--sdt-text);\n line-height: 1.2;\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-body {\n font-size: 11.5px;\n line-height: 1.45;\n color: var(--sdt-text-secondary);\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-action {\n min-width: 0;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n border-radius: var(--sdt-radius);\n border: 1px solid var(--sdt-border-subtle);\n background: var(--sdt-bg-elevated);\n padding: 4px 5px 4px 8px;\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-label {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--sdt-text-tertiary);\n }\n\n .hexclave-clickmap .sdt-hm-viewport-warning-code {\n font-family: var(--sdt-font-mono);\n font-size: 11.5px;\n font-weight: 650;\n color: var(--sdt-text);\n font-variant-numeric: tabular-nums;\n }\n\n .hexclave-clickmap .sdt-hm-copy-btn {\n height: 22px;\n border: 1px solid var(--sdt-border-subtle);\n border-radius: 999px;\n background: var(--sdt-bg);\n color: var(--sdt-text-secondary);\n padding: 0 8px;\n font: inherit;\n font-size: 10.5px;\n font-weight: 600;\n cursor: pointer;\n transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;\n }\n\n .hexclave-clickmap .sdt-hm-copy-btn:hover {\n background: var(--sdt-bg-hover);\n border-color: var(--sdt-border);\n color: var(--sdt-text);\n transition: none;\n }\n\n .hexclave-clickmap .sdt-hm-list {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n /* Datagrid-style header above the element list. Sticky inside the\n scrolling body (full-bleed via negative margins) so select-all and the\n bulk show/hide actions stay reachable while the list scrolls. The 24px\n left padding lines its master checkbox up with the row checkboxes\n (16px body padding + 8px row padding). */\n .hexclave-clickmap .sdt-hm-list-header {\n display: none;\n position: sticky;\n top: 0;\n z-index: 2;\n align-items: center;\n gap: 8px;\n margin: 0 -16px;\n padding: 8px 24px;\n background: var(--sdt-bg);\n border-bottom: 1px solid var(--sdt-border-subtle);\n }\n\n .hexclave-clickmap .sdt-hm-list-header-visible {\n display: flex;\n }\n\n .hexclave-clickmap .sdt-hm-list-header-summary {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 11px;\n font-weight: 600;\n color: var(--sdt-text-secondary);\n font-variant-numeric: tabular-nums;\n }\n\n /* Element search, compacted to header height. Shrinks before the summary\n does, but never below a usable width. */\n .hexclave-clickmap .sdt-hm-list-header .sdt-hm-filter-input {\n flex: 0 1 220px;\n width: auto;\n min-width: 90px;\n height: 24px;\n border-radius: 999px;\n font-size: 11px;\n padding: 0 10px;\n }\n\n .hexclave-clickmap .sdt-hm-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n border-radius: var(--sdt-radius);\n border: 1px dashed var(--sdt-border);\n color: var(--sdt-text-tertiary);\n font-size: 12px;\n text-align: center;\n padding: 0 16px;\n }\n\n .hexclave-clickmap .sdt-hm-row {\n width: 100%;\n display: grid;\n grid-template-columns: 16px minmax(42px, auto) minmax(0, 1fr) 24px;\n align-items: center;\n gap: 10px;\n border: 0;\n border-radius: var(--sdt-radius);\n background: transparent;\n color: var(--sdt-text);\n padding: 8px;\n text-align: left;\n cursor: pointer;\n font-family: var(--sdt-font);\n user-select: none;\n }\n\n .hexclave-clickmap .sdt-hm-row:hover {\n background: var(--sdt-bg-hover);\n transition: none;\n }\n\n .hexclave-clickmap .sdt-hm-row:focus-visible {\n outline: 2px solid var(--sdt-accent);\n outline-offset: 2px;\n }\n\n .hexclave-clickmap .sdt-hm-row-muted {\n opacity: 0.52;\n }\n\n .hexclave-clickmap .sdt-hm-row-highlighted {\n background: rgba(250, 204, 21, 0.12);\n }\n\n /* Declared after -highlighted and with a :hover pair so the selection tint\n wins over both the lead-highlight wash and the plain hover background. */\n .hexclave-clickmap .sdt-hm-row-selected,\n .hexclave-clickmap .sdt-hm-row-selected:hover {\n background: var(--sdt-accent-muted);\n }\n\n /* Row checkbox (also reused as the list header's master checkbox). A\n button with role=checkbox instead of a native input so it can render the\n overlay-themed check/indeterminate icons. */\n .hexclave-clickmap .sdt-hm-row-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n border: 1px solid var(--sdt-border);\n border-radius: calc(var(--sdt-radius) - 3px);\n background: var(--sdt-bg-elevated);\n color: white;\n appearance: none;\n padding: 0;\n cursor: pointer;\n }\n\n .hexclave-clickmap .sdt-hm-row-check:hover {\n border-color: var(--sdt-accent);\n }\n\n .hexclave-clickmap .sdt-hm-row-check[aria-checked=\"true\"],\n .hexclave-clickmap .sdt-hm-row-check[aria-checked=\"mixed\"] {\n background: var(--sdt-accent);\n border-color: var(--sdt-accent);\n }\n\n .hexclave-clickmap .sdt-hm-row-check:focus-visible {\n outline: 2px solid var(--sdt-accent);\n outline-offset: 2px;\n }\n\n .hexclave-clickmap .sdt-hm-row-check svg {\n pointer-events: none;\n }\n\n .hexclave-clickmap .sdt-hm-row-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n border-radius: calc(var(--sdt-radius) - 2px);\n background: var(--sdt-accent-muted);\n color: var(--sdt-accent-hover);\n padding: 0 7px;\n font-size: 12px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n font-family: var(--sdt-font);\n }\n\n .hexclave-clickmap .sdt-hm-row-muted .sdt-hm-row-count {\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-tertiary);\n }\n\n .hexclave-clickmap .sdt-hm-row-eye {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border: 1px solid var(--sdt-border-subtle);\n border-radius: calc(var(--sdt-radius) - 2px);\n background: var(--sdt-bg-elevated);\n color: var(--sdt-text-secondary);\n appearance: none;\n padding: 0;\n cursor: pointer;\n opacity: 0;\n pointer-events: none;\n }\n\n .hexclave-clickmap .sdt-hm-row:hover .sdt-hm-row-eye,\n .hexclave-clickmap .sdt-hm-row:focus-within .sdt-hm-row-eye,\n .hexclave-clickmap .sdt-hm-row-muted .sdt-hm-row-eye {\n opacity: 1;\n pointer-events: auto;\n }\n\n .hexclave-clickmap .sdt-hm-row-eye:hover {\n background: var(--sdt-bg-hover);\n border-color: var(--sdt-border);\n color: var(--sdt-text);\n transition: none;\n }\n\n .hexclave-clickmap .sdt-hm-row-eye:focus-visible {\n outline: 2px solid var(--sdt-accent);\n outline-offset: 2px;\n }\n\n .hexclave-clickmap .sdt-hm-row-meta {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n }\n\n .hexclave-clickmap .sdt-hm-row-label-row {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n }\n\n .hexclave-clickmap .sdt-hm-row-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n font-size: 12px;\n font-weight: 600;\n }\n\n .hexclave-clickmap .sdt-hm-row-dead {\n display: none;\n flex: none;\n align-items: center;\n height: 16px;\n border-radius: calc(var(--sdt-radius) - 3px);\n background: var(--sdt-error-muted);\n color: var(--sdt-error);\n padding: 0 5px;\n font-size: 10px;\n font-weight: 700;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n\n .hexclave-clickmap .sdt-hm-row-dead-visible {\n display: inline-flex;\n }\n\n .hexclave-clickmap .sdt-hm-row-selector {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--sdt-font-mono);\n font-size: 10.5px;\n color: var(--sdt-text-tertiary);\n }\n\n .sdt-hm-overlay-root {\n position: fixed;\n inset: 0;\n z-index: 2147483646;\n pointer-events: none;\n --resize-dur: 320ms;\n --resize-ease: cubic-bezier(0.22, 1, 0.36, 1);\n }\n\n .sdt-hm-overlay-root .sdt-hm-marker {\n position: fixed;\n transform: translate(-50%, -50%);\n min-width: 28px;\n height: 24px;\n border-radius: 999px;\n padding: 0 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 0;\n color: rgba(10, 10, 11, 0.92);\n font: 700 12px/1 var(--sdt-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);\n font-variant-numeric: tabular-nums;\n cursor: pointer;\n pointer-events: auto;\n transition: opacity 0.15s ease, transform 0.15s ease, filter 0.15s ease;\n }\n\n .sdt-hm-overlay-root .sdt-hm-marker:hover {\n transform: translate(-50%, -50%) scale(1.06);\n transition: none;\n }\n\n .sdt-hm-overlay-root .sdt-hm-marker-muted {\n opacity: 0.18;\n filter: saturate(0.25);\n text-decoration: line-through;\n }\n\n .sdt-hm-overlay-root .sdt-hm-marker-highlighted {\n transform: translate(-50%, -50%) scale(1.08);\n }\n\n .sdt-hm-overlay-root .sdt-hm-outline {\n position: fixed;\n border: 1px solid;\n border-radius: 4px;\n background: rgba(99, 102, 241, 0.04);\n transition: opacity 0.15s ease, background 0.15s ease, border-color 0.15s ease;\n }\n\n .sdt-hm-overlay-root .sdt-hm-outline-muted {\n opacity: 0;\n }\n\n .sdt-hm-overlay-root .sdt-hm-outline-highlighted {\n border-color: rgba(250, 204, 21, 0.92) !important;\n }\n\n .sdt-hm-overlay-root .sdt-hm-highlight {\n position: fixed;\n border-radius: 5px;\n background: rgba(250, 204, 21, 0.28);\n box-shadow: 0 0 0 1px rgba(250, 204, 21, 0.7), 0 0 0 9999px rgba(0, 0, 0, 0.04);\n opacity: 0;\n will-change: top, left, width, height;\n transition: opacity 0.18s ease;\n }\n\n .sdt-hm-overlay-root .sdt-hm-highlight-visible {\n opacity: 1;\n }\n\n .sdt-hm-overlay-root .sdt-hm-highlight-animating {\n transition:\n top var(--resize-dur) var(--resize-ease),\n left var(--resize-dur) var(--resize-ease),\n width var(--resize-dur) var(--resize-ease),\n height var(--resize-dur) var(--resize-ease),\n opacity 0.18s ease;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .sdt-hm-overlay-root .sdt-hm-highlight-animating {\n transition: opacity 0.18s ease;\n }\n }\n`;\n"],"mappings":";;;;;AAgBA,MAAa,mEAAiC,qBAAqB,GAAG"}
@@ -0,0 +1,16 @@
1
+ import { StackClientApp } from "../lib/hexclave-app/apps/interfaces/client-app.js";
2
+
3
+ //#region src/clickmap/index.d.ts
4
+ /**
5
+ * Mounts the clickmap overlay listener on the page.
6
+ *
7
+ * The clickmap is fully independent from the dev tool. It has no ambient UI:
8
+ * nothing renders until a dashboard-minted token is handed over (the
9
+ * CLICKMAP_OVERLAY_TOKEN_UPDATED event fired by the dashboard's console
10
+ * snippet) or a navigation-resume sentinel is present — only then is the
11
+ * actual overlay code lazily loaded and shown.
12
+ */
13
+ declare function mountClickmapOverlay(app: StackClientApp<true>): () => void;
14
+ //#endregion
15
+ export { mountClickmapOverlay };
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/clickmap/index.ts"],"mappings":";;;;;AA2EA;;;;;;;iBAAgB,oBAAA,CAAqB,GAAA,EAAK,cAAA"}
@@ -0,0 +1,74 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_chunk = require('../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_analytics_clickmap_overlay = require("@hexclave/shared/dist/utils/analytics-clickmap-overlay");
4
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
+ let ___in_page_ui_dom_js = require("../in-page-ui/dom.js");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
7
+
8
+ //#region src/clickmap/index.ts
9
+ function consumeResumeSentinel() {
10
+ try {
11
+ if (sessionStorage.getItem(_hexclave_shared_dist_utils_analytics_clickmap_overlay.CLICKMAP_OVERLAY_RESUME_STORAGE_KEY) !== "1") return false;
12
+ sessionStorage.removeItem(_hexclave_shared_dist_utils_analytics_clickmap_overlay.CLICKMAP_OVERLAY_RESUME_STORAGE_KEY);
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+ let activeApp = null;
19
+ let activeOverlayCleanup = null;
20
+ let openGeneration = 0;
21
+ let tokenListenerAttached = false;
22
+ let openClickmapOverlayPromise = null;
23
+ function loadOpenClickmapOverlay() {
24
+ if (!openClickmapOverlayPromise) openClickmapOverlayPromise = import("./clickmap-core.js").then((m) => m.openClickmapOverlay).catch((err) => {
25
+ openClickmapOverlayPromise = null;
26
+ throw err;
27
+ });
28
+ return openClickmapOverlayPromise;
29
+ }
30
+ function tryOpenOverlay() {
31
+ if (activeOverlayCleanup || !activeApp || !(0, ___in_page_ui_dom_js.canMountIntoDom)()) return;
32
+ const generation = ++openGeneration;
33
+ const app = activeApp;
34
+ (0, _hexclave_shared_dist_utils_promises.runAsynchronously)(async () => {
35
+ const openClickmapOverlay = await loadOpenClickmapOverlay();
36
+ if (generation !== openGeneration) return;
37
+ if (activeOverlayCleanup || activeApp !== app || !(0, ___in_page_ui_dom_js.canMountIntoDom)()) return;
38
+ activeOverlayCleanup = openClickmapOverlay(app, () => {
39
+ activeOverlayCleanup = null;
40
+ });
41
+ }, {
42
+ noErrorLogging: true,
43
+ onError: (error) => {
44
+ (0, _hexclave_shared_dist_utils_errors.captureError)("clickmap-mount", error);
45
+ }
46
+ });
47
+ }
48
+ /**
49
+ * Mounts the clickmap overlay listener on the page.
50
+ *
51
+ * The clickmap is fully independent from the dev tool. It has no ambient UI:
52
+ * nothing renders until a dashboard-minted token is handed over (the
53
+ * CLICKMAP_OVERLAY_TOKEN_UPDATED event fired by the dashboard's console
54
+ * snippet) or a navigation-resume sentinel is present — only then is the
55
+ * actual overlay code lazily loaded and shown.
56
+ */
57
+ function mountClickmapOverlay(app) {
58
+ activeApp = app;
59
+ if (typeof window !== "undefined" && !tokenListenerAttached) {
60
+ tokenListenerAttached = true;
61
+ window.addEventListener(_hexclave_shared_dist_utils_analytics_clickmap_overlay.CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT, tryOpenOverlay);
62
+ }
63
+ if ((0, ___in_page_ui_dom_js.canMountIntoDom)() && consumeResumeSentinel()) tryOpenOverlay();
64
+ return () => {
65
+ if (activeApp !== app) return;
66
+ activeApp = null;
67
+ openGeneration++;
68
+ activeOverlayCleanup?.();
69
+ };
70
+ }
71
+
72
+ //#endregion
73
+ exports.mountClickmapOverlay = mountClickmapOverlay;
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["CLICKMAP_OVERLAY_RESUME_STORAGE_KEY","CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT"],"sources":["../../src/clickmap/index.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport {\n CLICKMAP_OVERLAY_RESUME_STORAGE_KEY,\n CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT,\n} from \"@hexclave/shared/dist/utils/analytics-clickmap-overlay\";\nimport { captureError } from \"@hexclave/shared/dist/utils/errors\";\nimport { runAsynchronously } from \"@hexclave/shared/dist/utils/promises\";\nimport { canMountIntoDom } from \"../in-page-ui/dom\";\nimport type { StackClientApp } from \"../lib/hexclave-app\";\nimport type { openClickmapOverlay as OpenClickmapOverlayFn } from \"./clickmap-core\";\n\n// While the overlay is open it drops a sentinel into sessionStorage on unload\n// (see clickmap-core); consuming it here reopens the clickmap on the next page\n// so the user picks up where they left off.\nfunction consumeResumeSentinel(): boolean {\n try {\n if (sessionStorage.getItem(CLICKMAP_OVERLAY_RESUME_STORAGE_KEY) !== '1') return false;\n sessionStorage.removeItem(CLICKMAP_OVERLAY_RESUME_STORAGE_KEY);\n return true;\n } catch {\n return false;\n }\n}\n\nlet activeApp: StackClientApp<true> | null = null;\nlet activeOverlayCleanup: (() => void) | null = null;\nlet openGeneration = 0;\nlet tokenListenerAttached = false;\n\nlet openClickmapOverlayPromise: Promise<typeof OpenClickmapOverlayFn> | null = null;\nfunction loadOpenClickmapOverlay(): Promise<typeof OpenClickmapOverlayFn> {\n if (!openClickmapOverlayPromise) {\n openClickmapOverlayPromise = import(\"./clickmap-core\").then(m => m.openClickmapOverlay).catch((err) => {\n openClickmapOverlayPromise = null;\n throw err;\n });\n }\n return openClickmapOverlayPromise;\n}\n\nfunction tryOpenOverlay() {\n // Already open: the panel listens for the token event itself and refetches.\n if (activeOverlayCleanup || !activeApp || !canMountIntoDom()) return;\n\n const generation = ++openGeneration;\n const app = activeApp;\n\n runAsynchronously(async () => {\n const openClickmapOverlay = await loadOpenClickmapOverlay();\n if (generation !== openGeneration) return;\n if (activeOverlayCleanup || activeApp !== app || !canMountIntoDom()) return;\n activeOverlayCleanup = openClickmapOverlay(app, () => {\n activeOverlayCleanup = null;\n });\n }, {\n noErrorLogging: true,\n onError: (error) => {\n captureError(\"clickmap-mount\", error);\n },\n });\n}\n\n/**\n * Mounts the clickmap overlay listener on the page.\n *\n * The clickmap is fully independent from the dev tool. It has no ambient UI:\n * nothing renders until a dashboard-minted token is handed over (the\n * CLICKMAP_OVERLAY_TOKEN_UPDATED event fired by the dashboard's console\n * snippet) or a navigation-resume sentinel is present — only then is the\n * actual overlay code lazily loaded and shown.\n */\nexport function mountClickmapOverlay(app: StackClientApp<true>): () => void {\n activeApp = app;\n\n if (typeof window !== 'undefined' && !tokenListenerAttached) {\n tokenListenerAttached = true;\n window.addEventListener(CLICKMAP_OVERLAY_TOKEN_UPDATED_EVENT, tryOpenOverlay);\n }\n\n if (canMountIntoDom() && consumeResumeSentinel()) {\n tryOpenOverlay();\n }\n\n return () => {\n if (activeApp !== app) return;\n activeApp = null;\n openGeneration++;\n activeOverlayCleanup?.();\n };\n}\n\n"],"mappings":";;;;;;;;AAkBA,SAAS,wBAAiC;AACxC,KAAI;AACF,MAAI,eAAe,QAAQA,2FAAoC,KAAK,IAAK,QAAO;AAChF,iBAAe,WAAWA,2FAAoC;AAC9D,SAAO;SACD;AACN,SAAO;;;AAIX,IAAI,YAAyC;AAC7C,IAAI,uBAA4C;AAChD,IAAI,iBAAiB;AACrB,IAAI,wBAAwB;AAE5B,IAAI,6BAA2E;AAC/E,SAAS,0BAAiE;AACxE,KAAI,CAAC,2BACH,8BAA6B,OAAO,sBAAmB,MAAK,MAAK,EAAE,oBAAoB,CAAC,OAAO,QAAQ;AACrG,+BAA6B;AAC7B,QAAM;GACN;AAEJ,QAAO;;AAGT,SAAS,iBAAiB;AAExB,KAAI,wBAAwB,CAAC,aAAa,4CAAkB,CAAE;CAE9D,MAAM,aAAa,EAAE;CACrB,MAAM,MAAM;AAEZ,6DAAkB,YAAY;EAC5B,MAAM,sBAAsB,MAAM,yBAAyB;AAC3D,MAAI,eAAe,eAAgB;AACnC,MAAI,wBAAwB,cAAc,OAAO,4CAAkB,CAAE;AACrE,yBAAuB,oBAAoB,WAAW;AACpD,0BAAuB;IACvB;IACD;EACD,gBAAgB;EAChB,UAAU,UAAU;AAClB,wDAAa,kBAAkB,MAAM;;EAExC,CAAC;;;;;;;;;;;AAYJ,SAAgB,qBAAqB,KAAuC;AAC1E,aAAY;AAEZ,KAAI,OAAO,WAAW,eAAe,CAAC,uBAAuB;AAC3D,0BAAwB;AACxB,SAAO,iBAAiBC,6FAAsC,eAAe;;AAG/E,gDAAqB,IAAI,uBAAuB,CAC9C,iBAAgB;AAGlB,cAAa;AACX,MAAI,cAAc,IAAK;AACvB,cAAY;AACZ;AACA,0BAAwB"}
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
5
7
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
8
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
8
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
9
9
  let _hexclave_ui = require("@hexclave/ui");
10
10
  let react = require("react");
11
11
  let react_hook_form = require("react-hook-form");
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  let react_hook_form = require("react-hook-form");
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  react = require_chunk.__toESM(react);
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  let react_hook_form = require("react-hook-form");
@@ -1,5 +1,5 @@
1
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
1
  import { KnownError } from "@hexclave/shared";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/message-cards/known-error-message-card.d.ts
5
5
  declare function KnownErrorMessageCard({
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
6
5
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
7
7
  let _hexclave_ui = require("@hexclave/ui");
8
8
  let react = require("react");
9
9
  let ___index_js = require("../index.js");
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
4
3
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
4
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
5
5
  let _hexclave_ui = require("@hexclave/ui");
6
6
  let react = require("react");
7
7
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
4
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
4
5
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
5
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
6
  let _hexclave_ui = require("@hexclave/ui");
7
7
  let react = require("react");
8
8
  let react_hook_form = require("react-hook-form");
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
4
3
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
4
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
5
5
  let _hexclave_ui = require("@hexclave/ui");
6
6
  let react = require("react");
7
7
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
4
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
4
5
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
5
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
6
  let _hexclave_ui = require("@hexclave/ui");
7
7
  let react = require("react");
8
8
  let react_hook_form = require("react-hook-form");
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
4
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
4
5
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
5
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
6
  let _hexclave_ui = require("@hexclave/ui");
7
7
  let react = require("react");
8
8
  let react_hook_form = require("react-hook-form");
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_chunk = require('../../../chunk-BE-pF4vm.js');
3
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
4
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
4
5
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
5
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
6
  let _hexclave_ui = require("@hexclave/ui");
7
7
  let react = require("react");
8
8
  let react_hook_form = require("react-hook-form");
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
6
5
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
7
7
  let _hexclave_ui = require("@hexclave/ui");
8
8
  let react = require("react");
9
9
  let ___index_js = require("../index.js");
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
5
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
+ let ___lib_hexclave_app_common_js = require("../lib/hexclave-app/common.js");
6
7
  let _hexclave_ui = require("@hexclave/ui");
7
8
  let react = require("react");
8
9
  let ___lib_translations_js = require("../lib/translations.js");
9
10
  let react_jsx_runtime = require("react/jsx-runtime");
10
11
  let ___lib_hooks_js = require("../lib/hooks.js");
11
12
  let ___components_message_cards_message_card_js = require("../components/message-cards/message-card.js");
12
- let ___lib_hexclave_app_common_js = require("../lib/hexclave-app/common.js");
13
13
 
14
14
  //#region src/components-page/cli-auth-confirm.tsx
15
15
  async function postCliAuthComplete(app, body) {
@@ -1,11 +1,11 @@
1
1
  const require_chunk = require('../chunk-BE-pF4vm.js');
2
2
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
3
+ let ___lib_hexclave_app_common_js = require("../lib/hexclave-app/common.js");
3
4
  let react = require("react");
4
5
  react = require_chunk.__toESM(react);
5
6
  let react_jsx_runtime = require("react/jsx-runtime");
6
7
  let react_dom_client = require("react-dom/client");
7
8
  let vitest = require("vitest");
8
- let ___lib_hexclave_app_common_js = require("../lib/hexclave-app/common.js");
9
9
  let ___providers_hexclave_context_js = require("../providers/hexclave-context.js");
10
10
  let __cli_auth_confirm_js = require("./cli-auth-confirm.js");
11
11
 
@@ -1 +1 @@
1
- {"version":3,"file":"forgot-password.d.ts","names":[],"sources":["../../src/components-page/forgot-password.tsx"],"mappings":";;;iBAqBgB,kBAAA,CAAA;EAAqB;AAAA;EAAY,MAAA;AAAA,IAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAgDtD,cAAA,CAAe,KAAA;EAAS,QAAA;AAAA,IAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"forgot-password.d.ts","names":[],"sources":["../../src/components-page/forgot-password.tsx"],"mappings":";;;iBAqBgB,kBAAA,CAAA;EAAqB;AAAA;EAAY,MAAA;AAAA,IAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA+CtD,cAAA,CAAe,KAAA;EAAS,QAAA;AAAA,IAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  let react_hook_form = require("react-hook-form");
@@ -46,8 +46,7 @@ function ForgotPasswordForm({ onSent }) {
46
46
  id: "email",
47
47
  type: "email",
48
48
  autoComplete: "email",
49
- ...register("email"),
50
- onChange: () => clearErrors("email")
49
+ ...register("email", { onChange: () => clearErrors("email") })
51
50
  }),
52
51
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_elements_form_warning_js.FormWarningText, { text: errors.email?.message?.toString() }),
53
52
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Button, {
@@ -1 +1 @@
1
- {"version":3,"file":"forgot-password.js","names":["Label","Input","FormWarningText","Button","PredefinedMessageCard","MaybeFullPage","Typography","StyledLink"],"sources":["../../src/components-page/forgot-password.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@hexclave/shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { Button, Input, Label, Typography, cn } from \"@hexclave/ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {\n const { t } = useTranslation();\n\n const schema = yupObject({\n email: strictEmailSchema(t(\"Please enter a valid email\")).defined().nonEmpty(t(\"Please enter your email\"))\n });\n\n const { register, handleSubmit, formState: { errors }, clearErrors } = useForm({\n resolver: yupResolver(schema)\n });\n const hexclaveApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n await hexclaveApp.sendForgotPasswordEmail(email);\n onSent?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t(\"Your Email\")}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email')}\n onChange={() => clearErrors('email')}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t(\"Send Email\")}\n </Button>\n </form>\n );\n}\n\n\nexport function ForgotPassword(props: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const hexclaveApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={!!props.fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className={cn(\n \"stack-scope max-w-[380px] flex-basis-[380px]\",\n props.fullPage ? \"p-4\" : \"p-0\"\n )}>\n <div className=\"text-center\">\n <Typography type='h2'>{t(\"Reset Your Password\")}</Typography>\n <Typography>\n {t(\"Don't need to reset?\")}{\" \"}\n <StyledLink href={hexclaveApp.urls['signIn']}>\n {t(\"Sign in\")}\n </StyledLink>\n </Typography>\n </div>\n <div className=\"mt-6\">\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </div>\n </div>\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,mBAAmB,EAAE,UAAmC;CACtE,MAAM,EAAE,kDAAsB;CAM9B,MAAM,EAAE,UAAU,cAAc,WAAW,EAAE,UAAU,6CAAwB,EAC7E,sGALuB,EACvB,kEAAyB,EAAE,6BAA6B,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,0BAA0B,CAAC,EAC3G,CAAC,CAG6B,EAC9B,CAAC;CACF,MAAM,4CAA2B;CACjC,MAAM,CAAC,SAAS,kCAAuB,MAAM;CAE7C,MAAM,WAAW,OAAO,SAAuC;AAC7D,aAAW,KAAK;AAChB,MAAI;GACF,MAAM,EAAE,UAAU;AAClB,SAAM,YAAY,wBAAwB,MAAM;AAClD,aAAU;YACA;AACR,cAAW,MAAM;;;AAIrB,QACE,4CAAC;EACC,WAAU;EACV,WAAU,2EAAgC,aAAa,SAAS,CAAC,EAAE,CAAC;EACpE;;GAEA,2CAACA;IAAM,SAAQ;IAAQ,WAAU;cAAQ,EAAE,aAAa;KAAS;GACjE,2CAACC;IACC,IAAG;IACH,MAAK;IACL,cAAa;IACb,GAAI,SAAS,QAAQ;IACrB,gBAAgB,YAAY,QAAQ;KACpC;GACF,2CAACC,0DAAgB,MAAM,OAAO,OAAO,SAAS,UAAU,GAAI;GAE5D,2CAACC;IAAO,MAAK;IAAS,WAAU;IAAgB;cAC7C,EAAE,aAAa;KACT;;GACJ;;AAKX,SAAgB,eAAe,OAA+B;CAC5D,MAAM,EAAE,kDAAsB;CAC9B,MAAM,4CAA2B;CACjC,MAAM,iCAAgB;CACtB,MAAM,CAAC,MAAM,+BAAoB,MAAM;AAEvC,KAAI,KACF,QAAO,2CAACC;EAAsB,MAAK;EAAW,UAAU,CAAC,CAAC,MAAM;GAAY;AAG9E,KAAI,KACF,QAAO,2CAACA;EAAsB,MAAK;EAAY,UAAU,CAAC,CAAC,MAAM;GAAY;AAG/E,QACE,2CAACC;EAAc,UAAU,CAAC,CAAC,MAAM;YAC/B,4CAAC;GAAI,gCACH,gDACA,MAAM,WAAW,QAAQ,MAC1B;cACC,4CAAC;IAAI,WAAU;eACb,2CAACC;KAAW,MAAK;eAAM,EAAE,sBAAsB;MAAc,EAC7D,4CAACA;KACE,EAAE,uBAAuB;KAAE;KAC5B,2CAACC;MAAW,MAAM,YAAY,KAAK;gBAChC,EAAE,UAAU;OACF;QACF;KACT,EACN,2CAAC;IAAI,WAAU;cACb,2CAAC,sBAAmB,cAAc,QAAQ,KAAK,GAAI;KAC/C;IACF;GACQ"}
1
+ {"version":3,"file":"forgot-password.js","names":["Label","Input","FormWarningText","Button","PredefinedMessageCard","MaybeFullPage","Typography","StyledLink"],"sources":["../../src/components-page/forgot-password.tsx"],"sourcesContent":["'use client';\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { yupResolver } from \"@hookform/resolvers/yup\";\nimport { strictEmailSchema, yupObject } from \"@hexclave/shared/dist/schema-fields\";\nimport { runAsynchronouslyWithAlert } from \"@hexclave/shared/dist/utils/promises\";\nimport { Button, Input, Label, Typography, cn } from \"@hexclave/ui\";\nimport { useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport * as yup from \"yup\";\nimport { useStackApp, useUser } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { StyledLink } from \"../components/link\";\nimport { PredefinedMessageCard } from \"../components/message-cards/predefined-message-card\";\nimport { useTranslation } from \"../lib/translations\";\n\nexport function ForgotPasswordForm({ onSent }: { onSent?: () => void }) {\n const { t } = useTranslation();\n\n const schema = yupObject({\n email: strictEmailSchema(t(\"Please enter a valid email\")).defined().nonEmpty(t(\"Please enter your email\"))\n });\n\n const { register, handleSubmit, formState: { errors }, clearErrors } = useForm({\n resolver: yupResolver(schema)\n });\n const hexclaveApp = useStackApp();\n const [loading, setLoading] = useState(false);\n\n const onSubmit = async (data: yup.InferType<typeof schema>) => {\n setLoading(true);\n try {\n const { email } = data;\n await hexclaveApp.sendForgotPasswordEmail(email);\n onSent?.();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <form\n className=\"flex flex-col items-stretch stack-scope\"\n onSubmit={e => runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))}\n noValidate\n >\n <Label htmlFor=\"email\" className=\"mb-1\">{t(\"Your Email\")}</Label>\n <Input\n id=\"email\"\n type=\"email\"\n autoComplete=\"email\"\n {...register('email', { onChange: () => clearErrors('email') })}\n />\n <FormWarningText text={errors.email?.message?.toString()} />\n\n <Button type=\"submit\" className=\"mt-6\" loading={loading}>\n {t(\"Send Email\")}\n </Button>\n </form>\n );\n}\n\n\nexport function ForgotPassword(props: { fullPage?: boolean }) {\n const { t } = useTranslation();\n const hexclaveApp = useStackApp();\n const user = useUser();\n const [sent, setSent] = useState(false);\n\n if (user) {\n return <PredefinedMessageCard type='signedIn' fullPage={!!props.fullPage} />;\n }\n\n if (sent) {\n return <PredefinedMessageCard type='emailSent' fullPage={!!props.fullPage} />;\n }\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className={cn(\n \"stack-scope max-w-[380px] flex-basis-[380px]\",\n props.fullPage ? \"p-4\" : \"p-0\"\n )}>\n <div className=\"text-center\">\n <Typography type='h2'>{t(\"Reset Your Password\")}</Typography>\n <Typography>\n {t(\"Don't need to reset?\")}{\" \"}\n <StyledLink href={hexclaveApp.urls['signIn']}>\n {t(\"Sign in\")}\n </StyledLink>\n </Typography>\n </div>\n <div className=\"mt-6\">\n <ForgotPasswordForm onSent={() => setSent(true)} />\n </div>\n </div>\n </MaybeFullPage>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,mBAAmB,EAAE,UAAmC;CACtE,MAAM,EAAE,kDAAsB;CAM9B,MAAM,EAAE,UAAU,cAAc,WAAW,EAAE,UAAU,6CAAwB,EAC7E,sGALuB,EACvB,kEAAyB,EAAE,6BAA6B,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,0BAA0B,CAAC,EAC3G,CAAC,CAG6B,EAC9B,CAAC;CACF,MAAM,4CAA2B;CACjC,MAAM,CAAC,SAAS,kCAAuB,MAAM;CAE7C,MAAM,WAAW,OAAO,SAAuC;AAC7D,aAAW,KAAK;AAChB,MAAI;GACF,MAAM,EAAE,UAAU;AAClB,SAAM,YAAY,wBAAwB,MAAM;AAClD,aAAU;YACA;AACR,cAAW,MAAM;;;AAIrB,QACE,4CAAC;EACC,WAAU;EACV,WAAU,2EAAgC,aAAa,SAAS,CAAC,EAAE,CAAC;EACpE;;GAEA,2CAACA;IAAM,SAAQ;IAAQ,WAAU;cAAQ,EAAE,aAAa;KAAS;GACjE,2CAACC;IACC,IAAG;IACH,MAAK;IACL,cAAa;IACb,GAAI,SAAS,SAAS,EAAE,gBAAgB,YAAY,QAAQ,EAAE,CAAC;KAC/D;GACF,2CAACC,0DAAgB,MAAM,OAAO,OAAO,SAAS,UAAU,GAAI;GAE5D,2CAACC;IAAO,MAAK;IAAS,WAAU;IAAgB;cAC7C,EAAE,aAAa;KACT;;GACJ;;AAKX,SAAgB,eAAe,OAA+B;CAC5D,MAAM,EAAE,kDAAsB;CAC9B,MAAM,4CAA2B;CACjC,MAAM,iCAAgB;CACtB,MAAM,CAAC,MAAM,+BAAoB,MAAM;AAEvC,KAAI,KACF,QAAO,2CAACC;EAAsB,MAAK;EAAW,UAAU,CAAC,CAAC,MAAM;GAAY;AAG9E,KAAI,KACF,QAAO,2CAACA;EAAsB,MAAK;EAAY,UAAU,CAAC,CAAC,MAAM;GAAY;AAG/E,QACE,2CAACC;EAAc,UAAU,CAAC,CAAC,MAAM;YAC/B,4CAAC;GAAI,gCACH,gDACA,MAAM,WAAW,QAAQ,MAC1B;cACC,4CAAC;IAAI,WAAU;eACb,2CAACC;KAAW,MAAK;eAAM,EAAE,sBAAsB;MAAc,EAC7D,4CAACA;KACE,EAAE,uBAAuB;KAAE;KAC5B,2CAACC;MAAW,MAAM,YAAY,KAAK;gBAChC,EAAE,UAAU;OACF;QACF;KACT,EACN,2CAAC;IAAI,WAAU;cACb,2CAAC,sBAAmB,cAAc,QAAQ,KAAK,GAAI;KAC/C;IACF;GACQ"}
@@ -1,6 +1,6 @@
1
- import { AccountSettings } from "./account-settings.js";
2
1
  import { HandlerUrls } from "../lib/hexclave-app/common.js";
3
2
  import { StackClientApp } from "../lib/hexclave-app/apps/interfaces/client-app.js";
3
+ import { AccountSettings } from "./account-settings.js";
4
4
  import { CliAuthConfirmation } from "./cli-auth-confirm.js";
5
5
  import { EmailVerification } from "./email-verification.js";
6
6
  import { ErrorPage } from "./error-page.js";
@@ -128,22 +128,17 @@ function MFA(props) {
128
128
  const { t } = (0, ___lib_translations_js.useTranslation)();
129
129
  const headerText = t("Multi-Factor Authentication");
130
130
  const instructionText = t("Enter the six-digit code from your authenticator app");
131
- if (props.fullPage) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_elements_maybe_full_page_js.MaybeFullPage, {
132
- fullPage: true,
131
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_elements_maybe_full_page_js.MaybeFullPage, {
132
+ fullPage: !!props.fullPage,
133
133
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
134
- className: "stack-scope flex flex-col items-stretch",
135
- style: {
136
- maxWidth: "380px",
137
- flexBasis: "380px",
138
- padding: "1rem"
139
- },
134
+ className: (0, _hexclave_ui.cn)("stack-scope max-w-[380px] flex-basis-[380px]", props.fullPage ? "p-4" : "p-0"),
140
135
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
141
136
  className: "text-center mb-6",
142
137
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Typography, {
143
138
  type: "h2",
144
139
  children: headerText
145
140
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Typography, {
146
- className: "mt-2",
141
+ className: "mt-2 text-sm text-muted-foreground",
147
142
  children: instructionText
148
143
  })]
149
144
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MfaForm, {
@@ -152,16 +147,6 @@ function MFA(props) {
152
147
  })]
153
148
  })
154
149
  });
155
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
156
- className: "flex flex-col items-stretch stack-scope",
157
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Typography, {
158
- className: "mb-4 text-center",
159
- children: instructionText
160
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MfaForm, {
161
- onSuccess: props.onSuccess,
162
- onCancel: props.onCancel
163
- })]
164
- });
165
150
  }
166
151
 
167
152
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"mfa.js","names":["KnownErrors","InputOTP","InputOTPGroup","InputOTPSlot","CheckIcon","Typography","Spinner","FormWarningText","Button","MaybeFullPage"],"sources":["../../src/components-page/mfa.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@hexclave/shared\";\nimport {\n Button,\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n Spinner,\n Typography,\n cn,\n} from \"@hexclave/ui\";\nimport { CheckIcon } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useTranslation } from \"../lib/translations\";\n\nfunction MfaForm({ onSuccess, onCancel }: {\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const hexclaveApp = useStackApp();\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>(\"\");\n const formRef = useRef<HTMLFormElement>(null);\n\n const [submitting, setSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [verified, setVerified] = useState<boolean>(false);\n\n const [attemptCode, setAttemptCode] = useState<string | null>(null);\n\n useEffect(() => {\n if (!attemptCode && typeof window !== \"undefined\") {\n // Hexclave rebrand: prefer the new MFA attempt code key, fall back to the legacy key.\n const code = window.sessionStorage.getItem(\"hexclave_mfa_attempt_code\") ?? window.sessionStorage.getItem(\"stack_mfa_attempt_code\");\n if (code) {\n setAttemptCode(code);\n }\n }\n }, [ attemptCode]);\n\n // Handle OTP verification when code is complete\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n // Blur any focused inputs\n if (document.activeElement instanceof HTMLElement) {\n document.activeElement.blur();\n }\n if (formRef.current) {\n const inputs = formRef.current.querySelectorAll('input');\n for (const input of inputs) {\n input.blur();\n }\n }\n\n setSubmitting(true);\n setError(null);\n\n if (attemptCode) {\n hexclaveApp\n .signInWithMfa(otp, attemptCode, { noRedirect: true })\n .then(async (result) => {\n if (result.status === \"ok\") {\n setVerified(true);\n\n // Cleanup session storage\n if (typeof window !== \"undefined\") {\n // Hexclave rebrand: remove both the new and legacy MFA attempt code keys.\n window.sessionStorage.removeItem(\"hexclave_mfa_attempt_code\");\n window.sessionStorage.removeItem(\"stack_mfa_attempt_code\");\n }\n\n if (onSuccess) {\n onSuccess();\n } else {\n await hexclaveApp.redirectToAfterSignIn();\n }\n } else {\n throw result.error;\n }\n })\n .catch((e) => {\n if (e instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n setError(t(\"Verification failed\"));\n }\n })\n .finally(() => {\n setSubmitting(false);\n if (!verified) {\n setOtp(\"\");\n }\n });\n } else {\n setSubmitting(false);\n setError(t(\"Missing verification information\"));\n }\n }\n\n // Clear error when user is typing\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting, onSuccess, attemptCode, hexclaveApp, t, verified]);\n\n\n const inputStyleClass = useMemo(() => {\n if (verified) {\n return \"opacity-85 transition-all duration-300\";\n }\n\n if (error) {\n return \"ring-red-500 border-red-500\";\n }\n\n return \"focus:ring-primary/50\";\n }, [error, verified]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form ref={formRef} className=\"w-full flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"······\"\n value={otp}\n onChange={(value) => setOtp(value.toUpperCase())}\n disabled={submitting || verified}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot\n key={index}\n index={index}\n size=\"lg\"\n className={cn(\n \"border focus:ring-2 transition-all\",\n inputStyleClass,\n )}\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n\n {/* Verification Status */}\n <div className=\"h-8 flex flex-col gap-4 items-center justify-center w-full\">\n {verified ? (\n <div className=\"flex items-center gap-2 animate-in fade-in duration-300 slide-in-from-bottom-2\">\n <CheckIcon className=\"w-5 h-5 text-green-600 animate-in zoom-in duration-300\" />\n <Typography className=\"text-sm font-medium\">{t(\"Verified! Redirecting...\")}</Typography>\n </div>\n ) : submitting ? (\n <div className=\"flex items-center gap-2\">\n <Spinner className=\"text-primary h-4 w-4\" />\n <Typography className=\"text-sm\">{t(\"Verifying...\")}</Typography>\n </div>\n ) : null}\n\n {/* Error reporting */}\n {error !== null && !submitting && !verified ? <FormWarningText text={error} /> : null}\n </div>\n </form>\n\n {/* Cancel Button */}\n {onCancel && !verified && (\n <Button\n variant=\"link\"\n onClick={onCancel}\n className=\"underline mt-4 self-center\"\n disabled={submitting || verified}\n >\n {t(\"Cancel\")}\n </Button>\n )}\n </div>\n );\n}\n\nexport function MFA(props: {\n fullPage?: boolean,\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const { t } = useTranslation();\n\n const headerText = t(\"Multi-Factor Authentication\");\n const instructionText = t(\"Enter the six-digit code from your authenticator app\");\n\n if (props.fullPage) {\n return (\n <MaybeFullPage fullPage={true}>\n <div\n className=\"stack-scope flex flex-col items-stretch\"\n style={{ maxWidth: \"380px\", flexBasis: \"380px\", padding: \"1rem\" }}\n >\n <div className=\"text-center mb-6\">\n <Typography type=\"h2\">{headerText}</Typography>\n <Typography className=\"mt-2\">{instructionText}</Typography>\n </div>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n </MaybeFullPage>\n );\n }\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <Typography className=\"mb-4 text-center\">{instructionText}</Typography>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mfa.js","names":["KnownErrors","InputOTP","InputOTPGroup","InputOTPSlot","CheckIcon","Typography","Spinner","FormWarningText","Button","MaybeFullPage"],"sources":["../../src/components-page/mfa.tsx"],"sourcesContent":["\"use client\";\n\n\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template\n//===========================================\n\nimport { KnownErrors } from \"@hexclave/shared\";\nimport {\n Button,\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n Spinner,\n Typography,\n cn,\n} from \"@hexclave/ui\";\nimport { CheckIcon } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useStackApp } from \"..\";\nimport { FormWarningText } from \"../components/elements/form-warning\";\nimport { MaybeFullPage } from \"../components/elements/maybe-full-page\";\nimport { useTranslation } from \"../lib/translations\";\n\nfunction MfaForm({ onSuccess, onCancel }: {\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const hexclaveApp = useStackApp();\n const { t } = useTranslation();\n const [otp, setOtp] = useState<string>(\"\");\n const formRef = useRef<HTMLFormElement>(null);\n\n const [submitting, setSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [verified, setVerified] = useState<boolean>(false);\n\n const [attemptCode, setAttemptCode] = useState<string | null>(null);\n\n useEffect(() => {\n if (!attemptCode && typeof window !== \"undefined\") {\n // Hexclave rebrand: prefer the new MFA attempt code key, fall back to the legacy key.\n const code = window.sessionStorage.getItem(\"hexclave_mfa_attempt_code\") ?? window.sessionStorage.getItem(\"stack_mfa_attempt_code\");\n if (code) {\n setAttemptCode(code);\n }\n }\n }, [ attemptCode]);\n\n // Handle OTP verification when code is complete\n useEffect(() => {\n if (otp.length === 6 && !submitting) {\n // Blur any focused inputs\n if (document.activeElement instanceof HTMLElement) {\n document.activeElement.blur();\n }\n if (formRef.current) {\n const inputs = formRef.current.querySelectorAll('input');\n for (const input of inputs) {\n input.blur();\n }\n }\n\n setSubmitting(true);\n setError(null);\n\n if (attemptCode) {\n hexclaveApp\n .signInWithMfa(otp, attemptCode, { noRedirect: true })\n .then(async (result) => {\n if (result.status === \"ok\") {\n setVerified(true);\n\n // Cleanup session storage\n if (typeof window !== \"undefined\") {\n // Hexclave rebrand: remove both the new and legacy MFA attempt code keys.\n window.sessionStorage.removeItem(\"hexclave_mfa_attempt_code\");\n window.sessionStorage.removeItem(\"stack_mfa_attempt_code\");\n }\n\n if (onSuccess) {\n onSuccess();\n } else {\n await hexclaveApp.redirectToAfterSignIn();\n }\n } else {\n throw result.error;\n }\n })\n .catch((e) => {\n if (e instanceof KnownErrors.InvalidTotpCode) {\n setError(t(\"Invalid TOTP code\"));\n } else {\n setError(t(\"Verification failed\"));\n }\n })\n .finally(() => {\n setSubmitting(false);\n if (!verified) {\n setOtp(\"\");\n }\n });\n } else {\n setSubmitting(false);\n setError(t(\"Missing verification information\"));\n }\n }\n\n // Clear error when user is typing\n if (otp.length !== 0 && otp.length !== 6) {\n setError(null);\n }\n }, [otp, submitting, onSuccess, attemptCode, hexclaveApp, t, verified]);\n\n\n const inputStyleClass = useMemo(() => {\n if (verified) {\n return \"opacity-85 transition-all duration-300\";\n }\n\n if (error) {\n return \"ring-red-500 border-red-500\";\n }\n\n return \"focus:ring-primary/50\";\n }, [error, verified]);\n\n return (\n <div className=\"flex flex-col items-stretch stack-scope\">\n <form ref={formRef} className=\"w-full flex flex-col items-center gap-4\">\n <InputOTP\n maxLength={6}\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"······\"\n value={otp}\n onChange={(value) => setOtp(value.toUpperCase())}\n disabled={submitting || verified}\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((index) => (\n <InputOTPSlot\n key={index}\n index={index}\n size=\"lg\"\n className={cn(\n \"border focus:ring-2 transition-all\",\n inputStyleClass,\n )}\n />\n ))}\n </InputOTPGroup>\n </InputOTP>\n\n {/* Verification Status */}\n <div className=\"h-8 flex flex-col gap-4 items-center justify-center w-full\">\n {verified ? (\n <div className=\"flex items-center gap-2 animate-in fade-in duration-300 slide-in-from-bottom-2\">\n <CheckIcon className=\"w-5 h-5 text-green-600 animate-in zoom-in duration-300\" />\n <Typography className=\"text-sm font-medium\">{t(\"Verified! Redirecting...\")}</Typography>\n </div>\n ) : submitting ? (\n <div className=\"flex items-center gap-2\">\n <Spinner className=\"text-primary h-4 w-4\" />\n <Typography className=\"text-sm\">{t(\"Verifying...\")}</Typography>\n </div>\n ) : null}\n\n {/* Error reporting */}\n {error !== null && !submitting && !verified ? <FormWarningText text={error} /> : null}\n </div>\n </form>\n\n {/* Cancel Button */}\n {onCancel && !verified && (\n <Button\n variant=\"link\"\n onClick={onCancel}\n className=\"underline mt-4 self-center\"\n disabled={submitting || verified}\n >\n {t(\"Cancel\")}\n </Button>\n )}\n </div>\n );\n}\n\nexport function MFA(props: {\n fullPage?: boolean,\n onSuccess?: () => void,\n onCancel?: () => void,\n}) {\n const { t } = useTranslation();\n\n const headerText = t(\"Multi-Factor Authentication\");\n const instructionText = t(\"Enter the six-digit code from your authenticator app\");\n\n return (\n <MaybeFullPage fullPage={!!props.fullPage}>\n <div className={cn(\n \"stack-scope max-w-[380px] flex-basis-[380px]\",\n props.fullPage ? \"p-4\" : \"p-0\"\n )}>\n <div className=\"text-center mb-6\">\n <Typography type=\"h2\">{headerText}</Typography>\n <Typography className=\"mt-2 text-sm text-muted-foreground\">{instructionText}</Typography>\n </div>\n <MfaForm onSuccess={props.onSuccess} onCancel={props.onCancel} />\n </div>\n </MaybeFullPage>\n );\n}\n"],"mappings":"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"}
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
- let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
6
5
  let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
6
+ let _hexclave_shared_dist_utils_errors = require("@hexclave/shared/dist/utils/errors");
7
7
  let _hexclave_ui = require("@hexclave/ui");
8
8
  let react = require("react");
9
9
  let ___index_js = require("../index.js");
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  let react_hook_form = require("react-hook-form");
@@ -1 +1 @@
1
- {"version":3,"file":"password-reset.d.ts","names":[],"sources":["../../src/components-page/password-reset.tsx"],"mappings":";;;iBAyBwB,iBAAA,CAAkB,KAAA;EACxC,IAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA4Ge,aAAA,CAAA;EACd,YAAA;EACA;AAAA;EAEA,YAAA,EAAc,MAAA;EACd,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"password-reset.d.ts","names":[],"sources":["../../src/components-page/password-reset.tsx"],"mappings":";;;iBAyBwB,iBAAA,CAAkB,KAAA;EACxC,IAAA;EACA,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA0Ge,aAAA,CAAA;EACd,YAAA;EACA;AAAA;EAEA,YAAA,EAAc,MAAA;EACd,QAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4
4
  const require_chunk = require('../chunk-BE-pF4vm.js');
5
+ let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
5
6
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
6
7
  let _hexclave_shared_dist_schema_fields = require("@hexclave/shared/dist/schema-fields");
7
- let _hexclave_shared_dist_utils_promises = require("@hexclave/shared/dist/utils/promises");
8
8
  let _hexclave_ui = require("@hexclave/ui");
9
9
  let react = require("react");
10
10
  let react_hook_form = require("react-hook-form");
@@ -88,11 +88,10 @@ function PasswordResetForm(props) {
88
88
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.PasswordInput, {
89
89
  id: "password",
90
90
  autoComplete: "new-password",
91
- ...register("password"),
92
- onChange: () => {
91
+ ...register("password", { onChange: () => {
93
92
  clearErrors("password");
94
93
  clearErrors("passwordRepeat");
95
- }
94
+ } })
96
95
  }),
97
96
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_elements_form_warning_js.FormWarningText, { text: errors.password?.message?.toString() }),
98
97
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Label, {
@@ -103,11 +102,10 @@ function PasswordResetForm(props) {
103
102
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.PasswordInput, {
104
103
  id: "repeat-password",
105
104
  autoComplete: "new-password",
106
- ...register("passwordRepeat"),
107
- onChange: () => {
105
+ ...register("passwordRepeat", { onChange: () => {
108
106
  clearErrors("password");
109
107
  clearErrors("passwordRepeat");
110
- }
108
+ } })
111
109
  }),
112
110
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(___components_elements_form_warning_js.FormWarningText, { text: errors.passwordRepeat?.message?.toString() }),
113
111
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_hexclave_ui.Button, {