feat(user-apps): appearance settings (dark mode + reduced motion), product morph, filter sheet
Applies to both user-app and user-app-v2. Logic and structure are shared; each app keeps its own look. Appearance settings - New "تنظیمات ظاهری" page (/settings/appearance), opened from the dashboard and available without login. It offers a light/dark/system theme and a "fast & light" motion switch. - appearanceStore saves the choice to localStorage. A small inline boot script in index.html applies it before first paint so there is no white flash. The "system" option follows OS changes live. - New ToggleSwitch component. Dark mode - Theme LESS tokens now compile to CSS custom properties. Light/dark values come from a generated virtual:palette.css (themeConfig/ appearance.ts, with colors.json + new colors.dark.json). - New LESS alpha() plugin replaces fade() on theme tokens. - New semantic tokens: page, onInk, heroSurface, hairlineStrong, photoMat, photoStage. - The dark palette is layered (page < card < panel < border) so surfaces separate without shadows. - Hard-coded colors were replaced by tokens according to their role. - antd inputs/text get dark overrides; vant uses its own .van-theme-dark. - Light mode looks the same as before. Reduced motion - With html.motion-reduced, transitions are capped at 120ms, keyframe loops stop, and backdrop blurs and permanent will-change are dropped. - Spinners and the toast progress bar (which closes the toast) are exempt via .keep-motion. - Carousel autoplay, the v1 Lottie and the product morph honor the setting. Product detail - Opening a product is now a container-transform morph from the tapped card (ProductMorph). It replaces the bottom Drawer and uses composited transform/opacity only. - The detail view is seeded with the card's data, so it no longer opens blank and jumps. Filters and sheets - Filters are now a full-width bottom sheet. Selections stay a draft until applied, so the result list no longer re-renders while dragging the slider. - DropDown collapse animates grid-template-rows instead of a capped max-height. - v2 IslandSheet is restyled to the v2 design language (API unchanged). Fixes - filtersStore.reset() shallow-copied shared arrays, so clearing the filters never cleared the selected brands.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
<!--
|
||||
The visual half of an on/off switch: a track and a knob. Deliberately not a
|
||||
control on its own — the row that holds it is the <button role="switch">,
|
||||
so the whole row is one tap target and screen readers announce one switch
|
||||
(see views/user/AppearanceView.vue).
|
||||
|
||||
STRUCTURE IS SHARED, LOOK IS NOT: identical markup and script in user-app
|
||||
and user-app-v2; only the "Look" block differs, per app.
|
||||
-->
|
||||
<template>
|
||||
<span class="tsw" :class="{ 'is-on': on }" aria-hidden="true">
|
||||
<span class="tsw__knob"></span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{ on: boolean }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* ── Mechanics (same in both apps) ──────────────────────────── */
|
||||
.tsw {
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
height: 28px;
|
||||
border-radius: 999px;
|
||||
transition: background-color 0.22s ease;
|
||||
}
|
||||
|
||||
.tsw__knob {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
// RTL page: "off" sits on the right (start), "on" slides to the left (end).
|
||||
inset-inline-start: 3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 6px -1px rgba(20, 22, 26, 0.35);
|
||||
transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1), background-color 0.22s ease;
|
||||
}
|
||||
|
||||
.tsw.is-on .tsw__knob {
|
||||
transform: translateX(-18px);
|
||||
}
|
||||
|
||||
/* ── Look: user-app ─────────────────────────────────────────── */
|
||||
// The app's chosen state is brand green (@primary, as on chips and CTAs).
|
||||
.tsw {
|
||||
background: @lightGray1;
|
||||
}
|
||||
.tsw__knob {
|
||||
background: #fff;
|
||||
}
|
||||
.tsw.is-on {
|
||||
background: @primary;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user