From 96cffcf4d16c3d04d7275b0d6c6ab0fd5919a453 Mon Sep 17 00:00:00 2001 From: Type <79042381+TypeFor@users.noreply.github.com> Date: Sun, 16 Aug 2026 00:30:08 +0200 Subject: [PATCH] FIX - use standard tabbar for note formatting Migrates the note editor formatting controls to the shared SkyTabBar and SkyTabButton primitives. Removes the app-local toolbar geometry and adds a contract test for the shared component usage. --- .../NotesRichTextEditor.contract.test.ts | 20 ++ .../src/components/NotesRichTextEditor.vue | 292 +++++++----------- 2 files changed, 124 insertions(+), 188 deletions(-) create mode 100644 frontend/src/components/NotesRichTextEditor.contract.test.ts diff --git a/frontend/src/components/NotesRichTextEditor.contract.test.ts b/frontend/src/components/NotesRichTextEditor.contract.test.ts new file mode 100644 index 0000000..48ef9ab --- /dev/null +++ b/frontend/src/components/NotesRichTextEditor.contract.test.ts @@ -0,0 +1,20 @@ +import { readFileSync } from 'node:fs' + +import { describe, expect, it } from 'vitest' + +const source = readFileSync( + new URL('./NotesRichTextEditor.vue', import.meta.url), + 'utf8', +) + +describe('NotesRichTextEditor formatting tabbar', () => { + it('lists every formatting action through shared tabbar primitives', () => { + expect(source.match(/ Math.abs(event.deltaY) - ? event.deltaX - : event.deltaY -} - watch( () => props.modelValue, (body) => { @@ -241,128 +232,150 @@ onBeforeUnmount(() => editor.value?.destroy()) :editor="editor" /> - + + + @@ -390,8 +403,7 @@ onBeforeUnmount(() => editor.value?.destroy()) scrollbar-width: none; } -.notes-rich-editor__content::-webkit-scrollbar, -.notes-rich-editor__toolbar::-webkit-scrollbar { +.notes-rich-editor__content::-webkit-scrollbar { display: none; } @@ -494,89 +506,6 @@ onBeforeUnmount(() => editor.value?.destroy()) pointer-events: none; } -.notes-rich-editor__toolbar { - width: 100%; - min-height: 59px; - padding: 7px var(--sky-page-gutter) calc(var(--sky-safe-area-bottom) + 7px); - display: flex; - align-items: center; - gap: 6px; - overflow-x: auto; - overflow-y: hidden; - border-top: 1px solid rgb(60 60 67 / 18%); - background: rgb(246 246 248 / 96%); - box-shadow: 0 -9px 28px rgb(0 0 0 / 7%); - scrollbar-width: none; - touch-action: pan-x; -} - -.notes-rich-editor--dark .notes-rich-editor__toolbar { - border-top-color: rgb(255 255 255 / 12%); - background: rgb(27 27 29 / 97%); - box-shadow: 0 -10px 30px rgb(0 0 0 / 38%); -} - -.notes-rich-editor__toolbar button { - width: 42px; - height: 42px; - flex: 0 0 42px; - border: 1px solid rgb(60 60 67 / 14%); - border-radius: 14px; - display: grid; - place-items: center; - background: rgb(255 255 255 / 72%); - box-shadow: inset 0 1px rgb(255 255 255 / 65%); - color: inherit; - cursor: pointer; - transition: - transform 130ms ease, - background-color 150ms ease, - color 150ms ease; -} - -.notes-rich-editor--dark .notes-rich-editor__toolbar button { - border-color: rgb(255 255 255 / 10%); - background: linear-gradient(145deg, #303034, #202023); - box-shadow: inset 0 1px rgb(255 255 255 / 8%); -} - -.notes-rich-editor__toolbar button.is-active { - border-color: #ffcc00; - background: #ffcc00; - color: #171719; -} - -.notes-rich-editor__toolbar button:disabled { - opacity: 0.3; - cursor: default; -} - -.notes-rich-editor__toolbar button.is-unavailable { - opacity: 0.3; - cursor: default; -} - -.notes-rich-editor__toolbar button:active:not(:disabled) { - transform: scale(0.94); -} - -.notes-rich-editor__toolbar button:focus-visible { - outline: 2px solid #ffcc00; - outline-offset: 2px; -} - -.notes-rich-editor__separator { - width: 1px; - height: 24px; - flex: 0 0 1px; - margin: 0 1px; - background: rgb(60 60 67 / 20%); -} - -.notes-rich-editor--dark .notes-rich-editor__separator { - background: rgb(255 255 255 / 16%); -} - .notes-rich-editor__text-tool { font-size: 14px; font-weight: 650; @@ -585,17 +514,4 @@ onBeforeUnmount(() => editor.value?.destroy()) .notes-rich-editor__text-tool--large { font-size: 17px; } - -@media (hover: hover) { - .notes-rich-editor__toolbar button:hover:not(:disabled) { - transform: translateY(-1px); - filter: brightness(1.08); - } -} - -@media (prefers-reduced-motion: reduce) { - .notes-rich-editor__toolbar button { - transition: none; - } -}