Skip to content

T-RJVA-md-ui-find-outline-hover-lifts

State: closed/done · Impact: high · Complexity: medium

Find, outline and hover preview exist only inside the notes product, bound to its stores and notes-* test ids, so no other markdown surface can have them. This task lifts all three into the markdown-ui layer as MdFindBar + useMarkdownFind, MdOutline and MdHoverPreview, generalised over MarkdownProvider and the surface API.

LocationRole today
solutions/determined/experiences/notes/app/components/NotesFindBar.vueFind bar UI with notes-find-* test ids
solutions/determined/experiences/notes/app/composables/useNoteFind.ts#useNoteFindOrchestrates DOM find in read mode and editor search in live/source
solutions/determined/experiences/notes/app/utils/noteFind.tsfoldForFind, findMatches, collectFindText, findRange, rangeRect; the ::highlight plumbing
solutions/determined/experiences/notes/app/utils/noteFind.test.tsUnit suite that ports with the module
solutions/determined/experiences/notes/app/components/NotesOutline.vueOutline pane bound to notes state
solutions/determined/experiences/notes/app/components/NotesHoverPreview.vue#anchorToHover preview with its own position math
packages/ts/obsidian-editor/src/search.tssetNoteSearch, stepNoteSearch, clearNoteSearch, noteSearchStatus — the live/source path
packages/ts/obsidian-editor/src/outline.ts#extractOutlineOutline extraction the edit modes use
packages/ts/obsidian-md/src/slice.ts#sliceEmbedFragment slicing the hover preview renders

The layer, MdSurface and MdViewer come from T-A0HT-md-ui-layer-skeleton; useAnchoredPosition from T-6OI8-ui-extract-anchored-position-and-chords.

PieceDesign
app/utils/mdFind.tsnoteFind.ts moved and renamed: same functions, highlight name md-find-match, MD_-prefixed constants
useMarkdownFinduseNoteFind generalised over the surface: read mode → DOM path over the viewer root (::highlight(md-find-match) ranges); live/source → setNoteSearch / stepNoteSearch / clearNoteSearch with counts from noteSearchStatus; one API (query, open, count, index, next(), prev(), close()) across modes
MdFindBarNotesFindBar.vue generalised; every data-testid it carries today reappears with the md-find- prefix
MdOutlineNotesOutline.vue generalised over MdOutlineEntry (the engine OutlineEntry); renders the surface’s outline, emits select with the entry, DEmptyState when empty
MdHoverPreviewNotesHoverPreview.vue generalised: hovering a resolved wikilink in the viewer or editor DOM loads via provider.loadNote, slices with sliceEmbed, renders through MdViewer with { pre: undefined, table: undefined } component overrides, positioned by useAnchoredPosition

MdSurface wires find: boolean, v-model:findOpen, the find-scroll emit, hoverPreview, and exposes find on its API. markdown-ui.css gains the find-highlight and sticky-anchor section. The notes originals stay in place until T-3DFJ-notes-adopts-markdown-ui rewires the product and deletes them.

  1. Port noteFind.ts and its unit suite to packages/ts/markdown-ui/app/utils/mdFind.ts and packages/ts/markdown-ui/tests/mdFind.test.ts; rename ids and constants; the suite passes unchanged in substance.
  2. Write packages/ts/markdown-ui/tests/useMarkdownFind.test.ts (happy-dom): in read mode a query sets highlight ranges under the name md-find-match and count matches the fixture; in live mode the composable calls setNoteSearch and mirrors noteSearchStatus counts; next() wraps; close() clears both paths.
  3. Implement useMarkdownFind.ts and MdFindBar.vue with stories.
  4. Implement MdOutline.vue with its test (three-heading fixture renders three entries; click emits select; empty doc renders DEmptyState) and story.
  5. Implement MdHoverPreview.vue with its test (stub loadNote; hover over a resolved wikilink shows a preview containing the target’s rendered body; the pre/table overrides apply) and story.
  6. Wire MdSurface; add the stylesheet section; add a find playground page exercising bar, outline and hover on one surface.
  7. moon run markdown-ui:check markdown-ui:test; bun run storybook:build; just ci-guards.
LocationKindChange
packages/ts/markdown-ui/app/components/MdFindBar.vuenewGeneralised find bar, md-find-* ids
packages/ts/markdown-ui/app/components/MdFindBar.stories.tsnewStory
packages/ts/markdown-ui/app/components/MdOutline.vuenewOutline pane over MdOutlineEntry
packages/ts/markdown-ui/app/components/MdOutline.stories.tsnewStory
packages/ts/markdown-ui/app/components/MdHoverPreview.vuenewHover preview over loadNote + sliceEmbed + MdViewer
packages/ts/markdown-ui/app/components/MdHoverPreview.stories.tsnewStory
packages/ts/markdown-ui/app/composables/useMarkdownFind.tsnewMode-spanning find orchestration
packages/ts/markdown-ui/app/utils/mdFind.tsnewPorted find utilities
packages/ts/markdown-ui/app/components/MdSurface.vuenewCreated by T-A0HT-md-ui-layer-skeleton; find and hover wiring
packages/ts/markdown-ui/app/assets/css/markdown-ui.cssnewCreated by T-A0HT-md-ui-layer-skeleton; find highlight and sticky anchor section
packages/ts/markdown-ui/tests/mdFind.test.tsnewPorted unit suite
packages/ts/markdown-ui/tests/useMarkdownFind.test.tsnewMode-path tests
packages/ts/markdown-ui/tests/mdOutline.test.tsnewOutline tests
packages/ts/markdown-ui/tests/mdHoverPreview.test.tsnewHover preview tests
packages/ts/markdown-ui/playground/app/pages/find.vuenewBar, outline and hover on one surface
  • AC-1: moon run markdown-ui:check markdown-ui:test passes with the four new suites, and the ported mdFind.test.ts covers every case solutions/determined/experiences/notes/app/utils/noteFind.test.ts covers today.
  • AC-2: every data-testid value in solutions/determined/experiences/notes/app/components/NotesFindBar.vue reappears in MdFindBar.vue with notes-find- replaced by md-find-.
  • AC-3: in read mode a query highlights under the CSS highlight name md-find-match; in live mode the same query drives setNoteSearch and the bar’s count equals noteSearchStatus’s.
  • AC-4: MdOutline renders one entry per heading of the three-heading fixture and emits select with the clicked entry; an empty document renders DEmptyState.
  • AC-5: with a stub loadNote, hovering a resolved wikilink renders a preview containing the target’s body, and fenced code inside the preview renders without the custom code-block component (the { pre: undefined, table: undefined } overrides hold).
  • AC-6: just ci-guards passes and bun run storybook:build succeeds with the three new stories.

Member of milestone M-931L; the layer half of chrome step C3 of decision D-K3EM-markdown-editor-chrome-and-plugin-environment (the notes half is T-3DFJ-notes-adopts-markdown-ui).

T-A0HT-md-ui-layer-skeleton


← Back to Tasks