schon/storefront/app/components/store/top.vue
Alexandr SaVBaD Waltz 556354a44d feat(storefront): overhaul theming system and unify SCSS variables
Revamped the theming system with new SCSS variables for consistent styling across light and dark themes. Replaced static color values with dynamic variables for maintainability and improved theme adaptability. Updated components and layouts to use the new variables.

- Moved theme plugin logic for optimized handling of theme cookies and attributes.
- Enhanced `useThemes` composable for simplified client-side updates and SSR support.
- Replaced redundant SCSS color definitions with centralized variables.
- Improved page structure by introducing `ui-title` for reusable section headers.
- Unified transitions and border-radius for consistent design language.

Breaking Changes:
Theming system restructured—migrate to `$main`, `$primary`, and related variables for SCSS colors. Remove usage of `--color-*` variables in templates and styles.
2026-03-01 20:16:05 +03:00

137 lines
No EOL
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="top" :class="[{ filters: isFilters }]">
<div class="top__sorting">
<p>{{ t('store.sorting') }}</p>
<client-only>
<el-select
v-model="select"
size="large"
style="width: 240px"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</client-only>
</div>
<div class="top__view">
<button
class="top__view-button"
:class="{ active: productView === 'list' }"
@click="setView('list')"
>
<icon name="material-symbols:view-list-sharp" size="16" />
</button>
<button
class="top__view-button"
:class="{ active: productView === 'grid' }"
@click="setView('grid')"
>
<icon name="material-symbols:grid-view" size="16" />
</button>
</div>
</div>
</template>
<script setup lang="ts">
const {t} = useI18n();
const { $appHelpers } = useNuxtApp();
const props = defineProps<{
modelValue: string;
isFilters: boolean;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
(e: 'toggle-filter'): void;
}>();
const productView = useCookie($appHelpers.COOKIES_PRODUCT_VIEW_KEY as string);
function setView(view: 'list' | 'grid') {
productView.value = view;
}
const select = ref(props.modelValue || 'created');
const options = [
{
value: 'created',
label: 'New',
},
{
value: 'rating',
label: 'Rating',
},
{
value: 'price',
label: 'Сheap first',
},
{
value: '-price',
label: 'Expensive first',
}
];
watch(select, value => {
emit('update:modelValue', value);
});
</script>
<style scoped lang="scss">
.top {
margin-bottom: 20px;
width: 100%;
position: relative;
z-index: 2;
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 40px;
border-radius: $default_border_radius;
border: 1px solid $border;
padding: 16px;
&.filters {
justify-content: flex-end;
}
&__sorting {
display: flex;
align-items: center;
gap: 20px;
& p {
font-weight: 400;
font-size: 14px;
letter-spacing: -0.5px;
color: $text;
}
}
&__view {
display: flex;
align-items: center;
border-radius: $less_border_radius;
border: 1px solid $border;
&-button {
cursor: pointer;
background-color: $main;
display: grid;
place-items: center;
padding: 10px;
color: $primary_dark;
@include hover {
background-color: $main_hover;
}
&.active {
background-color: $link_secondary;
}
}
}
}
</style>