mirror of
https://github.com/rememberber/MooTool.git
synced 2026-08-29 02:10:53 +08:00
[next]随手记,页面顶部不够沉浸,重新设计下,还有左侧第一栏和第二栏中间不应有边距
This commit is contained in:
@@ -2,8 +2,11 @@ import DOMPurify from 'dompurify'
|
||||
import {
|
||||
Check,
|
||||
ChevronDown,
|
||||
Columns2,
|
||||
CopyPlus,
|
||||
Download,
|
||||
Eye,
|
||||
FilePenLine,
|
||||
FilePlus2,
|
||||
FolderOpen,
|
||||
FolderPlus,
|
||||
@@ -928,19 +931,9 @@ export function QuickNoteTool() {
|
||||
: state.quickReplaceOpen ? [320, 170] : [320]
|
||||
return (
|
||||
<section className="tool-page quick-note-tool">
|
||||
<div className="tool-page__header tool-page__header--actions quick-note-page-header">
|
||||
<h1 className="visually-hidden">{t('quickNote.title')}</h1>
|
||||
<WorkspaceDragZone />
|
||||
<div className="quick-note-view-switch segmented" role="tablist">
|
||||
{(['editor', 'split', 'preview'] as const).map((mode) => (
|
||||
<button className={state.viewMode === mode ? 'segmented__item segmented__item--active' : 'segmented__item'} type="button" role="tab" aria-selected={state.viewMode === mode} key={mode} onClick={() => update({ viewMode: mode })}>
|
||||
{t(`quickNote.view.${mode}` as MessageKey)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="visually-hidden">{t('quickNote.title')}</h1>
|
||||
|
||||
<div className={[state.treeOpen ? '' : 'quick-note-layout--tree-closed', state.quickReplaceOpen ? 'quick-note-layout--replace-open' : ''].filter(Boolean).join(' ') || undefined}>
|
||||
<div className={['quick-note-stage', state.treeOpen ? '' : 'quick-note-layout--tree-closed', state.quickReplaceOpen ? 'quick-note-layout--replace-open' : ''].filter(Boolean).join(' ')}>
|
||||
<ResizableColumns
|
||||
className="quick-note-layout"
|
||||
columns={quickNoteColumns}
|
||||
@@ -983,6 +976,27 @@ export function QuickNoteTool() {
|
||||
<section className="quick-note-editor-shell">
|
||||
<div className="quick-note-toolbar">
|
||||
<IconButton label={state.treeOpen ? t('quickNote.openVault') : t('quickNote.newNote')} icon={state.treeOpen ? PanelLeftClose : PanelLeftOpen} onClick={() => update({ treeOpen: !state.treeOpen })} />
|
||||
<div className="quick-note-view-switch segmented" role="tablist" aria-label={t('quickNote.title')}>
|
||||
{([
|
||||
{ id: 'editor', icon: FilePenLine },
|
||||
{ id: 'split', icon: Columns2 },
|
||||
{ id: 'preview', icon: Eye }
|
||||
] as const).map(({ id, icon: ViewIcon }) => (
|
||||
<button
|
||||
className={state.viewMode === id ? 'segmented__item segmented__item--active' : 'segmented__item'}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-label={t(`quickNote.view.${id}` as MessageKey)}
|
||||
aria-selected={state.viewMode === id}
|
||||
title={t(`quickNote.view.${id}` as MessageKey)}
|
||||
key={id}
|
||||
onClick={() => update({ viewMode: id })}
|
||||
>
|
||||
<ViewIcon size={15} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<span className="quick-note-toolbar__divider" aria-hidden="true" />
|
||||
<NoteColorPicker key={state.note?.relativePath ?? 'empty'} value={state.note?.metadata.color} disabled={!state.note} label={t('quickNote.color')} onChange={(color) => patchMetadata({ color })} />
|
||||
<select className="quick-note-syntax" aria-label={t('quickNote.syntax')} disabled={!state.note} value={state.note?.metadata.syntax ?? 'text/plain'} onChange={(event) => patchMetadata({ syntax: event.target.value })}>
|
||||
{syntaxOptions.map(([value, label]) => <option value={value} key={value}>{label}</option>)}
|
||||
@@ -1004,7 +1018,7 @@ export function QuickNoteTool() {
|
||||
<IconButton label={t('common.action.format')} icon={WandSparkles} disabled={!state.note || !state.content.trim()} onClick={() => { void formatCurrent() }} />
|
||||
<IconButton label={t('quickNote.bulletList')} icon={List} disabled={!state.note} onClick={() => prefixSelectedLines('bullet')} />
|
||||
<IconButton label={t('quickNote.numberedList')} icon={ListOrdered} disabled={!state.note} onClick={() => prefixSelectedLines('numbered')} />
|
||||
<span className="quick-note-toolbar__spacer" />
|
||||
<WorkspaceDragZone className="quick-note-toolbar__drag-zone" />
|
||||
<IconButton label={t('quickNote.find')} icon={Search} disabled={!state.note} active={state.findOpen} onClick={() => { if (state.findOpen) update({ findOpen: false }); else openFindReplace() }} />
|
||||
<IconButton label={t('quickNote.save')} icon={Save} disabled={!state.note || state.busy} active={dirty} onClick={() => { void saveCurrent() }} />
|
||||
<IconButton label={t('quickNote.duplicate')} icon={CopyPlus} disabled={!state.note} onClick={() => { void duplicateNote() }} />
|
||||
|
||||
@@ -645,16 +645,23 @@
|
||||
|
||||
/* Phase 6 Quick Note */
|
||||
|
||||
.quick-note-page-header {
|
||||
min-height: 36px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.quick-note-view-switch {
|
||||
gap: 1px;
|
||||
padding: 2px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.quick-note-tool > :nth-child(2) {
|
||||
.quick-note-view-switch .segmented__item {
|
||||
display: inline-flex;
|
||||
width: 28px;
|
||||
min-width: 28px;
|
||||
min-height: 28px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.quick-note-stage {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
@@ -662,7 +669,7 @@
|
||||
.quick-note-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 220px minmax(320px, 1fr);
|
||||
gap: 9px;
|
||||
gap: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
@@ -692,6 +699,14 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.quick-note-sidebar {
|
||||
border-width: 0 1px 0 0;
|
||||
}
|
||||
|
||||
.quick-replace-panel {
|
||||
border-width: 0 0 0 1px;
|
||||
}
|
||||
|
||||
.quick-note-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -865,7 +880,7 @@
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 24px var(--shadow-soft);
|
||||
overflow: hidden;
|
||||
@@ -910,9 +925,22 @@
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
.quick-note-toolbar__spacer {
|
||||
flex: 1 1 auto;
|
||||
min-width: 8px;
|
||||
.quick-note-toolbar__divider {
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
margin: 0 1px;
|
||||
background: var(--border-soft);
|
||||
flex: 0 0 1px;
|
||||
}
|
||||
|
||||
.quick-note-toolbar__drag-zone {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
flex: 1 1 56px;
|
||||
}
|
||||
|
||||
.tool-view-shell--detached.tool-view-shell--macos .quick-note-search {
|
||||
margin-left: 82px;
|
||||
}
|
||||
|
||||
.quick-note-icon-button {
|
||||
|
||||
@@ -206,35 +206,41 @@ test('keeps a custom-header tool immersive while preserving its view controls',
|
||||
await expect.poll(async () => (await evaluateTool('quickNote', `(() => {
|
||||
const shell = document.querySelector('.tool-view-shell')
|
||||
const page = document.querySelector('.quick-note-tool')
|
||||
const header = document.querySelector('.quick-note-page-header')?.getBoundingClientRect()
|
||||
const title = document.querySelector('.quick-note-page-header h1')?.getBoundingClientRect()
|
||||
const toolbar = document.querySelector('.quick-note-toolbar')?.getBoundingClientRect()
|
||||
const title = document.querySelector('.quick-note-tool > h1')?.getBoundingClientRect()
|
||||
const switcher = document.querySelector('.quick-note-view-switch')?.getBoundingClientRect()
|
||||
const workspaceDrag = document.querySelector('[data-window-drag-zone]')?.getBoundingClientRect()
|
||||
const sidebar = document.querySelector('.quick-note-sidebar')?.getBoundingClientRect()
|
||||
const editor = document.querySelector('.quick-note-editor-shell')?.getBoundingClientRect()
|
||||
const slot = document.querySelector('.tool-window-toggle-slot')?.getBoundingClientRect()
|
||||
if (!shell || !page || !header || !title || !switcher || !workspaceDrag || !slot) return null
|
||||
if (!shell || !page || !toolbar || !title || !switcher || !workspaceDrag || !sidebar || !editor || !slot) return null
|
||||
return {
|
||||
immersive: shell.classList.contains('tool-view-shell--immersive'),
|
||||
brandCount: shell.querySelectorAll('.tool-window-brand-zone').length,
|
||||
standaloneHeaderCount: page.querySelectorAll(':scope > .tool-page__header').length,
|
||||
pageTop: Math.round(page.getBoundingClientRect().top),
|
||||
headerTop: Math.round(header.top),
|
||||
headerCompact: header.height >= 42 && header.height <= 48,
|
||||
toolbarTop: Math.round(toolbar.top),
|
||||
toolbarCompact: toolbar.height >= 48 && toolbar.height <= 54,
|
||||
titleWidth: Math.round(title.width),
|
||||
titleHeight: Math.round(title.height),
|
||||
switchVisible: switcher.width > 0 && switcher.height > 0,
|
||||
switchInsideToolbar: switcher.top >= toolbar.top && switcher.bottom <= toolbar.bottom,
|
||||
firstColumnsGap: Math.round(editor.left - sidebar.right),
|
||||
dragRailCount: shell.querySelectorAll('[data-window-drag-rail]').length,
|
||||
workspaceDragUsable: workspaceDrag.width >= 48 && workspaceDrag.height >= 24,
|
||||
workspaceDragUsable: workspaceDrag.width >= 32 && workspaceDrag.height >= 24,
|
||||
workspaceDragRegion: getComputedStyle(document.querySelector('[data-window-drag-zone]')).getPropertyValue('-webkit-app-region'),
|
||||
edgeSlotWidth: Math.round(slot.width)
|
||||
}
|
||||
})()`)).value).toMatchObject({
|
||||
immersive: true,
|
||||
brandCount: 0,
|
||||
standaloneHeaderCount: 0,
|
||||
pageTop: 0,
|
||||
headerTop: 0,
|
||||
headerCompact: true,
|
||||
toolbarTop: 0,
|
||||
toolbarCompact: true,
|
||||
titleWidth: 1,
|
||||
titleHeight: 1,
|
||||
switchVisible: true,
|
||||
switchInsideToolbar: true,
|
||||
firstColumnsGap: 0,
|
||||
dragRailCount: 0,
|
||||
workspaceDragUsable: true,
|
||||
workspaceDragRegion: 'drag',
|
||||
@@ -246,12 +252,14 @@ test('keeps a custom-header tool immersive while preserving its view controls',
|
||||
return {
|
||||
controlsClass: document.querySelector('.tool-view-shell').classList.contains('tool-view-shell--window-controls-visible'),
|
||||
brandCount: document.querySelectorAll('.tool-window-brand-zone').length,
|
||||
headerTop: Math.round(document.querySelector('.quick-note-page-header').getBoundingClientRect().top)
|
||||
toolbarTop: Math.round(document.querySelector('.quick-note-toolbar').getBoundingClientRect().top),
|
||||
searchInset: Math.round(document.querySelector('.quick-note-search').getBoundingClientRect().left - document.querySelector('.quick-note-sidebar').getBoundingClientRect().left)
|
||||
}
|
||||
})()`)).value).toEqual({
|
||||
controlsClass: true,
|
||||
brandCount: 0,
|
||||
headerTop: 0
|
||||
toolbarTop: 0,
|
||||
searchInset: process.platform === 'darwin' ? 82 : 8
|
||||
})
|
||||
|
||||
await sendToolWindowControlsVisibility('quickNote', false)
|
||||
@@ -265,7 +273,7 @@ test('keeps double-clicked Quick Note split-preview text selected after auto-sav
|
||||
await mainPage.locator('.tool-button').filter({ hasText: '随手记' }).click()
|
||||
await waitForToolSelector('quickNote', '.quick-note-tool')
|
||||
await evaluateTool('quickNote', `(() => {
|
||||
const split = [...document.querySelectorAll('[role="tab"]')].find((tab) => tab.textContent === '分栏')
|
||||
const split = [...document.querySelectorAll('[role="tab"]')].find((tab) => tab.getAttribute('aria-label') === '分栏')
|
||||
if (!split) throw new Error('Quick Note split tab not found')
|
||||
split.click()
|
||||
})()`)
|
||||
|
||||
Reference in New Issue
Block a user