@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
@@ -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
@@ -0,0 +1,35 @@
1
+ /** One segment of a {@link SegmentedControl}. */
2
+ export interface SegmentedControlOption<Value extends string> {
3
+ /** The value the owner receives when this segment is chosen. */
4
+ value: Value;
5
+ /** Localized segment text. */
6
+ label: string;
7
+ /** Whether the segment refuses selection. */
8
+ disabled?: boolean;
9
+ /** Localized hover text, typically why the segment is locked. */
10
+ title?: string;
11
+ }
12
+ /**
13
+ * Render a segmented control.
14
+ * @param props.id - the owner's base id: each tab is `<id>-<value>` and names
15
+ * `<id>-<value>-panel` as the panel it controls.
16
+ * @param props.value - the selected option's value; the control is fully controlled.
17
+ * @param props.options - the segments in display order; at least two.
18
+ * @param props.onChange - called with the value a click or a walk key asks for,
19
+ * never with the value already selected.
20
+ * @param props.label - localized accessible name of the tablist.
21
+ * @param props.disabled - lock every segment, typically while the shown panel
22
+ * has a write or a fetch in flight that switching would orphan.
23
+ * @param props.className - extra class for layout placement.
24
+ * @returns the tablist element.
25
+ */
26
+ export declare function SegmentedControl<Value extends string>({ id, value, options, onChange, label, disabled, className, }: {
27
+ id: string;
28
+ value: Value;
29
+ options: readonly SegmentedControlOption<Value>[];
30
+ onChange: (next: Value) => void;
31
+ label: string;
32
+ disabled?: boolean;
33
+ className?: string | undefined;
34
+ }): import("react").JSX.Element;
35
+ //# sourceMappingURL=SegmentedControl.d.ts.map
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from 'react';
2
+ /** A tab links its localized label to a caller-owned panel. */
3
+ export interface SegmentedTab<Value extends string = string> {
4
+ value: Value;
5
+ label: ReactNode;
6
+ id: string;
7
+ panelId: string;
8
+ }
9
+ /**
10
+ * Render equal-width, controlled tabs with a sliding selection indicator.
11
+ * @param props.items - non-empty ordered tabs with unique values and DOM ids.
12
+ * @param props.value - selected value, which must belong to items.
13
+ * @param props.onChange - selection requested by click, Left/Right, or Home/End.
14
+ * Keyboard selection also moves focus; only the selected tab is a tab stop.
15
+ * @param props.label - localized accessible name for the tab list.
16
+ * @param props.className - layout placement; panels remain caller-owned.
17
+ * @returns the tab list, without its panels.
18
+ */
19
+ export declare function SegmentedTabs<Value extends string>({ items, value, onChange, label, className }: {
20
+ items: readonly [SegmentedTab<Value>, ...SegmentedTab<Value>[]];
21
+ value: Value;
22
+ onChange: (value: Value) => void;
23
+ label: string;
24
+ className?: string | undefined;
25
+ }): ReactNode;
26
+ //# 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
@@ -1,18 +1,20 @@
1
1
  /**
2
- * State semantic: green done / amber user-attention / blue running ring /
3
- * red error / grey idle for a tracked subject with nothing in progress.
2
+ * State semantic: green done / amber user-attention / tertiary-grey loading /
3
+ * red error / neutral-grey idle for a tracked subject with nothing in progress.
4
4
  */
5
5
  export type StateDotState = 'done' | 'warning' | 'ongoing' | 'error' | 'idle';
6
6
  /**
7
7
  * Render a state dot.
8
8
  * @param props.state - which of `done`, `warning`, `ongoing`, `error`, or `idle` to show.
9
- * @param props.size - outer diameter in px (default 10, the figma size).
9
+ * @param props.size - outer diameter in px; defaults to 14 for ongoing and 10 for solid states.
10
10
  * @param props.className - extra class for layout placement.
11
+ * @param props.appearance - compact dot by default; step uses a filled check or hollow pending circle.
11
12
  * @returns the dot element (aria-hidden; pair with text for accessibility).
12
13
  */
13
- export declare function StateDot({ state, size, className }: {
14
+ export declare function StateDot({ state, size, className, appearance }: {
14
15
  state: StateDotState;
15
16
  size?: number | undefined;
16
17
  className?: string | undefined;
18
+ appearance?: 'dot' | 'step';
17
19
  }): import("react").JSX.Element;
18
20
  //# sourceMappingURL=StateDot.d.ts.map
@@ -46,12 +46,24 @@ export interface TerminalBlockProps {
46
46
  /** Settled terminating signal name; any value renders the status pill, taking precedence over the exit code. */
47
47
  signal?: string | undefined;
48
48
  /**
49
- * The command is still running: the block shows the prompt line, and the
50
- * output printed so far when there is any, with no copy control until it settles.
49
+ * The command is still running: with no `output` the block shows the prompt
50
+ * line alone; with output it renders the live text under the running state.
51
51
  */
52
52
  running?: boolean | undefined;
53
53
  /** Height cap in output lines before the middle collapses (default {@link DEFAULT_TERMINAL_MAX_LINES}); Infinity disables the cap. */
54
54
  maxLines?: number | undefined;
55
+ /**
56
+ * Copy-control payload override; the control copies the raw output when
57
+ * absent. Supplying it also keeps the control rendered before any output
58
+ * exists — a command is copyable before it prints.
59
+ */
60
+ copyText?: string | undefined;
61
+ /**
62
+ * Draw the run-state dot and its assistive label in the card gutter
63
+ * (default true). Hosts whose surrounding row already carries the same
64
+ * state omit both and reclaim the gutter via `--dsl-terminal-gutter`.
65
+ */
66
+ runStateDot?: boolean | undefined;
55
67
  /** Extra class merged onto the wrapper (callers position; this component draws). */
56
68
  className?: string | undefined;
57
69
  /** Localized display copy supplied by the owning render site. */
@@ -62,5 +74,5 @@ export interface TerminalBlockProps {
62
74
  * @param props - see {@link TerminalBlockProps}.
63
75
  * @returns the terminal block element.
64
76
  */
65
- export declare function TerminalBlock({ command, cwd, home, output, exitCode, signal, running, maxLines, className, labels, }: TerminalBlockProps): import("react").JSX.Element;
77
+ export declare function TerminalBlock({ command, cwd, home, output, exitCode, signal, running, maxLines, copyText, runStateDot, className, labels, }: TerminalBlockProps): import("react").JSX.Element;
66
78
  //# sourceMappingURL=TerminalBlock.d.ts.map
@@ -0,0 +1,13 @@
1
+ /** Text and activity supplied by the owning row. */
2
+ export interface TextShimmerProps {
3
+ children: string;
4
+ active: boolean;
5
+ className?: string | undefined;
6
+ }
7
+ /**
8
+ * Render text with an optional moving highlight; inactive text keeps the same node.
9
+ * @param props - localized text, running state, and owner styling.
10
+ * @returns the retained text span.
11
+ */
12
+ export declare const TextShimmer: import("react").MemoExoticComponent<({ children, active, className }: TextShimmerProps) => import("react").JSX.Element>;
13
+ //# sourceMappingURL=TextShimmer.d.ts.map
@@ -6,6 +6,8 @@ import type { ReactNode } from 'react';
6
6
  * per-show sequence). Rendered through a body portal so an owner inside a
7
7
  * transformed or filtered ancestor cannot trap the fixed banner in that
8
8
  * ancestor's box.
9
+ * With unchanged holdMs, parent rerenders do not extend the lifetime.
10
+ * Completion calls the latest onDone handler; fully faded actions receive no input.
9
11
  *
10
12
  * The hold is the owner's to set, because how long a banner has to stay
11
13
  * depends on how much there is to read: a one-line limit lands in the default
@@ -14,7 +16,16 @@ import type { ReactNode } from 'react';
14
16
  * reads it as a custom property — so the two can no longer disagree and leave
15
17
  * the banner unmounting mid-fade.
16
18
  * @param props.text - resolved banner copy; the owner passes localized text.
17
- * @param props.icon - optional leading glyph (e.g. a warning icon).
19
+ * @param props.icon - optional leading glyph (e.g. a warning icon); ignored
20
+ * under `tone="success"`, which brings its own glyph.
21
+ * @param props.tone - 'success' renders the design's circled green check as
22
+ * the leading glyph; omitted, the icon seat keeps its warning tint.
23
+ * @param props.actions - optional inline actions continuing the sentence:
24
+ * each renders its plain-text `prefix` (a connective like 或) followed by its
25
+ * localized `label` as blue clickable text, flowing after `text` as one
26
+ * sentence. Each press is the owner's to handle (e.g. undo the reported
27
+ * change, then unmount the toast). The banner surface stays click-through —
28
+ * only the action text takes the pointer.
18
29
  * @param props.holdMs - full-opacity hold before the fade; defaults to 3000.
19
30
  * @param props.anchor - optional element whose horizontal center the banner
20
31
  * follows (e.g. the composer card, so the banner centers over the chat column
@@ -22,11 +33,17 @@ import type { ReactNode } from 'react';
22
33
  * @param props.onDone - called once the fade completes; unmount the toast here.
23
34
  * @returns the floating banner.
24
35
  */
25
- export declare function Toast({ text, icon, anchor, holdMs, onDone }: {
36
+ export declare function Toast({ text, icon, tone, anchor, holdMs, actions, onDone }: {
26
37
  text: string;
27
38
  icon?: ReactNode;
39
+ tone?: 'success';
28
40
  anchor?: HTMLElement | null;
29
41
  holdMs?: number;
42
+ actions?: readonly {
43
+ label: string;
44
+ prefix?: string;
45
+ onClick: () => void;
46
+ }[];
30
47
  onDone: () => void;
31
48
  }): import("react").ReactPortal;
32
49
  //# sourceMappingURL=Toast.d.ts.map
@@ -1,3 +1,4 @@
1
+ /** Anchor-preserving tooltips with optional body portals for clipping containers. */
1
2
  import type { FocusEventHandler, MouseEventHandler, ReactElement, Ref } from 'react';
2
3
  /** Bubble placement relative to the anchor. */
3
4
  export type TooltipSide = 'right' | 'bottom' | 'top';
@@ -6,6 +7,7 @@ interface AnchorProps {
6
7
  ref?: Ref<HTMLElement> | undefined;
7
8
  onMouseEnter?: MouseEventHandler | undefined;
8
9
  onMouseLeave?: MouseEventHandler | undefined;
10
+ onClick?: MouseEventHandler | undefined;
9
11
  onFocus?: FocusEventHandler | undefined;
10
12
  onBlur?: FocusEventHandler | undefined;
11
13
  }
@@ -14,19 +16,28 @@ type TooltipLabel = string | (() => string);
14
16
  * Attach a hover/focus tooltip to an anchor element.
15
17
  * @param props.label - bubble text, or a resolver evaluated only while the bubble is visible.
16
18
  * @param props.side - placement relative to the anchor (default 'right').
19
+ * @param props.align - horizontal anchor-edge alignment for 'bottom'/'top' bubbles: 'end' pins
20
+ * the bubble's right edge to the anchor's (for anchors beside other hover surfaces the centered
21
+ * bubble would overlap); default 'center'. Ignored for side 'right'.
22
+ * @param props.portal - render the bubble under document.body to escape containing blocks and clipping ancestors.
17
23
  * @param props.delayMs - hover delay in milliseconds; keyboard focus remains immediate.
18
24
  * @param props.disabled - suppress the bubble while true; the anchor renders identically so
19
25
  * toggling never remounts it (which would cut its CSS transitions).
20
26
  * @param props.maxWidth - bubble width cap in pixels, for labels long enough that the default
21
27
  * half-viewport cap would render a slab wider than the surface the anchor sits on.
22
28
  * @param props.children - a single anchor element; its own ref (callback or object) is forwarded alongside the tooltip's.
23
- * @returns the cloned anchor plus a fixed-position bubble while hovered/focused.
29
+ * @returns the cloned anchor plus a fixed-position bubble, optionally portaled to the body.
30
+ * The bubble stays hidden until ResizeObserver supplies its size for viewport fitting; clicking the
31
+ * anchor dismisses the bubble until the next trigger, and focus arriving after a pointer
32
+ * interaction (a closing menu refocusing its trigger) never raises it.
24
33
  */
25
- export declare function Tooltip({ label, side, delayMs, disabled, maxWidth, children }: {
34
+ export declare function Tooltip({ label, side, align, delayMs, disabled, portal, maxWidth, children }: {
26
35
  label: TooltipLabel;
27
36
  side?: TooltipSide;
37
+ align?: 'center' | 'end';
28
38
  delayMs?: number;
29
39
  disabled?: boolean;
40
+ portal?: boolean;
30
41
  maxWidth?: number;
31
42
  children: ReactElement<AnchorProps>;
32
43
  }): import("react").JSX.Element;
@@ -14,7 +14,7 @@ export interface FileTypeProjectContext {
14
14
  */
15
15
  export declare function isCodeFileType(type: string): type is CodeFileType;
16
16
  /**
17
- * Test whether an extension belonged to the established coarse LinkIcon code category.
17
+ * Test whether an extension belongs to the established coarse link-icon code category.
18
18
  * @param extension - Extension without a leading dot.
19
19
  * @returns Whether clickable links keep the code glyph for this extension.
20
20
  */
@@ -0,0 +1,19 @@
1
+ import { type HighlightSpan } from './markdown/highlight.ts';
2
+ /** Recognized filename suffixes whose source can use the shared syntax highlighter. */
3
+ export declare const CODE_HIGHLIGHT_EXTENSIONS: readonly string[];
4
+ /**
5
+ * Select the shared syntax highlighter's grammar from a filename.
6
+ * @param path - decoded source filename or path.
7
+ * @returns a supported grammar hint, or `undefined` for other suffixes.
8
+ */
9
+ export declare function languageForPath(path: string): string | undefined;
10
+ /** Highlight one source fragment into one token list per line. */
11
+ export type CodeHighlighter = (code: string) => HighlightSpan[][] | undefined;
12
+ /**
13
+ * Bind the shared lazy highlighter to one language and refresh after its grammar loads.
14
+ * @param language - grammar hint selected from the source filename.
15
+ * @returns a stable fragment highlighter; unknown and loading grammars return `undefined` for plain-text fallback.
16
+ */
17
+ export declare function useCodeHighlighter(language: string | undefined): CodeHighlighter;
18
+ export type { HighlightSpan };
19
+ //# sourceMappingURL=code-highlighting.d.ts.map