From 527b8e9f6486649d7e2bbf2af402658f2c56683e Mon Sep 17 00:00:00 2001 From: NGPixel Date: Wed, 12 Aug 2026 18:54:10 -0400 Subject: [PATCH] feat: mobile / table UI optimizations --- blocks/block-tabs/component.js | 16 ++ frontend/src/assets/icons.generated.js | 3 +- frontend/src/components/EditorMarkdown.vue | 16 +- frontend/src/components/FileManager.vue | 177 ++++++++++++- frontend/src/components/HeaderActionsMenu.vue | 4 +- frontend/src/components/HeaderNav.vue | 61 +++-- frontend/src/components/NavSidebar.vue | 12 +- frontend/src/components/PageActionsCol.vue | 27 ++ frontend/src/components/PageHeader.vue | 11 +- frontend/src/components/PageToc.vue | 2 +- frontend/src/components/shared/WDrawer.vue | 19 +- frontend/src/css/_base.scss | 44 ++++ frontend/src/css/_page-contents.scss | 32 +++ frontend/src/layouts/AdminLayout.vue | 65 ++++- frontend/src/layouts/MainLayout.vue | 116 ++++++--- frontend/src/layouts/ProfileLayout.vue | 227 ++++++++++++++++- frontend/src/pages/AdminSystem.vue | 4 +- frontend/src/pages/AdminTheme.vue | 4 +- frontend/src/pages/Index.vue | 240 +++++++++++++++++- frontend/src/pages/ProfileAvatar.vue | 17 +- frontend/src/pages/Search.vue | 235 ++++++++++++++++- 21 files changed, 1229 insertions(+), 103 deletions(-) diff --git a/blocks/block-tabs/component.js b/blocks/block-tabs/component.js index 123b2c6b3..71a4b358c 100644 --- a/blocks/block-tabs/component.js +++ b/blocks/block-tabs/component.js @@ -158,6 +158,22 @@ Content of the second tab. background-color: var(--tabs-panel-bg); } + /* + Tighter on a phone. The panel sits inside an article that pads by 8px there, so 20px of its own + put the text 28px in from the edge of the screen -- a third of the indent a 390px column can + afford, spent twice over on the same margin. + + 599.98px is the app's own phone breakpoint -- --breakpoint-sm is 600px in css/tailwind.css. A + block cannot read the app's Sass variables, so the value is written out, as block-infobox does + with its own. (No backticks in here: this whole stylesheet is a template literal, and one ends + it mid-rule.) + */ + @media (max-width: 599.98px) { + .panel { + padding: 12px; + } + } + /* -> The panel owns the spacing, so the content inside it does not add its own at the edges */ ::slotted(block-tab) { margin-bottom: 0; diff --git a/frontend/src/assets/icons.generated.js b/frontend/src/assets/icons.generated.js index 7dd13c0de..2f9306903 100644 --- a/frontend/src/assets/icons.generated.js +++ b/frontend/src/assets/icons.generated.js @@ -5,7 +5,7 @@ never waits on (or depends on) the icon service. Regenerate with `npm run icons` after adding or removing an icon; `check-icons.mjs` fails the build if this drifts. - 263 icons. + 264 icons. */ export const BUNDLED_ICONS = { "la:angle-double-right": {"body":"","width":32,"height":32}, @@ -189,6 +189,7 @@ export const BUNDLED_ICONS = { "mdi:eye-off-outline": {"body":"","width":24,"height":24}, "mdi:file-document-outline": {"body":"","width":24,"height":24}, "mdi:file-search-outline": {"body":"","width":24,"height":24}, + "mdi:file-tree": {"body":"","width":24,"height":24}, "mdi:flag-outline": {"body":"","width":24,"height":24}, "mdi:food-apple-outline": {"body":"","width":24,"height":24}, "mdi:format-align-center": {"body":"","width":24,"height":24}, diff --git a/frontend/src/components/EditorMarkdown.vue b/frontend/src/components/EditorMarkdown.vue index d1c1b66f3..ebaeb77a2 100644 --- a/frontend/src/components/EditorMarkdown.vue +++ b/frontend/src/components/EditorMarkdown.vue @@ -312,6 +312,7 @@ import { useI18n } from 'vue-i18n' import { bindCollabEditor, startCollabSession, stopCollabSession } from '@/composables/collab' import { dialog } from '@/composables/dialog' import { notify } from '@/composables/notify' +import { useMinWidth } from '@/composables/screen' import { assetPath } from '@/helpers/assets' import { blockMarkdown } from '@/helpers/blocks' import { findEditableTables } from '@/helpers/markdownTable' @@ -418,8 +419,21 @@ const HEADER_ICONS = [ */ const SYNC_SCROLL = { behavior: 'smooth', block: 'start', inline: 'nearest' } +/** + * Whether the window is wide enough to open the preview beside the source. + * + * 1024 is the app's `md` breakpoint (`css/tailwind.css`). Below it the two panes are half a small window + * each, and the source is the one being typed into — so the preview starts closed and is opened when + * wanted, from the toolbar button that takes its place. + */ +const isAtLeastMd = useMinWidth(1024) + const state = reactive({ - previewShown: true, + /* + Read once, as a DEFAULT rather than a binding: past this first value the pane is the author's to open + and close, and a bound one would slam it shut the moment a window was dragged narrower mid-edit. + */ + previewShown: isAtLeastMd.value, previewScrollSync: true }) diff --git a/frontend/src/components/FileManager.vue b/frontend/src/components/FileManager.vue index 0d5c0d7d1..9f69d833e 100644 --- a/frontend/src/components/FileManager.vue +++ b/frontend/src/components/FileManager.vue @@ -1,11 +1,17 @@