diff --git a/frontend/App.vue b/frontend/App.vue index 3773154e..64c16f38 100644 --- a/frontend/App.vue +++ b/frontend/App.vue @@ -60,6 +60,7 @@ import { useInfoMask } from '@/composables/use-info-mask.js'; import { useRefreshOrchestrator } from '@/composables/use-refresh-orchestrator.js'; import { useShortcuts } from '@/composables/use-shortcuts.js'; import { useSectionTracking } from '@/composables/use-section-tracking.js'; +import { useTheme } from '@/composables/use-theme.js'; const { t } = useI18n(); const store = useMainStore(); @@ -137,6 +138,9 @@ const { loadShortcuts } = useShortcuts({ // Scroll monitoring + section tracking (logic from widgets/Patch.vue) useSectionTracking(); +// Theme orchestration: initial apply, OS flip listener, preference watcher. +useTheme(); + onMounted(() => { loadingControl(); loadShortcuts(); diff --git a/frontend/components/Nav.vue b/frontend/components/Nav.vue index 242770f5..cf7ebb1d 100644 --- a/frontend/components/Nav.vue +++ b/frontend/components/Nav.vue @@ -1,7 +1,18 @@ diff --git a/frontend/components/ui/drawer/DrawerContent.vue b/frontend/components/ui/drawer/DrawerContent.vue index f31b1b3f..fe817ced 100644 --- a/frontend/components/ui/drawer/DrawerContent.vue +++ b/frontend/components/ui/drawer/DrawerContent.vue @@ -25,6 +25,7 @@ defineEmits(['close', 'escapeKeyDown']); 'fixed inset-x-0 bottom-0 z-[10001] mt-24 flex h-auto flex-col rounded-t-[14px] border bg-background shadow-lg outline-none', props.class, )" + :style="{ paddingBottom: 'env(safe-area-inset-bottom)' }" @escape-key-down="$emit('escapeKeyDown', $event)" > // shadcn-vue Sheet 面板:四向滑入,包含 overlay // 见 refactor/01 阶段 B +import { computed } from 'vue'; import { DialogContent, DialogOverlay, DialogPortal, DialogTitle, VisuallyHidden } from 'reka-ui'; import { cva } from 'class-variance-authority'; import { cn } from '@/lib/utils'; @@ -30,6 +31,25 @@ const props = defineProps({ onInteractOutside: { type: Function, default: undefined }, }); defineEmits(['close', 'escapeKeyDown']); + +// Push content past the iOS safe-area insets so it doesn't render +// behind the transparent status bar / home indicator. Inline style +// so consumers' `p-0` doesn't override it. +const safeAreaStyle = computed(() => { + switch (props.side) { + case 'top': + return { paddingTop: 'env(safe-area-inset-top)' }; + case 'bottom': + return { paddingBottom: 'env(safe-area-inset-bottom)' }; + case 'left': + case 'right': + default: + return { + paddingTop: 'env(safe-area-inset-top)', + paddingBottom: 'env(safe-area-inset-bottom)', + }; + } +});