@deepseek-ai/dsh-client-ui-primitives 0.1.6-alpha.2 → 0.1.7-alpha.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 (62) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +31 -13
  3. package/README.zh.md +31 -13
  4. package/lib/CodeCard.module.css +83 -0
  5. package/lib/ConnectionIndicator.module.css +1 -10
  6. package/lib/DiffBlock.module.css +24 -53
  7. package/lib/HoverCard.module.css +27 -0
  8. package/lib/Menu.module.css +68 -48
  9. package/lib/Modal.module.css +6 -2
  10. package/lib/OnboardingSurface.module.css +1 -2
  11. package/lib/PathLabel.module.css +28 -0
  12. package/lib/ReadBlock.module.css +13 -81
  13. package/lib/RiskConfirmation.module.css +1 -1
  14. package/lib/SegmentedControl.module.css +76 -0
  15. package/lib/SegmentedTabs.module.css +55 -0
  16. package/lib/StateDot.module.css +64 -37
  17. package/lib/TerminalBlock.module.css +13 -6
  18. package/lib/TextShimmer.module.css +27 -0
  19. package/lib/Toast.module.css +31 -2
  20. package/lib/Tooltip.module.css +12 -0
  21. package/lib/index.js +5892 -3142
  22. package/lib/markdown/CodeBlock.module.css +15 -0
  23. package/lib/markdown/MarkdownText.module.css +1 -19
  24. package/lib/settings-form/SettingsForm.module.css +53 -0
  25. package/lib/settings-form/fields.module.css +145 -0
  26. package/lib/types/CodeToolbar.d.ts +30 -0
  27. package/lib/types/ConfigField.d.ts +33 -0
  28. package/lib/types/DiffBlock.d.ts +3 -3
  29. package/lib/types/DisclosureRow.d.ts +4 -1
  30. package/lib/types/HoverCard.d.ts +14 -4
  31. package/lib/types/LinkIcon.d.ts +15 -30
  32. package/lib/types/Menu.d.ts +53 -8
  33. package/lib/types/PathLabel.d.ts +13 -0
  34. package/lib/types/PermissionIcon.d.ts +39 -0
  35. package/lib/types/ReadBlock.d.ts +2 -1
  36. package/lib/types/ReferenceIcon.d.ts +12 -7
  37. package/lib/types/SegmentedControl.d.ts +35 -0
  38. package/lib/types/SegmentedTabs.d.ts +26 -0
  39. package/lib/types/SiteGlyph.d.ts +1 -1
  40. package/lib/types/StateDot.d.ts +6 -4
  41. package/lib/types/TerminalBlock.d.ts +15 -3
  42. package/lib/types/TextShimmer.d.ts +13 -0
  43. package/lib/types/Toast.d.ts +19 -2
  44. package/lib/types/Tooltip.d.ts +13 -2
  45. package/lib/types/code-file-types.d.ts +1 -1
  46. package/lib/types/code-highlighting.d.ts +19 -0
  47. package/lib/types/icons/index.d.ts +376 -195
  48. package/lib/types/icons/props.d.ts +1 -1
  49. package/lib/types/icons/shared-artwork.d.ts +36 -0
  50. package/lib/types/index.d.ts +22 -4
  51. package/lib/types/markdown/CodeBlock.d.ts +6 -1
  52. package/lib/types/markdown/render.d.ts +3 -0
  53. package/lib/types/overlay-top-margin.d.ts +14 -0
  54. package/lib/types/plugin-artwork.d.ts +17 -0
  55. package/lib/types/settings-form/SettingsForm.d.ts +46 -0
  56. package/lib/types/settings-form/fields.d.ts +69 -0
  57. package/lib/types/settings-form/form-model.d.ts +214 -0
  58. package/lib/types/useAnchoredMaxHeight.d.ts +4 -1
  59. package/lib/types/useAnchoredPosition.d.ts +3 -1
  60. package/lib/types/user-text.d.ts +2 -2
  61. package/lib/user-text.module.css +4 -1
  62. package/package.json +5 -3
@@ -104,6 +104,21 @@
104
104
  color: var(--dsw-alias-label-primary);
105
105
  }
106
106
 
107
+ .card :where(pre) {
108
+ padding: 6px 22px 20px;
109
+ word-break: normal;
110
+ overflow-wrap: anywhere;
111
+ }
112
+
113
+ .card[data-code-wrap='false'] {
114
+ --dsl-code-block-line-white-space: pre;
115
+ }
116
+
117
+ .card[data-code-wrap='false'] :where(pre) {
118
+ white-space: pre;
119
+ overflow-wrap: normal;
120
+ }
121
+
107
122
  .numbered :where(pre) code {
108
123
  display: block;
109
124
  counter-reset: source-line;
@@ -207,7 +207,7 @@
207
207
  already the hover that re-enables scrolling. */
208
208
  .tableScroll:global(.md-table-wide) {
209
209
  overflow-x: hidden;
210
- padding-bottom: var(--dsh-scrollbar-width, 8px);
210
+ padding-bottom: var(--dsh-scrollbar-width, 5px);
211
211
  }
212
212
 
213
213
  .tableScroll:global(.md-table-wide):hover,
@@ -401,24 +401,6 @@
401
401
  z-index: auto;
402
402
  }
403
403
 
404
- .compact [data-code-block-banner] {
405
- padding: 4px 8px;
406
- font: inherit;
407
- }
408
-
409
- .compact [data-code-block-banner] > :first-child {
410
- font-size: inherit;
411
- line-height: inherit;
412
- color: inherit;
413
- }
414
-
415
- .compact pre {
416
- margin: 4px 0;
417
- padding: 8px;
418
- font-size: inherit;
419
- line-height: inherit;
420
- }
421
-
422
404
  /* Shiki writes token colors inline; compact code uses the surrounding text color. */
423
405
  .compact pre,
424
406
  .compact pre :is(code, span) {
@@ -0,0 +1,53 @@
1
+ /* Settings form: the controls a page shows under a plugin's title, and the save that writes them. */
2
+
3
+ .form {
4
+ display: flex;
5
+ flex-direction: column;
6
+ }
7
+
8
+ .readOnly,
9
+ .unavailable {
10
+ margin: 0 0 12px;
11
+ font-size: 12px;
12
+ line-height: 1.5;
13
+ color: var(--dsw-alias-label-tertiary);
14
+ }
15
+
16
+ .footer {
17
+ display: flex;
18
+ align-items: center;
19
+ gap: 8px;
20
+ padding-top: 16px;
21
+ }
22
+
23
+ .failed {
24
+ flex: 1;
25
+ min-width: 0;
26
+ margin: 0;
27
+ font-size: 12px;
28
+ line-height: 1.5;
29
+ color: var(--dsw-alias-label-error);
30
+ }
31
+
32
+ .save {
33
+ appearance: none;
34
+ border: 1px solid transparent;
35
+ border-radius: 8px;
36
+ padding: 5px 14px;
37
+ font: inherit;
38
+ font-size: 13px;
39
+ line-height: 1.5;
40
+ cursor: pointer;
41
+ background: var(--dsw-alias-label-primary);
42
+ color: var(--dsw-alias-bg-layer-3);
43
+ }
44
+
45
+ .save:disabled {
46
+ opacity: 0.4;
47
+ cursor: default;
48
+ }
49
+
50
+ .save:focus-visible {
51
+ outline: 2px solid var(--dsw-alias-brand-primary);
52
+ outline-offset: 1px;
53
+ }
@@ -0,0 +1,145 @@
1
+ /* Settings form fields: label, control, override badge, and hint. */
2
+
3
+ .field {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: 6px;
7
+ padding: 12px 0;
8
+ }
9
+
10
+ .field + .field {
11
+ border-top: 0.5px solid var(--dsw-alias-border-l2);
12
+ }
13
+
14
+ .head {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 8px;
18
+ }
19
+
20
+ .label {
21
+ flex: 1;
22
+ min-width: 0;
23
+ font-size: 13px;
24
+ font-weight: 500;
25
+ line-height: 1.5;
26
+ color: var(--dsw-alias-label-primary);
27
+ }
28
+
29
+ .labelGroup {
30
+ display: flex;
31
+ align-items: center;
32
+ gap: 4px;
33
+ flex: 1;
34
+ min-width: 0;
35
+ }
36
+
37
+ .labelGroup > .label {
38
+ flex: 0 1 auto;
39
+ }
40
+
41
+ .helpButton {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ flex: none;
46
+ width: 24px;
47
+ height: 24px;
48
+ padding: 0;
49
+ border: 0;
50
+ border-radius: 6px;
51
+ background: none;
52
+ color: var(--dsw-alias-label-tertiary);
53
+ cursor: pointer;
54
+ }
55
+
56
+ .helpButton:hover,
57
+ .helpButton[aria-expanded='true'] {
58
+ background: var(--dsw-alias-bg-layer-4);
59
+ color: var(--dsw-alias-label-secondary);
60
+ }
61
+
62
+ .helpButton:focus-visible {
63
+ outline: 2px solid var(--dsw-alias-brand-primary);
64
+ outline-offset: 1px;
65
+ }
66
+
67
+ .help {
68
+ padding: 10px 0 0;
69
+ font-size: 12px;
70
+ line-height: 1.6;
71
+ color: var(--dsw-alias-label-secondary);
72
+ }
73
+
74
+ .help > p {
75
+ margin: 0;
76
+ }
77
+
78
+ .help > p + p {
79
+ margin-top: 8px;
80
+ }
81
+
82
+ .badges {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: 8px;
86
+ }
87
+
88
+ .reset {
89
+ border: none;
90
+ background: none;
91
+ padding: 0;
92
+ font: inherit;
93
+ font-size: 12px;
94
+ line-height: 1.5;
95
+ color: var(--dsw-alias-label-secondary);
96
+ cursor: pointer;
97
+ }
98
+
99
+ .reset:hover:not(:disabled) {
100
+ color: var(--dsw-alias-label-primary);
101
+ }
102
+
103
+ .reset:disabled {
104
+ cursor: default;
105
+ }
106
+
107
+ .input {
108
+ height: 34px;
109
+ padding: 0 12px;
110
+ border: 0.5px solid var(--dsw-alias-border-l4);
111
+ border-radius: 8px;
112
+ background: var(--dsw-alias-bg-layer-3);
113
+ font: inherit;
114
+ font-size: 13px;
115
+ line-height: 1.5;
116
+ color: var(--dsw-alias-label-primary);
117
+ }
118
+
119
+ .input:focus-visible {
120
+ outline: none;
121
+ border-color: var(--dsw-alias-brand-primary);
122
+ }
123
+
124
+ .input:disabled {
125
+ color: var(--dsw-alias-label-tertiary);
126
+ cursor: default;
127
+ }
128
+
129
+ .input[aria-invalid='true'] {
130
+ border-color: var(--dsw-alias-state-error-primary);
131
+ }
132
+
133
+ .invalid {
134
+ margin: 0;
135
+ font-size: 12px;
136
+ line-height: 1.5;
137
+ color: var(--dsw-alias-state-error-primary);
138
+ }
139
+
140
+ .hint {
141
+ margin: 0;
142
+ font-size: 12px;
143
+ line-height: 1.5;
144
+ color: var(--dsw-alias-label-tertiary);
145
+ }
@@ -0,0 +1,30 @@
1
+ /** Localized language fallback and wrapping actions supplied by the card owner. */
2
+ export interface CodeToolbarLabels {
3
+ /** Title for an absent or unsupported language. */
4
+ codeLabel: string;
5
+ /** Action that enables wrapping. */
6
+ wrapLabel: string;
7
+ /** Action that preserves source columns with horizontal scrolling. */
8
+ unwrapLabel: string;
9
+ }
10
+ /** Display state and callbacks for a code card's toolbar. */
11
+ interface CodeToolbarProps {
12
+ lang?: string | undefined;
13
+ title?: string | undefined;
14
+ status?: string | undefined;
15
+ labels: CodeToolbarLabels;
16
+ copyLabel: string;
17
+ copiedLabel: string;
18
+ copied: boolean;
19
+ wrapped: boolean;
20
+ onCopy?: (() => void) | undefined;
21
+ onWrap?: (() => void) | undefined;
22
+ }
23
+ /**
24
+ * Render a language label and keyboard-accessible icon actions with tooltips.
25
+ * @param props - Localized labels, current state, and card-owned actions.
26
+ * @returns The shared code-card header.
27
+ */
28
+ export declare function CodeToolbar({ lang, title, status, labels, copyLabel, copiedLabel, copied, wrapped, onCopy, onWrap }: CodeToolbarProps): import("react").JSX.Element;
29
+ export {};
30
+ //# sourceMappingURL=CodeToolbar.d.ts.map
@@ -0,0 +1,33 @@
1
+ /** Field state and localized controls supplied by the owning form. */
2
+ export interface ConfigFieldProps {
3
+ /** Display label from the owning plugin. */
4
+ label: string;
5
+ /** Editable text; containers may use JSON. */
6
+ value: string;
7
+ /** Hide the input text and disable browser password autofill. */
8
+ secret: boolean;
9
+ /** Finite choices; an empty list uses a text control. */
10
+ choices: readonly string[];
11
+ /** Whether the field is currently read-only. */
12
+ disabled: boolean;
13
+ /** Whether the field has a user override. */
14
+ overridden: boolean;
15
+ /** Whether the draft fails validation. */
16
+ invalid: boolean;
17
+ /** Localized reset, inherited-value choice, and validation text. */
18
+ labels: {
19
+ reset: string;
20
+ inherited: string;
21
+ invalid: string;
22
+ };
23
+ /** Stage a new text value. */
24
+ onChange: (value: string) => void;
25
+ /** Stage removal of the user override. */
26
+ onReset: () => void;
27
+ }
28
+ /** Render a field without owning its schema, draft, or persistence.
29
+ * @param props Controlled field state and actions.
30
+ * @returns A labelled input with reset and validation feedback.
31
+ */
32
+ export declare function ConfigField(props: ConfigFieldProps): import("react").JSX.Element;
33
+ //# sourceMappingURL=ConfigField.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { type CodeToolbarLabels } from './CodeToolbar.tsx';
1
2
  /** Output lines shown before the height cap collapses the middle. */
2
3
  export declare const DEFAULT_DIFF_MAX_LINES = 16;
3
4
  /**
@@ -23,21 +24,20 @@ export interface DiffBlockProps {
23
24
  className?: string | undefined;
24
25
  }
25
26
  /** Localized chrome for {@link DiffBlock}. */
26
- export interface DiffBlockLabels {
27
+ export interface DiffBlockLabels extends CodeToolbarLabels {
27
28
  copy: string;
28
29
  copied: string;
29
30
  collapseAria: string;
30
31
  expandAria: (hidden: number) => string;
31
32
  collapse: string;
32
33
  expand: (hidden: number) => string;
33
- files: (count: number) => string;
34
34
  }
35
35
  /**
36
36
  * Count displayed additions and deletions. Exact patches exclude shared context;
37
37
  * comparisons exceeding the edit limit count both complete fragments as replaced.
38
38
  * Text follows {@link contentLines}'s terminator rule.
39
39
  * @param diffs - the hunks to count.
40
- * @returns the +/- totals for summaries and the card footer.
40
+ * @returns the +/- totals for tool summaries.
41
41
  */
42
42
  export declare function diffTotals(diffs: DiffHunk[]): {
43
43
  added: number;
@@ -6,6 +6,8 @@ export interface DisclosureRowProps {
6
6
  open: boolean;
7
7
  expandable: boolean;
8
8
  onToggle: () => void;
9
+ /** Animate the title while its owning operation is running. */
10
+ running?: boolean | undefined;
9
11
  /** Makes the complete title row the disclosure target. */
10
12
  expandOnRowClick?: boolean | undefined;
11
13
  /** Replaces the collapsed icon with a chevron while the row is hovered. */
@@ -22,8 +24,9 @@ export interface DisclosureRowProps {
22
24
  }
23
25
  /**
24
26
  * Render one disclosure header and its controlled expanded content.
27
+ * Shallow prop comparison requires stable callbacks and React nodes to skip unchanged renders.
25
28
  * @param props - Visual content, controlled state, and interaction policy.
26
29
  * @returns the disclosure row.
27
30
  */
28
- export declare function DisclosureRow({ icon, title, open, expandable, onToggle, expandOnRowClick, previewChevron, keepContentWhenOpen, collapsedContent, children, className, rowClassName, leadingClassName, chevronClassName, titleClassName, }: DisclosureRowProps): import("react").JSX.Element;
31
+ export declare const DisclosureRow: import("react").MemoExoticComponent<({ icon, title, open, expandable, onToggle, running, expandOnRowClick, previewChevron, keepContentWhenOpen, collapsedContent, children, className, rowClassName, leadingClassName, chevronClassName, titleClassName, }: DisclosureRowProps) => import("react").JSX.Element>;
29
32
  //# sourceMappingURL=DisclosureRow.d.ts.map
@@ -1,24 +1,34 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ReactNode, RefObject } from 'react';
2
2
  /**
3
3
  * Render an anchor with a hover-triggered preview card.
4
4
  * @param props.anchor - the hover target (rendered in place inside a wrapper span).
5
5
  * @param props.content - card content; the pointer may rest on it, so it is
6
6
  * readable and selectable, but it carries no dismissal affordance of its own.
7
7
  * @param props.openDelayMs - hover dwell before the card shows (default 500).
8
- * @param props.disabled - suppress opening; turning true closes an open card.
8
+ * @param props.variant - compact card beside the anchor, or a preview above/below it
9
+ * with 24px side insets, a 420px height cap, frame-top clearance, and 100ms opacity transitions.
10
+ * @param props.widthAnchorRef - optional element whose width and horizontal position size the preview.
11
+ * @param props.disabled - suppress opening; turning true dismisses an open card.
9
12
  * @param props.copyText - optional primary value copied by activation and
10
13
  * included in the card's accessible name.
11
14
  * @param props.copyLabel - localized accessible activation-label prefix.
12
15
  * @param props.copiedLabel - localized visible success label.
13
16
  * @returns anchor wrapper with the conditional portaled card.
14
17
  */
15
- export declare function HoverCard({ anchor, content, openDelayMs, disabled, copyText, copyLabel, copiedLabel, }: {
18
+ export declare function HoverCard({ anchor, content, openDelayMs, disabled, copyText, copyLabel, copiedLabel, variant, widthAnchorRef, }: {
16
19
  anchor: ReactNode;
17
20
  content: ReactNode;
18
21
  openDelayMs?: number;
19
22
  disabled?: boolean;
23
+ variant?: 'compact' | 'preview';
24
+ widthAnchorRef?: RefObject<HTMLElement | null>;
25
+ } & ({
20
26
  copyText?: string | undefined;
21
27
  copyLabel: string;
22
28
  copiedLabel: string;
23
- }): import("react").JSX.Element;
29
+ } | {
30
+ copyText?: undefined;
31
+ copyLabel?: string;
32
+ copiedLabel?: string;
33
+ })): import("react").JSX.Element;
24
34
  //# sourceMappingURL=HoverCard.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
@@ -24,6 +24,41 @@ export interface MenuLabel {
24
24
  }
25
25
  /** One primary-menu entry: a row, a separator, or a heading label. */
26
26
  export type MenuEntry = MenuItem | MenuSeparator | MenuLabel;
27
+ /** Props for one component-rendered menu row. */
28
+ export interface MenuItemButtonProps {
29
+ /** Visible row label. */
30
+ children: ReactNode;
31
+ /** Leading icon (figma .Menu_cell gap 8). */
32
+ icon?: ReactNode;
33
+ /** Whether the row cannot be activated. */
34
+ disabled?: boolean;
35
+ /** Destructive row: error-colored text/icon and danger hover fill. */
36
+ danger?: boolean;
37
+ /**
38
+ * Start a new group: a hairline above this row, the same one a
39
+ * `{ type: 'separator' }` data entry draws. It comes and goes with the row,
40
+ * so a row that renders nothing leaves no stray line; a data separator
41
+ * directly before it draws no second line, and the list's first row draws none.
42
+ */
43
+ separatorBefore?: boolean;
44
+ /** Row activation (click, Enter, or Tab on the focused row). */
45
+ onSelect: () => void;
46
+ }
47
+ /**
48
+ * Render one `role="menuitem"` row for a {@link Menu} whose rows are
49
+ * components rather than `items` data: the same markup and styling as a data
50
+ * row, so it joins the list's keyboard walk and post-selection focus return
51
+ * without any shared state. Closing the menu stays the owner's decision, as
52
+ * it is for data rows.
53
+ * @param props.children - visible row label.
54
+ * @param props.icon - optional leading icon.
55
+ * @param props.disabled - whether the row cannot be activated.
56
+ * @param props.danger - whether to use the destructive row colors.
57
+ * @param props.separatorBefore - whether this row starts a new group (hairline above it).
58
+ * @param props.onSelect - row activation callback.
59
+ * @returns one menu-item row.
60
+ */
61
+ export declare function MenuItemButton({ children, icon, disabled, danger, separatorBefore, onSelect, }: MenuItemButtonProps): import("react").JSX.Element;
27
62
  /**
28
63
  * Render an anchored dropdown menu. While the list is open its keys mirror the
29
64
  * composer's: Tab settles the focused row — from the trigger, Tab enters the
@@ -34,17 +69,17 @@ export type MenuEntry = MenuItem | MenuSeparator | MenuLabel;
34
69
  * @param props.autoFocus - focus the first item on open; the arrow keys walk the list either way.
35
70
  * @param props.open - whether the list is showing (owner-controlled).
36
71
  * @param props.anchor - the trigger element (rendered in place).
37
- * @param props.items - selectable rows and optional separators.
72
+ * @param props.items - selectable data rows and optional separators (default none; with no `children` either, the list is empty).
38
73
  * @param props.selectedId - row shown as selected.
39
74
  * @param props.selectedIds - rows shown as selected when a menu contains independent option groups.
40
- * @param props.onSelect - row click callback (not called for disabled rows or submenu parents that only open children).
75
+ * @param props.onSelect - data-row activation callback (not called for disabled rows or submenu parents that only open children).
41
76
  * @param props.onClose - invoked on outside click, Escape, or a window blur
42
77
  * that moved focus into an iframe (the only signal a pointerdown inside a
43
78
  * cross-origin iframe leaves).
44
79
  * @param props.align - list alignment against the anchor (default 'start').
45
80
  * @param props.side - open below (`bottom`, default) or above (`top`) the anchor.
46
81
  * @param props.portal - render the list into document.body, fixed-positioned
47
- * from the anchor rect (repositions on scroll/resize while open). Use when an
82
+ * from the anchor rect (follows movement and resizing while open). Use when an
48
83
  * ancestor's overflow clipping would crop the in-place list; default false
49
84
  * keeps the pure-CSS in-place behavior.
50
85
  * @param props.closeOnPointerLeave - close the list once the pointer has left
@@ -57,25 +92,34 @@ export type MenuEntry = MenuItem | MenuSeparator | MenuLabel;
57
92
  * directly (e.g. from a host-owned trigger button) instead of measuring the
58
93
  * Menu's own wrapper span. Required when the wrapper isn't itself laid out at
59
94
  * the trigger (render-prop anchors, effect-positioned proxies — measuring the
60
- * wrapper there races the host's layout effects). Called on open and on every
61
- * scroll/resize; return null to skip placement for that frame.
95
+ * wrapper there races the host's layout effects). Called on open, each animation
96
+ * frame, and scroll/resize; return null to skip placement for that frame.
62
97
  * @param props.footer - rows pinned below the scrolling items area, separated
63
98
  * by a hairline; they stay visible while the items above scroll.
99
+ * @param props.children - component rows rendered after `items` in the same
100
+ * list, each a `role="menuitem"` button such as {@link MenuItemButton}; they
101
+ * share the keyboard walk, the submenu exclusivity, and the post-selection
102
+ * focus return.
64
103
  * @param props.selection - how a selected row is marked: a trailing check
65
104
  * (`'check'`, default — figma .Menu_cell) or the hover fill held on the row
66
105
  * with no check (`'fill'`, for icon-labelled rows where a trailing glyph
67
106
  * crowds the cell).
107
+ * @param props.className - extra class on the anchor wrapper span.
108
+ * @param props.listClassName - extra class on the dropdown card itself; the
109
+ * only style hook that reaches a portaled list, which renders under
110
+ * document.body outside the owner's DOM subtree.
68
111
  * @returns anchor wrapper with the conditional list.
69
112
  */
70
- export declare function Menu({ open, anchor, items, selectedId, selectedIds, onSelect, onClose, align, side, portal, closeOnPointerLeave, dense, compact, autoFocus, selection, getAnchorRect, footer, className }: {
113
+ export declare function Menu({ open, anchor, items, children, selectedId, selectedIds, onSelect, onClose, align, side, portal, closeOnPointerLeave, dense, compact, autoFocus, selection, getAnchorRect, footer, className, listClassName }: {
71
114
  open: boolean;
72
115
  autoFocus?: boolean;
73
116
  anchor: ReactNode;
74
- items: readonly MenuEntry[];
117
+ items?: readonly MenuEntry[];
118
+ children?: ReactNode;
75
119
  footer?: readonly MenuEntry[];
76
120
  selectedId?: string | undefined;
77
121
  selectedIds?: readonly string[] | undefined;
78
- onSelect: (id: string) => void;
122
+ onSelect?: (id: string) => void;
79
123
  onClose: () => void;
80
124
  align?: 'start' | 'end';
81
125
  side?: 'bottom' | 'top' | 'right';
@@ -86,5 +130,6 @@ export declare function Menu({ open, anchor, items, selectedId, selectedIds, onS
86
130
  selection?: 'check' | 'fill';
87
131
  getAnchorRect?: () => DOMRect | null;
88
132
  className?: string | undefined;
133
+ listClassName?: string | undefined;
89
134
  }): import("react").JSX.Element;
90
135
  //# sourceMappingURL=Menu.d.ts.map
@@ -0,0 +1,13 @@
1
+ /** A single-line file path whose trailing characters remain visible in narrow toolbars. */
2
+ import { type HTMLAttributes } from 'react';
3
+ /**
4
+ * Render subdued directories and a primary filename, with the complete path on hover.
5
+ * Fitting text is left-aligned; overflow clips and fades at the left edge.
6
+ * The fade updates on path changes and, when ResizeObserver is available, size changes.
7
+ * @param props - File path and attributes for its outer span; callers own toolbar spacing.
8
+ * @returns the path label.
9
+ */
10
+ export declare function PathLabel({ path, className, ...attributes }: {
11
+ path: string;
12
+ } & Omit<HTMLAttributes<HTMLSpanElement>, 'children' | 'title'>): import("react").JSX.Element;
13
+ //# sourceMappingURL=PathLabel.d.ts.map
@@ -0,0 +1,39 @@
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
+ //# sourceMappingURL=PermissionIcon.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { type CodeToolbarLabels } from './CodeToolbar.tsx';
1
2
  /**
2
3
  * Content lines shown before the height cap collapses the middle. Matches
3
4
  * TerminalBlock's default so a long read and a long command output cut at the
@@ -28,7 +29,7 @@ export interface ReadBlockProps {
28
29
  className?: string | undefined;
29
30
  }
30
31
  /** Localized chrome for {@link ReadBlock}. */
31
- export interface ReadBlockLabels {
32
+ export interface ReadBlockLabels extends CodeToolbarLabels {
32
33
  window: (shown: number, total: number) => string;
33
34
  copy: string;
34
35
  copied: string;