itube-specs 0.0.923 → 0.0.927
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS/STYLES.md +10 -1
- package/assets/scss/base/_utils.scss +6 -0
- package/assets/scss/layout/_layout.scss +1 -1
- package/assets/scss/mixins/_badge.scss +18 -0
- package/assets/scss/mixins/_breakpoints.scss +24 -3
- package/assets/scss/mixins/_cards-grid.scss +32 -0
- package/assets/scss/mixins/_index.scss +2 -0
- package/assets/scss/mixins/_page.scss +5 -1
- package/assets/scss/mixins/_video-card.scss +3 -13
- package/assets/scss/themes/dark/_theme.scss +16 -6
- package/assets/scss/themes/light/_theme.scss +16 -6
- package/assets/scss/vars/_tokens.scss +5 -1
- package/components/grid/categories.vue +3 -6
- package/components/grid/channels.vue +2 -12
- package/components/grid/playlists.vue +2 -8
- package/components/layout/burger.vue +4 -3
- package/components/layout/footer-language.vue +37 -61
- package/components/layout/header-user.vue +1 -1
- package/components/layout/header.vue +42 -41
- package/components/layout/language.vue +89 -58
- package/components/layout/nav.vue +1 -1
- package/components/layout/niche.vue +5 -5
- package/components/layout/notifications.vue +1 -1
- package/components/search/main.vue +18 -10
- package/components/section/swiper-cards.vue +17 -4
- package/components/view/model-videos.vue +2 -1
- package/components/view/video.vue +2 -3
- package/components/view/videos.vue +1 -0
- package/config/css-breakpoints.ts +2 -1
- package/layouts/default.vue +1 -1
- package/lib/scheme/sort-items-default.ts +2 -0
- package/lib/scheme/sort-items-search.ts +2 -0
- package/package.json +1 -1
- package/runtime/utils/check-device-width.ts +7 -3
- package/runtime/utils/converters/__tests__/group-categories-by-first-letter.test.ts +2 -3
- package/runtime/utils/converters/group-categories-by-first-letter.ts +3 -3
- package/utils/category-letter-groups/__tests__/group-by-first-letter.test.ts +2 -2
- package/utils/category-letter-groups/group-by-first-letter.ts +3 -3
package/DOCS/STYLES.md
CHANGED
|
@@ -120,8 +120,17 @@ Text-only elements (`title`, `name`, `subtext`, `description`, `label`, `count`)
|
|
|
120
120
|
`font-size`/`line-height`.
|
|
121
121
|
- Breakpoints: `@include from-br(sm)`, `to-br(xs)`. Container: `from-cq($bp)`. JS mirror of `$brkpnts` in
|
|
122
122
|
`config/`, guarded by `check:breakpoints`.
|
|
123
|
+
- `$brkpnts` holds layout tiers only — points the whole page frame turns on, needed by many components. A
|
|
124
|
+
one-off threshold of a single block (how many columns fit, where a word wraps) stays a px literal next to
|
|
125
|
+
that block: `from-br`/`to-br` take a number too.
|
|
126
|
+
- Card grids (videos, channels, playlists, categories) all key off `mixins/_cards-grid.scss` — one ladder
|
|
127
|
+
1 → 2 (370px) → 3 (900px) → 4 (1440px). Take columns from `@include cards-grid-columns`, set `display` and
|
|
128
|
+
`gap` yourself; don't hand-roll a per-grid column ladder or an `auto-fill` variant.
|
|
129
|
+
- `$brkpnt-burger` (= `sd`, 1024px) is the burger ↔ desktop-menu line: below it the nav and the right half of
|
|
130
|
+
the header collapse into the burger. Header, nav, search, niche, language and `--header-height` key off this
|
|
131
|
+
variable, not off `sm` — move the line here, not per file. Utility classes: `._to-sd` / `._from-sd`.
|
|
123
132
|
|
|
124
133
|
**All mixins** (auto-injected, never `@use`): `font-4xs|3xs|xs|2xs|sm|md|base|lg|xl|2xl|3xl|4xl`,
|
|
125
134
|
`from-br|to-br`, `from-cq|to-cq`, `hover`, `surface`, `button-variant`, `page|page-title|page-footer-links`,
|
|
126
|
-
`video-card|video-card-grid|video-card-poster`, `area-point`. Signatures — SCSS-mixins table in the app's
|
|
135
|
+
`cards-grid-columns`, `video-card|video-card-grid|video-card-poster`, `area-point`. Signatures — SCSS-mixins table in the app's
|
|
127
136
|
`DOCS/CATALOG.md`.
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
// Виден только ниже sm (960px), на sm и шире скрыт.
|
|
7
7
|
@include from-br(sm) { ._to-sm { display: none !important; } }
|
|
8
8
|
|
|
9
|
+
// Виден только ниже sd (1024px, граница бургера), на sd и шире скрыт.
|
|
10
|
+
@include from-br(sd) { ._to-sd { display: none !important; } }
|
|
11
|
+
|
|
9
12
|
// Виден только ниже md (1350px), на md и шире скрыт.
|
|
10
13
|
@include from-br(md) { ._to-md { display: none !important; } }
|
|
11
14
|
|
|
@@ -18,6 +21,9 @@
|
|
|
18
21
|
// Виден с sm (960px) и шире, ниже скрыт.
|
|
19
22
|
@include to-br(sm) { ._from-sm { display: none !important; } }
|
|
20
23
|
|
|
24
|
+
// Виден с sd (1024px, граница бургера) и шире, ниже скрыт.
|
|
25
|
+
@include to-br(sd) { ._from-sd { display: none !important; } }
|
|
26
|
+
|
|
21
27
|
// Виден с md (1350px) и шире, ниже скрыт.
|
|
22
28
|
@include to-br(md) { ._from-md { display: none !important; } }
|
|
23
29
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@use 'font-sizes' as *;
|
|
2
|
+
@use 'vars' as *;
|
|
3
|
+
|
|
4
|
+
// Плашка с кодом локали в переключателях языка (шапка, футер, список языков).
|
|
5
|
+
// Цвета не задаёт — фон и текст ставит вызывающий компонент своими токенами.
|
|
6
|
+
@mixin locale-badge {
|
|
7
|
+
@include font-xs;
|
|
8
|
+
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
padding: 2px 6px;
|
|
13
|
+
border-radius: $radius-small;
|
|
14
|
+
font-weight: 600;
|
|
15
|
+
line-height: 1;
|
|
16
|
+
letter-spacing: var(--tracking-wide);
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
}
|
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
@use 'sass:map';
|
|
2
2
|
@use 'sass:list';
|
|
3
|
+
@use 'sass:math';
|
|
3
4
|
@use 'sass:meta';
|
|
4
5
|
|
|
5
|
-
//
|
|
6
|
+
// Тиры раскладки. Сюда попадают только точки, вокруг которых перестраивается общий каркас
|
|
7
|
+
// страницы, и потому нужные многим компонентам. Разовый порог одного блока (сколько колонок
|
|
8
|
+
// влезло, где переносится слово) держим литералом рядом с этим блоком — from-br/to-br
|
|
9
|
+
// принимают и число в px.
|
|
6
10
|
|
|
7
11
|
$brkpnts: (
|
|
8
12
|
xs: 475px,
|
|
9
13
|
xm: 650px,
|
|
10
14
|
sm: 960px,
|
|
15
|
+
sd: 1024px,
|
|
11
16
|
md: 1350px,
|
|
12
17
|
ml: 1500px,
|
|
13
18
|
lg: 1792px,
|
|
14
19
|
xl: 2560px,
|
|
15
20
|
);
|
|
16
21
|
|
|
22
|
+
/**
|
|
23
|
+
Граница «бургер ↔ десктопное меню»: ниже неё навигация и правая часть шапки свёрнуты
|
|
24
|
+
в бургер, выше — разложены в шапку и в строку навигации под ней. Отдельная переменная,
|
|
25
|
+
а не литерал `sd`, чтобы двигать эту границу, не перебирая шапку по файлам.
|
|
26
|
+
*/
|
|
27
|
+
$brkpnt-burger: sd;
|
|
28
|
+
|
|
29
|
+
// Литерал-порог можно писать и как 370, и как 370px — приводим к px.
|
|
30
|
+
@function _to-px($bp) {
|
|
31
|
+
@if math.is-unitless($bp) {
|
|
32
|
+
@return $bp * 1px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@return $bp;
|
|
36
|
+
}
|
|
37
|
+
|
|
17
38
|
/**
|
|
18
39
|
Mobile first брейкпоинты
|
|
19
40
|
@include from-br(sm) { ... }
|
|
@@ -27,7 +48,7 @@ $brkpnts: (
|
|
|
27
48
|
@content;
|
|
28
49
|
}
|
|
29
50
|
} @else if meta.type-of($bp) == 'number' {
|
|
30
|
-
$pixelyzed: $bp
|
|
51
|
+
$pixelyzed: _to-px($bp);
|
|
31
52
|
|
|
32
53
|
@media (min-width: $pixelyzed) {
|
|
33
54
|
@content;
|
|
@@ -49,7 +70,7 @@ $brkpnts: (
|
|
|
49
70
|
@content;
|
|
50
71
|
}
|
|
51
72
|
} @else if meta.type-of($bp) == 'number' {
|
|
52
|
-
$pixelyzed: $bp
|
|
73
|
+
$pixelyzed: _to-px($bp) - 1px;
|
|
53
74
|
|
|
54
75
|
@media (max-width: $pixelyzed) {
|
|
55
76
|
@content;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
@use 'breakpoints' as *;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Пороги плотности сеток карточек — тумб, каналов, плейлистов, категорий. Это не тиры
|
|
5
|
+
раскладки, а ответ на вопрос «сколько карточек влезает по ширине», поэтому литералы,
|
|
6
|
+
а не ключи $brkpnts: 900px и 1440px намеренно не совпадают с sm/md и в общую карту не идут.
|
|
7
|
+
*/
|
|
8
|
+
$cards-grid-2-cols: 370px;
|
|
9
|
+
$cards-grid-3-cols: 900px;
|
|
10
|
+
$cards-grid-4-cols: 1440px;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
Колонки сетки карточек: 1, 2 с 370px, 3 с 900px, 4 с 1440px. Только grid-template-columns —
|
|
14
|
+
`display` и `gap` остаются на вызывающей стороне, они у сеток разные.
|
|
15
|
+
minmax(0, 1fr) обязателен, не `1fr`: нешринкуемая мета-строка (карточка истории) задаёт
|
|
16
|
+
колонке min-content, из-за которого грид вылезает за контейнер на телефоне.
|
|
17
|
+
*/
|
|
18
|
+
@mixin cards-grid-columns {
|
|
19
|
+
grid-template-columns: minmax(0, 1fr);
|
|
20
|
+
|
|
21
|
+
@include from-br($cards-grid-2-cols) {
|
|
22
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@include from-br($cards-grid-3-cols) {
|
|
26
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@include from-br($cards-grid-4-cols) {
|
|
30
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -13,11 +13,15 @@
|
|
|
13
13
|
|
|
14
14
|
// Заголовок страницы: font-lg, uppercase, 700. В разметке — глобальный класс `._title`.
|
|
15
15
|
@mixin page-title {
|
|
16
|
-
@include font-
|
|
16
|
+
@include font-base;
|
|
17
17
|
|
|
18
18
|
text-transform: uppercase;
|
|
19
19
|
letter-spacing: var(--tracking-wide);
|
|
20
20
|
font-weight: 700;
|
|
21
|
+
|
|
22
|
+
@include from-br(xm) {
|
|
23
|
+
@include font-lg;
|
|
24
|
+
}
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
// Блок SEO-ссылок внизу страницы: прижат к низу (margin-top: auto) и отбит линией.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@use 'breakpoints' as *;
|
|
2
|
+
@use 'cards-grid' as *;
|
|
2
3
|
@use 'font-sizes' as *;
|
|
3
4
|
@use 'vars' as *;
|
|
4
5
|
|
|
@@ -10,27 +11,16 @@
|
|
|
10
11
|
align-content: start;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
Сетка карточек видео: 2 колонки, 3 с xs, 4 с md.
|
|
15
|
-
minmax(0, 1fr) обязателен, не `1fr`: мета-строка карточки истории нешринкуема и задаёт
|
|
16
|
-
колонке min-content, из-за которого грид вылезает за контейнер на телефоне.
|
|
17
|
-
*/
|
|
14
|
+
// Сетка карточек видео: колонки общие для всех сеток карточек, свой только зазор.
|
|
18
15
|
@mixin video-card-grid {
|
|
19
16
|
display: grid;
|
|
20
17
|
gap: 12px;
|
|
21
|
-
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
22
18
|
|
|
23
|
-
@include
|
|
24
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
25
|
-
}
|
|
19
|
+
@include cards-grid-columns;
|
|
26
20
|
|
|
27
21
|
@include from-br(sm) {
|
|
28
22
|
gap: 24px;
|
|
29
23
|
}
|
|
30
|
-
|
|
31
|
-
@include from-br(md) {
|
|
32
|
-
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
33
|
-
}
|
|
34
24
|
}
|
|
35
25
|
|
|
36
26
|
// Постер карточки: 16/9, скруглённый, с обрезкой — база для абсолютных бейджей поверх.
|
|
@@ -367,6 +367,8 @@ $language-icon: $color-zinc-400;
|
|
|
367
367
|
$language--current: $color-zinc-500;
|
|
368
368
|
$language-title: $color-zinc-500;
|
|
369
369
|
$language-item-text: $color-zinc-300;
|
|
370
|
+
$language-code-bg: $color-zinc-700;
|
|
371
|
+
$language-code-text: $color-zinc-200;
|
|
370
372
|
$language-item-bg--hover: $color-zinc-800;
|
|
371
373
|
$language-item-text--current: $color-white;
|
|
372
374
|
$language-item-bg--current: $color-zinc-700;
|
|
@@ -390,11 +392,12 @@ $niche-item-bg--current: $color-zinc-700;
|
|
|
390
392
|
$footer-language-bg: $color-zinc-800-50;
|
|
391
393
|
$footer-language-bg--hover: $color-zinc-700;
|
|
392
394
|
$footer-language-text: $color-zinc-400;
|
|
393
|
-
$footer-language-
|
|
394
|
-
$footer-language-
|
|
395
|
-
$footer-language-
|
|
396
|
-
$footer-language-
|
|
397
|
-
$footer-language-
|
|
395
|
+
$footer-language-badge-bg: $color-zinc-800;
|
|
396
|
+
$footer-language-badge-text: $color-zinc-200;
|
|
397
|
+
$footer-language-menu-bg: $color-night;
|
|
398
|
+
$footer-language-menu-border: $color-zinc-800;
|
|
399
|
+
$footer-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
|
|
400
|
+
$footer-language-menu-item--hover: $color-zinc-800-50;
|
|
398
401
|
|
|
399
402
|
// ─── Burger ───
|
|
400
403
|
$burger-backdrop: $mono-black-50;
|
|
@@ -422,9 +425,12 @@ $header-bg: $color-black;
|
|
|
422
425
|
$header-burger-icon: $color-zinc-200;
|
|
423
426
|
$header-user-icon: $color-zinc-500;
|
|
424
427
|
$header-language-trigger: $color-zinc-400;
|
|
425
|
-
$header-language-
|
|
428
|
+
$header-language-trigger--hover: $color-white;
|
|
429
|
+
$header-language-badge-bg: $color-zinc-800;
|
|
430
|
+
$header-language-badge-text: $color-zinc-200;
|
|
426
431
|
$header-language-menu-bg: $color-night;
|
|
427
432
|
$header-language-menu-border: $color-zinc-800;
|
|
433
|
+
$header-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
|
|
428
434
|
$header-language-menu-item--hover: $color-zinc-800-50;
|
|
429
435
|
|
|
430
436
|
// ─── notifications ───
|
|
@@ -540,6 +546,10 @@ $swiper-nav-bg--hover: transparent;
|
|
|
540
546
|
$swiper-nav-text: $color-white;
|
|
541
547
|
$swiper-nav-shadow: transparent;
|
|
542
548
|
|
|
549
|
+
// ─── Section swiper cards ───
|
|
550
|
+
$section-swiper-cards-link: $color-zinc-400;
|
|
551
|
+
$section-swiper-cards-link--hover: $color-white;
|
|
552
|
+
|
|
543
553
|
// ─── Select ───
|
|
544
554
|
$select-icon: $color-zinc-400;
|
|
545
555
|
$select-bg: $color-zinc-800-60;
|
|
@@ -424,6 +424,8 @@ $language-icon: $color-gray-400;
|
|
|
424
424
|
$language--current: $color-gray-400;
|
|
425
425
|
$language-title: $color-gray-400;
|
|
426
426
|
$language-item-text: $color-gray-300;
|
|
427
|
+
$language-code-bg: $color-slate-700;
|
|
428
|
+
$language-code-text: $color-white;
|
|
427
429
|
$language-item-bg--hover: $color-white-5;
|
|
428
430
|
$language-item-text--current: $color-white;
|
|
429
431
|
$language-item-bg--current: $color-slate-750;
|
|
@@ -447,11 +449,12 @@ $niche-item-bg--current: $color-indigo-soft;
|
|
|
447
449
|
$footer-language-bg: $color-slate-750;
|
|
448
450
|
$footer-language-bg--hover: $color-slate-700;
|
|
449
451
|
$footer-language-text: $color-white;
|
|
450
|
-
$footer-language-
|
|
451
|
-
$footer-language-
|
|
452
|
-
$footer-language-
|
|
453
|
-
$footer-language-
|
|
454
|
-
$footer-language-
|
|
452
|
+
$footer-language-badge-bg: $color-slate-850;
|
|
453
|
+
$footer-language-badge-text: $color-white;
|
|
454
|
+
$footer-language-menu-bg: $color-slate-850;
|
|
455
|
+
$footer-language-menu-border: $color-white-10;
|
|
456
|
+
$footer-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
|
|
457
|
+
$footer-language-menu-item--hover: $color-white-5;
|
|
455
458
|
|
|
456
459
|
// ─── Burger ───
|
|
457
460
|
$burger-backdrop: $mono-black-50;
|
|
@@ -479,9 +482,12 @@ $header-bg: $color-slate-800;
|
|
|
479
482
|
$header-burger-icon: $color-gray-200;
|
|
480
483
|
$header-user-icon: $color-gray-500;
|
|
481
484
|
$header-language-trigger: $color-gray-500;
|
|
482
|
-
$header-language-
|
|
485
|
+
$header-language-trigger--hover: $color-gray-300;
|
|
486
|
+
$header-language-badge-bg: $color-slate-750;
|
|
487
|
+
$header-language-badge-text: $color-white;
|
|
483
488
|
$header-language-menu-bg: $color-slate-850;
|
|
484
489
|
$header-language-menu-border: $color-white-10;
|
|
490
|
+
$header-language-menu-shadow: 0 20px 25px -5px #{$mono-black-25}, 0 8px 10px -6px #{$mono-black-25};
|
|
485
491
|
$header-language-menu-item--hover: $color-white-5;
|
|
486
492
|
$notifications-icon: $color-gray-300;
|
|
487
493
|
$notifications-icon--mobile: $color-gray-200;
|
|
@@ -591,6 +597,10 @@ $swiper-nav-bg: $color-white;
|
|
|
591
597
|
$swiper-nav-bg--hover: $color-gray-300;
|
|
592
598
|
$swiper-nav-shadow: $mono-black-10;
|
|
593
599
|
|
|
600
|
+
// ─── Section swiper cards ───
|
|
601
|
+
$section-swiper-cards-link: $color-gray-600;
|
|
602
|
+
$section-swiper-cards-link--hover: $color-gray-900;
|
|
603
|
+
|
|
594
604
|
// ─── Select ───
|
|
595
605
|
$select-bg: $color-white;
|
|
596
606
|
$select-icon: $color-gray-500;
|
|
@@ -38,9 +38,13 @@
|
|
|
38
38
|
--container-padding-inline: 24px;
|
|
39
39
|
--chips-height: 32px;
|
|
40
40
|
--chips-height-small: 28px;
|
|
41
|
-
--header-height: 71px;
|
|
42
41
|
--control-min-width: 296px;
|
|
43
42
|
--max-width-container: 1600px;
|
|
44
43
|
--card-round-size: 96px;
|
|
45
44
|
}
|
|
45
|
+
|
|
46
|
+
// Высота шапки меняется вместе с её раскладкой, а не на общем тире sm.
|
|
47
|
+
@include from-br($brkpnt-burger) {
|
|
48
|
+
--header-height: 71px;
|
|
49
|
+
}
|
|
46
50
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!--
|
|
1
|
+
<!-- Сетка карточек категорий, 1-4 колонки -->
|
|
2
2
|
<template>
|
|
3
3
|
<div class="grid-categories">
|
|
4
4
|
<CardCategory
|
|
@@ -22,15 +22,12 @@ defineProps<{
|
|
|
22
22
|
|
|
23
23
|
<style lang="scss">
|
|
24
24
|
.grid-categories {
|
|
25
|
-
--min-width: 150px;
|
|
26
|
-
|
|
27
25
|
display: grid;
|
|
28
26
|
gap: 12px;
|
|
29
|
-
grid-template-columns: repeat(auto-fill, minmax(var(--min-width), 1fr));
|
|
30
27
|
|
|
31
|
-
@include
|
|
32
|
-
--min-width: 250px;
|
|
28
|
+
@include cards-grid-columns;
|
|
33
29
|
|
|
30
|
+
@include from-br(sm) {
|
|
34
31
|
gap: 16px;
|
|
35
32
|
}
|
|
36
33
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Сетка карточек каналов,
|
|
1
|
+
<!-- Сетка карточек каналов, 1-4 колонки -->
|
|
2
2
|
<template>
|
|
3
3
|
<div
|
|
4
4
|
id="anchor"
|
|
@@ -28,16 +28,6 @@ defineProps<{
|
|
|
28
28
|
display: grid;
|
|
29
29
|
gap: 24px;
|
|
30
30
|
|
|
31
|
-
@include
|
|
32
|
-
grid-template-columns: repeat(2, 1fr);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@include from-br(sm) {
|
|
36
|
-
grid-template-columns: repeat(3, 1fr);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@include from-br(md) {
|
|
40
|
-
grid-template-columns: repeat(4, 1fr);
|
|
41
|
-
}
|
|
31
|
+
@include cards-grid-columns;
|
|
42
32
|
}
|
|
43
33
|
</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Сетка карточек плейлистов,
|
|
1
|
+
<!-- Сетка карточек плейлистов, 1-4 колонки; попап шаринга — один на список -->
|
|
2
2
|
<template>
|
|
3
3
|
<div class="grid-playlists">
|
|
4
4
|
<CardPlaylist
|
|
@@ -64,12 +64,6 @@ function onShare(card: IPlaylistCard) {
|
|
|
64
64
|
display: grid;
|
|
65
65
|
gap: 24px;
|
|
66
66
|
|
|
67
|
-
@include
|
|
68
|
-
grid-template-columns: repeat(2, 1fr);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@include from-br(sm) {
|
|
72
|
-
grid-template-columns: repeat(4, 1fr);
|
|
73
|
-
}
|
|
67
|
+
@include cards-grid-columns;
|
|
74
68
|
}
|
|
75
69
|
</style>
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
/>
|
|
75
75
|
|
|
76
76
|
<LayoutLanguage
|
|
77
|
+
burger
|
|
77
78
|
class="layout-burger__language"
|
|
78
79
|
icon-size="20"
|
|
79
80
|
/>
|
|
@@ -117,13 +118,13 @@ const { isAuthorized } = useUser(AuthorizationApiService);
|
|
|
117
118
|
const burgerRef = ref();
|
|
118
119
|
|
|
119
120
|
const breakpoints = CSS_BREAKPOINTS;
|
|
120
|
-
const {
|
|
121
|
+
const { isBurgerMenu } = checkDeviceWidth(breakpoints);
|
|
121
122
|
|
|
122
123
|
const { scrollLock, scrollUnlock } = useGlobalScrollLock();
|
|
123
124
|
|
|
124
125
|
watch(() => props.modelValue, (value) => {
|
|
125
126
|
if (value) {
|
|
126
|
-
if (
|
|
127
|
+
if (isBurgerMenu.value) {
|
|
127
128
|
burgerRef.value.showModal();
|
|
128
129
|
scrollLock();
|
|
129
130
|
} else {
|
|
@@ -132,7 +133,7 @@ watch(() => props.modelValue, (value) => {
|
|
|
132
133
|
} else {
|
|
133
134
|
burgerRef.value.close();
|
|
134
135
|
|
|
135
|
-
if (
|
|
136
|
+
if (isBurgerMenu.value) {
|
|
136
137
|
scrollUnlock();
|
|
137
138
|
}
|
|
138
139
|
}
|
|
@@ -4,56 +4,37 @@
|
|
|
4
4
|
class="layout-footer-language"
|
|
5
5
|
>
|
|
6
6
|
<button
|
|
7
|
+
:class="{'--open': isMenuShow}"
|
|
8
|
+
:aria-label="$t('language')"
|
|
7
9
|
class="layout-footer-language__button"
|
|
8
10
|
type="button"
|
|
9
11
|
@click="handler"
|
|
10
12
|
>
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
>
|
|
18
|
-
{{ localeName }}
|
|
13
|
+
<UiIcon
|
|
14
|
+
class="layout-footer-language__icon"
|
|
15
|
+
name="earth"
|
|
16
|
+
size="16"
|
|
17
|
+
/>
|
|
18
|
+
<span class="layout-footer-language__badge">{{ locale }}</span>
|
|
19
19
|
<UiIcon
|
|
20
20
|
class="layout-footer-language__angle"
|
|
21
21
|
name="angle-down"
|
|
22
22
|
size="12"
|
|
23
23
|
/>
|
|
24
24
|
</button>
|
|
25
|
-
<
|
|
25
|
+
<LazyLayoutLanguage
|
|
26
26
|
v-if="isMenuShow"
|
|
27
27
|
class="layout-footer-language__menu"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
:key="`header-language-${index}`"
|
|
32
|
-
:class="{'--active': locale === item.code}"
|
|
33
|
-
:href="switchLocalePath(item.code)"
|
|
34
|
-
:hreflang="item.value as string"
|
|
35
|
-
:lang="item.language"
|
|
36
|
-
class="layout-footer-language__menu-item"
|
|
37
|
-
@click.prevent="handleSwitch(item.code)"
|
|
38
|
-
>
|
|
39
|
-
<img
|
|
40
|
-
:src="`/icons/flags/${item.code}.svg`"
|
|
41
|
-
:alt="item.code"
|
|
42
|
-
class="layout-footer-language__icon"
|
|
43
|
-
width="20"
|
|
44
|
-
height="16"
|
|
45
|
-
>
|
|
46
|
-
{{ item.name }}
|
|
47
|
-
</a>
|
|
48
|
-
</div>
|
|
28
|
+
icon-size="20"
|
|
29
|
+
@change="isMenuShow = false"
|
|
30
|
+
/>
|
|
49
31
|
</div>
|
|
50
32
|
</template>
|
|
51
33
|
|
|
52
34
|
<script setup lang="ts">
|
|
53
35
|
import { onClickOutside } from '@vueuse/core';
|
|
54
36
|
|
|
55
|
-
const { locale
|
|
56
|
-
const switchLocalePath = useSwitchLocalePath();
|
|
37
|
+
const { locale } = useI18n();
|
|
57
38
|
|
|
58
39
|
const menuRef = ref();
|
|
59
40
|
const isMenuShow = ref(false);
|
|
@@ -65,17 +46,6 @@ onClickOutside(menuRef, () => {
|
|
|
65
46
|
function handler() {
|
|
66
47
|
isMenuShow.value = !isMenuShow.value;
|
|
67
48
|
}
|
|
68
|
-
|
|
69
|
-
const enabledLocales = useEnabledLocales();
|
|
70
|
-
|
|
71
|
-
const localeName = computed(() => locales.value.find(item => item.code === locale.value)?.name || 'English');
|
|
72
|
-
|
|
73
|
-
const handleSwitch = (newLocale: string) => {
|
|
74
|
-
const code = newLocale as Parameters<typeof setLocale>[0];
|
|
75
|
-
isMenuShow.value = false;
|
|
76
|
-
setLocale(code);
|
|
77
|
-
setTimeout(() => window.location.href = switchLocalePath(code), 100);
|
|
78
|
-
};
|
|
79
49
|
</script>
|
|
80
50
|
|
|
81
51
|
<style lang="scss">
|
|
@@ -100,32 +70,38 @@ const handleSwitch = (newLocale: string) => {
|
|
|
100
70
|
}
|
|
101
71
|
}
|
|
102
72
|
|
|
73
|
+
.layout-footer-language__badge {
|
|
74
|
+
@include locale-badge;
|
|
75
|
+
|
|
76
|
+
background-color: $footer-language-badge-bg;
|
|
77
|
+
color: $footer-language-badge-text;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.layout-footer-language__angle {
|
|
81
|
+
transition: var(--transition) transform;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.layout-footer-language__button.--open .layout-footer-language__angle {
|
|
85
|
+
transform: rotate(180deg);
|
|
86
|
+
}
|
|
87
|
+
|
|
103
88
|
.layout-footer-language__menu {
|
|
104
89
|
position: absolute;
|
|
105
|
-
|
|
90
|
+
bottom: calc(100% + 8px);
|
|
106
91
|
left: 50%;
|
|
107
92
|
z-index: $z-index-tooltip;
|
|
108
|
-
transform:
|
|
109
|
-
border-radius: $radius;
|
|
110
|
-
width:
|
|
93
|
+
transform: translateX(-50%);
|
|
94
|
+
border-radius: $radius-xl;
|
|
95
|
+
width: 288px;
|
|
111
96
|
border: 1px solid $footer-language-menu-border;
|
|
112
97
|
background-color: $footer-language-menu-bg;
|
|
98
|
+
box-shadow: $footer-language-menu-shadow;
|
|
113
99
|
overflow: hidden;
|
|
114
100
|
}
|
|
115
101
|
|
|
116
|
-
.layout-footer-language__menu-
|
|
117
|
-
@include
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
flex-wrap: nowrap;
|
|
121
|
-
gap: 12px;
|
|
122
|
-
align-items: center;
|
|
123
|
-
color: $footer-language-item-text;
|
|
124
|
-
padding: 10px 16px;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.layout-footer-language__menu-item.--active {
|
|
128
|
-
background-color: $footer-language-item-bg--active;
|
|
129
|
-
color: $footer-language-item-text--active;
|
|
102
|
+
.layout-footer-language__menu .layout-language__summary {
|
|
103
|
+
@include hover(background-color) {
|
|
104
|
+
background-color: $footer-language-menu-item--hover;
|
|
105
|
+
}
|
|
130
106
|
}
|
|
131
107
|
</style>
|