Preparing the preview…
} {state === 'failed' && (
@@ -119,13 +121,15 @@ export function ImagePreview({ data, path }: { data: Uint8Array; path: string })
0 ? naturalWidth * zoom : undefined }}
decoding="async"
draggable={false}
hidden={state !== 'ready'}
onError={() => {
setState('failed')
}}
- onLoad={() => {
+ onLoad={event => {
+ setNaturalWidth(event.currentTarget.naturalWidth)
setState('ready')
}}
referrerPolicy="no-referrer"
diff --git a/ui-web/src/sidebar-right/DocumentMarkdown.test.tsx b/ui-web/src/sidebar-right/DocumentMarkdown.test.tsx
new file mode 100644
index 000000000..6564c6d7b
--- /dev/null
+++ b/ui-web/src/sidebar-right/DocumentMarkdown.test.tsx
@@ -0,0 +1,23 @@
+import { cleanup, render, screen } from '@testing-library/react'
+import { afterEach, expect, it } from 'vitest'
+import DocumentMarkdown, { frontmatterFields, splitFrontmatter } from './DocumentMarkdown.tsx'
+
+afterEach(cleanup)
+it('renders YAML mappings as metadata and leaves the Markdown body intact', () => {
+ render(
{front.source} :
+ fields.length > 0 && Reading…
)} {viewer === 'html' && bytes !== undefined &&diff --git a/ui-web/src/sidebar-right/ZoomControls.tsx b/ui-web/src/sidebar-right/ZoomControls.tsx new file mode 100644 index 000000000..8ed7b14bc --- /dev/null +++ b/ui-web/src/sidebar-right/ZoomControls.tsx @@ -0,0 +1,19 @@ +import css from './TextPreview.module.css' +import { clampZoom, type PreviewZoom } from './zoom.ts' + +export function ZoomControls({ value, onChange, image = false }: { + value: PreviewZoom; onChange: (zoom: PreviewZoom) => void; image?: boolean +}) { + const scale = value === 'fit' ? 1 : value + return
{row.id}