diff --git a/frontend/src/components/NotesRichTextEditor.contract.test.ts b/frontend/src/components/NotesRichTextEditor.contract.test.ts index 48ef9ab..d74dea9 100644 --- a/frontend/src/components/NotesRichTextEditor.contract.test.ts +++ b/frontend/src/components/NotesRichTextEditor.contract.test.ts @@ -10,10 +10,17 @@ const source = readFileSync( describe('NotesRichTextEditor formatting tabbar', () => { it('lists every formatting action through shared tabbar primitives', () => { expect(source.match(/', + ) + expect(source).toContain(' @@ -543,4 +545,10 @@ onBeforeUnmount(() => editor.value?.destroy()) .notes-rich-editor__text-tool--large { font-size: 17px; } + +.notes-rich-editor__format-tool { + font-size: 17px; + font-weight: 500; + letter-spacing: -0.03em; +} diff --git a/frontend/src/ui/controls.css b/frontend/src/ui/controls.css index ed55b44..d75bb86 100644 --- a/frontend/src/ui/controls.css +++ b/frontend/src/ui/controls.css @@ -2724,10 +2724,25 @@ label.sky-list-item__row { padding: 0; } +.sky-glass.sky-fab--neutral { + background: var(--sky-glass-solid, rgba(247, 247, 248, 0.96)); + color: var(--sky-text, #000000); +} + +.sky-fab--neutral .sky-fab__accent-layer, +.sky-fab--neutral .sky-fab__dark-accent-layer, +.sky-fab--neutral .sky-fab__surface-layer { + display: none; +} + .sky-glass.sky-fab:active:not(:disabled) { background: transparent; } +.sky-glass.sky-fab--neutral:active:not(:disabled) { + background: var(--sky-glass-solid, rgba(247, 247, 248, 0.96)); +} + .sky-fab--disabled { cursor: default; opacity: 0.42; diff --git a/frontend/src/ui/controls/SkyFab.test.ts b/frontend/src/ui/controls/SkyFab.test.ts index d07d6ba..cc6bf7d 100644 --- a/frontend/src/ui/controls/SkyFab.test.ts +++ b/frontend/src/ui/controls/SkyFab.test.ts @@ -55,4 +55,22 @@ describe('SkyFab', () => { expect(fabTokens).toContain('--sky-fab-accent-inset-start') expect(fabTokens).not.toContain('rgba(10, 132, 255, 0.25)') }) + + it('offers a neutral glass variant without accent layers', async () => { + const html = await renderToString( + createSSRApp({ + render: () => h(SkyFab, { ariaLabel: 'Create', variant: 'neutral' }), + }), + ) + + expect(html).toContain('sky-fab--neutral') + + const controls = readFileSync( + fileURLToPath(new URL('../controls.css', import.meta.url)), + 'utf8', + ) + expect(controls).toMatch( + /\.sky-glass\.sky-fab--neutral\s*\{[^}]*background:\s*var\(--sky-glass-solid/s, + ) + }) }) diff --git a/frontend/src/ui/controls/SkyFab.vue b/frontend/src/ui/controls/SkyFab.vue index 6979cb9..131b901 100644 --- a/frontend/src/ui/controls/SkyFab.vue +++ b/frontend/src/ui/controls/SkyFab.vue @@ -14,6 +14,7 @@ const props = withDefaults( text?: string textPosition?: 'after' | 'before' type?: 'button' | 'reset' | 'submit' + variant?: 'neutral' | 'primary' }>(), { ariaLabel: '', @@ -23,6 +24,7 @@ const props = withDefaults( text: '', textPosition: 'after', type: 'button', + variant: 'primary', }, ) @@ -71,6 +73,7 @@ function handleClick(event: MouseEvent): void { :class="{ 'sky-fab--disabled': disabled, 'sky-fab--icon-only': !hasText, + 'sky-fab--neutral': variant === 'neutral', 'sky-fab--with-text': hasText, }" role="button" diff --git a/frontend/src/views/apps/NotesApp.menu.contract.test.ts b/frontend/src/views/apps/NotesApp.menu.contract.test.ts index d94f1f1..ed2df99 100644 --- a/frontend/src/views/apps/NotesApp.menu.contract.test.ts +++ b/frontend/src/views/apps/NotesApp.menu.contract.test.ts @@ -15,16 +15,22 @@ const listSource = source.slice( describe('NotesApp list controls', () => { it('places the Sky searchbar and create action together at the bottom', () => { const composerSource = listSource.slice( - listSource.indexOf('') + ''.length, + listSource.indexOf('') + ''.length, ) + expect(composerSource).toContain('component="footer"') + expect(listSource).toContain('') + expect(listSource).not.toContain('!pt-[44px]') }) }) diff --git a/frontend/src/views/apps/NotesApp.vue b/frontend/src/views/apps/NotesApp.vue index 20b10a0..84432ff 100644 --- a/frontend/src/views/apps/NotesApp.vue +++ b/frontend/src/views/apps/NotesApp.vue @@ -24,7 +24,14 @@ import NotesRichTextEditor from '@/components/NotesRichTextEditor.vue' import { useNotesStore } from '@/stores/notes' import { useEasyShareStore } from '@/stores/easyshare' import { usePhoneStore } from '@/stores/phone' -import { SkyActionSheet, SkyButton, SkyFab, SkySearchbar } from '@/ui' +import { + SkyActionSheet, + SkyButton, + SkyFab, + SkyScrollArea, + SkySearchbar, + SkyToolbar, +} from '@/ui' import type { Note } from '@/utils/notes' import { noteBodyToPlainText } from '@/utils/noteRichText' @@ -60,6 +67,7 @@ const visibleNotes = computed(() => { const editorLabels = computed(() => ({ bold: phone.t('Apps.notes.tools.bold'), bulletList: phone.t('Apps.notes.tools.bulletList'), + closeFormatting: phone.t('Common.close'), decreaseText: phone.t('Apps.notes.tools.decreaseText'), increaseText: phone.t('Apps.notes.tools.increaseText'), italic: phone.t('Apps.notes.tools.italic'), @@ -116,7 +124,10 @@ function editNote(note: Note): void { function persistDraft(): Note | undefined { const draft = { body: draftBody.value, - title: titleFromDraftBody(draftBody.value) || currentNote.value?.title.trim() || '', + title: + titleFromDraftBody(draftBody.value) || + currentNote.value?.title.trim() || + '', } if (editorId.value) { @@ -174,65 +185,70 @@ function shareNote(): void { + + + - + @@ -281,11 +297,7 @@ function shareNote(): void { {{ phone.t('Apps.easyShare.name') }} -