@openviking/react 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +57 -34
  2. package/dist/3~0.js +2117 -0
  3. package/dist/ark-message-list-view~0.js +310 -0
  4. package/dist/a~0.js +21 -0
  5. package/dist/c7~0.js +24 -0
  6. package/dist/client/client.d.ts +12 -0
  7. package/dist/client/errors.d.ts +30 -0
  8. package/dist/client/index.d.ts +4 -0
  9. package/dist/client/options.d.ts +101 -0
  10. package/dist/client/provider.d.ts +52 -0
  11. package/dist/client/types.d.ts +160 -0
  12. package/dist/client.js +239 -0
  13. package/dist/components/agent-connect/agent-connect-copy.d.ts +34 -0
  14. package/dist/components/agent-connect/agent-connect-design.d.ts +1781 -0
  15. package/dist/components/agent-connect/agent-connect-detail.d.ts +13 -0
  16. package/dist/components/agent-connect/agent-connect-installer.d.ts +3 -0
  17. package/dist/components/agent-connect/agent-connect-instructions-view.d.ts +14 -0
  18. package/dist/components/agent-connect/agent-connect-instructions.d.ts +145 -0
  19. package/dist/components/agent-connect/agent-connect-markdown.d.ts +3 -0
  20. package/dist/components/agent-connect/agent-connect.d.ts +4 -1
  21. package/dist/components/agent-connect/content-en.d.ts +137 -0
  22. package/dist/components/agent-connect/content-zh.d.ts +137 -0
  23. package/dist/components/agent-connect/index.d.ts +1 -0
  24. package/dist/components/agent-connect/style.css +503 -0
  25. package/dist/components/agent-connect/types.d.ts +29 -0
  26. package/dist/components/agent-connect.js +1 -0
  27. package/dist/components/file-preview/file-preview-adapters.d.ts +33 -0
  28. package/dist/components/file-preview/file-preview-body.d.ts +27 -0
  29. package/dist/components/file-preview/file-preview-breadcrumb-menu.d.ts +16 -0
  30. package/dist/components/file-preview/file-preview-breadcrumb.d.ts +21 -0
  31. package/dist/components/file-preview/file-preview-copy-path.d.ts +12 -0
  32. package/dist/components/file-preview/file-preview-editor.d.ts +22 -0
  33. package/dist/components/file-preview/file-preview-handle-adapters.d.ts +26 -0
  34. package/dist/components/file-preview/file-preview-header.d.ts +25 -0
  35. package/dist/components/file-preview/file-preview-labels.d.ts +16 -0
  36. package/dist/components/file-preview/file-preview-lazy-viewer.d.ts +3 -0
  37. package/dist/components/file-preview/file-preview-path.d.ts +30 -0
  38. package/dist/components/file-preview/file-preview-source.d.ts +24 -0
  39. package/dist/components/file-preview/file-preview-state.d.ts +28 -0
  40. package/dist/components/file-preview/file-preview-tab-row.d.ts +16 -0
  41. package/dist/components/file-preview/file-preview-viewer.d.ts +31 -0
  42. package/dist/components/file-preview/file-preview.d.ts +14 -1
  43. package/dist/components/file-preview/index.d.ts +1 -0
  44. package/dist/components/file-preview/style.css +4139 -0
  45. package/dist/components/file-preview/types.d.ts +516 -0
  46. package/dist/components/file-preview/use-file-preview-actions-context.d.ts +23 -0
  47. package/dist/components/file-preview/use-file-preview-actions.d.ts +19 -0
  48. package/dist/components/file-preview/use-file-preview-editing.d.ts +32 -0
  49. package/dist/components/file-preview/use-file-preview-ids.d.ts +24 -0
  50. package/dist/components/file-preview.js +1 -0
  51. package/dist/components/file-tree/file-tree-body.d.ts +18 -0
  52. package/dist/components/file-tree/file-tree-entry-row.d.ts +12 -0
  53. package/dist/components/file-tree/file-tree-icons.d.ts +15 -0
  54. package/dist/components/file-tree/file-tree-info-labels.d.ts +21 -0
  55. package/dist/components/file-tree/file-tree-info-tooltip.d.ts +43 -0
  56. package/dist/components/file-tree/file-tree-info.d.ts +29 -0
  57. package/dist/components/file-tree/file-tree-keyboard.d.ts +14 -0
  58. package/dist/components/file-tree/file-tree-row-context.d.ts +46 -0
  59. package/dist/components/file-tree/file-tree-row-shared.d.ts +11 -0
  60. package/dist/components/file-tree/file-tree-spinner.d.ts +10 -0
  61. package/dist/components/file-tree/file-tree-state-row.d.ts +7 -0
  62. package/dist/components/file-tree/file-tree-tooltip-surface.d.ts +22 -0
  63. package/dist/components/file-tree/file-tree-tooltip.d.ts +17 -0
  64. package/dist/components/file-tree/file-tree.d.ts +15 -1
  65. package/dist/components/file-tree/index.d.ts +1 -0
  66. package/dist/components/file-tree/style.css +410 -0
  67. package/dist/components/file-tree/types.d.ts +589 -0
  68. package/dist/components/file-tree/use-file-tree-actions.d.ts +17 -0
  69. package/dist/components/file-tree.js +1 -0
  70. package/dist/components/scope-switcher/index.d.ts +1 -0
  71. package/dist/components/scope-switcher/scope-keyboard.d.ts +2 -0
  72. package/dist/components/scope-switcher/scope-panel.d.ts +11 -0
  73. package/dist/components/scope-switcher/scope-selector.d.ts +2 -0
  74. package/dist/components/scope-switcher/scope-switcher.d.ts +6 -1
  75. package/dist/components/scope-switcher/style.css +452 -0
  76. package/dist/components/scope-switcher/types.d.ts +489 -0
  77. package/dist/components/scope-switcher.js +3 -0
  78. package/dist/components/style.css +14249 -18
  79. package/dist/components/tui/command-catalog.d.ts +58 -0
  80. package/dist/components/tui/command-completion.d.ts +19 -0
  81. package/dist/components/tui/command-definitions.d.ts +10 -0
  82. package/dist/components/tui/command-input.d.ts +16 -0
  83. package/dist/components/tui/index.d.ts +1 -0
  84. package/dist/components/tui/style.css +1552 -0
  85. package/dist/components/tui/tui-assist.d.ts +15 -0
  86. package/dist/components/tui/tui-code-block.d.ts +8 -0
  87. package/dist/components/tui/tui-command-help.d.ts +9 -0
  88. package/dist/components/tui/tui-command-text.d.ts +6 -0
  89. package/dist/components/tui/tui-composer.d.ts +24 -0
  90. package/dist/components/tui/tui-copy-button.d.ts +9 -0
  91. package/dist/components/tui/tui-input-mirror.d.ts +14 -0
  92. package/dist/components/tui/tui-labels-zh.d.ts +2 -0
  93. package/dist/components/tui/tui-labels.d.ts +5 -0
  94. package/dist/components/tui/tui-markdown-renderers.d.ts +10 -0
  95. package/dist/components/tui/tui-markdown.d.ts +6 -0
  96. package/dist/components/tui/tui-param-hint.d.ts +7 -0
  97. package/dist/components/tui/tui-record-time.d.ts +11 -0
  98. package/dist/components/tui/tui-record.d.ts +13 -0
  99. package/dist/components/tui/tui-resource-preview.d.ts +10 -0
  100. package/dist/components/tui/tui-resource-tree.d.ts +10 -0
  101. package/dist/components/tui/tui-result-header.d.ts +7 -0
  102. package/dist/components/tui/tui-result-text.d.ts +5 -0
  103. package/dist/components/tui/tui-search-list.d.ts +8 -0
  104. package/dist/components/tui/tui-skeleton.d.ts +6 -0
  105. package/dist/components/tui/tui-status-card.d.ts +7 -0
  106. package/dist/components/tui/tui-text.d.ts +10 -0
  107. package/dist/components/tui/tui-uri-text.d.ts +19 -0
  108. package/dist/components/tui/tui-write-result.d.ts +7 -0
  109. package/dist/components/tui/tui.d.ts +11 -1
  110. package/dist/components/tui/types.d.ts +527 -0
  111. package/dist/components/tui/use-tui-assist-position.d.ts +3 -0
  112. package/dist/components/tui/use-tui-completion.d.ts +14 -0
  113. package/dist/components/tui/use-tui-composer-keyboard.d.ts +25 -0
  114. package/dist/components/tui.js +1 -0
  115. package/dist/components/viking-bot/ark-adapter.d.ts +45 -0
  116. package/dist/components/viking-bot/ark-message-body.d.ts +16 -0
  117. package/dist/components/viking-bot/ark-message-list-view.d.ts +7 -0
  118. package/dist/components/viking-bot/ark-message-row.d.ts +19 -0
  119. package/dist/components/viking-bot/index.d.ts +10 -0
  120. package/dist/components/viking-bot/interaction/ask-human-fields.d.ts +10 -0
  121. package/dist/components/viking-bot/interaction/index.d.ts +4 -0
  122. package/dist/components/viking-bot/interaction/labels.d.ts +7 -0
  123. package/dist/components/viking-bot/interaction/lazy-interaction.d.ts +3 -0
  124. package/dist/components/viking-bot/interaction/schedule-input.d.ts +13 -0
  125. package/dist/components/viking-bot/interaction/style.css +189 -0
  126. package/dist/components/viking-bot/interaction/types.d.ts +188 -0
  127. package/dist/components/viking-bot/interaction/viking-bot-interaction.d.ts +9 -0
  128. package/dist/components/viking-bot/interaction.js +2 -0
  129. package/dist/components/viking-bot/labels.d.ts +2 -0
  130. package/dist/components/viking-bot/lazy-composer.d.ts +3 -0
  131. package/dist/components/viking-bot/message-groups.d.ts +12 -0
  132. package/dist/components/viking-bot/model.d.ts +252 -0
  133. package/dist/components/viking-bot/render-part.d.ts +12 -0
  134. package/dist/components/viking-bot/style.css +7133 -0
  135. package/dist/components/viking-bot/types.d.ts +140 -0
  136. package/dist/components/viking-bot/viking-bot-composer.d.ts +6 -0
  137. package/dist/components/viking-bot/viking-bot-message-list.d.ts +3 -0
  138. package/dist/components/viking-bot/viking-bot.d.ts +16 -1
  139. package/dist/components/viking-bot.js +4 -0
  140. package/dist/c~0.js +201 -0
  141. package/dist/file-preview-viewer~0.js +191 -0
  142. package/dist/f~0.js +356 -0
  143. package/dist/g~0.js +1207 -0
  144. package/dist/h~0.js +58 -0
  145. package/dist/icons/file-type-icon.d.ts +31 -0
  146. package/dist/icons/index.d.ts +33 -23
  147. package/dist/icons/nextjs-icon.d.ts +19 -0
  148. package/dist/icons.js +1 -25
  149. package/dist/index.d.ts +16 -2
  150. package/dist/index.js +8 -1
  151. package/dist/k~0.js +1440 -0
  152. package/dist/lk~0.js +233 -0
  153. package/dist/l~0.js +44 -0
  154. package/dist/modules/console/console.d.ts +4 -0
  155. package/dist/modules/console/index.d.ts +1 -0
  156. package/dist/modules/console/style.css +111 -0
  157. package/dist/modules/console/types.d.ts +101 -0
  158. package/dist/modules/console.js +1 -0
  159. package/dist/modules/file-browser/file-browser-toolbar-button.d.ts +10 -0
  160. package/dist/modules/file-browser/file-browser.d.ts +6 -0
  161. package/dist/modules/file-browser/index.d.ts +1 -0
  162. package/dist/modules/file-browser/style.css +158 -0
  163. package/dist/modules/file-browser/types.d.ts +101 -0
  164. package/dist/modules/file-browser.js +1 -0
  165. package/dist/modules/scope-cascade/controller.d.ts +6 -0
  166. package/dist/modules/scope-cascade/index.d.ts +3 -0
  167. package/dist/modules/scope-cascade/scope-cascade.d.ts +3 -0
  168. package/dist/modules/scope-cascade/style.css +456 -0
  169. package/dist/modules/scope-cascade/style.js +0 -0
  170. package/dist/modules/scope-cascade/types.d.ts +39 -0
  171. package/dist/modules/scope-cascade/use-scope-cascade.d.ts +5 -0
  172. package/dist/modules/scope-cascade.js +1 -0
  173. package/dist/modules/style.css +808 -0
  174. package/dist/modules/style.js +0 -0
  175. package/dist/n~0.js +727 -0
  176. package/dist/shared/components/tooltip/index.d.ts +1 -0
  177. package/dist/shared/components/tooltip/tooltip.d.ts +25 -0
  178. package/dist/shared/components/tooltip/types.d.ts +42 -0
  179. package/dist/shared/components/tooltip/use-tooltip-position.d.ts +38 -0
  180. package/dist/style.css +15138 -18
  181. package/dist/u~0.js +1601 -0
  182. package/dist/viking-bot-composer~0.js +164 -0
  183. package/dist/viking-bot-interaction~0.js +284 -0
  184. package/dist/w~0.js +19 -0
  185. package/package.json +46 -22
  186. package/dist/components/resource-import/resource-import.d.ts +0 -1
  187. package/dist/components/resource-import/style.css +0 -2
  188. package/dist/components/status-badge/status-badge.d.ts +0 -8
  189. package/dist/components/status-badge/style.css +0 -37
  190. package/dist/components/status-badge.js +0 -30
  191. /package/dist/components/{resource-import → viking-bot/interaction}/style.js +0 -0
  192. /package/dist/{components/status-badge → modules/console}/style.js +0 -0
  193. /package/dist/{components/resource-import.js → modules/file-browser/style.js} +0 -0
@@ -0,0 +1,101 @@
1
+ import type { OvRequestOptions } from '../../client/index.js';
2
+ import type { HTMLAttributes, ReactNode } from 'react';
3
+ /** 文件浏览模块的可替换文案。Replaceable copy of the file browser module. */
4
+ export interface FileBrowserLabels {
5
+ /**
6
+ * 占位说明。缺省为 `Placeholder. Functionality is not available yet.`。
7
+ * Placeholder description. Defaults to "Placeholder. Functionality is not
8
+ * available yet.".
9
+ */
10
+ description?: string;
11
+ /** 区域标题。Area title. */
12
+ title?: string;
13
+ /** 搜索框占位文案。Search placeholder. */
14
+ searchPlaceholder?: string;
15
+ /** 搜索无结果提示。Message shown when a search returns nothing. */
16
+ searchEmpty?: string;
17
+ /** 刷新按钮的无障碍名称。Accessible name of the refresh control. */
18
+ refresh?: string;
19
+ /** 未选中资源时的提示。Message shown when no resource is selected. */
20
+ empty?: string;
21
+ /** 加载失败提示。Load failure message. */
22
+ error?: string;
23
+ /** 重试按钮文案。Retry button label. */
24
+ retry?: string;
25
+ }
26
+ /**
27
+ * 工具栏按钮的属性。宿主在 `toolbarActions` 里用它组合自己的入口。
28
+ * Props of a toolbar button. The host composes its own entries with it inside
29
+ * `toolbarActions`.
30
+ */
31
+ export interface FileBrowserToolbarButtonProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
32
+ /** 按钮图标。Button icon. */
33
+ icon: ReactNode;
34
+ /** 按钮文案。Button label. */
35
+ children: ReactNode;
36
+ /** 是否禁用,缺省为 `false`。Whether the button is disabled; defaults to `false`. */
37
+ disabled?: boolean;
38
+ /** 点击后触发。Called on click. */
39
+ onClick?: () => void;
40
+ }
41
+ /**
42
+ * 文件浏览模块的属性。
43
+ *
44
+ * 模块自己通过 Hook 取数,props 里没有数据字段:宿主给配置、受控的当前资源、
45
+ * 工具栏入口、文案与请求配置。目录、搜索、预览页签与行级状态都在模块内维护,
46
+ * 宿主不需要重复组装。
47
+ *
48
+ * 模块只覆盖文件树与文件预览两块。命令面板属于 `console`。
49
+ *
50
+ * Props of the file browser module.
51
+ *
52
+ * The module loads its own data through a Hook, so no prop carries data: the
53
+ * host supplies configuration, the controlled current resource, the toolbar
54
+ * entries, copy and request configuration. The directory, search, preview tabs
55
+ * and per-row state all live inside the module, so the host does not assemble
56
+ * them again.
57
+ *
58
+ * The module covers only the file tree and the file preview. The command panel
59
+ * belongs to `console`.
60
+ */
61
+ export interface FileBrowserProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect' | 'children'> {
62
+ /**
63
+ * 受控的当前资源 URI。传入时由宿主决定当前资源,模块只上报切换意图。
64
+ * The controlled current resource URI. When given, the host owns the current
65
+ * resource and the module only reports switch intent.
66
+ */
67
+ uri?: string;
68
+ /**
69
+ * 非受控时的初始资源 URI。省略时不选中任何资源。
70
+ * Initial resource URI when uncontrolled. Nothing is selected when omitted.
71
+ */
72
+ defaultUri?: string;
73
+ /**
74
+ * 工具栏左侧的宿主入口,例如连接 Agent、导入资源。用
75
+ * {@link FileBrowserToolbarButton} 组合,保证与模块内置按钮外观一致。
76
+ * 搜索与刷新由模块渲染,入口之间的分隔线也由模块处理。
77
+ *
78
+ * Host entries on the left of the toolbar, for example connecting an agent or
79
+ * importing resources. Compose them with {@link FileBrowserToolbarButton} so
80
+ * they match the module's own buttons. Search and refresh are rendered by the
81
+ * module, and so are the dividers between entries.
82
+ */
83
+ toolbarActions?: ReactNode;
84
+ /**
85
+ * 当前资源变化后触发,参数为新的 URI;清除选中时传入 `null`。
86
+ * Called after the current resource changes, with the new URI; `null` when
87
+ * the selection is cleared.
88
+ */
89
+ onUriChange?: (uri: string | null) => void;
90
+ /**
91
+ * 可替换文案,缺省为英文。
92
+ * Replaceable copy; English by default.
93
+ */
94
+ labels?: FileBrowserLabels;
95
+ /**
96
+ * 请求配置覆盖,逐字段覆盖最近的 Provider。
97
+ * Request configuration override, applied field by field over the nearest
98
+ * Provider.
99
+ */
100
+ requestOptions?: OvRequestOptions;
101
+ }
@@ -0,0 +1 @@
1
+ export { FileBrowser, FileBrowserToolbarButton } from "../l~0.js";
@@ -0,0 +1,6 @@
1
+ import type { ScopeCascadeApi, ScopeCascadeController } from './types.js';
2
+ /** Instance-owned channels. Creating a controller does not start requests. */
3
+ export declare function createScopeController(): {
4
+ controller: ScopeCascadeController;
5
+ start(nextApi: ScopeCascadeApi): () => void;
6
+ };
@@ -0,0 +1,3 @@
1
+ export { ScopeCascade } from './scope-cascade.js';
2
+ export { useScopeCascade, useScopeCascadeLevel } from './use-scope-cascade.js';
3
+ export type { ScopeCascadeApi, ScopeCascadeController, ScopeCascadeIndex, ScopeCascadeLevel, ScopeCascadeProps, ScopeCascadeSnapshot, } from './types.js';
@@ -0,0 +1,3 @@
1
+ import type { ScopeCascadeProps } from './types.js';
2
+ /** Only leaf selectors subscribe. This wrapper stays outside the update path. */
3
+ export declare function ScopeCascade({ controller, labels, levelNames, retryLabel, ...props }: ScopeCascadeProps): import("react").JSX.Element;
@@ -0,0 +1,456 @@
1
+ .ov-agent-connect, .ov-file-browser, .ov-file-preview, .ov-file-tree, .ov-module-placeholder, .ov-scope-switcher, .ov-tooltip, .ov-tui, .ov-viking-bot, .ov-viking-bot__interaction {
2
+ --ov-ui-primary-default: #5252ff;
3
+ --ov-ui-primary-hover-default: #7075ff;
4
+ --ov-ui-primary-active-default: #3833d2;
5
+ --ov-ui-primary-light-default: #f5f7ff;
6
+ --ov-ui-connect-glow-warm-default: #ff952b0a;
7
+ --ov-ui-connect-glow-pink-default: #fb4fbc0f;
8
+ --ov-ui-connect-glow-pink-soft-default: #fb4fbc0a;
9
+ --ov-ui-on-primary-default: #fff;
10
+ --ov-ui-text-1-default: #0b0b0f;
11
+ --ov-ui-text-2-default: #3f3f51;
12
+ --ov-ui-text-3-default: #6e718c;
13
+ --ov-ui-text-description-default: #0006;
14
+ --ov-ui-text-disabled-default: #a5a7bb;
15
+ --ov-ui-border-1-default: #f0f2fa;
16
+ --ov-ui-border-2-default: #e1e4f2;
17
+ --ov-ui-border-3-default: #d7daea;
18
+ --ov-ui-bg-1-default: #fff;
19
+ --ov-ui-bg-3-default: #f7f8fd;
20
+ --ov-ui-bg-4-default: #f6f7fa;
21
+ --ov-ui-bg-5-default: #f1f2f9;
22
+ --ov-ui-status-success-default: #1f9d55;
23
+ --ov-ui-shadow-default: #0f172a;
24
+ --ov-ui-focus-default: #5252ff;
25
+ --ov-ui-fill-hover-default: #f1f2f9;
26
+ --ov-ui-status-error-default: #c43838;
27
+ --ov-ui-warning-default: #b26a00;
28
+ --ov-ui-warning-light-default: #fff0b3;
29
+ --ov-ui-tooltip-bg-default: #1f2329;
30
+ --ov-ui-tooltip-text-default: #fff;
31
+ }
32
+
33
+ .dark .ov-agent-connect, .dark .ov-file-browser, .dark .ov-file-preview, .dark .ov-file-tree, .dark .ov-module-placeholder, .dark .ov-scope-switcher, .dark .ov-tooltip, .dark .ov-tui, .dark .ov-viking-bot, .dark .ov-viking-bot__interaction {
34
+ --ov-ui-primary-default: #5f5fff;
35
+ --ov-ui-primary-hover-default: #7075ff;
36
+ --ov-ui-primary-active-default: #4242ba;
37
+ --ov-ui-primary-light-default: #1a1632;
38
+ --ov-ui-connect-glow-warm-default: #ff952b05;
39
+ --ov-ui-connect-glow-pink-default: #fb4fbc08;
40
+ --ov-ui-connect-glow-pink-soft-default: #fb4fbc05;
41
+ --ov-ui-text-1-default: #c7ccd6;
42
+ --ov-ui-text-2-default: #9da3af;
43
+ --ov-ui-text-3-default: #737a87;
44
+ --ov-ui-text-description-default: #fff6;
45
+ --ov-ui-text-disabled-default: #42464e;
46
+ --ov-ui-border-1-default: #23252a;
47
+ --ov-ui-border-2-default: #2e3138;
48
+ --ov-ui-border-3-default: #3a3d45;
49
+ --ov-ui-bg-1-default: #131416;
50
+ --ov-ui-bg-3-default: #1b1d21;
51
+ --ov-ui-bg-4-default: #202227;
52
+ --ov-ui-bg-5-default: #23252a;
53
+ --ov-ui-focus-default: #5f5fff;
54
+ --ov-ui-fill-hover-default: #23252a;
55
+ --ov-ui-status-error-default: #ff9595;
56
+ --ov-ui-warning-default: #e0a04a;
57
+ --ov-ui-warning-light-default: #3a2f14;
58
+ --ov-ui-tooltip-bg-default: #2a2d33;
59
+ --ov-ui-tooltip-text-default: #f0f1f3;
60
+ }
61
+
62
+ .ov-agent-connect {
63
+ --ov-ui-connect-card-default: #fbfbfc;
64
+ --ov-ui-connect-tabs-default: #f7f7f9;
65
+ --ov-ui-connect-selected-default: #f3f4f7;
66
+ --ov-ui-connect-border-default: #edeef2;
67
+ --ov-ui-connect-outline-default: #e1e3ea;
68
+ --ov-ui-connect-muted-default: #787c91;
69
+ --ov-ui-connect-notice-default: #2e2984;
70
+ }
71
+
72
+ .dark .ov-agent-connect {
73
+ --ov-ui-connect-card-default: var(--ov-ui-bg-3-default);
74
+ --ov-ui-connect-tabs-default: var(--ov-ui-bg-3-default);
75
+ --ov-ui-connect-selected-default: var(--ov-ui-bg-4-default);
76
+ --ov-ui-connect-border-default: var(--ov-ui-border-1-default);
77
+ --ov-ui-connect-outline-default: var(--ov-ui-border-2-default);
78
+ --ov-ui-connect-muted-default: var(--ov-ui-text-3-default);
79
+ --ov-ui-connect-notice-default: var(--ov-ui-text-2-default);
80
+ }
81
+
82
+ .ov-scope-switcher {
83
+ --ov-ui-scope-switcher-divider: var(--ov-ui-color-text-disabled, var(--ov-ui-text-disabled-default, #a5a7bb));
84
+ --ov-ui-scope-switcher-icon: var(--ov-ui-color-text-2, var(--ov-ui-text-2-default, #3f3f51));
85
+ --ov-ui-scope-switcher-option-icon: var(--ov-ui-scope-switcher-icon);
86
+ --ov-ui-scope-switcher-row-hover: var(--ov-ui-color-fill-hover, var(--ov-ui-fill-hover-default, #f1f2f9));
87
+ --ov-ui-scope-switcher-tag-background: var(--ov-ui-color-bg-5, var(--ov-ui-bg-5-default, #f1f2f9));
88
+ --ov-ui-scope-switcher-tag-text: var(--ov-ui-color-text-2, var(--ov-ui-text-2-default, #3f3f51));
89
+ --ov-ui-scope-switcher-panel-width: 272px;
90
+ --ov-ui-scope-switcher-option-height: 44px;
91
+ --ov-ui-scope-switcher-option-gap: 2px;
92
+ --ov-ui-scope-switcher-list-max-height: 288px;
93
+ --ov-ui-scope-switcher-panel-max-height: calc(var(--ov-ui-scope-switcher-list-max-height) + 54px);
94
+ --ov-ui-scope-switcher-option-icon-size: 24px;
95
+ --ov-ui-scope-switcher-option-icon-radius: 12px;
96
+ box-sizing: border-box;
97
+ max-width: 100%;
98
+ height: 32px;
99
+ color: var(--ov-ui-color-text-1, var(--ov-ui-text-1-default, #0b0b0f));
100
+ font-family: var(--ov-ui-font-family, "PingFang SC",
101
+ -apple-system,
102
+ BlinkMacSystemFont,
103
+ "Segoe UI",
104
+ sans-serif);
105
+ letter-spacing: .039px;
106
+ flex-wrap: nowrap;
107
+ align-items: center;
108
+ gap: 4px;
109
+ font-size: 13px;
110
+ line-height: 22px;
111
+ display: inline-flex;
112
+ }
113
+
114
+ .ov-scope-switcher *, .ov-scope-switcher :before, .ov-scope-switcher :after {
115
+ box-sizing: border-box;
116
+ }
117
+
118
+ .ov-scope-switcher__level {
119
+ flex-shrink: 1;
120
+ align-items: center;
121
+ gap: 4px;
122
+ min-width: 0;
123
+ max-width: 100%;
124
+ display: inline-flex;
125
+ position: relative;
126
+ }
127
+
128
+ .ov-scope-switcher__level + .ov-scope-switcher__level:before {
129
+ content: "/";
130
+ color: var(--ov-ui-color-text-disabled, var(--ov-ui-text-disabled-default, #a5a7bb));
131
+ letter-spacing: .039px;
132
+ margin-right: 4px;
133
+ font-size: 13px;
134
+ font-weight: 500;
135
+ line-height: 22px;
136
+ }
137
+
138
+ .ov-scope-switcher__trigger {
139
+ min-width: 0;
140
+ max-width: min(260px, 100%);
141
+ height: 32px;
142
+ color: inherit;
143
+ font: inherit;
144
+ vertical-align: middle;
145
+ background: none;
146
+ border: 1px solid #0000;
147
+ border-radius: 16px;
148
+ align-items: center;
149
+ gap: 8px;
150
+ padding: 0 8px;
151
+ font-weight: 500;
152
+ display: inline-flex;
153
+ }
154
+
155
+ button.ov-scope-switcher__trigger {
156
+ cursor: pointer;
157
+ }
158
+
159
+ button.ov-scope-switcher__trigger:hover:not(:disabled), button.ov-scope-switcher__trigger:focus-visible, button.ov-scope-switcher__trigger[aria-expanded="true"] {
160
+ border-color: var(--ov-ui-color-primary, var(--ov-ui-primary-default, #5252ff));
161
+ }
162
+
163
+ .ov-scope-switcher__label {
164
+ text-overflow: ellipsis;
165
+ white-space: nowrap;
166
+ min-width: 0;
167
+ overflow: hidden;
168
+ }
169
+
170
+ .ov-scope-switcher__icon {
171
+ width: 14px;
172
+ height: 14px;
173
+ color: var(--ov-ui-scope-switcher-icon);
174
+ flex: 0 0 14px;
175
+ justify-content: center;
176
+ align-items: center;
177
+ display: inline-flex;
178
+ }
179
+
180
+ .ov-scope-switcher__icon > svg, .ov-scope-switcher__icon > img {
181
+ width: 14px;
182
+ height: 14px;
183
+ display: block;
184
+ }
185
+
186
+ .ov-scope-switcher__tag {
187
+ border: 1px solid
188
+ var(--ov-ui-color-border-2, var(--ov-ui-border-2-default, #e1e4f2));
189
+ background: var(--ov-ui-scope-switcher-tag-background);
190
+ color: var(--ov-ui-scope-switcher-tag-text);
191
+ border-radius: 4px;
192
+ flex-shrink: 0;
193
+ padding: 1px 6px;
194
+ font-size: 10px;
195
+ font-weight: 500;
196
+ line-height: 16px;
197
+ }
198
+
199
+ .ov-scope-switcher__arrow {
200
+ width: 14px;
201
+ height: 14px;
202
+ color: var(--ov-ui-scope-switcher-icon);
203
+ flex: 0 0 14px;
204
+ justify-content: center;
205
+ align-items: center;
206
+ transition: transform .16s;
207
+ display: inline-flex;
208
+ }
209
+
210
+ .ov-scope-switcher__trigger[aria-expanded="true"] .ov-scope-switcher__arrow {
211
+ transform: rotate(180deg);
212
+ }
213
+
214
+ .ov-scope-switcher__trigger:disabled .ov-scope-switcher__arrow {
215
+ opacity: .55;
216
+ }
217
+
218
+ @media (prefers-reduced-motion: reduce) {
219
+ .ov-scope-switcher__arrow {
220
+ transition: none;
221
+ }
222
+ }
223
+
224
+ .ov-scope-switcher__panel {
225
+ z-index: 30;
226
+ width: min(var(--ov-ui-scope-switcher-panel-width), calc(100vw - 32px));
227
+ max-height: min(var(--ov-ui-scope-switcher-panel-max-height),
228
+ calc(100vh - 128px));
229
+ border: 1px solid
230
+ var(--ov-ui-color-border-1, var(--ov-ui-border-1-default, #f0f2fa));
231
+ background: var(--ov-ui-color-bg-1, var(--ov-ui-bg-1-default, #fff));
232
+ color: var(--ov-ui-color-text-1, var(--ov-ui-text-1-default, #0b0b0f));
233
+ letter-spacing: .039px;
234
+ border-radius: 12px;
235
+ flex-direction: column;
236
+ padding: 8px;
237
+ font-size: 13px;
238
+ line-height: 22px;
239
+ display: flex;
240
+ position: absolute;
241
+ top: calc(100% + 4px);
242
+ left: 0;
243
+ overflow: hidden;
244
+ box-shadow: 0 15px 35px -2px #0000000d, 0 5px 15px #0000000d;
245
+ }
246
+
247
+ .ov-scope-switcher__panel--custom {
248
+ min-height: 0;
249
+ overflow-y: auto;
250
+ }
251
+
252
+ .ov-scope-switcher__level:last-child:not(:first-child) .ov-scope-switcher__panel {
253
+ left: auto;
254
+ right: 0;
255
+ }
256
+
257
+ .ov-scope-switcher__panel-inner {
258
+ flex-direction: column;
259
+ flex: auto;
260
+ min-height: 0;
261
+ display: flex;
262
+ }
263
+
264
+ .ov-scope-switcher__panel-body {
265
+ flex-direction: column;
266
+ flex: auto;
267
+ gap: 8px;
268
+ min-height: 0;
269
+ display: flex;
270
+ }
271
+
272
+ .ov-scope-switcher__search-field {
273
+ border: 1px solid
274
+ var(--ov-ui-color-border-3, var(--ov-ui-border-3-default, #d7daea));
275
+ background: var(--ov-ui-color-bg-1, var(--ov-ui-bg-1-default, #fff));
276
+ border-radius: 6px;
277
+ flex-shrink: 0;
278
+ align-items: center;
279
+ gap: 4px;
280
+ height: 28px;
281
+ padding: 3px 8px;
282
+ display: flex;
283
+ }
284
+
285
+ .ov-scope-switcher__search-field:focus-within {
286
+ border-color: var(--ov-ui-color-primary, var(--ov-ui-primary-default, #5252ff));
287
+ }
288
+
289
+ .ov-scope-switcher__search-icon {
290
+ width: 16px;
291
+ height: 16px;
292
+ color: var(--ov-ui-scope-switcher-icon);
293
+ flex: 0 0 16px;
294
+ }
295
+
296
+ .ov-scope-switcher__search {
297
+ min-width: 0;
298
+ height: 100%;
299
+ color: inherit;
300
+ font: inherit;
301
+ background: none;
302
+ border: 0;
303
+ outline: none;
304
+ flex: 1;
305
+ padding: 0;
306
+ font-size: 12px;
307
+ line-height: 22px;
308
+ }
309
+
310
+ .ov-scope-switcher__search::placeholder {
311
+ color: var(--ov-ui-color-text-3, var(--ov-ui-text-3-default, #6e718c));
312
+ }
313
+
314
+ .ov-scope-switcher__list {
315
+ gap: var(--ov-ui-scope-switcher-option-gap);
316
+ min-height: 0;
317
+ max-height: var(--ov-ui-scope-switcher-list-max-height);
318
+ overscroll-behavior: contain;
319
+ flex-direction: column;
320
+ display: flex;
321
+ overflow-y: auto;
322
+ }
323
+
324
+ .ov-scope-switcher__option {
325
+ width: 100%;
326
+ min-height: var(--ov-ui-scope-switcher-option-height);
327
+ color: inherit;
328
+ font: inherit;
329
+ text-align: start;
330
+ cursor: pointer;
331
+ background: none;
332
+ border: 0;
333
+ border-radius: 6px;
334
+ flex-shrink: 0;
335
+ align-items: center;
336
+ gap: 8px;
337
+ padding: 2px 8px;
338
+ display: flex;
339
+ }
340
+
341
+ .ov-scope-switcher__option:hover:not([aria-disabled="true"]):not([aria-selected="true"]), .ov-scope-switcher__option:focus-visible:not([aria-disabled="true"]):not([aria-selected="true"]) {
342
+ background: var(--ov-ui-scope-switcher-row-hover);
343
+ }
344
+
345
+ .ov-scope-switcher__option[aria-selected="true"] {
346
+ background: var(--ov-ui-color-primary-light, var(--ov-ui-primary-light-default, #f5f7ff));
347
+ }
348
+
349
+ .ov-scope-switcher__option .ov-scope-switcher__icon {
350
+ flex: 0 0 var(--ov-ui-scope-switcher-option-icon-size);
351
+ width: var(--ov-ui-scope-switcher-option-icon-size);
352
+ height: var(--ov-ui-scope-switcher-option-icon-size);
353
+ border: .5px solid
354
+ var(--ov-ui-color-border-1, var(--ov-ui-border-1-default, #f0f2fa));
355
+ border-radius: var(--ov-ui-scope-switcher-option-icon-radius);
356
+ background: var(--ov-ui-color-bg-1, var(--ov-ui-bg-1-default, #fff));
357
+ color: var(--ov-ui-scope-switcher-option-icon);
358
+ }
359
+
360
+ .ov-scope-switcher__option .ov-scope-switcher__icon > svg, .ov-scope-switcher__option .ov-scope-switcher__icon > img {
361
+ width: 14px;
362
+ height: 14px;
363
+ }
364
+
365
+ .ov-scope-switcher__option-text {
366
+ flex-direction: column;
367
+ flex: 1;
368
+ min-width: 0;
369
+ display: flex;
370
+ overflow: hidden;
371
+ }
372
+
373
+ .ov-scope-switcher__option-text > span {
374
+ text-overflow: ellipsis;
375
+ white-space: nowrap;
376
+ overflow: hidden;
377
+ }
378
+
379
+ .ov-scope-switcher__option-text small {
380
+ color: var(--ov-ui-color-text-3, var(--ov-ui-text-3-default, #6e718c));
381
+ text-overflow: ellipsis;
382
+ white-space: nowrap;
383
+ font-size: 12px;
384
+ line-height: 20px;
385
+ overflow: hidden;
386
+ }
387
+
388
+ .ov-scope-switcher__option[aria-selected="true"] .ov-scope-switcher__option-text > span {
389
+ font-weight: 500;
390
+ }
391
+
392
+ .ov-scope-switcher__option mark {
393
+ color: var(--ov-ui-color-primary, var(--ov-ui-primary-default, #5252ff));
394
+ background: none;
395
+ padding: 0;
396
+ }
397
+
398
+ .ov-scope-switcher__check {
399
+ width: 16px;
400
+ height: 16px;
401
+ color: var(--ov-ui-color-primary, var(--ov-ui-primary-default, #5252ff));
402
+ flex: 0 0 16px;
403
+ justify-content: center;
404
+ align-items: center;
405
+ display: inline-flex;
406
+ }
407
+
408
+ .ov-scope-switcher__state {
409
+ min-height: 88px;
410
+ color: var(--ov-ui-color-text-3, var(--ov-ui-text-3-default, #6e718c));
411
+ text-align: center;
412
+ flex: 1;
413
+ justify-content: center;
414
+ align-items: center;
415
+ padding: 12px;
416
+ font-size: 13px;
417
+ line-height: 22px;
418
+ display: flex;
419
+ }
420
+
421
+ .ov-scope-switcher button:disabled {
422
+ cursor: default;
423
+ }
424
+
425
+ .ov-scope-switcher__option[aria-disabled="true"] {
426
+ opacity: .5;
427
+ cursor: not-allowed;
428
+ }
429
+
430
+ .ov-scope-switcher :focus-visible {
431
+ outline: 2px solid
432
+ var(--ov-ui-color-primary, var(--ov-ui-primary-default, #5252ff));
433
+ outline-offset: 2px;
434
+ }
435
+
436
+ .ov-scope-switcher__trigger:focus-visible, .ov-scope-switcher__search:focus-visible {
437
+ outline: none;
438
+ }
439
+
440
+ .ov-scope-switcher__option:focus-visible {
441
+ outline-offset: -2px;
442
+ }
443
+
444
+ @media (width <= 600px) {
445
+ .ov-scope-switcher__panel, .ov-scope-switcher__level:last-child:not(:first-child) .ov-scope-switcher__panel {
446
+ width: auto;
447
+ max-height: 60dvh;
448
+ position: fixed;
449
+ inset: auto 16px 16px;
450
+ }
451
+ }
452
+
453
+
454
+
455
+
456
+
File without changes
@@ -0,0 +1,39 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import type { ScopeSwitcherLabels, ScopeSwitcherOption } from '../../components/scope-switcher/index.js';
3
+ export interface ScopeCascadeApi {
4
+ loadLibraries: (signal: AbortSignal) => Promise<readonly ScopeSwitcherOption[]>;
5
+ loadSpaces: (libraryId: string, signal: AbortSignal) => Promise<readonly ScopeSwitcherOption[]>;
6
+ loadUsers: (libraryId: string, spaceId: string, signal: AbortSignal) => Promise<readonly ScopeSwitcherOption[]>;
7
+ }
8
+ export type ScopeCascadeIndex = 0 | 1 | 2;
9
+ export interface ScopeCascadeSnapshot {
10
+ readonly options: readonly ScopeSwitcherOption[];
11
+ readonly selected?: ScopeSwitcherOption;
12
+ readonly enabled: boolean;
13
+ readonly loading: boolean;
14
+ readonly error: Error | null;
15
+ /** Changes only when ancestor identities change. */
16
+ readonly scopeKey: string;
17
+ /** Ancestor IDs in library / space order, available to downstream consumers. */
18
+ readonly parentIds: readonly string[];
19
+ }
20
+ export interface ScopeCascadeLevel {
21
+ getSnapshot: () => ScopeCascadeSnapshot;
22
+ subscribe: (listener: () => void) => () => void;
23
+ select: (option: ScopeSwitcherOption) => void;
24
+ refresh: () => void;
25
+ }
26
+ export interface ScopeCascadeController {
27
+ readonly levels: readonly [
28
+ ScopeCascadeLevel,
29
+ ScopeCascadeLevel,
30
+ ScopeCascadeLevel
31
+ ];
32
+ }
33
+ export interface ScopeCascadeProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
34
+ controller: ScopeCascadeController;
35
+ /** Accessible names and placeholders, in library / space / user order. */
36
+ levelNames?: readonly [string, string, string];
37
+ retryLabel?: string;
38
+ labels?: ScopeSwitcherLabels;
39
+ }
@@ -0,0 +1,5 @@
1
+ import type { ScopeCascadeApi, ScopeCascadeLevel } from './types.js';
2
+ /** Creates a stable coordinator without subscribing the caller to its data. */
3
+ export declare function useScopeCascade({ loadLibraries, loadSpaces, loadUsers, }: ScopeCascadeApi): import("./types.js").ScopeCascadeController;
4
+ /** Call in a leaf, never aggregate all three subscriptions in the root. */
5
+ export declare function useScopeCascadeLevel(level: ScopeCascadeLevel): import("./types.js").ScopeCascadeSnapshot;
@@ -0,0 +1 @@
1
+ export { ScopeCascade, useScopeCascade, useScopeCascadeLevel } from "../lk~0.js";