itube-specs 0.0.723 → 0.0.726

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.
@@ -22,19 +22,25 @@
22
22
  icon="date"
23
23
  />
24
24
  </div>
25
- <SSelect
26
- v-for="(item, index) in scheme"
27
- :key="`scheme-${index}`"
28
- v-model="filterValue[item.name.toLowerCase()]"
29
- :name="item.title"
30
- :items="item.items"
31
- :label="item?.label"
32
- :label-icon="{
33
- icon: item.icon,
34
- prefix: 'categories'
35
- }"
36
- :placeholder="item.placeholder"
37
- />
25
+ <template v-if="scheme.length">
26
+ <SSelect
27
+ v-for="(item, index) in scheme"
28
+ :key="`scheme-${index}`"
29
+ v-model="filterValue[item.name.toLowerCase()]"
30
+ :name="item.title"
31
+ :items="item.items"
32
+ :label="item?.label"
33
+ :label-icon="{
34
+ icon: item.icon,
35
+ prefix: 'categories'
36
+ }"
37
+ :placeholder="item.placeholder"
38
+ />
39
+ </template>
40
+ <div
41
+ v-else
42
+ class="s-filter-popup__loading _loading"
43
+ ></div>
38
44
  </div>
39
45
 
40
46
  <template #footer>
@@ -62,7 +68,7 @@
62
68
  <script setup lang="ts">
63
69
  import type { IFilterScheme, ISelectItem } from '../../types';
64
70
 
65
- const { t } = useI18n()
71
+ const { t } = useI18n();
66
72
 
67
73
  const props = defineProps<{
68
74
  addedItems: ISelectItem[]
@@ -70,7 +76,7 @@ const props = defineProps<{
70
76
  modelValue: boolean
71
77
  scheme: IFilterScheme[]
72
78
  count: number
73
- }>()
79
+ }>();
74
80
 
75
81
  const durationValue = ref('');
76
82
  const addedValue = ref('');
@@ -87,39 +93,39 @@ const categoriesFromQuery = route.query.categories
87
93
  categoriesFromQuery.forEach(str => {
88
94
  const [key, ...rest] = str.split('_');
89
95
  if (key && rest.length > 0) {
90
- filterValue.value[ key ] = rest.join('_');
96
+ filterValue.value[key] = rest.join('_');
91
97
  }
92
98
  });
93
99
 
94
- durationValue.value = route.query[ 'duration' ] as string || '';
95
- addedValue.value = route.query[ 'added' ] as string || '';
100
+ durationValue.value = route.query['duration'] as string || '';
101
+ addedValue.value = route.query['added'] as string || '';
96
102
 
97
103
  const emit = defineEmits<{
98
104
  (eventName: 'update:modelValue', value: boolean): void
99
- }>()
105
+ }>();
100
106
 
101
- const isOpen = ref(props.modelValue)
107
+ const isOpen = ref(props.modelValue);
102
108
 
103
109
  function closePopup() {
104
110
  isOpen.value = false;
105
- emit('update:modelValue', isOpen.value)
111
+ emit('update:modelValue', isOpen.value);
106
112
  }
107
113
 
108
114
  const router = useRouter();
109
115
 
110
116
  function saveResult() {
111
117
  const oldQuery = { ...route.query };
112
- delete oldQuery[ 'page' ];
118
+ delete oldQuery['page'];
113
119
 
114
120
  const mainFiltersValue = {
115
121
  ...(durationValue.value ? { duration: durationValue.value } : {}),
116
- ...(addedValue.value ? { added: addedValue.value } : {})
122
+ ...(addedValue.value ? { added: addedValue.value } : {}),
117
123
  };
118
124
 
119
125
  const preserved = {
120
126
  ...mainFiltersValue,
121
127
  ...(oldQuery.sort ? { sort: oldQuery.sort } : {}),
122
- ...(oldQuery.page ? { page: oldQuery.page } : {})
128
+ ...(oldQuery.page ? { page: oldQuery.page } : {}),
123
129
  };
124
130
 
125
131
  const categories = Object.entries(filterValue.value)
@@ -132,7 +138,7 @@ function saveResult() {
132
138
  query: {
133
139
  ...preserved,
134
140
  categories: categories.length ? categoriesString : undefined,
135
- }
141
+ },
136
142
  });
137
143
 
138
144
  closePopup();
@@ -145,7 +151,7 @@ function reset() {
145
151
  router.push({
146
152
  query: {
147
153
  categories: null,
148
- }
154
+ },
149
155
  });
150
156
  }
151
157
 
@@ -154,16 +160,16 @@ const filterTitle = computed(() => {
154
160
  const hasAdded = addedValue.value ? 1 : 0;
155
161
  const count = Object.keys(filterValue.value).length + hasAdded + hasDuration;
156
162
  const filterText = count > 1 ? t('filters') : t('filter');
157
- return count > 0 ? `${filterText}: ${count}` : t('filter')
158
- })
163
+ return count > 0 ? `${filterText}: ${count}` : t('filter');
164
+ });
159
165
 
160
- const isFiltered = computed(() => !!route.query[ 'categories' ] || Object.keys(filterValue.value).length > 0 || durationValue.value || addedValue.value);
166
+ const isFiltered = computed(() => !!route.query['categories'] || Object.keys(filterValue.value).length > 0 || durationValue.value || addedValue.value);
161
167
 
162
168
  function translateTitle(array: ISelectItem[]) {
163
169
  return array.map((item: ISelectItem) => ({
164
170
  title: t(item.title),
165
171
  key: item.key,
166
- value: item.value
167
- }))
172
+ value: item.value,
173
+ }));
168
174
  }
169
175
  </script>
@@ -21,7 +21,7 @@
21
21
  </template>
22
22
 
23
23
  <script setup lang="ts">
24
- import type { ButtonSizes, ButtonThemes, IFilterScheme, ISelectItem } from '../../types';
24
+ import type { ButtonSizes, ButtonThemes, IFilterScheme, ISelectItem } from '../../types';
25
25
  import type { LocationQuery } from '#vue-router';
26
26
 
27
27
  const route = useRoute();
@@ -33,12 +33,20 @@ defineProps<{
33
33
  durationItems: ISelectItem[]
34
34
  buttonSize?: ButtonSizes
35
35
  buttonTheme?: ButtonThemes
36
- }>()
36
+ }>();
37
+
38
+ const emit = defineEmits<{
39
+ (e: 'open'): void
40
+ }>();
41
+
42
+ watch(filterOpen, (value) => {
43
+ if (value) emit('open');
44
+ });
37
45
 
38
46
  function getFilteredQuery(query: LocationQuery) {
39
47
  const result: string[] = [];
40
48
 
41
- const categoriesRaw = query[ 'categories' ];
49
+ const categoriesRaw = query['categories'];
42
50
  if (categoriesRaw) {
43
51
  if (Array.isArray(categoriesRaw)) {
44
52
  categoriesRaw.forEach(item => {
@@ -52,7 +60,7 @@ function getFilteredQuery(query: LocationQuery) {
52
60
  }
53
61
 
54
62
  ['duration', 'added'].forEach(key => {
55
- const val = query[ key ];
63
+ const val = query[key];
56
64
  if (typeof val === 'string' && val.length > 0) {
57
65
  result.push(val);
58
66
  }
@@ -63,9 +71,9 @@ function getFilteredQuery(query: LocationQuery) {
63
71
 
64
72
  const filterCount = ref(0);
65
73
 
66
- filterCount.value = getFilteredQuery(route.query).length
74
+ filterCount.value = getFilteredQuery(route.query).length;
67
75
 
68
76
  watch(() => route.query, (value) => {
69
- filterCount.value = getFilteredQuery(value).length
70
- })
77
+ filterCount.value = getFilteredQuery(value).length;
78
+ });
71
79
  </script>
@@ -6,7 +6,7 @@
6
6
  :loading="loading"
7
7
  :width="width"
8
8
  :height="height"
9
- :sizes="sizes"
9
+ :sizes="computedSizes"
10
10
  :alt="alt"
11
11
  :decoding="priority ? 'sync' : 'async'"
12
12
  :fetchpriority="priority ? 'high' : 'auto'"
@@ -22,7 +22,7 @@ const props = withDefaults(defineProps<{
22
22
  src?: string,
23
23
  width: string | number,
24
24
  height: string | number,
25
- sizes: string,
25
+ sizes?: string,
26
26
  urls?: IThumbUrls,
27
27
  alt?: string,
28
28
  loading?: 'lazy' | 'eager',
@@ -33,6 +33,11 @@ const props = withDefaults(defineProps<{
33
33
  fit: 'cover',
34
34
  })
35
35
 
36
+ const computedSizes = computed(() => {
37
+ if (props.loading === 'lazy') return 'auto';
38
+ return props.sizes;
39
+ });
40
+
36
41
  const imgSrc = computed(() => {
37
42
  if (props.src) return props.src
38
43
  if (props.urls) return props.urls.webp[ThumbSize.Medium]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itube-specs",
3
3
  "type": "module",
4
- "version": "0.0.723",
4
+ "version": "0.0.726",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "./types/index.d.ts",
7
7
  "scripts": {
@@ -1,57 +0,0 @@
1
- // @vitest-environment nuxt
2
- import { describe, it, expect } from 'vitest';
3
- import { useFilterScheme } from '../use-filter-scheme';
4
-
5
- const t = (key: string) => key;
6
-
7
- describe('useFilterScheme', () => {
8
- it('пустой массив для null', () => {
9
- const { filterScheme } = useFilterScheme(t, null);
10
- expect(filterScheme.value).toEqual([]);
11
- });
12
-
13
- it('трансформирует группы в схему', () => {
14
- const groups = [{
15
- title: 'Age', name: 'age', icon: 'age-icon',
16
- categories: [
17
- { title: 'teen', name: 'teen' },
18
- { title: 'milf', name: 'milf' },
19
- ],
20
- }];
21
- const { filterScheme } = useFilterScheme(t, groups);
22
- expect(filterScheme.value).toHaveLength(1);
23
- expect(filterScheme.value[0].label).toBe('Age');
24
- expect(filterScheme.value[0].items).toEqual([
25
- { title: 'Teen', value: 'teen' },
26
- { title: 'Milf', value: 'milf' },
27
- ]);
28
- });
29
-
30
- it('capitalize для multi-word', () => {
31
- const groups = [{
32
- title: 'Body', name: 'body', icon: '',
33
- categories: [{ title: 'big tits', name: 'big-tits' }],
34
- }];
35
- const { filterScheme } = useFilterScheme(t, groups);
36
- expect(filterScheme.value[0].items[0].title).toBe('Big Tits');
37
- });
38
-
39
- it('фильтрует пустые группы', () => {
40
- const groups = [
41
- { title: 'Empty', name: 'empty', icon: '', categories: [] },
42
- { title: 'Body', name: 'body', icon: '', categories: [{ title: 'slim', name: 'slim' }] },
43
- ];
44
- const { filterScheme } = useFilterScheme(t, groups);
45
- expect(filterScheme.value).toHaveLength(1);
46
- expect(filterScheme.value[0].name).toBe('body');
47
- });
48
-
49
- it('placeholder из t()', () => {
50
- const groups = [{
51
- title: 'Age', name: 'age', icon: '',
52
- categories: [{ title: 'teen', name: 'teen' }],
53
- }];
54
- const { filterScheme } = useFilterScheme(t, groups);
55
- expect(filterScheme.value[0].placeholder).toBe('choose_category');
56
- });
57
- });
@@ -1,32 +0,0 @@
1
- import type { IFilterScheme, IGroupCategories } from '../types';
2
- import { convertString } from '../runtime';
3
-
4
- /**
5
- * Строит вычисляемую схему фильтров из группированных категорий.
6
- * @param t - функция перевода (i18n)
7
- * @param groupsCategories - массив групп категорий
8
- */
9
- export const useFilterScheme = (t, groupsCategories: IGroupCategories[] | null) => {
10
- const getFilterSchemeCategories = (): IFilterScheme[] => {
11
- return groupsCategories?.map((item) => ({
12
- label: item.title,
13
- name: item.name,
14
- title: item.title,
15
- icon: item.icon,
16
- placeholder: t('choose_category'),
17
- items: item.categories?.map((subItem) => ({
18
- title: convertString().toCapitalize(subItem.title),
19
- value: subItem.name,
20
- })),
21
- })) || [];
22
- };
23
-
24
- const filterScheme = computed((): IFilterScheme[] => {
25
- if (!groupsCategories) {
26
- return [];
27
- }
28
- return getFilterSchemeCategories().filter(item => item?.items.length > 0);
29
- });
30
-
31
- return { filterScheme };
32
- };