@openviking/react 0.1.7 → 0.1.8-beta.10.1.g8e5299efeb0a

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 (113) hide show
  1. package/README.md +11 -1
  2. package/dist/1~0.js +57 -0
  3. package/dist/3~0.js +171 -5
  4. package/dist/5~0.js +181 -0
  5. package/dist/6~0.js +48 -0
  6. package/dist/components/agent-connect/style.css +4 -2
  7. package/dist/components/api-key-login-form/api-key-login-form.d.ts +2 -0
  8. package/dist/components/api-key-login-form/index.d.ts +3 -0
  9. package/dist/components/api-key-login-form/style.css +438 -0
  10. package/dist/components/api-key-login-form/style.js +0 -0
  11. package/dist/components/api-key-login-form/types.d.ts +7 -0
  12. package/dist/components/api-key-login-form.js +1 -0
  13. package/dist/components/directory-tour/directory-tour-intro.d.ts +3 -0
  14. package/dist/components/directory-tour/index.d.ts +2 -1
  15. package/dist/components/directory-tour/style.css +154 -26
  16. package/dist/components/directory-tour/tour-card.d.ts +14 -0
  17. package/dist/components/directory-tour/types.d.ts +24 -1
  18. package/dist/components/directory-tour/use-tour-anchor.d.ts +1 -0
  19. package/dist/components/directory-tour/use-tour-position.d.ts +4 -1
  20. package/dist/components/directory-tour/use-tour-theme.d.ts +2 -0
  21. package/dist/components/directory-tour.js +52 -1
  22. package/dist/components/email-login-form/email-login-form.d.ts +2 -0
  23. package/dist/components/email-login-form/index.d.ts +3 -0
  24. package/dist/components/email-login-form/style.css +438 -0
  25. package/dist/components/email-login-form/style.js +0 -0
  26. package/dist/components/email-login-form/types.d.ts +11 -0
  27. package/dist/components/email-login-form.js +1 -0
  28. package/dist/components/experience-dashboard/experience-impact.d.ts +3 -1
  29. package/dist/components/experience-dashboard/style.css +4 -2
  30. package/dist/components/file-browser-entries/style.css +12 -6
  31. package/dist/components/file-preview/file-preview-header.d.ts +4 -21
  32. package/dist/components/file-preview/file-preview-toolbar.d.ts +7 -0
  33. package/dist/components/file-preview/locales/en-US.d.ts +9 -0
  34. package/dist/components/file-preview/locales/zh-CN.d.ts +9 -0
  35. package/dist/components/file-preview/style.css +116 -2
  36. package/dist/components/file-preview/types.d.ts +14 -21
  37. package/dist/components/file-tree/style.css +4 -2
  38. package/dist/components/invitation-confirmation/index.d.ts +3 -0
  39. package/dist/components/invitation-confirmation/invitation-confirmation.d.ts +2 -0
  40. package/dist/components/invitation-confirmation/style.css +438 -0
  41. package/dist/components/invitation-confirmation/style.js +0 -0
  42. package/dist/components/invitation-confirmation/types.d.ts +20 -0
  43. package/dist/components/invitation-confirmation.js +1 -0
  44. package/dist/components/login-method-selector/index.d.ts +2 -0
  45. package/dist/components/login-method-selector/login-method-selector.d.ts +2 -0
  46. package/dist/components/login-method-selector/style.css +438 -0
  47. package/dist/components/login-method-selector/style.js +0 -0
  48. package/dist/components/login-method-selector/types.d.ts +14 -0
  49. package/dist/components/login-method-selector.js +1 -0
  50. package/dist/components/password-reset-request-form/index.d.ts +3 -0
  51. package/dist/components/password-reset-request-form/password-reset-request-form.d.ts +2 -0
  52. package/dist/components/password-reset-request-form/style.css +438 -0
  53. package/dist/components/password-reset-request-form/style.js +0 -0
  54. package/dist/components/password-reset-request-form/types.d.ts +13 -0
  55. package/dist/components/password-reset-request-form.js +1 -0
  56. package/dist/components/password-setup-form/index.d.ts +3 -0
  57. package/dist/components/password-setup-form/password-setup-form.d.ts +2 -0
  58. package/dist/components/password-setup-form/style.css +438 -0
  59. package/dist/components/password-setup-form/style.js +0 -0
  60. package/dist/components/password-setup-form/types.d.ts +10 -0
  61. package/dist/components/password-setup-form.js +1 -0
  62. package/dist/components/scope-switcher/style.css +4 -2
  63. package/dist/components/scope-switcher.js +1 -1
  64. package/dist/components/style.css +2966 -58
  65. package/dist/components/tui/style.css +8 -4
  66. package/dist/components/viking-bot/style.css +12 -6
  67. package/dist/components/wiki-dashboard/index.d.ts +1 -1
  68. package/dist/components/wiki-dashboard/style.css +16 -4
  69. package/dist/components/wiki-dashboard/types.d.ts +12 -16
  70. package/dist/components/wiki-dashboard/wiki-action-button.d.ts +2 -9
  71. package/dist/components/wiki-dashboard/wiki-conflict-card.d.ts +3 -10
  72. package/dist/d~0.js +28 -0
  73. package/dist/ep~0.js +281 -133
  74. package/dist/fi~0.js +339 -0
  75. package/dist/fj~0.js +32 -67
  76. package/dist/fl~0.js +3 -2
  77. package/dist/f~0.js +63 -326
  78. package/dist/g~0.js +135 -0
  79. package/dist/icons/index.d.ts +2 -0
  80. package/dist/icons.js +1 -1
  81. package/dist/index.d.ts +12 -0
  82. package/dist/index.js +8 -2
  83. package/dist/k~0.js +44 -4
  84. package/dist/l5~0.js +3813 -0
  85. package/dist/lk~0.js +1 -1
  86. package/dist/l~0.js +54 -3811
  87. package/dist/modules/console/style.css +28 -14
  88. package/dist/modules/file-browser/file-browser-detail-icons.d.ts +0 -6
  89. package/dist/modules/file-browser/file-browser-detail.d.ts +2 -23
  90. package/dist/modules/file-browser/file-browser.d.ts +1 -1
  91. package/dist/modules/file-browser/fs-file-editing.d.ts +4 -0
  92. package/dist/modules/file-browser/fs-preview-images.d.ts +3 -0
  93. package/dist/modules/file-browser/fs-read-file.d.ts +1 -1
  94. package/dist/modules/file-browser/style.css +156 -70
  95. package/dist/modules/file-browser/types.d.ts +2 -0
  96. package/dist/modules/file-browser/use-file-browser-acl.d.ts +1 -0
  97. package/dist/modules/file-browser/wiki-dashboard-pane.d.ts +2 -4
  98. package/dist/modules/file-browser.js +1 -1
  99. package/dist/modules/scope-cascade/style.css +4 -2
  100. package/dist/modules/style.css +192 -88
  101. package/dist/n~0.js +1 -1
  102. package/dist/p0~0.js +27 -0
  103. package/dist/p~0.js +34 -25
  104. package/dist/shared/auth/agreements.d.ts +10 -0
  105. package/dist/shared/auth/fields.d.ts +15 -0
  106. package/dist/shared/auth/form-frame.d.ts +12 -0
  107. package/dist/shared/auth/locales/en-US.d.ts +24 -0
  108. package/dist/shared/auth/locales/zh-CN.d.ts +24 -0
  109. package/dist/shared/auth/types.d.ts +61 -0
  110. package/dist/shared/auth/use-auth-labels.d.ts +3 -0
  111. package/dist/shared/auth/use-form.d.ts +8 -0
  112. package/dist/style.css +3364 -350
  113. package/package.json +32 -2
package/README.md CHANGED
@@ -6,7 +6,7 @@ Public UI components, composed modules accept optional `locale: 'zh-CN' | 'en-US
6
6
 
7
7
  React foundations for OpenViking AI application interfaces: build tooling, documentation, layered directories, and scoped styles. FileTree, Tui and FilePreview provide working views, alongside five file-type icons. FileBrowser coordinates browsing, previews and dashboards; Console provides a native command panel; ScopeCascade provides an integrated cascade selector.
8
8
 
9
- This package inherits the repository's AGPL-3.0-only license. The release workflow publishes it to npm when a `react@<version>` tag matches the version in this package's manifest.
9
+ This package inherits the repository's AGPL-3.0-only license. The release workflow publishes it to npm when the Changesets version PR is merged, or when a `react@<version>` tag matches this package's version.
10
10
 
11
11
  ## Module map
12
12
 
@@ -100,3 +100,13 @@ Dynamic messages use typed formatter functions; dates and numbers use `Intl`. `n
100
100
  Set `locale` on `OpenVikingProvider` for a subtree. Optional module and component Props override the nearest scope, then fall back to `en-US`. Standalone Hooks also inherit the Provider. The private `src/shared/locale-context.tsx` is shared across public entries and remains separate from request-client configuration, so language changes preserve requests and state.
101
101
 
102
102
  The internal Input, Button, Modal and Drawer adapt Arco Design logic (MIT); its notice ships in `LICENSE.arco-design`. Input and Button visual rules are adapted from the console's `@arco-design/theme-ve-o-aml-design@0.0.36` (MIT), rather than Arco's default skin. They have no public component entry.
103
+
104
+ ## Authentication forms
105
+
106
+ `EmailLoginForm`, `ApiKeyLoginForm`, `PasswordResetRequestForm`, `PasswordSetupForm`,
107
+ `LoginMethodSelector` and `InvitationConfirmation` are request-free React views.
108
+ Import components from the package root or their individual `components/<kebab-case-name>`
109
+ entries and import the matching `style.css`. Optional actions and agreements are configured
110
+ by the host. Password strength, asynchronous loading/errors, mail delivery, session/CSRF,
111
+ invitation routing and persistence are host responsibilities. No internal UI or theme
112
+ packages are required. See the authentication form examples in the UI documentation.
package/dist/1~0.js ADDED
@@ -0,0 +1,57 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useAuthLabels, Action } from "./g~0.js";
3
+ function InvitationConfirmation({ details, loading, disabled, error, decline, defer, className, onAccept, title, description, locale, acceptLabel }) {
4
+ const labels = useAuthLabels(locale);
5
+ return /*#__PURE__*/ jsxs("section", {
6
+ className: `ov-auth ${className ?? ''}`,
7
+ "aria-busy": loading || void 0,
8
+ children: [
9
+ title && /*#__PURE__*/ jsx("h2", {
10
+ children: title
11
+ }),
12
+ description && /*#__PURE__*/ jsx("p", {
13
+ className: "ov-auth__description",
14
+ children: description
15
+ }),
16
+ /*#__PURE__*/ jsx("dl", {
17
+ className: "ov-auth__details",
18
+ children: details.map((item, index)=>/*#__PURE__*/ jsxs("div", {
19
+ children: [
20
+ /*#__PURE__*/ jsx("dt", {
21
+ children: item.label
22
+ }),
23
+ /*#__PURE__*/ jsx("dd", {
24
+ children: item.value
25
+ })
26
+ ]
27
+ }, index))
28
+ }),
29
+ error && /*#__PURE__*/ jsx("div", {
30
+ className: "ov-auth__error",
31
+ role: "alert",
32
+ children: error
33
+ }),
34
+ /*#__PURE__*/ jsxs("fieldset", {
35
+ disabled: loading || disabled,
36
+ children: [
37
+ /*#__PURE__*/ jsxs("button", {
38
+ type: "button",
39
+ className: "ov-auth__primary ov-auth__submit",
40
+ onClick: onAccept,
41
+ children: [
42
+ acceptLabel ?? labels.acceptInvitation,
43
+ loading && ' …'
44
+ ]
45
+ }),
46
+ /*#__PURE__*/ jsx(Action, {
47
+ action: decline
48
+ }),
49
+ /*#__PURE__*/ jsx(Action, {
50
+ action: defer
51
+ })
52
+ ]
53
+ })
54
+ ]
55
+ });
56
+ }
57
+ export { InvitationConfirmation };
package/dist/3~0.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Fragment as external_react_Fragment, Suspense, forwardRef, lazy, useCallback, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import { button_Button } from "./e~0.js";
4
+ import { WikiEditIcon } from "./k~0.js";
4
5
  import { Tooltip } from "./rt~0.js";
5
6
  import { resolveLocale, mergeLabels } from "./nx~0.js";
6
7
  import { useLocale } from "./28~0.js";
@@ -223,6 +224,119 @@ function FilePreviewBody({ fileTab, text, locale, viewMode, editing, onViewModeC
223
224
  fileTab.source.url
224
225
  ]));
225
226
  }
227
+ function FilePreviewToolbar({ actions, text, extraActions }) {
228
+ const [copyResult, setCopyResult] = useState();
229
+ if (actions.editing) return null;
230
+ const hasActions = actions.canCopyContent || actions.canEdit || actions.canDownload || extraActions;
231
+ if (!actions.canSwitchView && !hasActions) return null;
232
+ const copyLabel = void 0 === copyResult ? text.copyContent : copyResult ? text.copied : text.copyFailed;
233
+ return /*#__PURE__*/ jsxs("div", {
234
+ className: "ov-file-preview__toolbar",
235
+ children: [
236
+ actions.canSwitchView ? /*#__PURE__*/ jsx("div", {
237
+ className: "ov-file-preview__switch",
238
+ role: "group",
239
+ "aria-label": text.viewSwitch,
240
+ children: [
241
+ 'preview',
242
+ 'source'
243
+ ].map((mode)=>/*#__PURE__*/ jsx("button", {
244
+ type: "button",
245
+ className: "ov-file-preview__switch-item",
246
+ "aria-pressed": actions.viewMode === mode,
247
+ disabled: actions.busy,
248
+ onClick: ()=>actions.setViewMode(mode),
249
+ children: 'preview' === mode ? text.previewMode : text.sourceMode
250
+ }, mode))
251
+ }) : null,
252
+ actions.canSwitchView && hasActions ? /*#__PURE__*/ jsx("span", {
253
+ className: "ov-file-preview__toolbar-divider",
254
+ "aria-hidden": "true"
255
+ }) : null,
256
+ actions.canCopyContent ? /*#__PURE__*/ jsxs(Fragment, {
257
+ children: [
258
+ /*#__PURE__*/ jsx(button_Button, {
259
+ size: "small",
260
+ type: "default",
261
+ iconOnly: true,
262
+ className: "ov-file-preview__toolbar-button",
263
+ "aria-label": text.copyContent,
264
+ title: copyLabel,
265
+ disabled: actions.busy,
266
+ onBlur: ()=>setCopyResult(void 0),
267
+ onClick: ()=>void actions.copyContent().then(setCopyResult),
268
+ children: /*#__PURE__*/ jsxs("svg", {
269
+ "aria-hidden": "true",
270
+ width: "14",
271
+ height: "14",
272
+ viewBox: "0 0 16 16",
273
+ fill: "none",
274
+ stroke: "currentColor",
275
+ strokeWidth: "1.4",
276
+ children: [
277
+ /*#__PURE__*/ jsx("rect", {
278
+ x: "5.5",
279
+ y: "5.5",
280
+ width: "8",
281
+ height: "8",
282
+ rx: "1.5"
283
+ }),
284
+ /*#__PURE__*/ jsx("path", {
285
+ d: "M10.5 5.5v-1a1.5 1.5 0 0 0-1.5-1.5H4a1.5 1.5 0 0 0-1.5 1.5v5A1.5 1.5 0 0 0 4 11h1"
286
+ })
287
+ ]
288
+ })
289
+ }),
290
+ void 0 !== copyResult ? /*#__PURE__*/ jsx("span", {
291
+ className: "ov-file-preview__sr-only",
292
+ role: "status",
293
+ children: copyLabel
294
+ }) : null
295
+ ]
296
+ }) : null,
297
+ actions.canEdit ? /*#__PURE__*/ jsxs(button_Button, {
298
+ size: "small",
299
+ type: "default",
300
+ className: "ov-file-preview__toolbar-button",
301
+ disabled: actions.busy,
302
+ onClick: actions.startEditing,
303
+ children: [
304
+ /*#__PURE__*/ jsx(WikiEditIcon, {
305
+ width: 14,
306
+ height: 14,
307
+ "aria-hidden": "true"
308
+ }),
309
+ text.edit
310
+ ]
311
+ }) : null,
312
+ actions.canDownload ? /*#__PURE__*/ jsx(button_Button, {
313
+ size: "small",
314
+ type: "default",
315
+ iconOnly: true,
316
+ className: "ov-file-preview__toolbar-button",
317
+ "aria-label": text.download,
318
+ title: text.download,
319
+ disabled: actions.busy,
320
+ onClick: actions.download,
321
+ children: /*#__PURE__*/ jsx("svg", {
322
+ "aria-hidden": "true",
323
+ width: "14",
324
+ height: "14",
325
+ viewBox: "0 0 16 16",
326
+ fill: "none",
327
+ stroke: "currentColor",
328
+ strokeWidth: "1.4",
329
+ strokeLinecap: "round",
330
+ strokeLinejoin: "round",
331
+ children: /*#__PURE__*/ jsx("path", {
332
+ d: "M8 2.5v8m-3-3 3 3 3-3M2.5 12.5h11"
333
+ })
334
+ })
335
+ }) : null,
336
+ extraActions
337
+ ]
338
+ });
339
+ }
226
340
  function FilePreviewLevelTabs({ levels, activeKey, disabled, onSelect }) {
227
341
  if (!levels?.length) return null;
228
342
  return /*#__PURE__*/ jsx("div", {
@@ -512,10 +626,14 @@ function getPathFileName(path) {
512
626
  const parts = trimmed.split(SEPARATOR).filter(Boolean);
513
627
  return parts[parts.length - 1];
514
628
  }
515
- function FilePreviewHeader({ levels, levelKey, onLevelChange, path, fileName, canOpenParent, titleExtra, slotActions, actions, text, onOpenParent }) {
629
+ function FilePreviewHeader({ levels, levelKey, onLevelChange, path, fileName, canOpenParent, titleExtra, slotActions, extraActions, actions, text, onOpenParent }) {
516
630
  const segments = splitPathSegments(path);
517
631
  const title = getPathFileName(path) ?? fileName;
518
- const actionNode = 'function' == typeof slotActions ? slotActions(actions) : slotActions;
632
+ const actionNode = 'function' == typeof slotActions ? slotActions(actions) : void 0 === slotActions ? /*#__PURE__*/ jsx(FilePreviewToolbar, {
633
+ actions: actions,
634
+ text: text,
635
+ extraActions: extraActions
636
+ }) : slotActions;
519
637
  return /*#__PURE__*/ jsxs(Fragment, {
520
638
  children: [
521
639
  /*#__PURE__*/ jsxs("div", {
@@ -584,8 +702,8 @@ function FilePreviewDirectoryBody({ tab, text, locale, actions, editing, viewMod
584
702
  const active = root.querySelector('[aria-selected="true"]');
585
703
  if (!active) return;
586
704
  setIndicator({
587
- left: active.offsetLeft,
588
- width: active.offsetWidth
705
+ left: active.offsetLeft + (active.offsetWidth - 14) / 2,
706
+ width: 14
589
707
  });
590
708
  };
591
709
  measure();
@@ -628,6 +746,7 @@ function FilePreviewDirectoryBody({ tab, text, locale, actions, editing, viewMod
628
746
  canOpenParent: Boolean(tab.operations?.openParent),
629
747
  titleExtra: tab.slots?.titleExtra,
630
748
  slotActions: tab.slots?.actions,
749
+ extraActions: tab.slots?.extraActions,
631
750
  actions: actions,
632
751
  text: text,
633
752
  onOpenParent: (uri)=>void tab.operations?.openParent?.(uri)
@@ -648,6 +767,7 @@ function FilePreviewDirectoryBody({ tab, text, locale, actions, editing, viewMod
648
767
  canOpenParent: Boolean(tab.operations?.openParent),
649
768
  titleExtra: tab.slots?.titleExtra,
650
769
  slotActions: tab.slots?.actions,
770
+ extraActions: tab.slots?.extraActions,
651
771
  actions: actions,
652
772
  text: text,
653
773
  onOpenParent: (uri)=>void tab.operations?.openParent?.(uri)
@@ -738,10 +858,38 @@ function FilePreviewPanels({ levelKey, onLevelChange, contentTab, directoryTab,
738
858
  canOpenParent: Boolean(fileTab.operations?.openParent),
739
859
  titleExtra: fileTab.slots?.titleExtra,
740
860
  slotActions: fileTab.slots?.actions,
861
+ extraActions: fileTab.slots?.extraActions,
741
862
  actions: actionContext,
742
863
  text: text,
743
864
  onOpenParent: (uri)=>void actions.openParent(activeTab, uri)
744
865
  }),
866
+ editing.editing && fileTab.slots?.actions === void 0 ? /*#__PURE__*/ jsxs("div", {
867
+ className: "ov-file-preview__edit-toolbar",
868
+ children: [
869
+ /*#__PURE__*/ jsx("span", {
870
+ children: text.editFile
871
+ }),
872
+ /*#__PURE__*/ jsxs("div", {
873
+ className: "ov-file-preview__toolbar",
874
+ children: [
875
+ /*#__PURE__*/ jsx(button_Button, {
876
+ size: "small",
877
+ type: "default",
878
+ disabled: editing.saving,
879
+ onClick: actionContext.cancelEditing,
880
+ children: text.leaveEditing
881
+ }),
882
+ /*#__PURE__*/ jsx(button_Button, {
883
+ size: "small",
884
+ type: "primary",
885
+ loading: editing.saving,
886
+ onClick: ()=>void actionContext.saveEditing(),
887
+ children: text.save
888
+ })
889
+ ]
890
+ })
891
+ ]
892
+ }) : null,
745
893
  /*#__PURE__*/ jsx("div", {
746
894
  className: "ov-file-preview__body",
747
895
  children: /*#__PURE__*/ jsx(FilePreviewBody, {
@@ -833,6 +981,15 @@ function useFilePreviewLevels(selected) {
833
981
  const messages = {
834
982
  showHiddenPath: 'Show hidden path levels',
835
983
  copyPath: 'Copy path',
984
+ copyContent: 'Copy content',
985
+ copied: 'Copied',
986
+ copyFailed: 'Could not copy',
987
+ previewMode: 'Preview',
988
+ sourceMode: 'Source',
989
+ viewSwitch: 'View mode',
990
+ edit: 'Edit',
991
+ editFile: 'Edit file',
992
+ save: 'Save',
836
993
  editor: 'Edit content',
837
994
  leaveEditing: 'Cancel',
838
995
  retry: 'Retry',
@@ -849,6 +1006,15 @@ const en_US = messages;
849
1006
  const zh_CN_messages = {
850
1007
  showHiddenPath: '显示隐藏的路径层级',
851
1008
  copyPath: '复制路径',
1009
+ copyContent: '复制正文',
1010
+ copied: '已复制',
1011
+ copyFailed: '复制失败',
1012
+ previewMode: '预览',
1013
+ sourceMode: '源码',
1014
+ viewSwitch: '显示模式',
1015
+ edit: '编辑',
1016
+ editFile: '编辑文件',
1017
+ save: '保存',
852
1018
  editor: '编辑正文',
853
1019
  leaveEditing: '取消',
854
1020
  retry: '重试',
@@ -1285,7 +1451,7 @@ const file_preview_FilePreview = /*#__PURE__*/ forwardRef(function({ tabs, activ
1285
1451
  switchTab,
1286
1452
  viewerHandle
1287
1453
  ]);
1288
- const canSwitchView = Boolean(fileTab) && viewModes.includes('preview') && viewModes.includes('source');
1454
+ const canSwitchView = Boolean(fileTab || directoryTab) && viewModes.includes('preview') && viewModes.includes('source');
1289
1455
  const onLinkClick = useCallback((_event, link)=>{
1290
1456
  if (fileTab) actions.openUri(fileTab, link.url);
1291
1457
  }, [
package/dist/5~0.js ADDED
@@ -0,0 +1,181 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useId, useRef, useState } from "react";
3
+ import { Action } from "./g~0.js";
4
+ function AgreementLinks({ agreements }) {
5
+ return /*#__PURE__*/ jsx(Fragment, {
6
+ children: agreements.items.map((item, index)=>/*#__PURE__*/ jsxs("span", {
7
+ children: [
8
+ ' ',
9
+ /*#__PURE__*/ jsx("a", {
10
+ href: item.href,
11
+ target: "_blank",
12
+ rel: "noopener noreferrer",
13
+ children: item.label
14
+ })
15
+ ]
16
+ }, `${item.href}-${index}`))
17
+ });
18
+ }
19
+ function AgreementDialog({ agreements, labels, onCancel, onAgree }) {
20
+ const dialog = useRef(null);
21
+ const titleId = useId();
22
+ const descriptionId = useId();
23
+ useEffect(()=>{
24
+ const element = dialog.current;
25
+ element?.showModal();
26
+ return ()=>element?.close();
27
+ }, []);
28
+ const text = agreements.confirmation;
29
+ return /*#__PURE__*/ jsxs("dialog", {
30
+ ref: dialog,
31
+ className: "ov-auth ov-auth__dialog",
32
+ "aria-labelledby": titleId,
33
+ "aria-describedby": descriptionId,
34
+ onCancel: (event)=>{
35
+ event.preventDefault();
36
+ onCancel();
37
+ },
38
+ children: [
39
+ /*#__PURE__*/ jsx("h2", {
40
+ id: titleId,
41
+ children: text?.title ?? labels.agreementTitle
42
+ }),
43
+ /*#__PURE__*/ jsxs("p", {
44
+ id: descriptionId,
45
+ children: [
46
+ text?.description ?? labels.agreementDescription,
47
+ /*#__PURE__*/ jsx(AgreementLinks, {
48
+ agreements: agreements
49
+ })
50
+ ]
51
+ }),
52
+ /*#__PURE__*/ jsxs("div", {
53
+ className: "ov-auth__actions",
54
+ children: [
55
+ /*#__PURE__*/ jsx("button", {
56
+ type: "button",
57
+ onClick: onCancel,
58
+ children: text?.cancelText ?? labels.cancel
59
+ }),
60
+ /*#__PURE__*/ jsx("button", {
61
+ className: "ov-auth__primary",
62
+ type: "button",
63
+ onClick: onAgree,
64
+ children: text?.confirmText ?? labels.agree
65
+ })
66
+ ]
67
+ })
68
+ ]
69
+ });
70
+ }
71
+ function FormFrame({ children, labels, submitLabel, validate, onSubmit, secondaryAction, ...options }) {
72
+ const [accepted, setAccepted] = useState(false);
73
+ const [confirming, setConfirming] = useState(false);
74
+ const agreements = options.agreements?.items.length ? options.agreements : void 0;
75
+ const blocked = options.loading || options.disabled;
76
+ const submit = (agreed = false)=>{
77
+ if (blocked || !validate()) return;
78
+ if (agreements && !accepted && !agreed) return void setConfirming(true);
79
+ if (agreed) setAccepted(true);
80
+ onSubmit();
81
+ };
82
+ return /*#__PURE__*/ jsxs("form", {
83
+ className: `ov-auth ${options.className ?? ''}`,
84
+ noValidate: true,
85
+ "aria-busy": options.loading || void 0,
86
+ onSubmit: (event)=>{
87
+ event.preventDefault();
88
+ submit();
89
+ },
90
+ children: [
91
+ /*#__PURE__*/ jsx(Action, {
92
+ action: options.back
93
+ }),
94
+ options.title && /*#__PURE__*/ jsx("h2", {
95
+ children: options.title
96
+ }),
97
+ options.description && /*#__PURE__*/ jsx("p", {
98
+ className: "ov-auth__description",
99
+ children: options.description
100
+ }),
101
+ /*#__PURE__*/ jsx("fieldset", {
102
+ disabled: blocked,
103
+ children: children
104
+ }),
105
+ options.error && /*#__PURE__*/ jsx("div", {
106
+ className: "ov-auth__error",
107
+ role: "alert",
108
+ children: options.error
109
+ }),
110
+ /*#__PURE__*/ jsxs("button", {
111
+ className: "ov-auth__primary ov-auth__submit",
112
+ type: "submit",
113
+ disabled: blocked,
114
+ children: [
115
+ submitLabel,
116
+ options.loading && /*#__PURE__*/ jsx("span", {
117
+ "aria-hidden": "true",
118
+ children: " …"
119
+ })
120
+ ]
121
+ }),
122
+ agreements && /*#__PURE__*/ jsxs("label", {
123
+ className: "ov-auth__consent",
124
+ children: [
125
+ /*#__PURE__*/ jsx("input", {
126
+ type: "checkbox",
127
+ checked: accepted,
128
+ disabled: blocked,
129
+ onChange: (event)=>setAccepted(event.target.checked)
130
+ }),
131
+ /*#__PURE__*/ jsxs("span", {
132
+ children: [
133
+ labels.agreementPrefix,
134
+ /*#__PURE__*/ jsx(AgreementLinks, {
135
+ agreements: agreements
136
+ })
137
+ ]
138
+ })
139
+ ]
140
+ }),
141
+ /*#__PURE__*/ jsx(Action, {
142
+ action: secondaryAction
143
+ }),
144
+ confirming && agreements && /*#__PURE__*/ jsx(AgreementDialog, {
145
+ agreements: agreements,
146
+ labels: labels,
147
+ onCancel: ()=>setConfirming(false),
148
+ onAgree: ()=>{
149
+ setConfirming(false);
150
+ submit(true);
151
+ }
152
+ })
153
+ ]
154
+ });
155
+ }
156
+ function useForm(initial, validate) {
157
+ const [values, setValues] = useState(initial);
158
+ const [errors, setErrors] = useState({});
159
+ const update = (key, value)=>{
160
+ setValues((current)=>({
161
+ ...current,
162
+ [key]: value
163
+ }));
164
+ setErrors((current)=>({
165
+ ...current,
166
+ [key]: void 0
167
+ }));
168
+ };
169
+ return {
170
+ values,
171
+ errors,
172
+ update,
173
+ validate: ()=>{
174
+ const next = validate(values);
175
+ setErrors(next);
176
+ return !Object.values(next).some((issue)=>void 0 !== issue);
177
+ }
178
+ };
179
+ }
180
+ const validEmail = (value)=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
181
+ export { FormFrame, useForm, validEmail };
package/dist/6~0.js ADDED
@@ -0,0 +1,48 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useId } from "react";
3
+ import { useAuthLabels, Field } from "./g~0.js";
4
+ import { validEmail, useForm, FormFrame } from "./5~0.js";
5
+ function PasswordResetRequestForm({ defaultEmail = '', sentMessage, retryAfter = 0, onSubmit, locale, labels: overrides, ...options }) {
6
+ const id = useId();
7
+ const labels = useAuthLabels(locale, overrides);
8
+ const form = useForm({
9
+ email: defaultEmail
10
+ }, ({ email })=>({
11
+ email: validEmail(email) ? void 0 : {
12
+ key: 'invalidEmail'
13
+ }
14
+ }));
15
+ const [sentEmail, message] = sentMessage ? [
16
+ sentMessage.email,
17
+ sentMessage.message
18
+ ] : [];
19
+ const sent = sentEmail === form.values.email.trim();
20
+ const remaining = Math.max(0, Math.ceil(retryAfter));
21
+ return /*#__PURE__*/ jsxs(FormFrame, {
22
+ ...options,
23
+ disabled: options.disabled || remaining > 0,
24
+ labels: labels,
25
+ submitLabel: `${sent ? labels.resend : labels.send}${remaining > 0 ? ` (${remaining}s)` : ''}`,
26
+ validate: form.validate,
27
+ onSubmit: ()=>onSubmit?.({
28
+ email: form.values.email.trim()
29
+ }),
30
+ children: [
31
+ /*#__PURE__*/ jsx(Field, {
32
+ id: `${id}-email`,
33
+ label: labels.email,
34
+ labels: labels,
35
+ value: form.values.email,
36
+ type: "email",
37
+ autoComplete: "email",
38
+ error: form.errors.email,
39
+ onChange: (value)=>form.update('email', value)
40
+ }),
41
+ sent && message && /*#__PURE__*/ jsx("p", {
42
+ role: "status",
43
+ children: message
44
+ })
45
+ ]
46
+ });
47
+ }
48
+ export { PasswordResetRequestForm };
@@ -167,9 +167,11 @@
167
167
  }
168
168
  }
169
169
 
170
- .ov-button, .ov-input, .ov-textarea, .ov-directory-tour, .ov-wiki-dashboard, .ov-experience-dashboard, .ov-agent-connect, .ov-console, .ov-divider, .ov-file-browser-entries, .ov-drawer, .ov-modal, .ov-file-browser, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-popover, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__popover, .ov-viking-bot__reference-picker--mention, .ov-viking-bot__interaction {
170
+ .ov-button, .ov-input, .ov-textarea, .ov-directory-tour, .ov-wiki-dashboard, .ov-experience-dashboard, .ov-auth, .ov-agent-connect, .ov-console, .ov-divider, .ov-file-browser-entries, .ov-drawer, .ov-modal, .ov-file-browser, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-popover, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__popover, .ov-viking-bot__reference-picker--mention, .ov-viking-bot__interaction {
171
171
  --ov-ui-tour-shadow-default: 0 15px 35px #0000000d, 0 5px 15px #0000000d;
172
172
  --ov-ui-tour-highlight-default: #5252ff14;
173
+ --ov-ui-auth-on-primary-default: #fff;
174
+ --ov-ui-auth-backdrop-default: #0006;
173
175
  --ov-ui-primary-default: #5252ff;
174
176
  --ov-ui-primary-hover-default: #7075ff;
175
177
  --ov-ui-primary-active-default: #3833d2;
@@ -226,7 +228,7 @@
226
228
  #bd9cff 100%);
227
229
  }
228
230
 
229
- html.dark .ov-button, html.dark .ov-input, html.dark .ov-textarea, .dark .ov-directory-tour, html.dark .ov-wiki-dashboard, html.dark .ov-experience-dashboard, .dark .ov-agent-connect, .dark .ov-console, .dark .ov-divider, .dark .ov-file-browser-entries, .dark .ov-drawer, .dark .ov-modal, .dark .ov-file-browser, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-popover, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__popover, .dark .ov-viking-bot__reference-picker--mention, .dark .ov-viking-bot__interaction {
231
+ html.dark .ov-button, html.dark .ov-input, html.dark .ov-textarea, .dark .ov-directory-tour, html.dark .ov-wiki-dashboard, html.dark .ov-experience-dashboard, .dark .ov-auth, .dark .ov-agent-connect, .dark .ov-console, .dark .ov-divider, .dark .ov-file-browser-entries, .dark .ov-drawer, .dark .ov-modal, .dark .ov-file-browser, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-popover, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__popover, .dark .ov-viking-bot__reference-picker--mention, .dark .ov-viking-bot__interaction {
230
232
  --ov-ui-primary-default: #5f5fff;
231
233
  --ov-ui-primary-hover-default: #7075ff;
232
234
  --ov-ui-primary-active-default: #4242ba;
@@ -0,0 +1,2 @@
1
+ import type { ApiKeyLoginFormProps } from './types.js';
2
+ export declare function ApiKeyLoginForm({ alternateLogin, onSubmit, locale, labels: overrides, ...options }: ApiKeyLoginFormProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export { ApiKeyLoginForm } from './api-key-login-form.js';
2
+ export type { ApiKeyLoginFormProps } from './types.js';
3
+ export type { AuthAction, AuthAgreements, AuthLabels, } from '../../shared/auth/types.js';