release: v0.20.0
This commit is contained in:
@@ -116,12 +116,19 @@ export function BlockFields({
|
||||
|
||||
{block.type === 'photo' && (
|
||||
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
||||
<div
|
||||
{/* A button, not a clickable div, so the keyboard reaches it. */}
|
||||
<button
|
||||
type="button"
|
||||
aria-label={block.assetId ? 'Change photo' : 'Pick a photo'}
|
||||
style={{
|
||||
width: '140px',
|
||||
height: '96px',
|
||||
flexShrink: 0,
|
||||
background: 'rgba(0,0,0,0.3)',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
color: 'inherit',
|
||||
font: 'inherit',
|
||||
borderRadius: '6px',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
@@ -140,13 +147,13 @@ export function BlockFields({
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={`/api/admin/thumbnail/${block.assetId}`}
|
||||
alt="Thumb"
|
||||
alt=""
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
) : (
|
||||
<span style={{ fontSize: '0.8rem', opacity: 0.6 }}>+ Pick</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div
|
||||
style={{
|
||||
@@ -213,10 +220,16 @@ export function BlockFields({
|
||||
}}
|
||||
>
|
||||
{[0, 1].map((pIdx) => (
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
key={pIdx}
|
||||
aria-label={`${block.assetIds[pIdx] ? 'Change' : 'Pick'} photo ${pIdx + 1} of the pair`}
|
||||
style={{
|
||||
height: '90px',
|
||||
width: '100%',
|
||||
padding: 0,
|
||||
color: 'inherit',
|
||||
font: 'inherit',
|
||||
background: 'rgba(0,0,0,0.3)',
|
||||
borderRadius: '6px',
|
||||
overflow: 'hidden',
|
||||
@@ -241,13 +254,13 @@ export function BlockFields({
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={`/api/admin/thumbnail/${block.assetIds[pIdx]}`}
|
||||
alt="Thumb"
|
||||
alt=""
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
) : (
|
||||
<span style={{ fontSize: '0.8rem', opacity: 0.6 }}>+ Pick Photo #{pIdx + 1}</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -401,25 +401,26 @@ export function JournalEditor({ slug, mapEnabled, onBack, kind = 'journal' }: Jo
|
||||
onChange={(e) => handleFrontmatterChange({ title: e.target.value })}
|
||||
/>
|
||||
|
||||
{/* The admin's segmented control (QA A-18). As `admin-btn-xs` buttons the
|
||||
active one never showed: `.admin-btn-xs` sets its own background
|
||||
after `.admin-btn-primary`, so both modes looked identical. */}
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
gap: '4px',
|
||||
background: 'rgba(255,255,255,0.06)',
|
||||
borderRadius: '6px',
|
||||
padding: '2px',
|
||||
}}
|
||||
className="segmented-control segmented-control--sm"
|
||||
role="group"
|
||||
aria-label="Editor mode"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={`admin-btn admin-btn-xs ${editorMode === 'blocks' ? 'admin-btn-primary' : ''}`}
|
||||
className={`segment-btn ${editorMode === 'blocks' ? 'active' : ''}`}
|
||||
aria-pressed={editorMode === 'blocks'}
|
||||
onClick={() => setEditorMode('blocks')}
|
||||
>
|
||||
Visual Blocks
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`admin-btn admin-btn-xs ${editorMode === 'markdown' ? 'admin-btn-primary' : ''}`}
|
||||
className={`segment-btn ${editorMode === 'markdown' ? 'active' : ''}`}
|
||||
aria-pressed={editorMode === 'markdown'}
|
||||
onClick={() => setEditorMode('markdown')}
|
||||
>
|
||||
Raw Markdown
|
||||
|
||||
@@ -92,17 +92,24 @@ export function JournalPreview({ parsed, albumAssets }: JournalPreviewProps) {
|
||||
<span className="journal-preview-bar-label">
|
||||
<IconEye size={13} /> Realtime Theme Preview
|
||||
</span>
|
||||
<div style={{ display: 'flex', gap: '4px' }}>
|
||||
{/* Same control and same fix as the editor's mode toggle. */}
|
||||
<div
|
||||
className="segmented-control segmented-control--sm"
|
||||
role="group"
|
||||
aria-label="Preview width"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className={`admin-btn admin-btn-xs ${viewport === 'desktop' ? 'admin-btn-primary' : ''}`}
|
||||
className={`segment-btn ${viewport === 'desktop' ? 'active' : ''}`}
|
||||
aria-pressed={viewport === 'desktop'}
|
||||
onClick={() => setViewport('desktop')}
|
||||
>
|
||||
Desktop
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`admin-btn admin-btn-xs ${viewport === 'mobile' ? 'admin-btn-primary' : ''}`}
|
||||
className={`segment-btn ${viewport === 'mobile' ? 'active' : ''}`}
|
||||
aria-pressed={viewport === 'mobile'}
|
||||
onClick={() => setViewport('mobile')}
|
||||
>
|
||||
Mobile
|
||||
|
||||
@@ -110,11 +110,12 @@ export function JournalStudio({ slug: activeSlug, mapEnabled }: JournalStudioPro
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (slug: string) => {
|
||||
const handleDelete = async (slug: string, title?: string) => {
|
||||
// Named by title, as the page delete is; the slug only when there is none.
|
||||
const ok = await confirm({
|
||||
title: `Delete “${slug}”?`,
|
||||
title: `Delete “${title || slug}”?`,
|
||||
message: 'A copy is kept and can be restored under Backups.',
|
||||
confirmLabel: 'Delete',
|
||||
confirmLabel: 'Delete entry',
|
||||
danger: true,
|
||||
});
|
||||
if (!ok) return;
|
||||
@@ -244,7 +245,7 @@ export function JournalStudio({ slug: activeSlug, mapEnabled }: JournalStudioPro
|
||||
<button
|
||||
type="button"
|
||||
className="admin-btn admin-btn-sm admin-btn-danger"
|
||||
onClick={() => handleDelete(entry.slug)}
|
||||
onClick={() => handleDelete(entry.slug, entry.frontmatter.title)}
|
||||
title="Delete entry"
|
||||
style={{ marginLeft: 'auto' }}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/* ── Journal Studio & Editor CSS ──────────────────────────────────── */
|
||||
|
||||
/*
|
||||
* The studio is a full-width workspace: it breaks out of the 1120px
|
||||
* `.admin-main` column so the split view has room for editor *and* preview.
|
||||
* The studio is a full-width workspace: it breaks out of the shared
|
||||
* `--admin-content-width` column so the split view has room for editor *and*
|
||||
* preview.
|
||||
*/
|
||||
.admin-main:has(> .journal-studio),
|
||||
.admin-main:has(> .journal-editor-container) {
|
||||
|
||||
Reference in New Issue
Block a user