@openviking/react 0.1.4 → 0.1.6

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 (139) hide show
  1. package/README.md +15 -11
  2. package/dist/28~0.js +15 -0
  3. package/dist/2~0.js +6 -3
  4. package/dist/37~0.js +27 -0
  5. package/dist/3c~0.js +17 -9
  6. package/dist/3~0.js +4 -2
  7. package/dist/ae~0.js +6 -2
  8. package/dist/a~0.js +79 -72
  9. package/dist/ck~0.js +4 -0
  10. package/dist/client/paths.d.ts +4 -0
  11. package/dist/client/provider.d.ts +10 -6
  12. package/dist/components/agent-connect/agent-connect-code-block.d.ts +14 -0
  13. package/dist/components/agent-connect/agent-connect-copy.d.ts +3 -0
  14. package/dist/components/agent-connect/agent-connect-design.d.ts +1 -1
  15. package/dist/components/agent-connect/agent-connect-installer.d.ts +1 -0
  16. package/dist/components/agent-connect/agent-connect-instructions-view.d.ts +4 -6
  17. package/dist/components/agent-connect/agent-connect-instructions.d.ts +13 -0
  18. package/dist/components/agent-connect/agent-connect-markdown.d.ts +8 -2
  19. package/dist/components/agent-connect/agent-connect-mask.d.ts +10 -0
  20. package/dist/components/agent-connect/agent-connect.d.ts +1 -1
  21. package/dist/components/agent-connect/locales/en-US.d.ts +3 -0
  22. package/dist/components/agent-connect/style.css +163 -5
  23. package/dist/components/agent-connect/types.d.ts +5 -3
  24. package/dist/components/agent-connect/use-agent-connect-copy.d.ts +6 -0
  25. package/dist/components/directory-tour/style.css +46 -2
  26. package/dist/components/directory-tour/types.d.ts +2 -1
  27. package/dist/components/experience-dashboard/dashboard-tabs.d.ts +11 -0
  28. package/dist/components/experience-dashboard/experience-dashboard.d.ts +2 -0
  29. package/dist/components/experience-dashboard/experience-impact.d.ts +11 -0
  30. package/dist/components/experience-dashboard/experience-list.d.ts +9 -0
  31. package/dist/components/experience-dashboard/experience-pagination.d.ts +8 -0
  32. package/dist/components/experience-dashboard/experience-tests.d.ts +6 -0
  33. package/dist/components/experience-dashboard/experience-trajectories.d.ts +6 -0
  34. package/dist/components/experience-dashboard/index.d.ts +2 -0
  35. package/dist/components/experience-dashboard/labels.d.ts +2 -0
  36. package/dist/components/experience-dashboard/style.css +699 -0
  37. package/dist/components/experience-dashboard/style.js +0 -0
  38. package/dist/components/experience-dashboard/types.d.ts +106 -0
  39. package/dist/components/experience-dashboard.js +1 -0
  40. package/dist/components/file-browser-entries/file-browser-entries.d.ts +1 -1
  41. package/dist/components/file-browser-entries/style.css +259 -13
  42. package/dist/components/file-browser-entries/types.d.ts +2 -2
  43. package/dist/components/file-preview/style.css +48 -4
  44. package/dist/components/file-preview/types.d.ts +2 -2
  45. package/dist/components/file-tree/style.css +63 -4
  46. package/dist/components/file-tree/types.d.ts +2 -2
  47. package/dist/components/scope-switcher/scope-switcher.d.ts +2 -2
  48. package/dist/components/scope-switcher/style.css +48 -4
  49. package/dist/components/scope-switcher/types.d.ts +5 -5
  50. package/dist/components/scope-switcher.js +1 -1
  51. package/dist/components/style.css +2451 -139
  52. package/dist/components/tui/style.css +122 -36
  53. package/dist/components/tui/tui.d.ts +1 -1
  54. package/dist/components/tui/types.d.ts +2 -2
  55. package/dist/components/viking-bot/ark-message-list-view.d.ts +4 -1
  56. package/dist/components/viking-bot/interaction/types.d.ts +2 -2
  57. package/dist/components/viking-bot/interaction/viking-bot-interaction.d.ts +1 -1
  58. package/dist/components/viking-bot/session-actions.d.ts +2 -2
  59. package/dist/components/viking-bot/style.css +159 -12
  60. package/dist/components/viking-bot/types.d.ts +7 -7
  61. package/dist/components/viking-bot/viking-bot.d.ts +1 -1
  62. package/dist/components/wiki-dashboard/index.d.ts +2 -0
  63. package/dist/components/wiki-dashboard/labels.d.ts +2 -0
  64. package/dist/components/wiki-dashboard/style.css +741 -0
  65. package/dist/components/wiki-dashboard/style.js +0 -0
  66. package/dist/components/wiki-dashboard/types.d.ts +92 -0
  67. package/dist/components/wiki-dashboard/wiki-action-button.d.ts +9 -0
  68. package/dist/components/wiki-dashboard/wiki-conflict-card.d.ts +15 -0
  69. package/dist/components/wiki-dashboard/wiki-dashboard.d.ts +2 -0
  70. package/dist/components/wiki-dashboard/wiki-file-icon.d.ts +3 -0
  71. package/dist/components/wiki-dashboard/wiki-severity-filter.d.ts +8 -0
  72. package/dist/components/wiki-dashboard.js +1 -0
  73. package/dist/c~0.js +169 -155
  74. package/dist/e~0.js +3 -1
  75. package/dist/fi~0.js +354 -0
  76. package/dist/fj~0.js +503 -0
  77. package/dist/f~0.js +661 -309
  78. package/dist/icons/index.d.ts +28 -0
  79. package/dist/icons.js +1 -1
  80. package/dist/index.d.ts +4 -0
  81. package/dist/index.js +3 -1
  82. package/dist/k~0.js +277 -1
  83. package/dist/lk~0.js +55 -13
  84. package/dist/l~0.js +1096 -187
  85. package/dist/modules/console/console.d.ts +1 -1
  86. package/dist/modules/console/index.d.ts +1 -2
  87. package/dist/modules/console/style.css +377 -56
  88. package/dist/modules/console/types.d.ts +2 -2
  89. package/dist/modules/console/use-console.d.ts +1 -1
  90. package/dist/modules/console.js +1 -1
  91. package/dist/modules/file-browser/dashboard-data.d.ts +9 -0
  92. package/dist/modules/file-browser/dashboard-indicator.d.ts +8 -0
  93. package/dist/modules/file-browser/dashboard-labels.d.ts +9 -0
  94. package/dist/modules/file-browser/dashboard-model.d.ts +14 -0
  95. package/dist/modules/file-browser/dashboard-resource.d.ts +12 -0
  96. package/dist/modules/file-browser/experience-dashboard-pane.d.ts +8 -0
  97. package/dist/modules/file-browser/experience-data.d.ts +31 -0
  98. package/dist/modules/file-browser/file-browser-labels.d.ts +1 -1
  99. package/dist/modules/file-browser/file-browser-tree-pane.d.ts +3 -2
  100. package/dist/modules/file-browser/file-browser.d.ts +1 -1
  101. package/dist/modules/file-browser/fs-directories.d.ts +8 -0
  102. package/dist/modules/file-browser/fs-lines.d.ts +36 -0
  103. package/dist/modules/file-browser/fs-memory-fields.d.ts +65 -0
  104. package/dist/modules/file-browser/fs-model.d.ts +12 -2
  105. package/dist/modules/file-browser/fs-read-file.d.ts +14 -0
  106. package/dist/modules/file-browser/fs-selection.d.ts +4 -0
  107. package/dist/modules/file-browser/index.d.ts +2 -2
  108. package/dist/modules/file-browser/style.css +1883 -25
  109. package/dist/modules/file-browser/types.d.ts +64 -2
  110. package/dist/modules/file-browser/use-browser-dashboards.d.ts +31 -0
  111. package/dist/modules/file-browser/use-dashboard-query.d.ts +9 -0
  112. package/dist/modules/file-browser/use-experience-dashboard.d.ts +27 -0
  113. package/dist/modules/file-browser/use-file-browser.d.ts +2 -45
  114. package/dist/modules/file-browser/use-fs-tree.d.ts +2 -0
  115. package/dist/modules/file-browser/use-wiki-dashboard.d.ts +17 -0
  116. package/dist/modules/file-browser/wiki-conflicts.d.ts +12 -0
  117. package/dist/modules/file-browser/wiki-dashboard-pane.d.ts +14 -0
  118. package/dist/modules/file-browser.js +1 -1
  119. package/dist/modules/scope-cascade/controller.d.ts +2 -2
  120. package/dist/modules/scope-cascade/index.d.ts +1 -2
  121. package/dist/modules/scope-cascade/scope-cascade.d.ts +2 -2
  122. package/dist/modules/scope-cascade/style.css +48 -4
  123. package/dist/modules/scope-cascade/types.d.ts +9 -4
  124. package/dist/modules/scope-cascade/use-scope-cascade.d.ts +2 -2
  125. package/dist/modules/scope-cascade.js +1 -1
  126. package/dist/modules/style.css +2459 -192
  127. package/dist/n~0.js +16 -130
  128. package/dist/rt~0.js +152 -0
  129. package/dist/r~0.js +17 -38
  130. package/dist/shared/components/popover/popover.d.ts +1 -1
  131. package/dist/shared/components/popover/types.d.ts +7 -1
  132. package/dist/shared/dashboard/dashboard-state.d.ts +12 -0
  133. package/dist/shared/locale-context.d.ts +8 -0
  134. package/dist/static/image/dashboard-background.png +0 -0
  135. package/dist/style.css +9445 -4822
  136. package/dist/u~0.js +324 -96
  137. package/dist/viking-bot-composer~0.js +4 -2
  138. package/dist/viking-bot-interaction~0.js +3 -1
  139. package/package.json +14 -2
package/dist/n~0.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { cloneElement, forwardRef, useCallback, useEffect, useId, useImperativeHandle, useRef, useState } from "react";
3
- import { createPortal } from "react-dom";
2
+ import { forwardRef, useImperativeHandle, useRef, useState } from "react";
4
3
  import { resolveLocale, mergeLabels } from "./nx~0.js";
5
4
  import { FolderOpenIcon, FolderIcon, ChevronRightIcon, DocumentIcon } from "./k~0.js";
6
- import { useOverlayPosition } from "./o~0.js";
5
+ import { Popover } from "./r~0.js";
7
6
  import { searchreact } from "./p~0.js";
7
+ import { useLocale } from "./28~0.js";
8
8
  const messages = {
9
9
  search: 'Search files…',
10
10
  refresh: 'Refresh file tree',
@@ -277,131 +277,6 @@ function resolveInfoCopy(key, hostLabels) {
277
277
  triggerBehavior: triggerBehavior || void 0
278
278
  };
279
279
  }
280
- function useMergedRef(ref, target) {
281
- return useCallback((node)=>{
282
- target.current = node;
283
- if ('function' == typeof ref) ref(node);
284
- else if (ref) ref.current = node;
285
- }, [
286
- ref,
287
- target
288
- ]);
289
- }
290
- function Popover({ children, content, placement = 'right', trigger = 'hover', delay = 300, disabled = false, className, style, onOpenChange }) {
291
- const [open, setOpen] = useState(false);
292
- const triggerRef = useRef(null);
293
- const timerRef = useRef(void 0);
294
- const [surfaceNode, setSurfaceNode] = useState(null);
295
- const id = useId();
296
- const position = useOverlayPosition(open, triggerRef, surfaceNode, placement);
297
- const change = useCallback((next)=>{
298
- setOpen(next);
299
- onOpenChange?.(next);
300
- }, [
301
- onOpenChange
302
- ]);
303
- const clearTimer = useCallback(()=>{
304
- if (void 0 !== timerRef.current) {
305
- window.clearTimeout(timerRef.current);
306
- timerRef.current = void 0;
307
- }
308
- }, []);
309
- useEffect(()=>clearTimer, [
310
- clearTimer
311
- ]);
312
- useEffect(()=>{
313
- if (disabled) {
314
- clearTimer();
315
- setOpen(false);
316
- }
317
- }, [
318
- disabled,
319
- clearTimer
320
- ]);
321
- useEffect(()=>{
322
- if (!open || 'click' !== trigger) return;
323
- const onPointerDown = (event)=>{
324
- const target = event.target;
325
- if (surfaceNode?.contains(target) || triggerRef.current?.contains(target)) return;
326
- change(false);
327
- };
328
- const onKeyDown = (event)=>{
329
- if ('Escape' === event.key) change(false);
330
- };
331
- document.addEventListener('mousedown', onPointerDown);
332
- document.addEventListener('keydown', onKeyDown);
333
- return ()=>{
334
- document.removeEventListener('mousedown', onPointerDown);
335
- document.removeEventListener('keydown', onKeyDown);
336
- };
337
- }, [
338
- change,
339
- open,
340
- surfaceNode,
341
- trigger
342
- ]);
343
- const show = ()=>{
344
- if (disabled) return;
345
- if ('click' === trigger) return void change(!open);
346
- clearTimer();
347
- timerRef.current = window.setTimeout(()=>{
348
- change(true);
349
- timerRef.current = void 0;
350
- }, delay);
351
- };
352
- const hide = ()=>{
353
- if ('click' === trigger) return;
354
- clearTimer();
355
- change(false);
356
- };
357
- const child = children;
358
- const childProps = child.props;
359
- const childRef = child.ref;
360
- const mergedRef = useMergedRef(childRef, triggerRef);
361
- const declaresExpanded = 'aria-expanded' in childProps;
362
- const triggerElement = /*#__PURE__*/ cloneElement(child, {
363
- ref: mergedRef,
364
- ...declaresExpanded ? {} : {
365
- 'aria-expanded': open
366
- },
367
- onMouseEnter: (event)=>{
368
- childProps.onMouseEnter?.(event);
369
- if ('hover' === trigger) show();
370
- },
371
- onMouseLeave: (event)=>{
372
- childProps.onMouseLeave?.(event);
373
- if ('hover' === trigger) hide();
374
- },
375
- onClick: (event)=>{
376
- childProps.onClick?.(event);
377
- if ('click' === trigger) show();
378
- }
379
- });
380
- const surface = open ? /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
381
- ref: setSurfaceNode,
382
- id: id,
383
- role: 'click' === trigger ? 'dialog' : 'note',
384
- className: [
385
- 'ov-popover',
386
- className
387
- ].filter(Boolean).join(' '),
388
- "data-placement": position.placement,
389
- style: {
390
- top: position.top,
391
- left: position.left,
392
- ...style
393
- },
394
- onMouseEnter: 'hover' === trigger ? clearTimer : void 0,
395
- onMouseLeave: 'hover' === trigger ? hide : void 0,
396
- children: content
397
- }), document.body) : null;
398
- return /*#__PURE__*/ jsxs(Fragment, {
399
- children: [
400
- triggerElement,
401
- surface
402
- ]
403
- });
404
- }
405
280
  const DEFAULT_FIELDS = {
406
281
  description: "Description",
407
282
  triggerBehavior: 'Trigger',
@@ -508,6 +383,7 @@ function Guides({ depth }) {
508
383
  }
509
384
  const FILE_TREE_ROW_ATTRIBUTE = 'data-file-tree-row-id';
510
385
  function FileTreeRowView({ row, ctx }) {
386
+ const anchorRef = useRef(null);
511
387
  const { text, selectedId, getRowAttributes, renderDashboard, renderRowTooltip, renderRowIcon, onSelect, onToggleExpand, onOpenRetentionSettings, onRowKeyDown } = ctx;
512
388
  const isDirectory = 'directory' === row.type;
513
389
  const canExpand = isDirectory && false !== row.hasChildren;
@@ -613,7 +489,15 @@ function FileTreeRowView({ row, ctx }) {
613
489
  dashboard ? /*#__PURE__*/ jsx("span", {
614
490
  className: "ov-file-tree__dashboard",
615
491
  children: dashboard
616
- }) : null
492
+ }) : null,
493
+ /*#__PURE__*/ jsx("span", {
494
+ className: "ov-file-tree__popover-anchor-container",
495
+ "aria-hidden": "true",
496
+ children: /*#__PURE__*/ jsx("span", {
497
+ ref: anchorRef,
498
+ className: "ov-file-tree__popover-anchor"
499
+ })
500
+ })
617
501
  ]
618
502
  });
619
503
  const custom = renderRowTooltip?.(row);
@@ -627,6 +511,7 @@ function FileTreeRowView({ row, ctx }) {
627
511
  return /*#__PURE__*/ jsx(Popover, {
628
512
  content: tooltipContent,
629
513
  placement: "right",
514
+ anchorRef: anchorRef,
630
515
  trigger: "hover",
631
516
  children: rowNode
632
517
  });
@@ -904,7 +789,8 @@ function FileTreeSpinner({ className, ...rest }) {
904
789
  function findRow(root, id) {
905
790
  return root?.querySelector(`[${FILE_TREE_ROW_ATTRIBUTE}="${CSS.escape(id)}"]`) ?? null;
906
791
  }
907
- const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, locale, operations, selectedId, search, refresh, isReady = true, loadingFallback, errorFallback, emptyFallback, slots, labels, getRowAttributes, renderDashboard, renderRowTooltip, renderRowIcon, onSelect, onToggleExpand, onLoadMore, onRetry, onOpenRetentionSettings, onSearch, onRefresh, className, ...rest }, ref) {
792
+ const file_tree_FileTree = /*#__PURE__*/ forwardRef(function({ rows, locale: localeProp, operations, selectedId, search, refresh, isReady = true, loadingFallback, errorFallback, emptyFallback, slots, labels, getRowAttributes, renderDashboard, renderRowTooltip, renderRowIcon, onSelect, onToggleExpand, onLoadMore, onRetry, onOpenRetentionSettings, onSearch, onRefresh, className, ...rest }, ref) {
793
+ const locale = useLocale(localeProp);
908
794
  const rootRef = useRef(null);
909
795
  const text = resolveFileTreeLabels(locale, labels);
910
796
  const actions = useFileTreeActions({
package/dist/rt~0.js ADDED
@@ -0,0 +1,152 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { cloneElement, useCallback, useEffect, useId, useRef, useState } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { useOverlayPosition } from "./o~0.js";
5
+ const DEFAULT_LABELS = {
6
+ close: 'Close'
7
+ };
8
+ function useMergedRef(ref, target) {
9
+ const merged = useCallback((node)=>{
10
+ target.current = node;
11
+ if ('function' == typeof ref) ref(node);
12
+ else if (ref) ref.current = node;
13
+ }, [
14
+ ref,
15
+ target
16
+ ]);
17
+ return merged;
18
+ }
19
+ function Tooltip({ children, content, placement = 'top', trigger = 'hover', delay = 300, disabled = false, className, style, onOpenChange, labels }) {
20
+ const text = {
21
+ ...DEFAULT_LABELS,
22
+ ...labels
23
+ };
24
+ const [open, setOpen] = useState(false);
25
+ const triggerRef = useRef(null);
26
+ const timerRef = useRef(void 0);
27
+ const [surfaceNode, setSurfaceNode] = useState(null);
28
+ const id = useId();
29
+ const position = useOverlayPosition(open, triggerRef, surfaceNode, placement);
30
+ const change = useCallback((next)=>{
31
+ setOpen(next);
32
+ onOpenChange?.(next);
33
+ }, [
34
+ onOpenChange
35
+ ]);
36
+ const clearTimer = useCallback(()=>{
37
+ if (void 0 !== timerRef.current) {
38
+ window.clearTimeout(timerRef.current);
39
+ timerRef.current = void 0;
40
+ }
41
+ }, []);
42
+ useEffect(()=>clearTimer, [
43
+ clearTimer
44
+ ]);
45
+ useEffect(()=>{
46
+ if (disabled) {
47
+ clearTimer();
48
+ setOpen(false);
49
+ }
50
+ }, [
51
+ disabled,
52
+ clearTimer
53
+ ]);
54
+ useEffect(()=>{
55
+ if (!open) return;
56
+ const onPointerDown = (event)=>{
57
+ const target = event.target;
58
+ if (surfaceNode?.contains(target) || triggerRef.current?.contains(target)) return;
59
+ change(false);
60
+ };
61
+ const onKeyDown = (event)=>{
62
+ if ('Escape' === event.key) {
63
+ clearTimer();
64
+ change(false);
65
+ }
66
+ };
67
+ if ('click' === trigger) document.addEventListener('mousedown', onPointerDown);
68
+ document.addEventListener('keydown', onKeyDown);
69
+ return ()=>{
70
+ if ('click' === trigger) document.removeEventListener('mousedown', onPointerDown);
71
+ document.removeEventListener('keydown', onKeyDown);
72
+ };
73
+ }, [
74
+ change,
75
+ clearTimer,
76
+ open,
77
+ surfaceNode,
78
+ trigger
79
+ ]);
80
+ const show = ()=>{
81
+ if (disabled) return;
82
+ if ('click' === trigger) return void change(!open);
83
+ clearTimer();
84
+ timerRef.current = window.setTimeout(()=>{
85
+ change(true);
86
+ timerRef.current = void 0;
87
+ }, delay);
88
+ };
89
+ const hide = ()=>{
90
+ if ('click' === trigger) return;
91
+ clearTimer();
92
+ timerRef.current = window.setTimeout(()=>{
93
+ change(false);
94
+ timerRef.current = void 0;
95
+ }, 120);
96
+ };
97
+ const child = children;
98
+ const childProps = child.props;
99
+ const childRef = child.ref;
100
+ const mergedRef = useMergedRef(childRef, triggerRef);
101
+ const triggerElement = /*#__PURE__*/ cloneElement(child, {
102
+ ref: mergedRef,
103
+ 'aria-describedby': open && 'hover' === trigger ? id : void 0,
104
+ 'aria-expanded': 'click' === trigger ? open : childProps['aria-expanded'],
105
+ onMouseEnter: (event)=>{
106
+ childProps.onMouseEnter?.(event);
107
+ if ('hover' === trigger) show();
108
+ },
109
+ onMouseLeave: (event)=>{
110
+ childProps.onMouseLeave?.(event);
111
+ if ('hover' === trigger) hide();
112
+ },
113
+ onFocus: (event)=>{
114
+ childProps.onFocus?.(event);
115
+ if ('hover' === trigger) show();
116
+ },
117
+ onBlur: (event)=>{
118
+ childProps.onBlur?.(event);
119
+ hide();
120
+ },
121
+ onClick: (event)=>{
122
+ childProps.onClick?.(event);
123
+ if ('click' === trigger) show();
124
+ }
125
+ });
126
+ const surface = open ? /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
127
+ ref: setSurfaceNode,
128
+ id: id,
129
+ role: 'hover' === trigger ? 'tooltip' : 'dialog',
130
+ "aria-label": 'click' === trigger ? text.close : void 0,
131
+ className: [
132
+ 'ov-tooltip',
133
+ className
134
+ ].filter(Boolean).join(' '),
135
+ "data-placement": position.placement,
136
+ style: {
137
+ top: position.top,
138
+ left: position.left,
139
+ ...style
140
+ },
141
+ onMouseEnter: 'hover' === trigger ? clearTimer : void 0,
142
+ onMouseLeave: 'hover' === trigger ? hide : void 0,
143
+ children: content
144
+ }), document.body) : null;
145
+ return /*#__PURE__*/ jsxs(Fragment, {
146
+ children: [
147
+ triggerElement,
148
+ surface
149
+ ]
150
+ });
151
+ }
152
+ export { Tooltip };
package/dist/r~0.js CHANGED
@@ -2,11 +2,8 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cloneElement, useCallback, useEffect, useId, useRef, useState } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { useOverlayPosition } from "./o~0.js";
5
- const DEFAULT_LABELS = {
6
- close: 'Close'
7
- };
8
5
  function useMergedRef(ref, target) {
9
- const merged = useCallback((node)=>{
6
+ return useCallback((node)=>{
10
7
  target.current = node;
11
8
  if ('function' == typeof ref) ref(node);
12
9
  else if (ref) ref.current = node;
@@ -14,19 +11,15 @@ function useMergedRef(ref, target) {
14
11
  ref,
15
12
  target
16
13
  ]);
17
- return merged;
18
14
  }
19
- function Tooltip({ children, content, placement = 'top', trigger = 'hover', delay = 300, disabled = false, className, style, onOpenChange, labels }) {
20
- const text = {
21
- ...DEFAULT_LABELS,
22
- ...labels
23
- };
24
- const [open, setOpen] = useState(false);
15
+ function Popover({ children, content, placement = 'right', anchorRef, trigger = 'hover', delay = 300, open: controlledOpen, role, disabled = false, className, style, onOpenChange }) {
16
+ const [localOpen, setOpen] = useState(false);
17
+ const open = !disabled && (controlledOpen ?? localOpen);
25
18
  const triggerRef = useRef(null);
26
19
  const timerRef = useRef(void 0);
27
20
  const [surfaceNode, setSurfaceNode] = useState(null);
28
21
  const id = useId();
29
- const position = useOverlayPosition(open, triggerRef, surfaceNode, placement);
22
+ const position = useOverlayPosition(open, anchorRef ?? triggerRef, surfaceNode, placement);
30
23
  const change = useCallback((next)=>{
31
24
  setOpen(next);
32
25
  onOpenChange?.(next);
@@ -52,27 +45,23 @@ function Tooltip({ children, content, placement = 'top', trigger = 'hover', dela
52
45
  clearTimer
53
46
  ]);
54
47
  useEffect(()=>{
55
- if (!open) return;
48
+ if (!open || 'click' !== trigger) return;
56
49
  const onPointerDown = (event)=>{
57
50
  const target = event.target;
58
51
  if (surfaceNode?.contains(target) || triggerRef.current?.contains(target)) return;
59
52
  change(false);
60
53
  };
61
54
  const onKeyDown = (event)=>{
62
- if ('Escape' === event.key) {
63
- clearTimer();
64
- change(false);
65
- }
55
+ if ('Escape' === event.key) change(false);
66
56
  };
67
- if ('click' === trigger) document.addEventListener('mousedown', onPointerDown);
57
+ document.addEventListener('mousedown', onPointerDown);
68
58
  document.addEventListener('keydown', onKeyDown);
69
59
  return ()=>{
70
- if ('click' === trigger) document.removeEventListener('mousedown', onPointerDown);
60
+ document.removeEventListener('mousedown', onPointerDown);
71
61
  document.removeEventListener('keydown', onKeyDown);
72
62
  };
73
63
  }, [
74
64
  change,
75
- clearTimer,
76
65
  open,
77
66
  surfaceNode,
78
67
  trigger
@@ -89,19 +78,18 @@ function Tooltip({ children, content, placement = 'top', trigger = 'hover', dela
89
78
  const hide = ()=>{
90
79
  if ('click' === trigger) return;
91
80
  clearTimer();
92
- timerRef.current = window.setTimeout(()=>{
93
- change(false);
94
- timerRef.current = void 0;
95
- }, 120);
81
+ change(false);
96
82
  };
97
83
  const child = children;
98
84
  const childProps = child.props;
99
85
  const childRef = child.ref;
100
86
  const mergedRef = useMergedRef(childRef, triggerRef);
87
+ const declaresExpanded = 'aria-expanded' in childProps;
101
88
  const triggerElement = /*#__PURE__*/ cloneElement(child, {
102
89
  ref: mergedRef,
103
- 'aria-describedby': open && 'hover' === trigger ? id : void 0,
104
- 'aria-expanded': 'click' === trigger ? open : childProps['aria-expanded'],
90
+ ...declaresExpanded ? {} : {
91
+ 'aria-expanded': open
92
+ },
105
93
  onMouseEnter: (event)=>{
106
94
  childProps.onMouseEnter?.(event);
107
95
  if ('hover' === trigger) show();
@@ -110,14 +98,6 @@ function Tooltip({ children, content, placement = 'top', trigger = 'hover', dela
110
98
  childProps.onMouseLeave?.(event);
111
99
  if ('hover' === trigger) hide();
112
100
  },
113
- onFocus: (event)=>{
114
- childProps.onFocus?.(event);
115
- if ('hover' === trigger) show();
116
- },
117
- onBlur: (event)=>{
118
- childProps.onBlur?.(event);
119
- hide();
120
- },
121
101
  onClick: (event)=>{
122
102
  childProps.onClick?.(event);
123
103
  if ('click' === trigger) show();
@@ -126,10 +106,9 @@ function Tooltip({ children, content, placement = 'top', trigger = 'hover', dela
126
106
  const surface = open ? /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx("div", {
127
107
  ref: setSurfaceNode,
128
108
  id: id,
129
- role: 'hover' === trigger ? 'tooltip' : 'dialog',
130
- "aria-label": 'click' === trigger ? text.close : void 0,
109
+ role: role ?? ('click' === trigger ? 'dialog' : 'note'),
131
110
  className: [
132
- 'ov-tooltip',
111
+ 'ov-popover',
133
112
  className
134
113
  ].filter(Boolean).join(' '),
135
114
  "data-placement": position.placement,
@@ -149,4 +128,4 @@ function Tooltip({ children, content, placement = 'top', trigger = 'hover', dela
149
128
  ]
150
129
  });
151
130
  }
152
- export { Tooltip };
131
+ export { Popover };
@@ -20,4 +20,4 @@ export type { PopoverPlacement, PopoverProps, PopoverTrigger, } from './types.js
20
20
  * tooltip is one dark line, a popover is a white card. What they share — the
21
21
  * portal, positioning and theme-variable syncing — lives in `overlay/`.
22
22
  */
23
- export declare function Popover({ children, content, placement, trigger, delay, disabled, className, style, onOpenChange, }: PopoverProps): import("react").JSX.Element;
23
+ export declare function Popover({ children, content, placement, anchorRef, trigger, delay, open: controlledOpen, role, disabled, className, style, onOpenChange, }: PopoverProps): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import type { OverlayPlacement } from '../overlay/types.js';
2
- import type { CSSProperties, ReactElement, ReactNode } from 'react';
2
+ import type { AriaRole, CSSProperties, ReactElement, ReactNode, RefObject } from 'react';
3
3
  /**
4
4
  * 弹出层的方位,与提示共用一套取值。空间不足时自动翻到对侧。
5
5
  * Where the popover sits relative to its trigger, sharing the tooltip's values.
@@ -35,10 +35,16 @@ export interface PopoverProps {
35
35
  content: ReactNode;
36
36
  /** 方位,默认 `right`——内容在行尾展开,不遮挡左侧。 Placement, `right` by default. */
37
37
  placement?: PopoverPlacement;
38
+ /** 可选的定位元素,触发事件仍在 children 上。 Optional anchor; children still handle the trigger. */
39
+ anchorRef?: RefObject<HTMLElement | null>;
38
40
  /** 触发方式,默认 `hover`。 Trigger mode, `hover` by default. */
39
41
  trigger?: PopoverTrigger;
40
42
  /** 悬停后多久展示,单位毫秒。延迟只作用于 `hover`。 Hover delay in ms; `hover` only. */
41
43
  delay?: number;
44
+ /** Controlled visibility; omitted values use instance-local state. */
45
+ open?: boolean;
46
+ /** Surface semantics; defaults to dialog for click and note for hover. */
47
+ role?: AriaRole;
42
48
  /** 为真时不展示浮层。 Suppresses the surface; the trigger still renders. */
43
49
  disabled?: boolean;
44
50
  /** 浮层容器的额外类名。 Extra class names for the surface. */
@@ -0,0 +1,12 @@
1
+ export interface DashboardStatus {
2
+ loading?: boolean;
3
+ error?: Error | null;
4
+ onRetry?: () => void;
5
+ }
6
+ export declare function DashboardState({ state, empty, loading, failed, retry, }: {
7
+ state?: DashboardStatus;
8
+ empty: string;
9
+ loading: string;
10
+ failed: string;
11
+ retry: string;
12
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { Locale } from './locale.js';
3
+ /** A local prop overrides the nearest language scope without changing requests. */
4
+ export declare function useLocale(locale?: Locale): Locale;
5
+ export declare function LocaleProvider({ locale, children, }: {
6
+ locale?: Locale;
7
+ children?: ReactNode;
8
+ }): import("react").JSX.Element;