From 00051a0eac0b77706763010a6aee5448d596717f Mon Sep 17 00:00:00 2001 From: jxxghp Date: Tue, 30 Jun 2026 06:21:37 +0800 Subject: [PATCH] Fix dashboard settings and FAB folding --- .../dialog/ContentToggleSettingsDialog.vue | 27 +++- src/styles/common.scss | 135 ++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/src/components/dialog/ContentToggleSettingsDialog.vue b/src/components/dialog/ContentToggleSettingsDialog.vue index d8b40fe9..84786c06 100644 --- a/src/components/dialog/ContentToggleSettingsDialog.vue +++ b/src/components/dialog/ContentToggleSettingsDialog.vue @@ -61,17 +61,42 @@ const elevatedValue = computed({ }) watch( - () => [props.enabled, props.elevated, props.items], + () => props.enabled, () => { resetLocalSettings() }, { deep: true, immediate: true }, ) +watch( + () => props.elevated, + value => { + localElevated.value = value + }, +) + +watch( + () => props.items.map(item => getItemValue(item)).join('\u0000'), + () => { + syncLocalEnabledItems() + }, +) + // 重置弹窗内部设置副本,避免直接修改父级 props。 function resetLocalSettings() { localEnabled.value = { ...props.enabled } localElevated.value = props.elevated + syncLocalEnabledItems() +} + +// 同步新增设置项的默认状态,避免刷新列表时覆盖用户正在编辑的本地选择。 +function syncLocalEnabledItems() { + props.items.forEach(item => { + const key = getItemValue(item) + if (key && !(key in localEnabled.value)) { + localEnabled.value[key] = Boolean(props.enabled[key]) + } + }) } // 获取设置项的稳定键值。 diff --git a/src/styles/common.scss b/src/styles/common.scss index aec9c5bf..7fd59645 100644 --- a/src/styles/common.scss +++ b/src/styles/common.scss @@ -1100,6 +1100,11 @@ html[data-theme="transparent"] .app-card-colorful, pointer-events: auto; } +.compact-fab-stack > :last-child { + position: relative; + z-index: 1; +} + .compact-fab-stack--history { inset-block-end: max(4.5rem, calc(env(safe-area-inset-bottom) + 4.5rem)); } @@ -1162,6 +1167,136 @@ html[data-theme="transparent"] .app-card-colorful, } } +@media (hover: hover) and (pointer: fine) and (width > 768px) { + .compact-fab-stack:has(> :nth-child(2)) { + --compact-fab-step: 3.75rem; + + padding-block-start: calc((var(--compact-fab-count, 8) - 1) * var(--compact-fab-step)); + } + + .compact-fab-stack:has(> :nth-child(2)):hover, + .compact-fab-stack:has(> :nth-child(2)):focus-within { + pointer-events: auto; + } + + .compact-fab-stack:has(> :nth-child(2):last-child) { + --compact-fab-count: 2; + } + + .compact-fab-stack:has(> :nth-child(3):last-child) { + --compact-fab-count: 3; + } + + .compact-fab-stack:has(> :nth-child(4):last-child) { + --compact-fab-count: 4; + } + + .compact-fab-stack:has(> :nth-child(5):last-child) { + --compact-fab-count: 5; + } + + .compact-fab-stack:has(> :nth-child(6):last-child) { + --compact-fab-count: 6; + } + + .compact-fab-stack:has(> :nth-child(7):last-child) { + --compact-fab-count: 7; + } + + .compact-fab-stack:has(> :nth-child(8):last-child) { + --compact-fab-count: 8; + } + + .compact-fab-stack:has(> :nth-child(2)) > :not(:last-child) { + opacity: 0; + pointer-events: none; + transform: translateY(calc(var(--compact-fab-order, 1) * var(--compact-fab-step))); + transition: + opacity 0.12s ease, + transform 0.12s ease; + } + + .compact-fab-stack:has(> :nth-child(2)) > :last-child .v-btn { + opacity: 0.78; + } + + .compact-fab-stack:has(> :nth-child(2)):not(:hover):not(:focus-within) > :last-child .v-icon { + opacity: 0; + } + + .compact-fab-stack:has(> :nth-child(2)):not(:hover):not(:focus-within) > :last-child .v-btn__content { + position: relative; + } + + .compact-fab-stack:has(> :nth-child(2)):not(:hover):not(:focus-within) > :last-child .v-btn__content::before { + position: absolute; + display: block; + block-size: 0.94rem; + background: + radial-gradient(circle, currentcolor 0 38%, transparent 42%) center 0 / 0.32rem 0.32rem no-repeat, + radial-gradient(circle, currentcolor 0 38%, transparent 42%) center 50% / 0.32rem 0.32rem no-repeat, + radial-gradient(circle, currentcolor 0 38%, transparent 42%) center 100% / 0.32rem 0.32rem no-repeat; + content: ''; + inline-size: 0.94rem; + inset-block-start: 55%; + inset-inline-start: 50%; + transform: translate(-50%, -50%); + } + + .compact-fab-stack:has(> :nth-child(2)):not(:hover):not(:focus-within) > :last-child .v-btn__content::after { + position: absolute; + display: block; + block-size: 0.46rem; + border-block-start: 0.15rem solid currentcolor; + border-inline-start: 0.15rem solid currentcolor; + content: ''; + inline-size: 0.46rem; + inset-block-start: 17%; + inset-inline-start: 50%; + transform: translate(-50%, -50%) rotate(45deg); + } + + .compact-fab-stack:has(> :nth-child(2)):hover > :not(:last-child), + .compact-fab-stack:has(> :nth-child(2)):focus-within > :not(:last-child) { + opacity: 1; + pointer-events: auto; + transform: translateY(0); + } + + .compact-fab-stack:has(> :nth-child(2)):hover > :last-child .v-btn, + .compact-fab-stack:has(> :nth-child(2)):focus-within > :last-child .v-btn { + opacity: 0.98; + } + + .compact-fab-stack > :nth-last-child(2) { + --compact-fab-order: 1; + } + + .compact-fab-stack > :nth-last-child(3) { + --compact-fab-order: 2; + } + + .compact-fab-stack > :nth-last-child(4) { + --compact-fab-order: 3; + } + + .compact-fab-stack > :nth-last-child(5) { + --compact-fab-order: 4; + } + + .compact-fab-stack > :nth-last-child(6) { + --compact-fab-order: 5; + } + + .compact-fab-stack > :nth-last-child(7) { + --compact-fab-order: 6; + } + + .compact-fab-stack > :nth-last-child(8) { + --compact-fab-order: 7; + } +} + .compact-fab .v-btn:active { box-shadow: var(--app-fab-shadow-active); transform: translateY(0) scale(0.98);