@workos-inc/widgets 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/README.md +68 -1
  2. package/dist/cjs/card-list.d.ts +6 -0
  3. package/dist/cjs/card-list.d.ts.map +1 -0
  4. package/dist/cjs/card-list.js +13 -0
  5. package/dist/cjs/card-list.js.map +1 -0
  6. package/dist/cjs/index.d.ts +3 -0
  7. package/dist/cjs/index.d.ts.map +1 -1
  8. package/dist/cjs/index.js +7 -1
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/lib/add-mfa-dialog.d.ts +9 -0
  11. package/dist/cjs/lib/add-mfa-dialog.d.ts.map +1 -0
  12. package/dist/cjs/lib/add-mfa-dialog.js +135 -0
  13. package/dist/cjs/lib/add-mfa-dialog.js.map +1 -0
  14. package/dist/cjs/lib/api/user.d.ts +13 -57
  15. package/dist/cjs/lib/api/user.d.ts.map +1 -1
  16. package/dist/cjs/lib/api/user.js +44 -314
  17. package/dist/cjs/lib/api/user.js.map +1 -1
  18. package/dist/cjs/lib/change-password-dialog.d.ts +8 -0
  19. package/dist/cjs/lib/change-password-dialog.d.ts.map +1 -0
  20. package/dist/cjs/lib/change-password-dialog.js +97 -0
  21. package/dist/cjs/lib/change-password-dialog.js.map +1 -0
  22. package/dist/cjs/lib/copy-button.d.ts +8 -0
  23. package/dist/cjs/lib/copy-button.d.ts.map +1 -0
  24. package/dist/cjs/lib/copy-button.js +63 -0
  25. package/dist/cjs/lib/copy-button.js.map +1 -0
  26. package/dist/cjs/lib/delete-user-dialog.d.ts +2 -2
  27. package/dist/cjs/lib/delete-user-dialog.d.ts.map +1 -1
  28. package/dist/cjs/lib/delete-user-dialog.js +1 -1
  29. package/dist/cjs/lib/delete-user-dialog.js.map +1 -1
  30. package/dist/cjs/lib/edit-user-profile-dialog.d.ts +10 -0
  31. package/dist/cjs/lib/edit-user-profile-dialog.d.ts.map +1 -0
  32. package/dist/cjs/lib/edit-user-profile-dialog.js +85 -0
  33. package/dist/cjs/lib/edit-user-profile-dialog.js.map +1 -0
  34. package/dist/cjs/lib/edit-user-role-dialog.d.ts +12 -0
  35. package/dist/cjs/lib/edit-user-role-dialog.d.ts.map +1 -0
  36. package/dist/cjs/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +11 -7
  37. package/dist/cjs/lib/edit-user-role-dialog.js.map +1 -0
  38. package/dist/cjs/lib/elements.d.ts +1 -0
  39. package/dist/cjs/lib/elements.d.ts.map +1 -1
  40. package/dist/cjs/lib/elements.js +10 -4
  41. package/dist/cjs/lib/elements.js.map +1 -1
  42. package/dist/cjs/lib/elevated-access.d.ts +8 -0
  43. package/dist/cjs/lib/elevated-access.d.ts.map +1 -0
  44. package/dist/cjs/lib/elevated-access.js +130 -0
  45. package/dist/cjs/lib/elevated-access.js.map +1 -0
  46. package/dist/cjs/lib/generic-error.d.ts +4 -0
  47. package/dist/cjs/lib/generic-error.d.ts.map +1 -0
  48. package/dist/cjs/lib/generic-error.js +57 -0
  49. package/dist/cjs/lib/generic-error.js.map +1 -0
  50. package/dist/cjs/lib/icon-panel.d.ts +3 -0
  51. package/dist/cjs/lib/icon-panel.d.ts.map +1 -0
  52. package/dist/cjs/lib/icon-panel.js +16 -0
  53. package/dist/cjs/lib/icon-panel.js.map +1 -0
  54. package/dist/cjs/lib/icons.d.ts +3 -0
  55. package/dist/cjs/lib/icons.d.ts.map +1 -0
  56. package/dist/cjs/lib/icons.js +8 -0
  57. package/dist/cjs/lib/icons.js.map +1 -0
  58. package/dist/cjs/lib/invite-user-dialog.d.ts.map +1 -1
  59. package/dist/cjs/lib/invite-user-dialog.js +7 -5
  60. package/dist/cjs/lib/invite-user-dialog.js.map +1 -1
  61. package/dist/cjs/lib/logout-all-sessions-dialog.d.ts +9 -0
  62. package/dist/cjs/lib/logout-all-sessions-dialog.d.ts.map +1 -0
  63. package/dist/cjs/lib/logout-all-sessions-dialog.js +52 -0
  64. package/dist/cjs/lib/logout-all-sessions-dialog.js.map +1 -0
  65. package/dist/cjs/lib/logout-dialog.d.ts +10 -0
  66. package/dist/cjs/lib/logout-dialog.d.ts.map +1 -0
  67. package/dist/cjs/lib/logout-dialog.js +58 -0
  68. package/dist/cjs/lib/logout-dialog.js.map +1 -0
  69. package/dist/cjs/lib/marker.d.ts +14 -0
  70. package/dist/cjs/lib/marker.d.ts.map +1 -0
  71. package/dist/cjs/lib/marker.js +38 -0
  72. package/dist/cjs/lib/marker.js.map +1 -0
  73. package/dist/cjs/lib/oauth-icons.d.ts +4 -0
  74. package/dist/cjs/lib/oauth-icons.d.ts.map +1 -0
  75. package/dist/cjs/lib/oauth-icons.js +67 -0
  76. package/dist/cjs/lib/oauth-icons.js.map +1 -0
  77. package/dist/cjs/lib/organization-switcher.d.ts +24 -0
  78. package/dist/cjs/lib/organization-switcher.d.ts.map +1 -0
  79. package/dist/cjs/lib/organization-switcher.js +35 -0
  80. package/dist/cjs/lib/organization-switcher.js.map +1 -0
  81. package/dist/cjs/lib/otp-input.d.ts +20 -0
  82. package/dist/cjs/lib/otp-input.d.ts.map +1 -0
  83. package/dist/cjs/lib/otp-input.js +174 -0
  84. package/dist/cjs/lib/otp-input.js.map +1 -0
  85. package/dist/cjs/lib/resend-invite-dialog.d.ts +2 -2
  86. package/dist/cjs/lib/resend-invite-dialog.d.ts.map +1 -1
  87. package/dist/cjs/lib/resend-invite-dialog.js +1 -1
  88. package/dist/cjs/lib/resend-invite-dialog.js.map +1 -1
  89. package/dist/cjs/lib/reset-mfa-dialog.d.ts +9 -0
  90. package/dist/cjs/lib/reset-mfa-dialog.d.ts.map +1 -0
  91. package/dist/cjs/lib/reset-mfa-dialog.js +60 -0
  92. package/dist/cjs/lib/reset-mfa-dialog.js.map +1 -0
  93. package/dist/cjs/lib/revoke-invite-dialog.d.ts +2 -2
  94. package/dist/cjs/lib/revoke-invite-dialog.d.ts.map +1 -1
  95. package/dist/cjs/lib/revoke-invite-dialog.js +1 -1
  96. package/dist/cjs/lib/revoke-invite-dialog.js.map +1 -1
  97. package/dist/cjs/lib/save-button.d.ts +11 -0
  98. package/dist/cjs/lib/save-button.d.ts.map +1 -0
  99. package/dist/cjs/lib/save-button.js +47 -0
  100. package/dist/cjs/lib/save-button.js.map +1 -0
  101. package/dist/cjs/lib/set-password-dialog.d.ts +8 -0
  102. package/dist/cjs/lib/set-password-dialog.d.ts.map +1 -0
  103. package/dist/cjs/lib/set-password-dialog.js +80 -0
  104. package/dist/cjs/lib/set-password-dialog.js.map +1 -0
  105. package/dist/cjs/lib/use-dialog-close.d.ts +2 -0
  106. package/dist/cjs/lib/use-dialog-close.d.ts.map +1 -0
  107. package/dist/cjs/lib/use-dialog-close.js +43 -0
  108. package/dist/cjs/lib/use-dialog-close.js.map +1 -0
  109. package/dist/cjs/lib/use-security-settings.d.ts +11 -0
  110. package/dist/cjs/lib/use-security-settings.d.ts.map +1 -0
  111. package/dist/cjs/lib/use-security-settings.js +39 -0
  112. package/dist/cjs/lib/use-security-settings.js.map +1 -0
  113. package/dist/cjs/lib/user-actions-dropdown.d.ts +2 -2
  114. package/dist/cjs/lib/user-actions-dropdown.d.ts.map +1 -1
  115. package/dist/cjs/lib/user-actions-dropdown.js +8 -4
  116. package/dist/cjs/lib/user-actions-dropdown.js.map +1 -1
  117. package/dist/cjs/lib/user-profile.d.ts +11 -0
  118. package/dist/cjs/lib/user-profile.d.ts.map +1 -0
  119. package/dist/cjs/lib/user-profile.js +36 -0
  120. package/dist/cjs/lib/user-profile.js.map +1 -0
  121. package/dist/cjs/lib/user-security.d.ts +11 -0
  122. package/dist/cjs/lib/user-security.d.ts.map +1 -0
  123. package/dist/cjs/lib/user-security.js +64 -0
  124. package/dist/cjs/lib/user-security.js.map +1 -0
  125. package/dist/cjs/lib/user-sessions.d.ts +12 -0
  126. package/dist/cjs/lib/user-sessions.d.ts.map +1 -0
  127. package/dist/cjs/lib/user-sessions.js +72 -0
  128. package/dist/cjs/lib/user-sessions.js.map +1 -0
  129. package/dist/cjs/lib/users-filter.d.ts +2 -2
  130. package/dist/cjs/lib/users-filter.d.ts.map +1 -1
  131. package/dist/cjs/lib/users-filter.js.map +1 -1
  132. package/dist/cjs/lib/users-management-context.d.ts +0 -9
  133. package/dist/cjs/lib/users-management-context.d.ts.map +1 -1
  134. package/dist/cjs/lib/users-management-context.js +13 -26
  135. package/dist/cjs/lib/users-management-context.js.map +1 -1
  136. package/dist/cjs/lib/users-management-state.d.ts +3 -3
  137. package/dist/cjs/lib/users-management-state.d.ts.map +1 -1
  138. package/dist/cjs/lib/users-management-state.js.map +1 -1
  139. package/dist/cjs/lib/users-management.d.ts +3 -4
  140. package/dist/cjs/lib/users-management.d.ts.map +1 -1
  141. package/dist/cjs/lib/users-management.js +8 -26
  142. package/dist/cjs/lib/users-management.js.map +1 -1
  143. package/dist/cjs/lib/utils.d.ts +10 -2
  144. package/dist/cjs/lib/utils.d.ts.map +1 -1
  145. package/dist/cjs/lib/utils.js +18 -0
  146. package/dist/cjs/lib/utils.js.map +1 -1
  147. package/dist/cjs/organization-switcher.client.d.ts +8 -0
  148. package/dist/cjs/organization-switcher.client.d.ts.map +1 -0
  149. package/dist/cjs/organization-switcher.client.js +37 -0
  150. package/dist/cjs/organization-switcher.client.js.map +1 -0
  151. package/dist/cjs/user-profile.client.d.ts +7 -0
  152. package/dist/cjs/user-profile.client.d.ts.map +1 -0
  153. package/dist/cjs/user-profile.client.js +31 -0
  154. package/dist/cjs/user-profile.client.js.map +1 -0
  155. package/dist/cjs/user-security.client.d.ts +7 -0
  156. package/dist/cjs/user-security.client.d.ts.map +1 -0
  157. package/dist/cjs/user-security.client.js +27 -0
  158. package/dist/cjs/user-security.client.js.map +1 -0
  159. package/dist/cjs/user-sessions.client.d.ts +12 -0
  160. package/dist/cjs/user-sessions.client.d.ts.map +1 -0
  161. package/dist/cjs/user-sessions.client.js +48 -0
  162. package/dist/cjs/user-sessions.client.js.map +1 -0
  163. package/dist/cjs/users-management.client.d.ts +2 -1
  164. package/dist/cjs/users-management.client.d.ts.map +1 -1
  165. package/dist/cjs/users-management.client.js +12 -43
  166. package/dist/cjs/users-management.client.js.map +1 -1
  167. package/dist/esm/card-list.d.ts +6 -0
  168. package/dist/esm/card-list.d.ts.map +1 -0
  169. package/dist/esm/card-list.js +9 -0
  170. package/dist/esm/card-list.js.map +1 -0
  171. package/dist/esm/index.d.ts +3 -0
  172. package/dist/esm/index.d.ts.map +1 -1
  173. package/dist/esm/index.js +3 -0
  174. package/dist/esm/index.js.map +1 -1
  175. package/dist/esm/lib/add-mfa-dialog.d.ts +9 -0
  176. package/dist/esm/lib/add-mfa-dialog.d.ts.map +1 -0
  177. package/dist/esm/lib/add-mfa-dialog.js +109 -0
  178. package/dist/esm/lib/add-mfa-dialog.js.map +1 -0
  179. package/dist/esm/lib/api/user.d.ts +13 -57
  180. package/dist/esm/lib/api/user.d.ts.map +1 -1
  181. package/dist/esm/lib/api/user.js +44 -313
  182. package/dist/esm/lib/api/user.js.map +1 -1
  183. package/dist/esm/lib/change-password-dialog.d.ts +8 -0
  184. package/dist/esm/lib/change-password-dialog.d.ts.map +1 -0
  185. package/dist/esm/lib/change-password-dialog.js +71 -0
  186. package/dist/esm/lib/change-password-dialog.js.map +1 -0
  187. package/dist/esm/lib/copy-button.d.ts +8 -0
  188. package/dist/esm/lib/copy-button.d.ts.map +1 -0
  189. package/dist/esm/lib/copy-button.js +37 -0
  190. package/dist/esm/lib/copy-button.js.map +1 -0
  191. package/dist/esm/lib/delete-user-dialog.d.ts +2 -2
  192. package/dist/esm/lib/delete-user-dialog.d.ts.map +1 -1
  193. package/dist/esm/lib/delete-user-dialog.js +1 -1
  194. package/dist/esm/lib/delete-user-dialog.js.map +1 -1
  195. package/dist/esm/lib/edit-user-profile-dialog.d.ts +10 -0
  196. package/dist/esm/lib/edit-user-profile-dialog.d.ts.map +1 -0
  197. package/dist/esm/lib/edit-user-profile-dialog.js +59 -0
  198. package/dist/esm/lib/edit-user-profile-dialog.js.map +1 -0
  199. package/dist/esm/lib/edit-user-role-dialog.d.ts +12 -0
  200. package/dist/esm/lib/edit-user-role-dialog.d.ts.map +1 -0
  201. package/dist/esm/lib/{edit-user-details-dialog.js → edit-user-role-dialog.js} +10 -6
  202. package/dist/esm/lib/edit-user-role-dialog.js.map +1 -0
  203. package/dist/esm/lib/elements.d.ts +1 -0
  204. package/dist/esm/lib/elements.d.ts.map +1 -1
  205. package/dist/esm/lib/elements.js +9 -3
  206. package/dist/esm/lib/elements.js.map +1 -1
  207. package/dist/esm/lib/elevated-access.d.ts +8 -0
  208. package/dist/esm/lib/elevated-access.d.ts.map +1 -0
  209. package/dist/esm/lib/elevated-access.js +104 -0
  210. package/dist/esm/lib/elevated-access.js.map +1 -0
  211. package/dist/esm/lib/generic-error.d.ts +4 -0
  212. package/dist/esm/lib/generic-error.d.ts.map +1 -0
  213. package/dist/esm/lib/generic-error.js +31 -0
  214. package/dist/esm/lib/generic-error.js.map +1 -0
  215. package/dist/esm/lib/icon-panel.d.ts +3 -0
  216. package/dist/esm/lib/icon-panel.d.ts.map +1 -0
  217. package/dist/esm/lib/icon-panel.js +13 -0
  218. package/dist/esm/lib/icon-panel.js.map +1 -0
  219. package/dist/esm/lib/icons.d.ts +3 -0
  220. package/dist/esm/lib/icons.d.ts.map +1 -0
  221. package/dist/esm/lib/icons.js +5 -0
  222. package/dist/esm/lib/icons.js.map +1 -0
  223. package/dist/esm/lib/invite-user-dialog.d.ts.map +1 -1
  224. package/dist/esm/lib/invite-user-dialog.js +7 -5
  225. package/dist/esm/lib/invite-user-dialog.js.map +1 -1
  226. package/dist/esm/lib/logout-all-sessions-dialog.d.ts +9 -0
  227. package/dist/esm/lib/logout-all-sessions-dialog.d.ts.map +1 -0
  228. package/dist/esm/lib/logout-all-sessions-dialog.js +26 -0
  229. package/dist/esm/lib/logout-all-sessions-dialog.js.map +1 -0
  230. package/dist/esm/lib/logout-dialog.d.ts +10 -0
  231. package/dist/esm/lib/logout-dialog.d.ts.map +1 -0
  232. package/dist/esm/lib/logout-dialog.js +32 -0
  233. package/dist/esm/lib/logout-dialog.js.map +1 -0
  234. package/dist/esm/lib/marker.d.ts +14 -0
  235. package/dist/esm/lib/marker.d.ts.map +1 -0
  236. package/dist/esm/lib/marker.js +9 -0
  237. package/dist/esm/lib/marker.js.map +1 -0
  238. package/dist/esm/lib/oauth-icons.d.ts +4 -0
  239. package/dist/esm/lib/oauth-icons.d.ts.map +1 -0
  240. package/dist/esm/lib/oauth-icons.js +39 -0
  241. package/dist/esm/lib/oauth-icons.js.map +1 -0
  242. package/dist/esm/lib/organization-switcher.d.ts +24 -0
  243. package/dist/esm/lib/organization-switcher.d.ts.map +1 -0
  244. package/dist/esm/lib/organization-switcher.js +29 -0
  245. package/dist/esm/lib/organization-switcher.js.map +1 -0
  246. package/dist/esm/lib/otp-input.d.ts +20 -0
  247. package/dist/esm/lib/otp-input.d.ts.map +1 -0
  248. package/dist/esm/lib/otp-input.js +148 -0
  249. package/dist/esm/lib/otp-input.js.map +1 -0
  250. package/dist/esm/lib/resend-invite-dialog.d.ts +2 -2
  251. package/dist/esm/lib/resend-invite-dialog.d.ts.map +1 -1
  252. package/dist/esm/lib/resend-invite-dialog.js +1 -1
  253. package/dist/esm/lib/resend-invite-dialog.js.map +1 -1
  254. package/dist/esm/lib/reset-mfa-dialog.d.ts +9 -0
  255. package/dist/esm/lib/reset-mfa-dialog.d.ts.map +1 -0
  256. package/dist/esm/lib/reset-mfa-dialog.js +34 -0
  257. package/dist/esm/lib/reset-mfa-dialog.js.map +1 -0
  258. package/dist/esm/lib/revoke-invite-dialog.d.ts +2 -2
  259. package/dist/esm/lib/revoke-invite-dialog.d.ts.map +1 -1
  260. package/dist/esm/lib/revoke-invite-dialog.js +1 -1
  261. package/dist/esm/lib/revoke-invite-dialog.js.map +1 -1
  262. package/dist/esm/lib/save-button.d.ts +11 -0
  263. package/dist/esm/lib/save-button.d.ts.map +1 -0
  264. package/dist/esm/lib/save-button.js +44 -0
  265. package/dist/esm/lib/save-button.js.map +1 -0
  266. package/dist/esm/lib/set-password-dialog.d.ts +8 -0
  267. package/dist/esm/lib/set-password-dialog.d.ts.map +1 -0
  268. package/dist/esm/lib/set-password-dialog.js +54 -0
  269. package/dist/esm/lib/set-password-dialog.js.map +1 -0
  270. package/dist/esm/lib/use-dialog-close.d.ts +2 -0
  271. package/dist/esm/lib/use-dialog-close.d.ts.map +1 -0
  272. package/dist/esm/lib/use-dialog-close.js +17 -0
  273. package/dist/esm/lib/use-dialog-close.js.map +1 -0
  274. package/dist/esm/lib/use-security-settings.d.ts +11 -0
  275. package/dist/esm/lib/use-security-settings.d.ts.map +1 -0
  276. package/dist/esm/lib/use-security-settings.js +36 -0
  277. package/dist/esm/lib/use-security-settings.js.map +1 -0
  278. package/dist/esm/lib/user-actions-dropdown.d.ts +2 -2
  279. package/dist/esm/lib/user-actions-dropdown.d.ts.map +1 -1
  280. package/dist/esm/lib/user-actions-dropdown.js +8 -4
  281. package/dist/esm/lib/user-actions-dropdown.js.map +1 -1
  282. package/dist/esm/lib/user-profile.d.ts +11 -0
  283. package/dist/esm/lib/user-profile.d.ts.map +1 -0
  284. package/dist/esm/lib/user-profile.js +27 -0
  285. package/dist/esm/lib/user-profile.js.map +1 -0
  286. package/dist/esm/lib/user-security.d.ts +11 -0
  287. package/dist/esm/lib/user-security.d.ts.map +1 -0
  288. package/dist/esm/lib/user-security.js +32 -0
  289. package/dist/esm/lib/user-security.js.map +1 -0
  290. package/dist/esm/lib/user-sessions.d.ts +12 -0
  291. package/dist/esm/lib/user-sessions.d.ts.map +1 -0
  292. package/dist/esm/lib/user-sessions.js +40 -0
  293. package/dist/esm/lib/user-sessions.js.map +1 -0
  294. package/dist/esm/lib/users-filter.d.ts +2 -2
  295. package/dist/esm/lib/users-filter.d.ts.map +1 -1
  296. package/dist/esm/lib/users-filter.js.map +1 -1
  297. package/dist/esm/lib/users-management-context.d.ts +0 -9
  298. package/dist/esm/lib/users-management-context.d.ts.map +1 -1
  299. package/dist/esm/lib/users-management-context.js +13 -25
  300. package/dist/esm/lib/users-management-context.js.map +1 -1
  301. package/dist/esm/lib/users-management-state.d.ts +3 -3
  302. package/dist/esm/lib/users-management-state.d.ts.map +1 -1
  303. package/dist/esm/lib/users-management-state.js.map +1 -1
  304. package/dist/esm/lib/users-management.d.ts +3 -4
  305. package/dist/esm/lib/users-management.d.ts.map +1 -1
  306. package/dist/esm/lib/users-management.js +9 -27
  307. package/dist/esm/lib/users-management.js.map +1 -1
  308. package/dist/esm/lib/users-search.d.ts +1 -1
  309. package/dist/esm/lib/users-search.d.ts.map +1 -1
  310. package/dist/esm/lib/utils.d.ts +10 -2
  311. package/dist/esm/lib/utils.d.ts.map +1 -1
  312. package/dist/esm/lib/utils.js +16 -0
  313. package/dist/esm/lib/utils.js.map +1 -1
  314. package/dist/esm/organization-switcher.client.d.ts +8 -0
  315. package/dist/esm/organization-switcher.client.d.ts.map +1 -0
  316. package/dist/esm/organization-switcher.client.js +33 -0
  317. package/dist/esm/organization-switcher.client.js.map +1 -0
  318. package/dist/esm/user-profile.client.d.ts +7 -0
  319. package/dist/esm/user-profile.client.d.ts.map +1 -0
  320. package/dist/esm/user-profile.client.js +27 -0
  321. package/dist/esm/user-profile.client.js.map +1 -0
  322. package/dist/esm/user-security.client.d.ts +7 -0
  323. package/dist/esm/user-security.client.d.ts.map +1 -0
  324. package/dist/esm/user-security.client.js +23 -0
  325. package/dist/esm/user-security.client.js.map +1 -0
  326. package/dist/esm/user-sessions.client.d.ts +12 -0
  327. package/dist/esm/user-sessions.client.d.ts.map +1 -0
  328. package/dist/esm/user-sessions.client.js +44 -0
  329. package/dist/esm/user-sessions.client.js.map +1 -0
  330. package/dist/esm/users-management.client.d.ts +2 -1
  331. package/dist/esm/users-management.client.d.ts.map +1 -1
  332. package/dist/esm/users-management.client.js +12 -20
  333. package/dist/esm/users-management.client.js.map +1 -1
  334. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  335. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  336. package/package.json +10 -4
  337. package/src/card-list.tsx +26 -0
  338. package/src/index.ts +3 -0
  339. package/src/lib/add-mfa-dialog.tsx +379 -0
  340. package/src/lib/api/user.ts +54 -458
  341. package/src/lib/card-list.css +3 -0
  342. package/src/lib/change-password-dialog.tsx +290 -0
  343. package/src/lib/copy-button.tsx +53 -0
  344. package/src/lib/delete-user-dialog.tsx +9 -6
  345. package/src/lib/edit-user-profile-dialog.tsx +181 -0
  346. package/src/lib/{edit-user-details-dialog.tsx → edit-user-role-dialog.tsx} +12 -9
  347. package/src/lib/elements.tsx +34 -1
  348. package/src/lib/elevated-access.tsx +261 -0
  349. package/src/lib/generic-error.tsx +70 -0
  350. package/src/lib/icon-panel.tsx +26 -0
  351. package/src/lib/icons.tsx +21 -0
  352. package/src/lib/invite-user-dialog.tsx +15 -10
  353. package/src/lib/logout-all-sessions-dialog.tsx +82 -0
  354. package/src/lib/logout-dialog.tsx +89 -0
  355. package/src/lib/marker.css +81 -0
  356. package/src/lib/marker.tsx +39 -0
  357. package/src/lib/oauth-icons.tsx +138 -0
  358. package/src/lib/organization-switcher.tsx +160 -0
  359. package/src/lib/otp-input.tsx +276 -0
  360. package/src/lib/resend-invite-dialog.tsx +9 -6
  361. package/src/lib/reset-mfa-dialog.tsx +104 -0
  362. package/src/lib/revoke-invite-dialog.tsx +9 -6
  363. package/src/lib/save-button.css +60 -0
  364. package/src/lib/save-button.tsx +113 -0
  365. package/src/lib/set-password-dialog.tsx +204 -0
  366. package/src/lib/use-dialog-close.tsx +19 -0
  367. package/src/lib/use-security-settings.tsx +49 -0
  368. package/src/lib/user-actions-dropdown.tsx +10 -6
  369. package/src/lib/user-profile.tsx +247 -0
  370. package/src/lib/user-security.tsx +187 -0
  371. package/src/lib/user-sessions.tsx +204 -0
  372. package/src/lib/users-filter.tsx +2 -2
  373. package/src/lib/users-management-context.tsx +21 -36
  374. package/src/lib/users-management-state.ts +3 -3
  375. package/src/lib/users-management.tsx +21 -77
  376. package/src/lib/utils.ts +30 -2
  377. package/src/organization-switcher.client.tsx +77 -0
  378. package/src/styles.css +44 -0
  379. package/src/user-profile.client.tsx +51 -0
  380. package/src/user-security.client.tsx +55 -0
  381. package/src/user-sessions.client.tsx +96 -0
  382. package/src/users-management.client.tsx +28 -39
  383. package/dist/cjs/lib/api/role.d.ts +0 -9
  384. package/dist/cjs/lib/api/role.d.ts.map +0 -1
  385. package/dist/cjs/lib/api/role.js +0 -115
  386. package/dist/cjs/lib/api/role.js.map +0 -1
  387. package/dist/cjs/lib/edit-user-details-dialog.d.ts +0 -12
  388. package/dist/cjs/lib/edit-user-details-dialog.d.ts.map +0 -1
  389. package/dist/cjs/lib/edit-user-details-dialog.js.map +0 -1
  390. package/dist/esm/lib/api/role.d.ts +0 -9
  391. package/dist/esm/lib/api/role.d.ts.map +0 -1
  392. package/dist/esm/lib/api/role.js +0 -110
  393. package/dist/esm/lib/api/role.js.map +0 -1
  394. package/dist/esm/lib/edit-user-details-dialog.d.ts +0 -12
  395. package/dist/esm/lib/edit-user-details-dialog.d.ts.map +0 -1
  396. package/dist/esm/lib/edit-user-details-dialog.js.map +0 -1
  397. package/src/lib/api/role.ts +0 -147
@@ -0,0 +1,261 @@
1
+ import * as Form from "@radix-ui/react-form";
2
+ import { AlertDialog, Callout, Dialog, Flex, Text } from "@radix-ui/themes";
3
+ import {
4
+ useElevatedAccessToken,
5
+ useMe,
6
+ useSendVerification,
7
+ useVerify,
8
+ } from "@repo/api";
9
+ import { PropsWithChildren, useEffect, useRef, useState } from "react";
10
+ import { PrimaryButton, SecondaryButton } from "./elements";
11
+ import * as Otp from "./otp-input";
12
+
13
+ interface ElevatedAccessProps extends PropsWithChildren {
14
+ onVerified?: () => Promise<unknown>;
15
+ type?: "dialog" | "alert";
16
+ }
17
+
18
+ export function ElevatedAccess({
19
+ type = "dialog",
20
+ children,
21
+ onVerified,
22
+ }: ElevatedAccessProps) {
23
+ const { elevatedAccess } = useElevatedAccessToken();
24
+ const [authenticationChallengeId, setAuthenticationChallengeId] =
25
+ useState<string>();
26
+
27
+ const prevAccessToken = useRef(elevatedAccess);
28
+
29
+ useEffect(() => {
30
+ prevAccessToken.current = elevatedAccess;
31
+ }, [elevatedAccess]);
32
+
33
+ if (elevatedAccess) {
34
+ return <>{children}</>;
35
+ }
36
+
37
+ if (!authenticationChallengeId) {
38
+ const hasTokenExpired = !!prevAccessToken.current;
39
+
40
+ return (
41
+ <SendVerificationEmailForm
42
+ type={type}
43
+ hasTokenExpired={hasTokenExpired}
44
+ onSuccess={(challengeId) => {
45
+ setAuthenticationChallengeId(challengeId);
46
+ }}
47
+ />
48
+ );
49
+ }
50
+
51
+ if (authenticationChallengeId) {
52
+ return (
53
+ <VerificationIdentityForm
54
+ type={type}
55
+ authenticationChallengeId={authenticationChallengeId}
56
+ onSuccess={() => {
57
+ // Reset the challenge id
58
+ setAuthenticationChallengeId(undefined);
59
+
60
+ return onVerified?.();
61
+ }}
62
+ />
63
+ );
64
+ }
65
+
66
+ return null;
67
+ }
68
+
69
+ interface SendVerificationEmailFormProps {
70
+ onSuccess: (challengeId: string) => unknown | Promise<unknown>;
71
+ type: "dialog" | "alert";
72
+ hasTokenExpired: boolean;
73
+ }
74
+
75
+ function SendVerificationEmailForm({
76
+ onSuccess,
77
+ type,
78
+ hasTokenExpired,
79
+ }: SendVerificationEmailFormProps) {
80
+ const { data: me } = useMe();
81
+ const sendVerification = useSendVerification({
82
+ mutation: { onSuccess: (data) => onSuccess(data.authenticationChallenge) },
83
+ });
84
+
85
+ const Title = type === "dialog" ? Dialog.Title : AlertDialog.Title;
86
+ const Description =
87
+ type === "dialog" ? Dialog.Description : AlertDialog.Description;
88
+ const Close = type === "dialog" ? Dialog.Close : AlertDialog.Cancel;
89
+
90
+ const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
91
+ event.preventDefault();
92
+
93
+ sendVerification.mutate();
94
+ };
95
+
96
+ return (
97
+ <form onSubmit={handleSubmit}>
98
+ <Title>
99
+ {hasTokenExpired
100
+ ? "Your verification token has expired"
101
+ : "Verify your identity"}
102
+ </Title>
103
+
104
+ <Description color="gray" mb="5">
105
+ To continue, we need to confirm your identity. We'll send a temporary
106
+ verification code to{" "}
107
+ <Text weight="bold" highContrast>
108
+ {me?.email}
109
+ </Text>
110
+ .
111
+ </Description>
112
+
113
+ {sendVerification.error && (
114
+ <Callout.Root color="red" mt="-2" mb="0">
115
+ <Callout.Text>
116
+ {getMutationErrorMessage(sendVerification.error)}
117
+ </Callout.Text>
118
+ </Callout.Root>
119
+ )}
120
+
121
+ <Flex justify="end" align="center" gap="3" mt="5">
122
+ <Close>
123
+ <SecondaryButton type="button" disabled={sendVerification.isPending}>
124
+ Cancel
125
+ </SecondaryButton>
126
+ </Close>
127
+ <PrimaryButton type="submit" loading={sendVerification.isPending}>
128
+ Send verification code
129
+ </PrimaryButton>
130
+ </Flex>
131
+ </form>
132
+ );
133
+ }
134
+
135
+ interface VerificationIdentityFormProps {
136
+ onSuccess?: () => unknown | Promise<unknown>;
137
+ authenticationChallengeId: string;
138
+ type: "dialog" | "alert";
139
+ }
140
+
141
+ function VerificationIdentityForm({
142
+ onSuccess,
143
+ authenticationChallengeId,
144
+ type,
145
+ }: VerificationIdentityFormProps) {
146
+ const { data: me } = useMe();
147
+ const { setElevatedAccess } = useElevatedAccessToken();
148
+ const verifyIdentity = useVerify();
149
+ const [isSubmitting, setIsSubmitting] = useState(false);
150
+
151
+ const Title = type === "dialog" ? Dialog.Title : AlertDialog.Title;
152
+ const Description =
153
+ type === "dialog" ? Dialog.Description : AlertDialog.Description;
154
+ const Close = type === "dialog" ? Dialog.Close : AlertDialog.Cancel;
155
+ const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
156
+ event.preventDefault();
157
+
158
+ const formData = new FormData(event.currentTarget);
159
+ const code = formData.get("otp-code")?.toString() ?? "";
160
+
161
+ setIsSubmitting(true);
162
+
163
+ try {
164
+ // Mutate async so we can wait for the onSuccess callback as well
165
+ const newAuthState = await verifyIdentity.mutateAsync({
166
+ data: {
167
+ code,
168
+ authenticationChallengeId,
169
+ },
170
+ });
171
+
172
+ const in10Seconds = new Date(Date.now() + 5 * 1000);
173
+
174
+ setElevatedAccess({
175
+ token: newAuthState.elevatedAccessToken,
176
+ // expiresAt: newAuthState.expiresAt,
177
+ expiresAt: in10Seconds.toISOString(),
178
+ });
179
+
180
+ if (onSuccess) {
181
+ await new Promise((resolve) => setTimeout(resolve, 200));
182
+ await onSuccess();
183
+ }
184
+ } catch (error) {
185
+ console.error(error);
186
+ }
187
+
188
+ setIsSubmitting(false);
189
+ };
190
+
191
+ return (
192
+ <Form.Root onSubmit={handleSubmit}>
193
+ <Title>Verify your identity</Title>
194
+
195
+ <Description color="gray">
196
+ A verification code was sent to{" "}
197
+ <Text weight="bold" highContrast>
198
+ {me?.email}
199
+ </Text>
200
+ . Please enter it below.
201
+ </Description>
202
+
203
+ <Flex direction="column" gap="2" mt="5" mx="auto" width="fit-content">
204
+ <Otp.Root
205
+ autoSubmit
206
+ gap="2"
207
+ justify="center"
208
+ columns="repeat(6, 48px)"
209
+ width="fit-content"
210
+ rows="48px"
211
+ name="otp-code"
212
+ readOnly={isSubmitting}
213
+ >
214
+ <Otp.Input required autoFocus autoComplete="off" />
215
+ <Otp.Input required />
216
+ <Otp.Input required />
217
+ <Otp.Input required />
218
+ <Otp.Input required />
219
+ <Otp.Input required />
220
+ </Otp.Root>
221
+
222
+ {verifyIdentity.error && (
223
+ <Text color="red" size="2" as="p">
224
+ {getMutationErrorMessage(verifyIdentity.error)}
225
+ </Text>
226
+ )}
227
+ </Flex>
228
+
229
+ <Flex justify="end" align="center" gap="3" mt="5">
230
+ <Close>
231
+ <SecondaryButton type="button">Cancel</SecondaryButton>
232
+ </Close>
233
+
234
+ <PrimaryButton type="submit" loading={isSubmitting}>
235
+ Confirm
236
+ </PrimaryButton>
237
+ </Flex>
238
+ </Form.Root>
239
+ );
240
+ }
241
+
242
+ function getMutationErrorMessage(error: unknown) {
243
+ let message = typeof error === "string" ? error : "";
244
+
245
+ if (error instanceof Error) {
246
+ message = error.message;
247
+ } else if (
248
+ typeof error === "object" &&
249
+ error !== null &&
250
+ "message" in error &&
251
+ typeof error.message === "string"
252
+ ) {
253
+ message = error.message;
254
+ }
255
+
256
+ if (!message || message === "Bad Request") {
257
+ message = "Invalid code, please try again.";
258
+ }
259
+
260
+ return message;
261
+ }
@@ -0,0 +1,70 @@
1
+ import * as React from "react";
2
+ import { Flex, Heading, Text } from "@radix-ui/themes";
3
+ import { ApiError, FetchError, NoAuthTokenError } from "./errors";
4
+ import { Cross2Icon } from "@radix-ui/react-icons";
5
+
6
+ export function GenericError({ error }: { error: unknown }) {
7
+ React.useEffect(() => {
8
+ console.error(error);
9
+ }, [error]);
10
+
11
+ const render = (heading: string, message: React.ReactNode) => (
12
+ <Flex p="6" justify="center" align="center" direction="column">
13
+ <Flex
14
+ align="center"
15
+ justify="center"
16
+ width="32px"
17
+ height="32px"
18
+ mb="2"
19
+ style={{
20
+ borderRadius: "9999px",
21
+ backgroundColor: "var(--red-a4)",
22
+ color: "var(--red-a11)",
23
+ }}
24
+ >
25
+ <Cross2Icon width="24px" height="24px" />
26
+ </Flex>
27
+
28
+ <Flex direction="column" gap="1" maxWidth="420px">
29
+ <Heading size="5" align="center" mb="1" wrap="balance" as="h3">
30
+ {heading}
31
+ </Heading>
32
+
33
+ <Text as="p" align="center" wrap="balance" color="gray">
34
+ {message}
35
+ </Text>
36
+ </Flex>
37
+ </Flex>
38
+ );
39
+
40
+ if (error instanceof FetchError) {
41
+ return render(
42
+ "Error fetching data",
43
+ "An error occurred. You may need to configure CORS in the WorkOS Dashboard. " +
44
+ "Contact your organization admin for support.",
45
+ );
46
+ }
47
+
48
+ if (error instanceof NoAuthTokenError) {
49
+ return render(
50
+ "Error fetching data",
51
+ "Authorization error. You likely forgot to provide an authorization " +
52
+ "token to the Users Management Widget.",
53
+ );
54
+ }
55
+
56
+ if (error instanceof ApiError && error.status === 404) {
57
+ // The widgets API treats all authorization errors as 404s. If there is a
58
+ // legitimate 404, it's a bug on our end but there's currently no way to
59
+ // distinguish between the two.
60
+ return render(
61
+ "Error fetching data",
62
+ "Authorization error. Contact your organization admin for support.",
63
+ );
64
+ }
65
+
66
+ return render(
67
+ "Error fetching data",
68
+ "An unknown error occurred. If the problem continues, contact the site owner.",
69
+ );
70
+ }
@@ -0,0 +1,26 @@
1
+ import { Flex, FlexProps } from "@radix-ui/themes";
2
+ import { forwardRef } from "react";
3
+
4
+ export const IconPanel = forwardRef<HTMLDivElement, FlexProps>(
5
+ function IconPanel({ children, ...props }, ref) {
6
+ return (
7
+ <Flex
8
+ ref={ref}
9
+ width="32px"
10
+ height="32px"
11
+ align="center"
12
+ justify="center"
13
+ style={{
14
+ borderWidth: 1,
15
+ borderStyle: "solid",
16
+ borderColor: "var(--gray-4)",
17
+ borderRadius: "var(--radius-3)",
18
+ backgroundColor: "var(--gray-2)",
19
+ }}
20
+ {...props}
21
+ >
22
+ {children}
23
+ </Flex>
24
+ );
25
+ },
26
+ );
@@ -0,0 +1,21 @@
1
+ import { SVGProps } from "react";
2
+
3
+ export function PasskeyIcon(props: SVGProps<SVGSVGElement>) {
4
+ return (
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ width={16}
8
+ height={16}
9
+ viewBox="0 0 16 16"
10
+ fill="none"
11
+ {...props}
12
+ >
13
+ <path
14
+ fill="currentColor"
15
+ fillRule="evenodd"
16
+ d="M5.86 1.005a2.86 2.86 0 1 0 0 5.719 2.86 2.86 0 0 0 0-5.72ZM2 3.865a3.86 3.86 0 1 1 4.899 3.717c.974.166 1.699.58 2.368 1.196a.5.5 0 1 1-.678.735C7.882 8.862 7.136 8.5 5.859 8.5c-2.036 0-3.195.693-3.867 1.613-.602.824-.86 1.893-.917 2.986h8.618a.5.5 0 0 1 0 1H.563a.5.5 0 0 1-.5-.5c0-1.356.248-2.88 1.121-4.076.743-1.018 1.897-1.741 3.582-1.957A3.861 3.861 0 0 1 2 3.864Zm12.185 6.509a2.892 2.892 0 1 0-2.212-.024v4.428L13.197 16l2.036-2.037-1.271-1.27 1.271-1.272-1.046-1.047Zm-.212-3.423a.847.847 0 1 1-1.695 0 .847.847 0 0 1 1.695 0Z"
17
+ clipRule="evenodd"
18
+ />
19
+ </svg>
20
+ );
21
+ }
@@ -9,8 +9,6 @@ import {
9
9
  VisuallyHidden,
10
10
  } from "@radix-ui/themes";
11
11
  import * as React from "react";
12
- import { type Role, useRoles } from "./api/role";
13
- import { type InviteUserPayload, useInviteUser } from "./api/user";
14
12
  import {
15
13
  DialogContent,
16
14
  PrimaryButton,
@@ -22,6 +20,8 @@ import {
22
20
  } from "./elements";
23
21
  import { Label } from "./elements";
24
22
  import { isErrorLike } from "./utils";
23
+ import { useInviteUser } from "./api/user";
24
+ import { InviteMemberInput, MemberRole, useRoles } from "@repo/api";
25
25
 
26
26
  /**
27
27
  * Used to stub a fake value for the role select. It will be selected by default
@@ -41,7 +41,9 @@ export function InviteUserDialog({ children }: InviteUserDialogProps) {
41
41
  const formId = toId(dialogId, "form");
42
42
 
43
43
  const inviteUser = useInviteUser();
44
- const rolesQuery = useRoles();
44
+ const rolesQuery = useRoles({
45
+ query: { initialData: [] },
46
+ });
45
47
  const roles = rolesQuery.data;
46
48
  const [selectedRole, setSelectedRole] = React.useState(
47
49
  () => getDefaultRole(roles)?.slug || PLACEHOLDER_ROLE,
@@ -58,15 +60,18 @@ export function InviteUserDialog({ children }: InviteUserDialogProps) {
58
60
  });
59
61
  }, [roles]);
60
62
 
61
- const onSubmitForm = (data: InviteUserPayload) => {
63
+ const onSubmitForm = (data: InviteMemberInput) => {
62
64
  if (inviteUser.isPending || rolesQuery.status !== "success") {
63
65
  return;
64
66
  }
65
- inviteUser.mutate(data, {
66
- onSuccess: () => {
67
- setOpen(false);
67
+ inviteUser.mutate(
68
+ { data },
69
+ {
70
+ onSuccess: () => {
71
+ setOpen(false);
72
+ },
68
73
  },
69
- });
74
+ );
70
75
  };
71
76
 
72
77
  const formErrors = getFormErrors(inviteUser.error);
@@ -88,7 +93,7 @@ export function InviteUserDialog({ children }: InviteUserDialogProps) {
88
93
  event.preventDefault();
89
94
  onSubmitForm({
90
95
  email: event.currentTarget.email.value,
91
- role: selectedRole,
96
+ roles: [selectedRole],
92
97
  });
93
98
  }}
94
99
  >
@@ -317,6 +322,6 @@ function useFormFieldFocusOnError(dialogId: string, queryError: unknown) {
317
322
  }, [dialogId, queryError]);
318
323
  }
319
324
 
320
- function getDefaultRole(roles: Role[]) {
325
+ function getDefaultRole(roles: MemberRole[]) {
321
326
  return roles.find((role) => role.default) || roles[0];
322
327
  }
@@ -0,0 +1,82 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { AlertDialog, Flex } from "@radix-ui/themes";
5
+ import { type ReactNode } from "react";
6
+ import {
7
+ AlertDialogContent,
8
+ DestructiveButton,
9
+ SecondaryButton,
10
+ } from "./elements";
11
+ import { getSessionsQueryKey, useRevokeAllSessions } from "@repo/api";
12
+ import { useQueryClient } from "@tanstack/react-query";
13
+ import { SaveButton } from "./save-button";
14
+
15
+ interface LogoutAllSessionsDialogProps extends AlertDialog.RootProps {
16
+ children?: ReactNode;
17
+ currentSessionId: string;
18
+ }
19
+
20
+ export function LogoutAllSessionsDialog({
21
+ open,
22
+ onOpenChange,
23
+ children,
24
+ currentSessionId,
25
+ ...props
26
+ }: LogoutAllSessionsDialogProps) {
27
+ const client = useQueryClient();
28
+
29
+ const revokeAllSessions = useRevokeAllSessions();
30
+
31
+ const onSubmitForm = () => {
32
+ revokeAllSessions.mutate({ data: { currentSessionId } });
33
+ };
34
+
35
+ const handleDone = React.useCallback(() => {
36
+ onOpenChange?.(false);
37
+
38
+ client.invalidateQueries({
39
+ queryKey: getSessionsQueryKey(),
40
+ });
41
+ }, [client, onOpenChange]);
42
+
43
+ return (
44
+ <AlertDialog.Root open={open} onOpenChange={onOpenChange} {...props}>
45
+ <AlertDialogContent maxWidth="480px">
46
+ <AlertDialog.Title>Sign out of all other devices?</AlertDialog.Title>
47
+ <AlertDialog.Description>
48
+ You will be logged out of all other active sessions on other devices,
49
+ except this one.
50
+ </AlertDialog.Description>
51
+
52
+ <Flex gap="3" justify="end" mt="5" asChild>
53
+ <form
54
+ onSubmit={(event) => {
55
+ event.preventDefault();
56
+ onSubmitForm();
57
+ }}
58
+ >
59
+ <AlertDialog.Cancel>
60
+ <SecondaryButton
61
+ disabled={
62
+ revokeAllSessions.isPending || revokeAllSessions.isSuccess
63
+ }
64
+ >
65
+ Cancel
66
+ </SecondaryButton>
67
+ </AlertDialog.Cancel>
68
+
69
+ <SaveButton
70
+ asChild
71
+ loading={revokeAllSessions.isPending}
72
+ done={revokeAllSessions.isSuccess}
73
+ onDone={handleDone}
74
+ >
75
+ <DestructiveButton type="submit">Sign out</DestructiveButton>
76
+ </SaveButton>
77
+ </form>
78
+ </Flex>
79
+ </AlertDialogContent>
80
+ </AlertDialog.Root>
81
+ );
82
+ }
@@ -0,0 +1,89 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { AlertDialog, Flex, Strong } from "@radix-ui/themes";
5
+ import { type ReactNode } from "react";
6
+ import {
7
+ AlertDialogContent,
8
+ DestructiveButton,
9
+ SecondaryButton,
10
+ } from "./elements";
11
+ import {
12
+ ActiveSession,
13
+ getSessionsQueryKey,
14
+ useRevokeSession,
15
+ } from "@repo/api";
16
+ import { useQueryClient } from "@tanstack/react-query";
17
+ import { SaveButton } from "./save-button";
18
+ import { parseUserAgent } from "./utils";
19
+
20
+ interface LogoutDialogProps extends AlertDialog.RootProps {
21
+ children?: ReactNode;
22
+ session: ActiveSession;
23
+ }
24
+
25
+ export function LogoutDialog({
26
+ children,
27
+ session,
28
+ open,
29
+ onOpenChange,
30
+ ...props
31
+ }: LogoutDialogProps) {
32
+ const client = useQueryClient();
33
+ const userAgent = parseUserAgent(session.userAgent);
34
+ const device = userAgent.pretty;
35
+
36
+ const revokeSession = useRevokeSession();
37
+
38
+ const handleDone = React.useCallback(() => {
39
+ onOpenChange?.(false);
40
+
41
+ client.invalidateQueries({
42
+ queryKey: getSessionsQueryKey(),
43
+ exact: false,
44
+ });
45
+ }, [onOpenChange, client]);
46
+
47
+ const onSubmitForm = () => {
48
+ revokeSession.mutate({
49
+ sessionId: session.id,
50
+ });
51
+ };
52
+
53
+ return (
54
+ <AlertDialog.Root open={open} onOpenChange={onOpenChange} {...props}>
55
+ <AlertDialogContent maxWidth="480px">
56
+ <AlertDialog.Title>Sign out of device?</AlertDialog.Title>
57
+ <AlertDialog.Description>
58
+ You will be signed out of <Strong>{device}.</Strong>
59
+ </AlertDialog.Description>
60
+
61
+ <Flex gap="3" justify="end" mt="5" asChild>
62
+ <form
63
+ onSubmit={(event) => {
64
+ event.preventDefault();
65
+ onSubmitForm();
66
+ }}
67
+ >
68
+ <AlertDialog.Cancel>
69
+ <SecondaryButton
70
+ disabled={revokeSession.isPending || revokeSession.isSuccess}
71
+ >
72
+ Cancel
73
+ </SecondaryButton>
74
+ </AlertDialog.Cancel>
75
+
76
+ <SaveButton
77
+ asChild
78
+ loading={revokeSession.isPending}
79
+ done={revokeSession.isSuccess}
80
+ onDone={handleDone}
81
+ >
82
+ <DestructiveButton type="submit">Sign out</DestructiveButton>
83
+ </SaveButton>
84
+ </form>
85
+ </Flex>
86
+ </AlertDialogContent>
87
+ </AlertDialog.Root>
88
+ );
89
+ }
@@ -0,0 +1,81 @@
1
+ .woswidgets-marker {
2
+ /* Reset letter-spacing so the Marker content doesn’t appear off-center when nested in other elements */
3
+ letter-spacing: 0;
4
+ line-height: normal;
5
+ }
6
+ .woswidgets-marker-circle::before {
7
+ background-color: var(--gray-a4);
8
+ }
9
+
10
+ .woswidgets-marker[data-accent-color] {
11
+ color: var(--accent-a11);
12
+ }
13
+ .woswidgets-marker[data-accent-color] .woswidgets-marker-circle::before {
14
+ background-color: var(--accent-a4);
15
+ }
16
+
17
+ .woswidgets-marker {
18
+ color: var(--gray-11);
19
+ }
20
+
21
+ .woswidgets-marker-circle {
22
+ position: relative;
23
+ text-align: center;
24
+ user-select: none;
25
+ height: 1em;
26
+ min-width: 1em;
27
+ padding-left: 0.05em;
28
+ padding-right: 0.05em;
29
+ box-sizing: border-box;
30
+
31
+ /* Would be easier to use "inline-flex", but that messes up copy-pasted text formatting */
32
+ display: inline-block;
33
+
34
+ /* Align middle of the element with the baseline plus half the x-height of the parent */
35
+ vertical-align: middle;
36
+
37
+ /* Add the missing half of the x-height to align with the middle of the parent */
38
+ top: -0.11em;
39
+
40
+ /* Collapse own line height so it doesn't influence the inner element position */
41
+ line-height: 0;
42
+ }
43
+
44
+ .woswidgets-marker-circle::before {
45
+ content: "";
46
+ position: absolute;
47
+ inset: -10%;
48
+ border-radius: 1em;
49
+ }
50
+
51
+ .woswidgets-marker-circle svg {
52
+ width: 1.125em;
53
+ height: 1.125em;
54
+ }
55
+
56
+ .woswidgets-marker-content {
57
+ position: relative;
58
+ display: inline-block;
59
+ vertical-align: middle;
60
+ font-size: calc(0.8em * var(--marker-font-size-adjust, 1));
61
+ font-weight: var(--marker-font-weight, bold);
62
+ line-height: 1;
63
+ transform: translateY(-50%);
64
+ top: 50%;
65
+
66
+ /* We are trying to achieve "cursor: default", but also have the pointer finger cursor when Marker is inside a link */
67
+ /* Its ::before element will get pointer events anyway, so we are just getting rid of the text cursor on content. */
68
+ pointer-events: none;
69
+ }
70
+
71
+ .woswidgets-marker-hidden {
72
+ /* Make the text visually hidden without breaking copy-paste */
73
+ font-size: 0;
74
+ line-height: 0;
75
+
76
+ /* Prevent the dot from making it into copy-pasted text without the marker */
77
+ user-select: none;
78
+
79
+ /* Prevent copy-pasted whitespace from being collapsed when used in lists */
80
+ white-space: pre;
81
+ }