@qilin-agent/client-ui-primitives 3.1.6 → 3.1.8

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 (63) hide show
  1. package/README.i18n.yaml +8 -8
  2. package/README.md +11 -4
  3. package/README.zh.md +12 -4
  4. package/lib/AnimatedRows.module.css +7 -0
  5. package/lib/Button.module.css +6 -3
  6. package/lib/DetailDocument.module.css +67 -0
  7. package/lib/HoverCard.module.css +3 -3
  8. package/lib/ImageLightbox.module.css +1 -1
  9. package/lib/InlineEditor.module.css +1 -1
  10. package/lib/Input.module.css +2 -2
  11. package/lib/Menu.module.css +127 -78
  12. package/lib/MenuSurface.module.css +23 -7
  13. package/lib/QuotePreview.module.css +89 -0
  14. package/lib/RowDragPreview.module.css +12 -0
  15. package/lib/SegmentedTabs.module.css +4 -1
  16. package/lib/Tag.module.css +1 -1
  17. package/lib/TerminalBlock.module.css +1 -1
  18. package/lib/Toast.module.css +28 -0
  19. package/lib/Tooltip.module.css +18 -3
  20. package/lib/UserMessageBubble.module.css +11 -0
  21. package/lib/index.js +4919 -2423
  22. package/lib/markdown/CodeBlock.module.css +23 -0
  23. package/lib/markdown/JsonBlock.module.css +1 -1
  24. package/lib/markdown/MarkdownText.module.css +11 -7
  25. package/lib/settings-form/fields.module.css +2 -2
  26. package/lib/types/AnimatedRows.d.ts +46 -0
  27. package/lib/types/Button.d.ts +13 -4
  28. package/lib/types/DetailDocument.d.ts +79 -0
  29. package/lib/types/ImageLightbox.d.ts +3 -1
  30. package/lib/types/LinkIcon.d.ts +15 -30
  31. package/lib/types/Menu.d.ts +30 -9
  32. package/lib/types/MenuSurface.d.ts +9 -0
  33. package/lib/types/PermissionIcon.d.ts +51 -0
  34. package/lib/types/QuotePreview.d.ts +26 -0
  35. package/lib/types/ReferenceIcon.d.ts +12 -7
  36. package/lib/types/SegmentedTabs.d.ts +3 -1
  37. package/lib/types/SiteGlyph.d.ts +1 -1
  38. package/lib/types/Toast.d.ts +19 -1
  39. package/lib/types/Tooltip.d.ts +36 -21
  40. package/lib/types/UserMessageBubble.d.ts +11 -0
  41. package/lib/types/code-file-types.d.ts +1 -1
  42. package/lib/types/code-highlighting.d.ts +12 -0
  43. package/lib/types/focus.d.ts +8 -0
  44. package/lib/types/icons/index.d.ts +405 -216
  45. package/lib/types/icons/props.d.ts +1 -1
  46. package/lib/types/icons/shared-artwork.d.ts +44 -0
  47. package/lib/types/index.d.ts +23 -6
  48. package/lib/types/markdown/MarkdownDelegate.d.ts +19 -2
  49. package/lib/types/markdown/MarkdownText.d.ts +3 -1
  50. package/lib/types/markdown/file-link.d.ts +13 -3
  51. package/lib/types/markdown/mathCompatibility.d.ts +12 -5
  52. package/lib/types/markdown/render.d.ts +2 -1
  53. package/lib/types/markdown/windows-path-destinations.d.ts +12 -0
  54. package/lib/types/motion.d.ts +13 -0
  55. package/lib/types/overlay-top-margin.d.ts +10 -2
  56. package/lib/types/quote-text.d.ts +69 -0
  57. package/lib/types/tooltip-placement.d.ts +35 -0
  58. package/lib/types/use-clipboard-copy.d.ts +14 -0
  59. package/lib/types/useAnchoredPosition.d.ts +31 -18
  60. package/lib/types/useRowDragPreview.d.ts +20 -0
  61. package/lib/types/user-text.d.ts +24 -2
  62. package/package.json +8 -6
  63. package/lib/types/use-copy-feedback.d.ts +0 -14
@@ -104,6 +104,29 @@
104
104
  color: var(--qilin-alias-label-primary);
105
105
  }
106
106
 
107
+ /* Line-level hover: the source line under the pointer takes the interactive
108
+ wash so a reader can follow one line across a wide block. The rule paints a
109
+ background only — selection, the copy button's textContent read, and the
110
+ gutter's counters are untouched. Shiki, the plain arm, and the streaming arm
111
+ all emit one `span.line` per source line, so the selector covers every arm. */
112
+ .block :where(pre) code > :global(.line) {
113
+ border-radius: 4px;
114
+ transition: background-color 120ms ease;
115
+ }
116
+
117
+ @media (hover: hover) {
118
+ .block :where(pre) code > :global(.line):hover {
119
+ background-color: var(--qilin-alias-interactive-bg-hover);
120
+ }
121
+ }
122
+
123
+ /* A reader who asked for less motion gets the wash without the fade. */
124
+ @media (prefers-reduced-motion: reduce) {
125
+ .block :where(pre) code > :global(.line) {
126
+ transition: none;
127
+ }
128
+ }
129
+
107
130
  .numbered :where(pre) code {
108
131
  display: block;
109
132
  counter-reset: source-line;
@@ -23,7 +23,7 @@
23
23
  max-height: 200px;
24
24
  overflow: auto;
25
25
  background: var(--qilin-alias-markdown-code-block);
26
- border: 0.5px solid var(--qilin-alias-border-l1);
26
+ border: 1px solid var(--qilin-alias-border-l1);
27
27
  border-radius: 6px;
28
28
  font-family: var(--ds-font-family-code);
29
29
  font-size: 11px;
@@ -143,7 +143,7 @@
143
143
  .markdown hr {
144
144
  display: block;
145
145
  border: none;
146
- height: 0.5px;
146
+ height: 1px;
147
147
  margin: 32px 0;
148
148
  background: var(--qilin-alias-border-l2);
149
149
  }
@@ -168,7 +168,7 @@
168
168
  font-family: var(--ds-font-family-code);
169
169
  font-size: 0.875em !important;
170
170
  background-color: var(--qilin-alias-markdown-inline-code);
171
- border: 0.5px solid var(--qilin-alias-border-l1);
171
+ border: 1px solid var(--qilin-alias-border-l1);
172
172
  border-radius: 6px;
173
173
  padding: 0 5px;
174
174
  }
@@ -244,7 +244,7 @@
244
244
  .tableScroll th {
245
245
  text-align: start;
246
246
  padding: 10px 16px;
247
- border-bottom: 0.5px solid var(--qilin-alias-border-l3);
247
+ border-bottom: 1px solid var(--qilin-alias-border-l3);
248
248
  border-top: none;
249
249
  font: var(--qilin-font-markdown-table-head);
250
250
  max-width: 320px;
@@ -254,7 +254,7 @@
254
254
 
255
255
  .tableScroll td {
256
256
  padding: 10px 16px;
257
- border-bottom: 0.5px solid var(--qilin-alias-border-l2);
257
+ border-bottom: 1px solid var(--qilin-alias-border-l2);
258
258
  font: var(--qilin-font-markdown-table);
259
259
  max-width: 320px;
260
260
  max-width: min(30vw, 320px);
@@ -305,10 +305,14 @@
305
305
  on hover/focus. An underline at rest reads badly inside the code chip, where
306
306
  it collides with monospace descenders and the pill background. */
307
307
  .fileMention {
308
- margin: 0;
309
- padding: 0;
308
+ /* A mention of a file the agent produced highlights its code chip: the
309
+ negative margins fill the chip's own padding so the accent pill covers
310
+ the whole chip rather than nesting inside it. */
311
+ margin: 0 -5px;
312
+ padding: 0 5px;
310
313
  border: none;
311
- background: none;
314
+ border-radius: 6px;
315
+ background: var(--qilin-specific-bubble-highlight);
312
316
  font: inherit;
313
317
  font-weight: 500;
314
318
  color: var(--qilin-alias-link);
@@ -8,7 +8,7 @@
8
8
  }
9
9
 
10
10
  .field + .field {
11
- border-top: 0.5px solid var(--qilin-alias-border-l2);
11
+ border-top: 1px solid var(--qilin-alias-border-l2);
12
12
  }
13
13
 
14
14
  .head {
@@ -107,7 +107,7 @@
107
107
  .input {
108
108
  height: 34px;
109
109
  padding: 0 12px;
110
- border: 0.5px solid var(--qilin-alias-border-l4);
110
+ border: 1px solid var(--qilin-alias-border-l4);
111
111
  border-radius: var(--qilin-radius-md);
112
112
  background: var(--qilin-alias-bg-layer-3);
113
113
  font: inherit;
@@ -0,0 +1,46 @@
1
+ /** React-commit-driven movement and entry/exit fades for keyed rows. */
2
+ import { Component, type AriaRole, type ReactNode } from 'react';
3
+ /** Keyed row content, list semantics, and animation readiness. */
4
+ export interface AnimatedRowsProps {
5
+ children: ReactNode;
6
+ className: string;
7
+ role?: AriaRole;
8
+ label?: string;
9
+ /** Unique DOM-order keys matching the rendered data-row-key attributes. */
10
+ rowKeys: readonly string[];
11
+ ready: boolean;
12
+ /** Changes that replace the view or reveal hidden rows settle immediately. */
13
+ resetKey: string;
14
+ }
15
+ interface RowPosition {
16
+ element: HTMLElement;
17
+ rect: DOMRect;
18
+ opacity: number;
19
+ }
20
+ interface RowSnapshot {
21
+ positions: Map<string, RowPosition>;
22
+ removed: Map<string, RowPosition>;
23
+ }
24
+ /**
25
+ * Animates keyed rows only when their rendered membership or order changes.
26
+ * Motion starts after the first pointer or keyboard input inside the mounted list.
27
+ * The parent supplies a positioned container for the inert exit overlay.
28
+ */
29
+ export declare class AnimatedRows extends Component<AnimatedRowsProps> {
30
+ private armed;
31
+ private readonly list;
32
+ private readonly overlay;
33
+ private readonly movements;
34
+ private readonly exits;
35
+ getSnapshotBeforeUpdate(previous: AnimatedRowsProps): RowSnapshot | null;
36
+ componentDidUpdate(previous: AnimatedRowsProps, _state: unknown, snapshot: RowSnapshot | null): void;
37
+ componentWillUnmount(): void;
38
+ private readPositions;
39
+ private move;
40
+ private cancelMovements;
41
+ private removeExit;
42
+ private clear;
43
+ render(): ReactNode;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=AnimatedRows.d.ts.map
@@ -1,18 +1,27 @@
1
- import type { ButtonHTMLAttributes, ReactNode } from 'react';
1
+ import { type ButtonHTMLAttributes, type ReactNode } from 'react';
2
2
  /** Visual variant, each backed by its --qilin-alias-button-* token family. */
3
3
  export type ButtonVariant = 'primary' | 'ghost' | 'outline' | 'toolbar';
4
+ /** Props accepted by {@link Button}. */
5
+ export type ButtonProps = {
6
+ variant?: ButtonVariant;
7
+ size?: 'md' | 'sm';
8
+ icon?: ReactNode;
9
+ className?: string | undefined;
10
+ children?: ReactNode;
11
+ } & ButtonHTMLAttributes<HTMLButtonElement>;
4
12
  /**
5
13
  * Render a button.
6
14
  * @param props.variant - visual family (default 'ghost').
7
15
  * @param props.size - 'md' 36px capsule (figma Button) or 'sm' 28px compact.
8
16
  * @param props.icon - optional leading 16px icon node.
17
+ * @param ref - native button for focus management and overlay anchors.
9
18
  * @returns the button element; native button attributes pass through.
10
19
  */
11
- export declare function Button({ variant, size, icon, className, children, ...rest }: {
20
+ export declare const Button: import("react").ForwardRefExoticComponent<{
12
21
  variant?: ButtonVariant;
13
- size?: 'md' | 'sm';
22
+ size?: "md" | "sm";
14
23
  icon?: ReactNode;
15
24
  className?: string | undefined;
16
25
  children?: ReactNode;
17
- } & ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
26
+ } & ButtonHTMLAttributes<HTMLButtonElement> & import("react").RefAttributes<HTMLButtonElement>>;
18
27
  //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1,79 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type MarkdownLabels, type MarkdownPathImages } from './markdown/MarkdownText.tsx';
3
+ /** One read of a long Markdown description, such as a plugin's detail document. */
4
+ export type DetailDocumentState = {
5
+ readonly status: 'loading';
6
+ } | {
7
+ readonly status: 'found';
8
+ readonly markdown: string;
9
+ } | {
10
+ readonly status: 'none';
11
+ } | {
12
+ readonly status: 'error';
13
+ readonly message: string;
14
+ };
15
+ /** A read as owners track it: in flight, settled with a document or none, or failed with a localized message. */
16
+ export type DetailDocumentRead = undefined | {
17
+ readonly status: 'loading';
18
+ } | {
19
+ readonly status: 'ready';
20
+ readonly markdown: string | undefined;
21
+ } | {
22
+ readonly status: 'error';
23
+ readonly message: string;
24
+ };
25
+ /**
26
+ * The state {@link DetailDocument} shows for an owner's read: loading until it settles, then the document, none, or the
27
+ * failure.
28
+ * @param read - the owner's read; undefined before it starts.
29
+ * @returns the state to show.
30
+ */
31
+ export declare function detailDocumentState(read: DetailDocumentRead): DetailDocumentState;
32
+ /** Translated strings of a detail document's chrome, as an owner's dictionary supplies them. */
33
+ export interface DetailDocumentCopy {
34
+ readonly title: string;
35
+ readonly loading: string;
36
+ readonly retry: string;
37
+ readonly copy: string;
38
+ readonly copied: string;
39
+ /** Alt text naming an on-page Mermaid diagram. */
40
+ readonly diagram: string;
41
+ /** Alt text naming an enlarged Mermaid diagram. */
42
+ readonly enlarged: string;
43
+ readonly footnotes: string;
44
+ }
45
+ /**
46
+ * Assemble reference-stable labels for {@link DetailDocument} from translated strings.
47
+ * @param copy - the translated strings.
48
+ * @returns labels that keep their identity while the strings stay equal.
49
+ */
50
+ export declare function useDetailDocumentLabels(copy: DetailDocumentCopy): DetailDocumentLabels;
51
+ /** Localized chrome of a detail document. */
52
+ export interface DetailDocumentLabels {
53
+ /** Accessible name of the scrollable document region; the section shows no heading of its own. */
54
+ readonly title: string;
55
+ /** Accessible name of the loading placeholder. */
56
+ readonly loading: string;
57
+ /** Retry button text. */
58
+ readonly retry: string;
59
+ readonly markdown: MarkdownLabels;
60
+ }
61
+ /**
62
+ * A section showing a long Markdown description, without a heading of its own: three skeleton lines while it loads, the
63
+ * document once found, or the owner's failure message with a retry. Nothing renders for `none`. A document taller than
64
+ * the section's height limit scrolls inside it, and the scroll region, named by `labels.title`, takes keyboard focus.
65
+ * Raw HTML is omitted, relative links stay text, and only images the owner's `images` resolver accepts, or absolute
66
+ * HTTP(S) images, load.
67
+ * @param props.state - the read to show.
68
+ * @param props.labels - localized region name, placeholder name, retry text, and Markdown chrome; keep `markdown` reference-stable.
69
+ * @param props.images - resolves the document's relative image destinations to displayable URLs.
70
+ * @param props.onRetry - reads the document again after a failure.
71
+ * @returns the section, or null.
72
+ */
73
+ export declare function DetailDocument({ state, labels, images, onRetry }: {
74
+ readonly state: DetailDocumentState;
75
+ readonly labels: DetailDocumentLabels;
76
+ readonly images?: MarkdownPathImages | undefined;
77
+ readonly onRetry: () => void;
78
+ }): ReactNode;
79
+ //# sourceMappingURL=DetailDocument.d.ts.map
@@ -1,3 +1,4 @@
1
+ import type { HTMLAttributes } from 'react';
1
2
  /** Lightbox strings the owner resolves from its own locale namespace. */
2
3
  export interface ImageLightboxLabels {
3
4
  /** Accessible name of the preview dialog. */
@@ -18,10 +19,11 @@ export interface ImageLightboxLabels {
18
19
  * @param props.onClose - dismiss callback owned by the opener.
19
20
  * @returns the modal preview dialog.
20
21
  */
21
- export declare function ImageLightbox({ src, alt, labels, onClose }: {
22
+ export declare function ImageLightbox({ src, alt, labels, onClose, contextMenuProps }: {
22
23
  src: string;
23
24
  alt: string;
24
25
  labels: ImageLightboxLabels;
25
26
  onClose: () => void;
27
+ contextMenuProps?: Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'> | undefined;
26
28
  }): import("react").ReactPortal;
27
29
  //# sourceMappingURL=ImageLightbox.d.ts.map
@@ -1,34 +1,15 @@
1
1
  /**
2
- * Leading category glyph for clickable artifact links (anchors, file
3
- * mentions, produced-file chips). One component keyed by link category;
4
- * every glyph renders fill="currentColor" and so rides the link's own
5
- * color. Glyphs stay private to this module: the public surface is the
6
- * category vocabulary, not the individual glyph components, so consumers
7
- * cannot compose a glyph outside a link. Design sources:
8
- * ic_globe_language_outline_20, ic_code_outline_20, ic_folder_outline_20,
9
- * ic_photo_outline_20, ic_paper_doc_outline_20, ic_paper_outline_20.
10
- *
11
- * A `url` glyph whose destination names a well-known site is that site's own
12
- * mark instead of the globe (`SiteGlyph.tsx`); every mark keeps the same
13
- * currentColor-only rule.
2
+ * Leading current-color category glyphs for clickable artifact links. The
3
+ * public component keeps individual artwork private to the link vocabulary.
14
4
  */
15
5
  import type { ReactNode } from 'react';
16
6
  import type { IconProps } from './icons/props.ts';
17
- /**
18
- * Link categories with distinct leading glyphs. `url` and `folder` are
19
- * destination categories the consumer states directly; the rest are file
20
- * categories `classifyLinkPath` derives from a path. Code, web, and data
21
- * files share the `code` glyph by design.
22
- */
7
+ /** Link categories with distinct leading glyphs. */
23
8
  export type LinkIconKind = 'url' | 'folder' | 'code' | 'image' | 'document' | 'other';
24
- /** Props for {@link LinkIcon}: the category plus the shared icon sizing seat. */
9
+ /** Props for link icons: the category plus the shared icon sizing seat. */
25
10
  export interface LinkIconProps extends IconProps {
26
11
  kind: LinkIconKind;
27
- /**
28
- * Destination of a `url` link. A well-known site draws its own mark, so
29
- * callers that know the destination should pass it; anything else keeps the
30
- * globe. Other kinds ignore it — their destination is a path, not a site.
31
- */
12
+ /** Destination of a URL link; known HTTP(S) hosts render their site mark. */
32
13
  href?: string | undefined;
33
14
  }
34
15
  /**
@@ -39,11 +20,15 @@ export interface LinkIconProps extends IconProps {
39
20
  */
40
21
  export declare function classifyLinkPath(path: string): LinkIconKind;
41
22
  /**
42
- * Render the leading glyph for one clickable artifact link.
43
- * @param props - The link category, the optional destination that can select a
44
- * site mark, optional size (default 14px — the inline link text size these
45
- * glyphs sit beside), and optional CSS class.
46
- * @returns The category's SVG glyph, riding currentColor.
23
+ * Render a regular one-pixel link icon.
24
+ * @param props - Link category, size, and optional class.
25
+ * @returns The regular decorative link glyph.
26
+ */
27
+ export declare function LinkIconRegular(props: LinkIconProps): ReactNode;
28
+ /**
29
+ * Render a medium 1.3px link icon.
30
+ * @param props - Link category, size, and optional class.
31
+ * @returns The medium decorative link glyph.
47
32
  */
48
- export declare function LinkIcon({ kind, href, size, className }: LinkIconProps): ReactNode;
33
+ export declare function LinkIconMedium(props: LinkIconProps): ReactNode;
49
34
  //# sourceMappingURL=LinkIcon.d.ts.map
@@ -14,7 +14,7 @@ export interface MenuItem {
14
14
  /** Destructive row: error-colored text/icon and danger hover fill. */
15
15
  danger?: boolean;
16
16
  /** Nested card opened to the right on hover/focus. */
17
- submenu?: readonly MenuItem[];
17
+ submenu?: readonly MenuEntry[];
18
18
  }
19
19
  /** Hairline between item groups (not selectable). */
20
20
  export interface MenuSeparator {
@@ -37,8 +37,16 @@ export interface MenuItemButtonProps {
37
37
  shortcut?: MenuItem['shortcut'];
38
38
  /** Leading icon (figma .Menu_cell gap 8). */
39
39
  icon?: ReactNode;
40
+ /** Whether this row identifies the currently displayed page or view. */
41
+ current?: boolean;
40
42
  /** Whether the row cannot be activated. */
41
43
  disabled?: boolean;
44
+ /**
45
+ * Why the disabled row cannot be activated. The row then stays hoverable and
46
+ * focusable, shows the reason in a tooltip, and exposes it as the row's
47
+ * description; an enabled row ignores it.
48
+ */
49
+ disabledReason?: string | undefined;
42
50
  /** Destructive row: error-colored text/icon and danger hover fill. */
43
51
  danger?: boolean;
44
52
  /**
@@ -60,13 +68,15 @@ export interface MenuItemButtonProps {
60
68
  * @param props.children - visible row label.
61
69
  * @param props.shortcut - effective key labels and accessible combination.
62
70
  * @param props.icon - optional leading icon.
71
+ * @param props.current - whether the row identifies the currently displayed page or view.
63
72
  * @param props.disabled - whether the row cannot be activated.
73
+ * @param props.disabledReason - why a disabled row cannot be activated, shown in a tooltip and read as its description.
64
74
  * @param props.danger - whether to use the destructive row colors.
65
75
  * @param props.separatorBefore - whether this row starts a new group (hairline above it).
66
76
  * @param props.onSelect - row activation callback.
67
77
  * @returns one menu-item row.
68
78
  */
69
- export declare function MenuItemButton({ children, shortcut, icon, disabled, danger, separatorBefore, onSelect, }: MenuItemButtonProps): import("react").JSX.Element;
79
+ export declare function MenuItemButton({ children, shortcut, icon, current, disabled, disabledReason, danger, separatorBefore, onSelect, }: MenuItemButtonProps): import("react").JSX.Element;
70
80
  /**
71
81
  * Render an anchored dropdown menu. While the list is open its keys mirror the
72
82
  * composer's: Tab settles the focused row — from the trigger, Tab enters the
@@ -74,6 +84,9 @@ export declare function MenuItemButton({ children, shortcut, icon, disabled, dan
74
84
  * anchor's first button, and selecting a row does the same — the rows unmount
75
85
  * with the list. Only a keyboard on the trigger or inside the list is
76
86
  * intercepted; Tab presses elsewhere on the page stay the browser's.
87
+ * @param props.contextual - cursor positioning, context dismissal, and per-divider icon alignment.
88
+ * @param props.exiting - retain an inert popup during dismissal or replacement fade.
89
+ * @param props.returnFocus - original control captured before asynchronous menu preparation.
77
90
  * @param props.autoFocus - focus the first item on open; the arrow keys walk the list either way.
78
91
  * @param props.open - whether the list is showing (owner-controlled).
79
92
  * @param props.anchor - the trigger element (rendered in place).
@@ -87,9 +100,9 @@ export declare function MenuItemButton({ children, shortcut, icon, disabled, dan
87
100
  * @param props.align - list alignment against the anchor (default 'start').
88
101
  * @param props.side - open below (`bottom`, default) or above (`top`) the anchor.
89
102
  * @param props.portal - render the list into document.body, fixed-positioned
90
- * from the anchor rect (follows movement and resizing while open). Use when an
91
- * ancestor's overflow clipping would crop the in-place list; default false
92
- * keeps the pure-CSS in-place behavior.
103
+ * synchronously (follows movement, resizing, and browser zoom while open)
104
+ * and clamped inside the visual viewport. Use when an ancestor's overflow clipping would crop the
105
+ * in-place list; default false keeps the pure-CSS in-place behavior.
93
106
  * @param props.closeOnPointerLeave - close the list once the pointer has left
94
107
  * both trigger and list for the pointer grace (default false keeps it open
95
108
  * until outside click/Escape/selection). The grace makes the 4px trigger->list
@@ -100,10 +113,11 @@ export declare function MenuItemButton({ children, shortcut, icon, disabled, dan
100
113
  * directly (e.g. from a host-owned trigger button) instead of measuring the
101
114
  * Menu's own wrapper span. Required when the wrapper isn't itself laid out at
102
115
  * the trigger (render-prop anchors, effect-positioned proxies — measuring the
103
- * wrapper there races the host's layout effects). Called on open, each animation
104
- * frame, and scroll/resize; return null to skip placement for that frame.
116
+ * wrapper there races the host's layout effects). Called while tracking the
117
+ * anchor and on scroll/resize; return null to defer placement.
118
+ * @param props.minWidthFromAnchor - in portal mode, keep the menu at least as wide as its anchor, bounded by viewport margins.
105
119
  * @param props.footer - rows pinned below the scrolling items area, separated
106
- * by a hairline; they stay visible while the items above scroll.
120
+ * by a hairline; contextual menus reuse an explicit leading separator. These rows stay visible while the items above scroll.
107
121
  * @param props.children - component rows rendered after `items` in the same
108
122
  * list, each a `role="menuitem"` button such as {@link MenuItemButton}; they
109
123
  * share the keyboard walk, the submenu exclusivity, and the post-selection
@@ -118,8 +132,14 @@ export declare function MenuItemButton({ children, shortcut, icon, disabled, dan
118
132
  * document.body outside the owner's DOM subtree.
119
133
  * @returns anchor wrapper with the conditional list.
120
134
  */
121
- export declare function Menu({ open, anchor, items, children, selectedId, selectedIds, onSelect, onClose, align, side, portal, closeOnPointerLeave, dense, compact, autoFocus, selection, getAnchorRect, footer, className, listClassName }: {
135
+ export declare function Menu({ open, anchor, items, children, selectedId, selectedIds, onSelect, onClose, align, side, portal, closeOnPointerLeave, dense, compact, autoFocus, selection, getAnchorRect, minWidthFromAnchor, footer, className, listClassName, contextual, exiting, returnFocus }: {
122
136
  open: boolean;
137
+ /** Pointer-positioned popup: cursor clearance, grouped icons, and context gestures. */
138
+ contextual?: boolean;
139
+ /** Resolve the original control for focus restoration and inert/hidden dismissal. */
140
+ returnFocus?: (() => HTMLElement | null) | undefined;
141
+ /** Retain a dismissed context popup during its short fade. */
142
+ exiting?: 'dismiss' | 'replace' | undefined;
123
143
  autoFocus?: boolean;
124
144
  anchor: ReactNode;
125
145
  items?: readonly MenuEntry[];
@@ -137,6 +157,7 @@ export declare function Menu({ open, anchor, items, children, selectedId, select
137
157
  compact?: boolean;
138
158
  selection?: 'check' | 'fill';
139
159
  getAnchorRect?: () => DOMRect | null;
160
+ minWidthFromAnchor?: boolean;
140
161
  className?: string | undefined;
141
162
  listClassName?: string | undefined;
142
163
  }): import("react").JSX.Element;
@@ -1,9 +1,18 @@
1
1
  /** Shared menu material and the macOS backing that lets Chromium blur transparent windows. */
2
2
  import { type ComponentPropsWithoutRef } from 'react';
3
+ /** Context-menu transition durations in milliseconds, shared with its lifecycle owner. */
4
+ export declare const MENU_TRANSITION_MS: Readonly<{
5
+ enter: 40;
6
+ dismiss: 80;
7
+ replace: 10;
8
+ prepare: 20;
9
+ }>;
3
10
  /** Menu containers preserve native div props and refs. */
4
11
  export interface MenuSurfaceProps extends ComponentPropsWithoutRef<'div'> {
5
12
  /** Match the shared compact menu's smaller outer radius. */
6
13
  compact?: boolean;
14
+ /** Fade direct content, material, and native backing without isolating the material's backdrop. */
15
+ phase?: 'enter' | 'dismiss' | 'replace' | undefined;
7
16
  }
8
17
  /**
9
18
  * Paint a menu and, on macOS, an opaque backing behind the page content within its bounds.
@@ -0,0 +1,51 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { IconProps } from './icons/props.ts';
3
+ /**
4
+ * Render the read-only permission icon with a one-pixel stroke.
5
+ * @param props - Size and optional class.
6
+ * @returns The regular decorative permission glyph.
7
+ */
8
+ export declare function PermissionIconReadOnlyRegular(props: IconProps): ReactNode;
9
+ /**
10
+ * Render the read-only permission icon with a 1.3px stroke.
11
+ * @param props - Size and optional class.
12
+ * @returns The medium decorative permission glyph.
13
+ */
14
+ export declare function PermissionIconReadOnlyMedium(props: IconProps): ReactNode;
15
+ /**
16
+ * Render the workspace-write permission icon with a one-pixel stroke.
17
+ * @param props - Size and optional class.
18
+ * @returns The regular decorative permission glyph.
19
+ */
20
+ export declare function PermissionIconWorkspaceWriteRegular(props: IconProps): ReactNode;
21
+ /**
22
+ * Render the workspace-write permission icon with a 1.3px stroke.
23
+ * @param props - Size and optional class.
24
+ * @returns The medium decorative permission glyph.
25
+ */
26
+ export declare function PermissionIconWorkspaceWriteMedium(props: IconProps): ReactNode;
27
+ /**
28
+ * Render the full-access permission icon with a one-pixel stroke.
29
+ * @param props - Size and optional class.
30
+ * @returns The regular decorative permission glyph.
31
+ */
32
+ export declare function PermissionIconFullAccessRegular(props: IconProps): ReactNode;
33
+ /**
34
+ * Render the full-access permission icon with a 1.3px stroke.
35
+ * @param props - Size and optional class.
36
+ * @returns The medium decorative permission glyph.
37
+ */
38
+ export declare function PermissionIconFullAccessMedium(props: IconProps): ReactNode;
39
+ /**
40
+ * Render the auto-review permission icon with a one-pixel stroke.
41
+ * @param props - Size and optional class.
42
+ * @returns The regular decorative permission glyph.
43
+ */
44
+ export declare function PermissionIconAutoReviewRegular(props: IconProps): ReactNode;
45
+ /**
46
+ * Render the auto-review permission icon with a 1.3px stroke.
47
+ * @param props - Size and optional class.
48
+ * @returns The medium decorative permission glyph.
49
+ */
50
+ export declare function PermissionIconAutoReviewMedium(props: IconProps): ReactNode;
51
+ //# sourceMappingURL=PermissionIcon.d.ts.map
@@ -0,0 +1,26 @@
1
+ import type { JSX } from 'react';
2
+ /** Localized names of the quote controls; a caller owns every string. */
3
+ export interface QuotePreviewLabels {
4
+ /** Accessible name of the copy control. */
5
+ readonly copy: string;
6
+ /** Accessible name after an accepted copy. */
7
+ readonly copied: string;
8
+ /** Accessible name of the jump control. */
9
+ readonly jump: string;
10
+ }
11
+ /** Presentation inputs for one quoted excerpt. */
12
+ export interface QuotePreviewProps {
13
+ /** Excerpt text as decoded from the message, without its source marker line. */
14
+ readonly text: string;
15
+ /** Localized control names. */
16
+ readonly labels: QuotePreviewLabels;
17
+ /** Reveal the quoted source; omission hides the jump control. */
18
+ readonly onJump?: (() => void) | undefined;
19
+ }
20
+ /**
21
+ * Render one quoted excerpt with its copy and optional jump controls.
22
+ * @param props - excerpt text, control names, and the reveal action.
23
+ * @returns the quote surface, with the full text on hover while clipped.
24
+ */
25
+ export declare function QuotePreview({ text, labels, onJump }: QuotePreviewProps): JSX.Element;
26
+ //# sourceMappingURL=QuotePreview.d.ts.map
@@ -1,16 +1,21 @@
1
1
  import type { ReactNode } from 'react';
2
+ import type { IconProps } from './icons/props.ts';
2
3
  /** Reference domains with distinct composer and transcript glyphs. */
3
4
  export type ReferenceIconKind = 'session' | 'file' | 'folder';
4
5
  /** Props shared by inline reference glyphs. */
5
- export interface ReferenceIconProps {
6
+ export interface ReferenceIconProps extends IconProps {
6
7
  kind: ReferenceIconKind;
7
- size?: number;
8
- className?: string | undefined;
9
8
  }
10
9
  /**
11
- * Render the icon that identifies one inline reference domain.
12
- * @param props - Reference kind, optional size, and optional CSS class.
13
- * @returns The corresponding current-color SVG glyph.
10
+ * Render a regular one-pixel reference icon.
11
+ * @param props - Reference kind, size, and optional class.
12
+ * @returns The regular decorative reference glyph.
14
13
  */
15
- export declare function ReferenceIcon({ kind, size, className }: ReferenceIconProps): ReactNode;
14
+ export declare function ReferenceIconRegular(props: ReferenceIconProps): ReactNode;
15
+ /**
16
+ * Render a medium 1.3px reference icon.
17
+ * @param props - Reference kind, size, and optional class.
18
+ * @returns The medium decorative reference glyph.
19
+ */
20
+ export declare function ReferenceIconMedium(props: ReferenceIconProps): ReactNode;
16
21
  //# sourceMappingURL=ReferenceIcon.d.ts.map
@@ -14,13 +14,15 @@ export interface SegmentedTab<Value extends string = string> {
14
14
  * Keyboard selection also moves focus; only the selected tab is a tab stop.
15
15
  * @param props.label - localized accessible name for the tab list.
16
16
  * @param props.className - layout placement; panels remain caller-owned.
17
+ * @param props.size - `sm` draws 30px tabs with a 2px inset (34px tall); the default `md` draws 34px tabs with a 4px inset (42px tall).
17
18
  * @returns the tab list, without its panels.
18
19
  */
19
- export declare function SegmentedTabs<Value extends string>({ items, value, onChange, label, className }: {
20
+ export declare function SegmentedTabs<Value extends string>({ items, value, onChange, label, className, size }: {
20
21
  items: readonly [SegmentedTab<Value>, ...SegmentedTab<Value>[]];
21
22
  value: Value;
22
23
  onChange: (value: Value) => void;
23
24
  label: string;
24
25
  className?: string | undefined;
26
+ size?: 'sm' | 'md' | undefined;
25
27
  }): ReactNode;
26
28
  //# sourceMappingURL=SegmentedTabs.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Site marks for well-known external link hosts. {@link LinkIcon} renders one in
2
+ * Site marks for well-known external link hosts. {@link LinkIconMedium} renders one in
3
3
  * the leading glyph seat, so a familiar destination leads with its own mark
4
4
  * instead of the generic globe. The marks are the `simple-icons` artwork set
5
5
  * (CC0-1.0), pinned by this package's dependency on it; each mark takes the
@@ -7,6 +7,16 @@ import type { ReactNode } from 'react';
7
7
  * transformed or filtered ancestor cannot trap the fixed banner in that
8
8
  * ancestor's box.
9
9
  *
10
+ * Actions extend the sentence with inline choices: each renders its plain-text
11
+ * `prefix` (a connective such as "or") followed by its localized `label` as
12
+ * clickable text inside the banner. Each press is the owner's to handle (undo
13
+ * the reported change, then unmount the toast). The banner surface stays
14
+ * click-through — only the action text takes the pointer — and a fully faded
15
+ * banner takes no input at all.
16
+ *
17
+ * With an unchanged holdMs, a parent rerender does not extend the lifetime:
18
+ * the completion call reaches the latest onDone handler.
19
+ *
10
20
  * The hold is the owner's to set, because how long a banner has to stay
11
21
  * depends on how much there is to read: a one-line limit lands in the default
12
22
  * window, while a failure that names what broke does not. One value drives
@@ -18,6 +28,9 @@ import type { ReactNode } from 'react';
18
28
  * under `tone="success"`, which brings its own glyph.
19
29
  * @param props.tone - 'success' renders the success check as the leading
20
30
  * glyph; omitted, the icon seat keeps its warning tint.
31
+ * @param props.actions - optional inline actions continuing the sentence;
32
+ * each renders its plain-text `prefix` followed by its localized `label`
33
+ * as clickable text flowing after `text` as one sentence.
21
34
  * @param props.holdMs - full-opacity hold before the fade; defaults to 3000.
22
35
  * @param props.anchor - optional element whose horizontal center the banner
23
36
  * follows (e.g. the composer card, so the banner centers over the chat column
@@ -25,12 +38,17 @@ import type { ReactNode } from 'react';
25
38
  * @param props.onDone - called once the fade completes; unmount the toast here.
26
39
  * @returns the floating banner.
27
40
  */
28
- export declare function Toast({ text, icon, tone, anchor, holdMs, onDone }: {
41
+ export declare function Toast({ text, icon, tone, anchor, holdMs, actions, onDone }: {
29
42
  text: string;
30
43
  icon?: ReactNode;
31
44
  tone?: 'success';
32
45
  anchor?: HTMLElement | null;
33
46
  holdMs?: number;
47
+ actions?: readonly {
48
+ label: string;
49
+ prefix?: string;
50
+ onClick: () => void;
51
+ }[];
34
52
  onDone: () => void;
35
53
  }): import("react").ReactPortal;
36
54
  //# sourceMappingURL=Toast.d.ts.map