@seekbuddy/dsh-ui 0.2.0-beta.0 → 0.2.0-beta.1

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 (97) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/README.zh.md +1 -1
  4. package/THIRD_PARTY_NOTICES.md +1 -1
  5. package/UPSTREAM.md +7 -4
  6. package/dist/blocks.js +170 -135
  7. package/dist/chunks/{chunk-VIH56PDF.js → chunk-6SGSJ5KW.js} +2 -2
  8. package/dist/chunks/{chunk-QJKAQ6PO.js → chunk-7NH2UOZO.js} +2 -2
  9. package/dist/chunks/{chunk-KETGFAOH.js → chunk-7SKW4S35.js} +2 -2
  10. package/dist/chunks/chunk-ENKPNYOB.js +26 -0
  11. package/dist/chunks/{chunk-WUL523OW.js → chunk-EWAZFWLW.js} +1 -1
  12. package/dist/chunks/{chunk-5JXG4BHW.js → chunk-FFJ6TCCF.js} +1 -1
  13. package/dist/chunks/{chunk-R6AUJQ3G.js → chunk-FZXK4LTI.js} +1 -1
  14. package/dist/chunks/chunk-JA3XDLIA.js +1115 -0
  15. package/dist/chunks/{chunk-TUK6UGXM.js → chunk-L7XALG4J.js} +1 -1
  16. package/dist/chunks/{chunk-AY44MQMD.js → chunk-OCAQFVT3.js} +180 -60
  17. package/dist/chunks/{chunk-CI73NXA5.js → chunk-RAXDA2PT.js} +4 -4
  18. package/dist/chunks/{chunk-5XDVPALS.js → chunk-SN6RSUWC.js} +1 -1
  19. package/dist/chunks/{chunk-CTQPGUZP.js → chunk-SNVSQWCU.js} +1 -1
  20. package/dist/chunks/{chunk-ZZNL5PWF.js → chunk-SO3DCAWG.js} +2 -2
  21. package/dist/chunks/{chunk-IOBKTEKP.js → chunk-UAEFKTV3.js} +1 -1
  22. package/dist/chunks/{chunk-NE62SYOZ.js → chunk-UGEORMLD.js} +2 -2
  23. package/dist/chunks/{chunk-TQU54HSM.js → chunk-W6FLI3AK.js} +1 -1
  24. package/dist/chunks/{chunk-TZ7HRE6D.js → chunk-WX46TSKP.js} +1 -1
  25. package/dist/chunks/{chunk-XX6MSZLS.js → chunk-XL33IPCV.js} +1 -1
  26. package/dist/chunks/chunk-XW4L4ZGL.js +967 -0
  27. package/dist/chunks/chunk-YOBY6PSL.js +850 -0
  28. package/dist/icons.js +58 -2
  29. package/dist/index.js +810 -317
  30. package/dist/markdown.js +84 -7
  31. package/dist/meta.json +1038 -339
  32. package/dist/root-inputs.json +20 -1
  33. package/dist/seekbuddy-card.js +1 -1
  34. package/dist/seekbuddy-empty.js +2 -2
  35. package/dist/seekbuddy-internal/Message.js +2 -2
  36. package/dist/seekbuddy-internal/Pagination.js +1 -1
  37. package/dist/seekbuddy-internal/StatusBadge.js +1 -1
  38. package/dist/seekbuddy-internal/Switch.js +1 -1
  39. package/dist/seekbuddy-internal/Upload.js +1 -1
  40. package/dist/seekbuddy-internal/date/Calendar.js +1 -1
  41. package/dist/seekbuddy-internal/date/DatePicker.js +2 -2
  42. package/dist/seekbuddy-internal/date/DateRangePicker.js +2 -2
  43. package/dist/seekbuddy-internal/date/TimePicker.js +1 -1
  44. package/dist/seekbuddy-internal/date/fields.js +5 -5
  45. package/dist/seekbuddy-spinner.js +1 -1
  46. package/dist/seekbuddy-tabs.js +1 -1
  47. package/dist/seekbuddy-timeline.js +2 -2
  48. package/dist/seekbuddy.js +15 -15
  49. package/dist/tokens.css +60 -20
  50. package/dist/types/AnimatedRows.d.ts +45 -0
  51. package/dist/types/Button.d.ts +1 -1
  52. package/dist/types/CommandText.d.ts +15 -0
  53. package/dist/types/DetailDocument.d.ts +77 -0
  54. package/dist/types/DisclosureRow.d.ts +4 -2
  55. package/dist/types/DraggableImage.d.ts +18 -0
  56. package/dist/types/HoverCard.d.ts +11 -3
  57. package/dist/types/HoverCardGroup.d.ts +24 -0
  58. package/dist/types/ImageLightbox.d.ts +4 -1
  59. package/dist/types/InlineEditor.d.ts +22 -0
  60. package/dist/types/Menu.d.ts +30 -9
  61. package/dist/types/MenuSurface.d.ts +9 -0
  62. package/dist/types/PermissionIcon.d.ts +12 -0
  63. package/dist/types/QuotePreview.d.ts +23 -0
  64. package/dist/types/SegmentedTabs.d.ts +3 -1
  65. package/dist/types/TerminalBlock.d.ts +10 -2
  66. package/dist/types/Tooltip.d.ts +21 -15
  67. package/dist/types/UserMessageBubble.d.ts +10 -0
  68. package/dist/types/ZoomControls.d.ts +26 -0
  69. package/dist/types/blocks.d.ts +2 -0
  70. package/dist/types/document-zoom.d.ts +16 -0
  71. package/dist/types/file-drag-actions.d.ts +36 -0
  72. package/dist/types/focus.d.ts +7 -0
  73. package/dist/types/icons/artwork.d.ts +421 -0
  74. package/dist/types/icons/index.d.ts +205 -192
  75. package/dist/types/icons/shared-artwork.d.ts +6 -12
  76. package/dist/types/icons.d.ts +1 -1
  77. package/dist/types/image-drag.d.ts +16 -0
  78. package/dist/types/index.d.ts +21 -3
  79. package/dist/types/markdown/MarkdownDelegate.d.ts +26 -3
  80. package/dist/types/markdown/MarkdownText.d.ts +12 -5
  81. package/dist/types/markdown/file-link.d.ts +13 -3
  82. package/dist/types/markdown/highlight.d.ts +22 -0
  83. package/dist/types/markdown/quote-text.d.ts +7 -0
  84. package/dist/types/markdown/render.d.ts +9 -4
  85. package/dist/types/markdown/windows-path-destinations.d.ts +10 -0
  86. package/dist/types/markdown.d.ts +5 -2
  87. package/dist/types/overlay-top-margin.d.ts +9 -2
  88. package/dist/types/tooltip-placement.d.ts +34 -0
  89. package/dist/types/use-clipboard-copy.d.ts +13 -0
  90. package/dist/types/useAnchoredPosition.d.ts +22 -22
  91. package/dist/types/useRowDragPreview.d.ts +19 -0
  92. package/dist/types/user-text.d.ts +26 -31
  93. package/package.json +2 -2
  94. package/dist/chunks/chunk-3HCOU44R.js +0 -697
  95. package/dist/chunks/chunk-LA3QDZYN.js +0 -2777
  96. package/dist/chunks/chunk-OQPH36OI.js +0 -754
  97. package/dist/types/use-copy-feedback.d.ts +0 -13
@@ -3,38 +3,32 @@ interface WeightedArtworkProps extends IconProps {
3
3
  strokeWidth: number;
4
4
  }
5
5
  /**
6
- * Render new-conversation geometry — the bubble around a plus — for product icons.
7
- * @param props - Size, optional CSS class, and inherited stroke width.
8
- * @returns The decorative SVG artwork.
9
- */
10
- export declare const NewChatOutlineArtwork: ({ size, className, strokeWidth }: WeightedArtworkProps) => import("react").JSX.Element;
11
- /**
12
- * Render shared conversation geometry — the chat bubble around two text
13
- * lines — for the queue product icon and session reference icons.
6
+ * Render conversation geometry — the chat bubble around two text lines —
7
+ * for session reference icons; it matches the `queue-outline` product glyph.
14
8
  * @param props - Size, optional CSS class, and inherited stroke width.
15
9
  * @returns The decorative SVG artwork.
16
10
  */
17
11
  export declare const ChatLinesOutlineArtwork: ({ size, className, strokeWidth }: WeightedArtworkProps) => import("react").JSX.Element;
18
12
  /**
19
- * Render shared globe geometry for product and link icons.
13
+ * Render globe geometry for link icons; it matches the `globe-outline` product glyph.
20
14
  * @param props - Size, optional CSS class, and inherited stroke width.
21
15
  * @returns The decorative SVG artwork.
22
16
  */
23
17
  export declare const GlobeOutlineArtwork: ({ size, className, strokeWidth }: WeightedArtworkProps) => import("react").JSX.Element;
24
18
  /**
25
- * Render shared code-bracket geometry for product and link icons.
19
+ * Render code-bracket geometry for link icons; it matches the `inspect-outline` product glyph.
26
20
  * @param props - Size, optional CSS class, and inherited stroke width.
27
21
  * @returns The decorative SVG artwork.
28
22
  */
29
23
  export declare const CodeBracketsArtwork: ({ size, className, strokeWidth }: WeightedArtworkProps) => import("react").JSX.Element;
30
24
  /**
31
- * Render shared document-browse geometry for product and reference icons.
25
+ * Render document-browse geometry for reference icons; it matches the `browse-outline` product glyph.
32
26
  * @param props - Size, optional CSS class, and inherited stroke width.
33
27
  * @returns The decorative SVG artwork.
34
28
  */
35
29
  export declare const BrowseOutlineArtwork: ({ size, className, strokeWidth }: WeightedArtworkProps) => import("react").JSX.Element;
36
30
  /**
37
- * Render shared closed-folder geometry for product, reference, and link icons.
31
+ * Render closed-folder geometry for reference and link icons; it matches the `folder-close` product glyph.
38
32
  * @param props - Size, optional CSS class, and inherited stroke width.
39
33
  * @returns The decorative SVG artwork.
40
34
  */
@@ -1,5 +1,5 @@
1
1
  export * from './icons/index.js';
2
- export { PermissionIconFullAccessMedium, PermissionIconFullAccessRegular, PermissionIconReadOnlyMedium, PermissionIconReadOnlyRegular, PermissionIconWorkspaceWriteMedium, PermissionIconWorkspaceWriteRegular, } from './PermissionIcon.js';
2
+ export { PermissionIconAutoReviewMedium, PermissionIconAutoReviewRegular, PermissionIconFullAccessMedium, PermissionIconFullAccessRegular, PermissionIconReadOnlyMedium, PermissionIconReadOnlyRegular, PermissionIconWorkspaceWriteMedium, PermissionIconWorkspaceWriteRegular, } from './PermissionIcon.js';
3
3
  export { ReferenceIconMedium, ReferenceIconRegular } from './ReferenceIcon.js';
4
4
  export type { ReferenceIconKind, ReferenceIconProps } from './ReferenceIcon.js';
5
5
  export { PluginArtworkTerminal, PluginArtworkLoop, PluginArtworkSubagent, PluginArtworkSearch, PluginArtworkDefault, } from './plugin-artwork.js';
@@ -0,0 +1,16 @@
1
+ /** Image gestures delegate file preparation and transport to the owning feature. */
2
+ import { type ImgHTMLAttributes } from 'react';
3
+ import type { FileDragActions } from './file-drag-actions.js';
4
+ type ImageGestures = Required<Pick<ImgHTMLAttributes<HTMLImageElement>, 'onPointerEnter' | 'onPointerDown' | 'onPointerLeave' | 'onDragStart' | 'onDragEnd' | 'onClickCapture'>>;
5
+ /**
6
+ * Prepare resource-backed images on primary press, other images also on hover; release on leave.
7
+ * Releasing inside the image retains preparation for the next gesture; cancelled drags never start late.
8
+ * @param actions - stable file preparation and error callbacks.
9
+ * @param src - displayed image URL.
10
+ * @param name - proposed export name.
11
+ * @param original - already loaded original bytes.
12
+ * @param resourceAddress - verifiable reference to an unmodified local original.
13
+ * @returns image gesture handlers; overflowing images remain owned by their pan handler.
14
+ */
15
+ export declare function useImageDrag(actions: FileDragActions, src: string, name: string, original?: File, resourceAddress?: string): ImageGestures;
16
+ export {};
@@ -20,7 +20,7 @@ export type { SegmentedControlOption } from './SegmentedControl.js';
20
20
  export { Checkbox } from './Checkbox.js';
21
21
  export { Input } from './Input.js';
22
22
  export { Menu, MenuItemButton } from './Menu.js';
23
- export { MenuSurface } from './MenuSurface.js';
23
+ export { MenuSurface, MENU_TRANSITION_MS } from './MenuSurface.js';
24
24
  export type { MenuSurfaceProps } from './MenuSurface.js';
25
25
  export { MenuGroup, observeStickyMenuGroups } from './MenuGroup.js';
26
26
  export type { MenuItemButtonProps, MenuEntry, MenuItem, MenuSeparator, MenuLabel } from './Menu.js';
@@ -29,16 +29,32 @@ export { useAnchoredPosition } from './useAnchoredPosition.js';
29
29
  export type { AnchoredPositionOptions } from './useAnchoredPosition.js';
30
30
  export { useDismissOnOutsidePointer } from './useDismissOnOutsidePointer.js';
31
31
  export { HoverCard } from './HoverCard.js';
32
+ export { HoverCardGroup } from './HoverCardGroup.js';
32
33
  export { ShortcutKeys } from './ShortcutKeys.js';
33
34
  export { observeComposition } from './keyboard-composition.js';
34
- export { focusWithoutRing } from './focus.js';
35
+ export { focusWithoutRing, isMobileDevice } from './focus.js';
35
36
  export { closeTopModal, isBehindModal, modalSelector, useModalLayer } from './useModalLayer.js';
36
37
  export { Modal } from './Modal.js';
37
38
  export { RiskConfirmation } from './RiskConfirmation.js';
38
39
  export type { RiskConfirmationProps } from './RiskConfirmation.js';
39
40
  export { ConnectionIndicator } from './ConnectionIndicator.js';
40
41
  export type { ConnectionIndicatorState } from './ConnectionIndicator.js';
41
- export { projectUserText, type UserTextReferences } from './user-text.js';
42
+ export { UserTextRun, ReferenceChip, type UserTextRunProps, type ReferenceChipProps } from './user-text.js';
43
+ export { UserMessageBubble } from './UserMessageBubble.js';
44
+ export type { UserMessageBubbleProps } from './UserMessageBubble.js';
45
+ export { AnimatedRows } from './AnimatedRows.js';
46
+ export type { AnimatedRowsProps } from './AnimatedRows.js';
47
+ export { useRowDragPreview } from './useRowDragPreview.js';
48
+ export { ZoomControls } from './ZoomControls.js';
49
+ export type { ZoomControlsHandle } from './ZoomControls.js';
50
+ export { DOCUMENT_ZOOM } from './document-zoom.js';
51
+ export type { DocumentZoomLabels } from './document-zoom.js';
52
+ export { InlineEditor } from './InlineEditor.js';
53
+ export type { FileDragActions, FileDragSource, PreparedFileDrag } from './file-drag-actions.js';
54
+ export { DraggableImage } from './DraggableImage.js';
55
+ export type { DraggableImageProps } from './DraggableImage.js';
56
+ export { QuotePreview } from './QuotePreview.js';
57
+ export type { QuotePreviewProps, QuotePreviewRemoval } from './QuotePreview.js';
42
58
  export { Tooltip } from './Tooltip.js';
43
59
  export type { TooltipSide } from './Tooltip.js';
44
60
  export { pointerModality } from './input-modality.js';
@@ -47,6 +63,8 @@ export { ImageLightbox } from './ImageLightbox.js';
47
63
  export type { ImageLightboxLabels } from './ImageLightbox.js';
48
64
  export { fileSizeText } from './file-size.js';
49
65
  export { writeClipboard } from './clipboard.js';
66
+ export { useClipboardCopy } from './use-clipboard-copy.js';
67
+ export type { ClipboardCopyState } from './use-clipboard-copy.js';
50
68
  export { relativeTime } from './relative-time.js';
51
69
  export { rankByName } from './rank-by-name.js';
52
70
  export { isDarwinDesktop } from './darwin-desktop.js';
@@ -1,15 +1,38 @@
1
- import type { ReactNode } from 'react';
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import type { FileDragActions } from '../file-drag-actions.js';
2
3
  import type { ImageLightboxLabels } from '../ImageLightbox.js';
3
4
  /**
4
5
  * Handle one sanitized absolute HTTP(S) URL selected from Markdown.
5
6
  * @param href - destination URL.
6
7
  */
7
8
  export type MarkdownExternalLinkHandler = (href: string) => void;
9
+ /** Explicit object and viewport coordinates from the element owning a context gesture. */
10
+ export type MarkdownMenuTarget = {
11
+ kind: 'file';
12
+ path: string;
13
+ line?: number;
14
+ } | {
15
+ kind: 'url';
16
+ url: string;
17
+ } | {
18
+ kind: 'image';
19
+ url: string;
20
+ path?: string;
21
+ name?: string;
22
+ mediaType?: string;
23
+ };
8
24
  /** Navigation capabilities supplied by the nearest Markdown owner. */
9
25
  export interface MarkdownDelegate {
10
- /** Image previews for decoded local paths in this owner's workspace. */
26
+ /** Open an object menu without executing its normal activation. */
27
+ readonly getTriggerProps?: ((target: MarkdownMenuTarget) => Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>) | undefined;
28
+ /**
29
+ * Image previews for decoded local paths in this owner's workspace. The renderer
30
+ * appends a per-mount `load` query parameter to `api/file` route URLs.
31
+ */
11
32
  readonly fileImages?: {
33
+ fileDrag: FileDragActions;
12
34
  resolve: (path: string) => string | undefined;
35
+ resourceAddress?: ((path: string) => string) | undefined;
13
36
  labels: ImageLightboxLabels & {
14
37
  open: string;
15
38
  loading: string;
@@ -37,7 +60,7 @@ export interface MarkdownDelegateProviderProps extends MarkdownDelegate {
37
60
  * @param props - Child tree and its file and HTTP(S) link handlers.
38
61
  * @returns the scoped child tree.
39
62
  */
40
- export declare function MarkdownDelegateProvider({ children, openExternalLink, openFile, fileImages, }: MarkdownDelegateProviderProps): ReactNode;
63
+ export declare function MarkdownDelegateProvider({ children, openExternalLink, openFile, fileImages, getTriggerProps, }: MarkdownDelegateProviderProps): ReactNode;
41
64
  /**
42
65
  * Read the nearest Markdown navigation capabilities.
43
66
  * @returns Owner callbacks, or an empty delegate outside a provider.
@@ -30,18 +30,25 @@ export type { MarkdownCodeLabels, MarkdownFileMentions, MarkdownLabels, Markdown
30
30
  * `MarkdownDelegateProvider` can delegate ordinary HTTP(S) activation while
31
31
  * modified clicks retain native behavior. `variant="compact"` uses secondary
32
32
  * text sizing, uniform bold headings, and tight block spacing; the default
33
- * `body` variant uses the full document typography.
33
+ * `body` variant uses the full document typography. `omitHtml` renders raw
34
+ * HTML as nothing instead of literal text, for documents written for HTML
35
+ * renderers, such as package READMEs. `textInteractionSource` marks the
36
+ * existing root as a source for text selection interactions.
34
37
  * The provider's `openFile` enables local Markdown links in settled messages,
35
- * including `#L24` and `#L24-L30` destinations (ranges open at their first line).
36
- * @returns A GFM document with TeX math rendered through KaTeX; raw HTML and
37
- * unsafe protocols are disabled. Local links without an opener remain text;
38
+ * including `#L24` / `#L24-L30` fragments and `:24` / `:24-30` / `:24:5` suffixes
39
+ * (ranges open at their first line, columns are ignored, and invalid locations
40
+ * open only the file; see the README for URL/path classification).
41
+ * @returns A GFM document with TeX math rendered through KaTeX; raw HTML never
42
+ * renders as markup, and unsafe protocols are disabled. Local links without an opener remain text;
38
43
  * absolute HTTP(S) images render directly.
39
44
  */
40
- export declare const MarkdownText: import("react").MemoExoticComponent<({ text, streaming, labels, fileMentions, pathImages, variant, }: {
45
+ export declare const MarkdownText: import("react").MemoExoticComponent<({ text, streaming, labels, fileMentions, pathImages, variant, omitHtml, textInteractionSource, }: {
41
46
  text: string;
42
47
  streaming?: boolean;
43
48
  labels: MarkdownLabels;
44
49
  fileMentions?: MarkdownFileMentions | undefined;
45
50
  pathImages?: MarkdownPathImages | undefined;
46
51
  variant?: 'body' | 'compact';
52
+ omitHtml?: boolean;
53
+ textInteractionSource?: boolean;
47
54
  }) => import("react").JSX.Element>;
@@ -1,10 +1,20 @@
1
1
  /** Local Markdown destinations accepted by the file-preview callback. */
2
2
  /**
3
- * Decode a file destination and its optional GitHub-style line fragment.
4
- * Literal `?` and `#` in filenames must be percent-encoded.
3
+ * Recognize a relative, rooted, or absolute Windows path before URL parsing.
4
+ * @param value - A decoded or URI-normalized destination.
5
+ * @returns Whether a filesystem prefix makes the destination unambiguous.
6
+ */
7
+ export declare function isExplicitFilePath(value: string): boolean;
8
+ /**
9
+ * Decode a file destination with a fragment, line range, or line/column suffix.
10
+ * Explicit relative, slash/backslash-rooted, and Windows drive paths take
11
+ * precedence over URLs. Other parseable absolute URLs are not file links.
12
+ * Fragments take precedence over colon suffixes; invalid locations open the
13
+ * file without selecting a line. Columns are consumed but not selected.
14
+ * Percent-encode literal `?`, `#`, and numeric colon suffixes in filenames.
5
15
  * @param value - Parsed Markdown link destination.
6
16
  * @returns A local path and optional first line, or undefined for URLs,
7
- * fragment-only links, queries, malformed escapes, or invalid line ranges.
17
+ * fragment-only links, queries, malformed escapes, or control characters.
8
18
  */
9
19
  export declare function parseFileLink(value: string): {
10
20
  path: string;
@@ -17,7 +17,28 @@
17
17
  * An unknown or absent language falls back to plain text (no highlighting, still
18
18
  * monospace) — never an error.
19
19
  */
20
+ import langTs from '@shikijs/langs/typescript';
20
21
  import type { CSSProperties } from 'react';
22
+ /** A shiki grammar module's default export (a `LanguageRegistration[]`), taken
23
+ * from a boot grammar so no direct `@shikijs/types` dependency is needed. */
24
+ type LangModule = {
25
+ default: typeof langTs;
26
+ };
27
+ /**
28
+ * Replace the Go grammar's repeated one-line struct-field rule with the rule
29
+ * worlpaker/go-syntax merged in 4a9b120a52c (https://github.com/worlpaker/go-syntax/pull/25):
30
+ * the repeated rule backtracks exponentially on lines such as a brace-bearing
31
+ * comment after `struct {`. Delete this patch once `@shikijs/langs` ships that
32
+ * commit; 4.5.0 does not. The rule is located as the only rule in
33
+ * `struct_variables_types_fields` containing the field-token literal below,
34
+ * taken from `@shikijs/langs` 4.4.3.
35
+ * @param grammars - the `@shikijs/langs/go` default export, left unmodified.
36
+ * @returns copies of `grammars` with that rule's match replaced in the `go` grammar.
37
+ * @throws When the module has no `go` grammar, the grammar lacks
38
+ * `struct_variables_types_fields`, or that entry has no or several such rules.
39
+ * The lazy load then rejects unhandled and Go code renders as plain text.
40
+ */
41
+ export declare function patchGoGrammar(grammars: LangModule['default']): LangModule['default'];
21
42
  /**
22
43
  * Resolve a language hint to the grammar id {@link LANG_ALIASES} selects.
23
44
  * @param lang - Language hint from a code surface: a canonical grammar id or the read card's persisted short id.
@@ -145,3 +166,4 @@ export interface StreamingHighlightFrame {
145
166
  * @returns one entry per source line (each an array of runs), or `undefined` for unknown or not-yet-loaded languages.
146
167
  */
147
168
  export declare function highlightLines(code: string, lang: string | undefined): HighlightSpan[][] | undefined;
169
+ export {};
@@ -0,0 +1,7 @@
1
+ /** Shared Markdown blockquote formatting for browser text. */
2
+ /**
3
+ * Project selected visible text as an ordinary Markdown blockquote.
4
+ * @param text - selected visible text without quote markers.
5
+ * @returns one `> `-prefixed line per normalized input line.
6
+ */
7
+ export declare function formatQuoteText(text: string): string;
@@ -4,17 +4,18 @@
4
4
  * cache frozen blocks as React elements; the rendered DOM is pinned
5
5
  * byte-for-byte by `tests/fixtures/markdown-dom` and must not drift.
6
6
  *
7
- * External link and image destinations pass a protocol allowlist; settled
7
+ * External links reject executable and embedded-document protocols; settled
8
8
  * local file links use an explicit owner callback. Images additionally require
9
9
  * absolute HTTP(S), raw HTML renders as literal text (no HTML enters the
10
- * DOM), and KaTeX runs without trusted commands. Fragment-anchor URLs fail
11
- * the allowlist, so footnote references and back-references render as plain
10
+ * DOM), and KaTeX runs without trusted commands. Fragment-only URLs are not
11
+ * absolute, so footnote references and back-references render as plain
12
12
  * text rather than in-page links.
13
13
  *
14
14
  * Merge-extensible node unions fall through the documented default (render
15
15
  * nothing) rather than ending in assertNever: grammars registered elsewhere
16
16
  * may add node types this renderer has no mapping for.
17
17
  */
18
+ import type { HTMLAttributes } from 'react';
18
19
  import type { ReactNode } from 'react';
19
20
  import type * as Md from 'mdast';
20
21
  import type { CodeToolbarLabels } from '../CodeToolbar.js';
@@ -65,7 +66,8 @@ export interface MarkdownPathImages {
65
66
  * Resolve one authored image destination.
66
67
  * @param value - The destination exactly as the markdown author wrote it.
67
68
  * @returns A displayable absolute URL, or undefined when the destination
68
- * names no displayable image — it then stays inert alt text.
69
+ * names no displayable image — it then stays inert alt text. The renderer
70
+ * appends a per-mount `load` query parameter to `api/file` route results.
69
71
  */
70
72
  resolve(value: string): string | undefined;
71
73
  }
@@ -83,6 +85,7 @@ export interface MarkdownFileMentions {
83
85
  */
84
86
  resolve(value: string): {
85
87
  open: () => void;
88
+ contextMenuProps?: Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>;
86
89
  label: string;
87
90
  title: string;
88
91
  } | undefined;
@@ -102,6 +105,8 @@ export interface MarkdownRenderContext {
102
105
  readonly fileMentions: MarkdownFileMentions | undefined;
103
106
  /** Local-path image vocabulary; absent wherever no rewriting owner exists. */
104
107
  readonly pathImages: MarkdownPathImages | undefined;
108
+ /** Raw HTML renders nothing instead of literal text. */
109
+ readonly omitHtml: boolean;
105
110
  /** Inside an anchor's children: interactive mentions must not nest there. */
106
111
  readonly inLink?: boolean;
107
112
  /** Reference targets visible to this pass. */
@@ -0,0 +1,10 @@
1
+ import type { Extension } from 'mdast-util-from-markdown';
2
+ /**
3
+ * CommonMark reads `\.` or `\_` in a destination as an escaped character, so
4
+ * `D:\repo\.github` would parse as `D:\repo.github`. For a destination that
5
+ * is a Windows path, this `fromMarkdown` extension keeps every backslash
6
+ * literally, including one before punctuation such as `\(`, while character
7
+ * references such as `&amp;` still decode; other destinations parse unchanged.
8
+ * @returns The mdast extension.
9
+ */
10
+ export declare function windowsPathDestinations(): Extension;
@@ -1,9 +1,12 @@
1
1
  export { CodeBlock } from './markdown/CodeBlock.js';
2
2
  export type { CodeBlockProps } from './markdown/CodeBlock.js';
3
3
  export { JsonBlock } from './markdown/JsonBlock.js';
4
- export { MarkdownDelegateProvider } from './markdown/MarkdownDelegate.js';
5
- export type { MarkdownDelegate, MarkdownDelegateProviderProps, MarkdownExternalLinkHandler, } from './markdown/MarkdownDelegate.js';
4
+ export { MarkdownDelegateProvider, useMarkdownDelegate } from './markdown/MarkdownDelegate.js';
5
+ export type { MarkdownMenuTarget, MarkdownDelegate, MarkdownDelegateProviderProps, MarkdownExternalLinkHandler, } from './markdown/MarkdownDelegate.js';
6
+ export { DetailDocument, detailDocumentState, useDetailDocumentLabels } from './DetailDocument.js';
7
+ export type { DetailDocumentCopy, DetailDocumentLabels, DetailDocumentRead, DetailDocumentState, } from './DetailDocument.js';
6
8
  export { MarkdownText } from './markdown/MarkdownText.js';
7
9
  export type { MarkdownCodeLabels, MarkdownFileMentions, MarkdownLabels, MarkdownPathImages, } from './markdown/MarkdownText.js';
10
+ export { formatQuoteText } from './markdown/quote-text.js';
8
11
  export { extractMarkdownPlainText } from './markdown/plain-text.js';
9
12
  export type { MarkdownPlainTextMode, MarkdownPlainTextOptions } from './markdown/plain-text.js';
@@ -2,6 +2,13 @@
2
2
  /**
3
3
  * Resolve the top margin an overlay keeps from the viewport edge.
4
4
  * @param min - the overlay's own viewport margin in px, used as the floor.
5
- * @returns the larger of `min` and the frame clearance plus 20px; fullscreen keeps only the 20px gap.
5
+ * @param anchor - the overlay's anchor rect in viewport coordinates. While the anchor's top edge is inside the
6
+ * viewport, the margin never exceeds `anchor.bottom + gap`, so an overlay opened from a control inside the top strip
7
+ * stays next to it.
8
+ * @param gap - the distance the overlay keeps below `anchor`.
9
+ * @returns the frame clearance plus 20px (20px in fullscreen), capped by a visible `anchor`, but never below `min`.
6
10
  */
7
- export declare function overlayTopMargin(min: number): number;
11
+ export declare function overlayTopMargin(min: number, anchor?: {
12
+ readonly top: number;
13
+ readonly bottom: number;
14
+ }, gap?: number): number;
@@ -0,0 +1,34 @@
1
+ /** Deterministic tooltip placement using measured border boxes and viewport coordinates. */
2
+ /** Bubble placement relative to the anchor. */
3
+ export type TooltipSide = 'right' | 'left' | 'bottom' | 'top';
4
+ interface PlacementInput {
5
+ anchor: {
6
+ left: number;
7
+ right: number;
8
+ top: number;
9
+ bottom: number;
10
+ };
11
+ width: number;
12
+ height: number;
13
+ viewportWidth: number;
14
+ viewportHeight: number;
15
+ side: TooltipSide;
16
+ align: 'center' | 'end';
17
+ gap: number;
18
+ }
19
+ interface TooltipPlacement {
20
+ left: number;
21
+ top: number;
22
+ width: number;
23
+ height: number;
24
+ side: TooltipSide;
25
+ /** No complete side fits, so placement is bounded by the viewport instead. */
26
+ overflow: boolean;
27
+ }
28
+ /**
29
+ * Prefer the requested side, its opposite, then perpendicular sides without covering the anchor.
30
+ * @param input - Observed dimensions, anchor edges, viewport and requested placement; horizontal gaps remain 10px.
31
+ * @returns Border-box coordinates and the selected side; if no side fits, a viewport-bounded fallback.
32
+ */
33
+ export declare function placeTooltip(input: PlacementInput): TooltipPlacement;
34
+ export {};
@@ -0,0 +1,13 @@
1
+ /** Clipboard action and its temporary success state. */
2
+ export interface ClipboardCopyState {
3
+ /** True for one second after an accepted clipboard write. */
4
+ readonly copied: boolean;
5
+ /** Write the current text unless a write or success indication is already active. */
6
+ readonly onCopy: () => void;
7
+ }
8
+ /**
9
+ * Keep clipboard feedback local to the mounted control and release its reset timer on unmount.
10
+ * @param text - Exact text to copy when the action is invoked.
11
+ * @returns Success feedback and a callback stable while text and feedback are unchanged.
12
+ */
13
+ export declare function useClipboardCopy(text: string): ClipboardCopyState;
@@ -1,35 +1,35 @@
1
- /**
2
- * Keep a fixed-position floating element anchored to a trigger.
3
- *
4
- * A portaled panel is positioned from its anchor's viewport rect, which stops
5
- * being true the moment anything scrolls or the window resizes. This owns that
6
- * one concern: measure the anchor, offset the panel below or above it, clamp
7
- * the result inside the viewport, and re-run on scroll (capture phase, so
8
- * scrollers nested inside the page are caught too), on resize, and on the
9
- * panel's own size changes while the element is open.
10
- * @module @deepseek-ai/dsh-client-ui-primitives/useAnchoredPosition
11
- */
1
+ /** Synchronous placement for body-portaled panels with a viewport fixed-position containing block. */
12
2
  import { type CSSProperties, type RefObject } from 'react';
13
3
  /** Inputs for {@link useAnchoredPosition}. */
14
4
  export interface AnchoredPositionOptions {
15
- /** Whether the floating element is mounted and should track its anchor. */
5
+ /** Whether the panel is mounted and should track its anchor. */
16
6
  open: boolean;
17
- /** The element the panel is placed from. */
7
+ /** Element whose viewport rect anchors the panel. */
18
8
  anchorRef: RefObject<HTMLElement | null>;
19
- /** The floating element, measured so the clamp uses real dimensions. */
9
+ /** Body-portaled, fixed-position panel; its ancestors must not establish a containing block. */
20
10
  panelRef: RefObject<HTMLElement | null>;
21
- /** Which anchor edge the panel hangs from: below it (`bottom`, the default) or above it (`top`). */
22
- side?: 'top' | 'bottom';
23
- /** Which anchor edge the panel lines up with: its left edge (`start`, the default) or its right edge (`end`). */
11
+ /** Preferred anchor edge; right-side panels align their top edges. */
12
+ side?: 'top' | 'bottom' | 'right';
13
+ /** Horizontal alignment for panels above or below the anchor. */
24
14
  align?: 'start' | 'end';
25
- /** Distance kept between the anchor edge named by `side` and the panel. */
15
+ /** Distance from the preferred anchor edge, in CSS pixels. */
26
16
  gap: number;
27
- /** Distance kept between the panel and each viewport edge; the frame's overlay inset widens the top margin. */
17
+ /** Minimum viewport inset; desktop frame clearance can increase the top inset. */
28
18
  margin: number;
19
+ /** Reserve desktop frame clearance in addition to the margin; false keeps only the viewport margin. Defaults to true. */
20
+ frameClearance?: boolean;
21
+ /** Host-supplied client rect; null hides the panel until the anchor is available. */
22
+ getAnchorRect?: () => DOMRect | null;
23
+ /** Re-measure a committed content change before paint. */
24
+ layoutKey?: string | number;
25
+ /** Minimum panel width follows the anchor, bounded by the visible viewport. */
26
+ minWidthFromAnchor?: boolean;
29
27
  }
30
28
  /**
31
- * Track an anchor and return the panel's fixed coordinates.
32
- * @param options - the open state, the two refs, the placement side and alignment, and the gap/margin distances.
33
- * @returns `left`/`top` for the panel, or `null` before the first measurement.
29
+ * Keep a fixed panel aligned and constrained to the visible viewport.
30
+ * Panel CSS consumes `--dsh-anchored-max-width` and `--dsh-anchored-max-height` for size limits.
31
+ * The hook owns those inline variables and optional min-width while open, restoring them on cleanup.
32
+ * @param options - Open state, element refs, placement, and optional host rect or content change key.
33
+ * @returns Fixed left/top coordinates, or null while closed or awaiting an anchor; the first measurement completes before paint.
34
34
  */
35
35
  export declare function useAnchoredPosition(options: AnchoredPositionOptions): CSSProperties | null;
@@ -0,0 +1,19 @@
1
+ import type { DragEvent } from 'react';
2
+ /**
3
+ * Own a row's inert drag preview until drag end, replacement, or unmount.
4
+ * The offscreen copy keeps WebKit snapshots separate from overlapping panels.
5
+ * The wrapper copies only explicitly requested computed custom properties.
6
+ * Its cloned slot DOM remains in document.body for that lifetime; query live rows
7
+ * within their list to exclude duplicate text and element IDs.
8
+ * @param className - preview background matching the row's surface; WebKit fills
9
+ * transparent snapshot pixels white, including rounded corners.
10
+ * @param inheritedProperties - custom-property names whose computed values the preview needs.
11
+ * Omit to copy none. Keep the list reference stable; replacing it clears the active preview.
12
+ * @returns preview callbacks; cleanup reports whether this row started a drag,
13
+ * even when its preview failed or the row became non-draggable before drag end.
14
+ * Start accepts the source row when a child handle owns the drag event.
15
+ */
16
+ export declare function useRowDragPreview(className: string, inheritedProperties?: readonly `--${string}`[]): {
17
+ start: (event: DragEvent<HTMLElement>, row?: HTMLElement) => void;
18
+ clear: () => boolean;
19
+ };
@@ -1,36 +1,31 @@
1
+ /** Inline text and reference presentation; business rules supply resolved JSON data and actions. */
2
+ import type { HTMLAttributes } from 'react';
3
+ import type { ReactNode } from 'react';
4
+ import { type ReferenceIconKind } from './ReferenceIcon.js';
5
+ /** Plain text follows the wrapping and typography of its host. */
6
+ export interface UserTextRunProps {
7
+ readonly text: string;
8
+ }
1
9
  /**
2
- * Display projection of reference forms in sent user text (bubble and queue
3
- * rows). The logged model text remains the single truth; this is presentation
4
- * only. Inline references follow the consumer's wrapping policy and keep long
5
- * labels within its width. Four decoration sources, by precedence: the wire session form
6
- * `@[label](dsh-session:...)` folds to its label; exact session labels
7
- * supplied by an adjacent recall decorate their bare `@label` mention; plain
8
- * `@name` word-boundary tokens decorate by shape alone; and a plain `/name`
9
- * token decorates only when the caller names it — a skill the host actually
10
- * loaded for that message (ui-chat reads the step's `skill-invocation`
11
- * injections) or the command a command-input bubble echoes — so `/123` or a
12
- * stray `/word` stays plain text. A `/name` token is whitespace-bounded like
13
- * the host skill gesture (`dsh-tool-skill`): it ends at whitespace or the
14
- * text end, so slash paths (`/nfs-hg/xxx`, `/plan.md`) and punctuation-glued
15
- * tokens (`/plan。`) stay plain even for a loaded name.
10
+ * Render an uninterpreted inline text run.
11
+ * @param props - text retained verbatim from the caller's document.
12
+ * @returns one inline run without Markdown or reference recognition.
16
13
  */
17
- import type { ReactNode } from 'react';
18
- /** Optional navigation supplied by consumers that can preview references. */
19
- export interface UserTextReferences {
20
- /** Open a file path decoded from an `@` mention. */
21
- openFile: (path: string) => void;
22
- /** Open the source of a skill loaded for this message. */
23
- openSkill: (name: string) => void;
14
+ export declare function UserTextRun({ text }: UserTextRunProps): ReactNode;
15
+ /** Presentation selected by a reference renderer, independent of its matching grammar. */
16
+ export interface ReferenceChipProps {
17
+ readonly appearance: ReferenceIconKind | 'skill' | 'command';
18
+ /** Explicit object-menu gesture bindings; absent for display-only references. */
19
+ readonly contextMenuProps?: Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>;
20
+ readonly label: string;
21
+ readonly title: string;
22
+ /** Absent for display-only references and previews. */
23
+ readonly onActivate?: () => void;
24
24
  }
25
25
  /**
26
- * Split one sent text into inline plain runs and reference chips.
27
- * @param text - the logged model text of the message or queue row.
28
- * @param sessionLabels - exact session mention labels associated by an adjacent recall.
29
- * @param slashNames - names a `/name` token may decorate as: the skills the
30
- * host loaded for this message, or the command a command bubble echoes
31
- * (unsent queue rows pass none).
32
- * @param slashKind - the chip kind those tokens render as.
33
- * @param references - optional file and skill preview actions; session and command tokens stay labels.
34
- * @returns inline nodes covering the whole text.
26
+ * Render a reference label or its explicitly supplied activation action.
27
+ * Text selection and repeated pointer clicks do not activate the reference.
28
+ * @param props - resolved visual fields and optional action from the owning renderer.
29
+ * @returns an inline label, or a keyboard-accessible button when activation is supplied.
35
30
  */
36
- export declare function projectUserText(text: string, sessionLabels: readonly string[], slashNames?: readonly string[], slashKind?: 'skill' | 'command', references?: UserTextReferences): ReactNode;
31
+ export declare function ReferenceChip({ appearance, label, title, onActivate, contextMenuProps, }: ReferenceChipProps): ReactNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seekbuddy/dsh-ui",
3
- "version": "0.2.0-beta.0",
3
+ "version": "0.2.0-beta.1",
4
4
  "description": "Unofficial React components in the DeepSeek Harness (DSH) web UI design system: the DSH primitives plus the components DSH does not provide (cards, tabs, pagination, messages, upload, date/time pickers), on the same --dsw-* tokens. Not affiliated with or endorsed by DeepSeek.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -112,7 +112,7 @@
112
112
  "react-dom": "^18.2.0 || ^19.0.0"
113
113
  },
114
114
  "dependencies": {
115
- "@deepseek-ai/dsh-util-code-language": "0.2.0-rc.2",
115
+ "@deepseek-ai/dsh-util-code-language": "0.2.2-rc.1",
116
116
  "@shikijs/langs": "^4.3.1",
117
117
  "@types/mdast": "^4.0.4",
118
118
  "anser": "^2.3.5",