UI polish: frameless plugin blocks in read mode, sticky toolbar, pinned footer, icon uninstall
All checks were successful
CD / Build and push images (push) Successful in 1m11s
CD / Deploy to Test (push) Successful in 11s
CD / Smoke tests against Test (push) Successful in 1m14s
CD / Promote to Int (push) Successful in 10s
CI / Lint, typecheck, test (push) Successful in 4m5s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m35s
CI / Import/export fidelity gate (push) Successful in 47s
Release / Build release images and notes (push) Successful in 1m6s
Release / Release-candidate operations QA (push) Successful in 40s
Prod deploy / Deploy the released images to Prod (push) Successful in 15s
All checks were successful
CD / Build and push images (push) Successful in 1m11s
CD / Deploy to Test (push) Successful in 11s
CD / Smoke tests against Test (push) Successful in 1m14s
CD / Promote to Int (push) Successful in 10s
CI / Lint, typecheck, test (push) Successful in 4m5s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 5m35s
CI / Import/export fidelity gate (push) Successful in 47s
Release / Build release images and notes (push) Successful in 1m6s
Release / Release-candidate operations QA (push) Successful in 40s
Prod deploy / Deploy the released images to Prod (push) Successful in 15s
Three refinements from Stefan's review of the plugin work: - read mode integrates plugin output like normal content: no border, no name bar, no selection outline around plugin blocks — same principle as the frameless reading shell (M10) - the editor toolbar pins to the top of the scrolling content area on long articles instead of scrolling away (position: sticky within the main scroll container) - the app footer (connection status + legal links) moved out of the scroll container into a main-column wrapper — always visible at the bottom edge of the window on every view - the plugin uninstall buttons in the admin list are icon buttons now (Trash2, house pattern: aria-label keeps the accessible name) - lint hygiene: eslint/prettier ignore packages/plugins/*/vendor — the unpacked drawio webapp drove eslint out of memory Verified in the browser against a local stack (5/5 scripted checks: icon buttons, toolbar sticky at scroll bottom, footer pinned in edit and read mode, plugin block computed border/outline none in read mode) plus 8 layout-sensitive e2e packs re-run individually, all green (comments, collab, legal, content, plugin-admin, plugin-blocks, page-tools, plugins). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
This commit is contained in:
parent
97f94f247b
commit
c8ec549fa5
@ -14,3 +14,4 @@ fixtures/import/*.src.html
|
|||||||
# Export fidelity corpus (issue #69): the round-trip snapshots must stay exactly
|
# Export fidelity corpus (issue #69): the round-trip snapshots must stay exactly
|
||||||
# as pandoc reads the exported document back — Prettier would break them.
|
# as pandoc reads the exported document back — Prettier would break them.
|
||||||
fixtures/export/*.expected.md
|
fixtures/export/*.expected.md
|
||||||
|
packages/plugins/*/vendor/
|
||||||
|
|||||||
@ -63,10 +63,14 @@ export function AppLayout(): React.JSX.Element {
|
|||||||
>
|
>
|
||||||
<Sidebar collapsed={collapsed} />
|
<Sidebar collapsed={collapsed} />
|
||||||
{!collapsed && <SidebarResizer widthRem={widthRem} onResize={setSidebarWidth} />}
|
{!collapsed && <SidebarResizer widthRem={widthRem} onResize={setSidebarWidth} />}
|
||||||
<main className="main">
|
<div className="main-column">
|
||||||
<Outlet />
|
<main className="main">
|
||||||
|
<Outlet />
|
||||||
|
</main>
|
||||||
|
{/* Outside the scroll container: always visible at the bottom
|
||||||
|
edge of the window (M10 follow-up 3). */}
|
||||||
<Footer />
|
<Footer />
|
||||||
</main>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageActionsSlotContext.Provider>
|
</PageActionsSlotContext.Provider>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Trash2 } from 'lucide-react';
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
@ -122,12 +123,15 @@ export function PluginManager(): React.JSX.Element {
|
|||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="button button--danger"
|
className="icon-button plugin-manager__uninstall"
|
||||||
disabled={plugin.mode === 'required'}
|
disabled={plugin.mode === 'required'}
|
||||||
title={plugin.mode === 'required' ? t('admin.requiredLocked') : undefined}
|
aria-label={t('admin.uninstall')}
|
||||||
|
title={
|
||||||
|
plugin.mode === 'required' ? t('admin.requiredLocked') : t('admin.uninstall')
|
||||||
|
}
|
||||||
onClick={() => uninstall.mutate(plugin.id)}
|
onClick={() => uninstall.mutate(plugin.id)}
|
||||||
>
|
>
|
||||||
{t('admin.uninstall')}
|
<Trash2 aria-hidden />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -248,8 +248,16 @@ button {
|
|||||||
max-width: 36rem;
|
max-width: 36rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-column {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--space-6) var(--space-8);
|
padding: var(--space-6) var(--space-8);
|
||||||
@ -497,9 +505,10 @@ button {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
margin-top: var(--space-8);
|
flex-shrink: 0;
|
||||||
padding-top: var(--space-3);
|
padding: var(--space-2) var(--space-8);
|
||||||
border-top: 1px solid var(--color-border);
|
border-top: 1px solid var(--color-border);
|
||||||
|
background: var(--color-bg);
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
@ -832,6 +841,11 @@ button {
|
|||||||
padding: var(--space-2) var(--space-3);
|
padding: var(--space-2) var(--space-3);
|
||||||
border-bottom: 1px solid var(--color-border);
|
border-bottom: 1px solid var(--color-border);
|
||||||
background: var(--color-bg-subtle);
|
background: var(--color-bg-subtle);
|
||||||
|
/* Long articles: the toolbar pins to the top of the scrolling content
|
||||||
|
area instead of scrolling away. */
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar__group {
|
.editor-toolbar__group {
|
||||||
@ -931,6 +945,20 @@ button {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read mode integrates plugin output like normal content: no frame, no
|
||||||
|
name bar — same principle as the frameless reading shell (M10). */
|
||||||
|
.editor-shell--reading .plugin-block {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
|
/* No selection outline either — reading is not editing. */
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-shell--reading .plugin-block__bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.plugin-block__fallback {
|
.plugin-block__fallback {
|
||||||
padding: var(--space-2) var(--space-3);
|
padding: var(--space-2) var(--space-3);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,8 @@ export default tseslint.config(
|
|||||||
{
|
{
|
||||||
ignores: [
|
ignores: [
|
||||||
'**/dist/**',
|
'**/dist/**',
|
||||||
|
// Vendored third-party apps bundled into plugins (drawio) — never linted.
|
||||||
|
'packages/plugins/*/vendor/**',
|
||||||
'**/node_modules/**',
|
'**/node_modules/**',
|
||||||
'**/coverage/**',
|
'**/coverage/**',
|
||||||
'**/.pnpm-store/**',
|
'**/.pnpm-store/**',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user