itube-specs 0.0.1045 → 0.0.1047
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Инфо-блок модели: портрет 3:4, псевдонимы, соцсети, шапка с действиями, рождение, описание, сводка-чипсы; «About» и группы параметров — по «Show more
|
|
1
|
+
<!-- Инфо-блок модели: портрет 3:4, псевдонимы, соцсети, шапка с действиями, рождение, описание, сводка-чипсы; «About» и группы параметров — по «Show more», на десктопе свёрнутые доливают колонку до низа портрета -->
|
|
2
2
|
<template>
|
|
3
3
|
<section class="info-model">
|
|
4
4
|
<div class="info-model__aside">
|
|
@@ -122,7 +122,8 @@
|
|
|
122
122
|
|
|
123
123
|
<div
|
|
124
124
|
v-if="hasMore"
|
|
125
|
-
|
|
125
|
+
ref="detailsRef"
|
|
126
|
+
:class="{'--collapsed': !isExpanded}"
|
|
126
127
|
class="info-model__details"
|
|
127
128
|
>
|
|
128
129
|
<div
|
|
@@ -146,7 +147,9 @@
|
|
|
146
147
|
|
|
147
148
|
<button
|
|
148
149
|
v-if="hasMore"
|
|
150
|
+
ref="moreRef"
|
|
149
151
|
:aria-expanded="isExpanded"
|
|
152
|
+
:class="{'--fit': !hasCut && !isExpanded}"
|
|
150
153
|
class="info-model__more"
|
|
151
154
|
type="button"
|
|
152
155
|
@click="isExpanded = !isExpanded"
|
|
@@ -245,6 +248,79 @@ const isExpanded = ref(false);
|
|
|
245
248
|
|
|
246
249
|
const hasMore = computed(() => groupedParameters.value.length > 0 || Boolean(props.card.fullDescription));
|
|
247
250
|
|
|
251
|
+
/** Единицы, которые прячутся только целиком: заголовки, абзацы, плашки. Порядок — документный. */
|
|
252
|
+
const FIT_SELECTOR = 'h3, .info-model__about-text, .info-grid__plain-text, .info-grid__item';
|
|
253
|
+
|
|
254
|
+
/** Если всё целиком выпирает ниже портрета не больше чем на столько — показываем всё без «Show more». */
|
|
255
|
+
const FIT_TOLERANCE = 64;
|
|
256
|
+
|
|
257
|
+
const detailsRef = ref<HTMLElement>();
|
|
258
|
+
const moreRef = ref<HTMLElement>();
|
|
259
|
+
const hasCut = ref(true);
|
|
260
|
+
|
|
261
|
+
/** Строка грида под кнопкой (с её отступами): без «Show more» она достаётся деталям. */
|
|
262
|
+
function getMoreRowHeight(box: HTMLElement) {
|
|
263
|
+
const more = moreRef.value;
|
|
264
|
+
if (!more || !more.offsetParent) return 0;
|
|
265
|
+
|
|
266
|
+
return more.getBoundingClientRect().bottom + Number.parseFloat(getComputedStyle(more).marginBottom)
|
|
267
|
+
- box.getBoundingClientRect().bottom;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* На десктопе высоту свёрнутых деталей задаёт грид — остаток колонки до низа портрета.
|
|
272
|
+
* Всё, что не влезло целиком, прячем; заголовок без единой видимой строки под ним — тоже.
|
|
273
|
+
* Небольшой хвост в пределах допуска не прячем, а вытягиваем блок под него через `min-height`.
|
|
274
|
+
*/
|
|
275
|
+
function measureDetails() {
|
|
276
|
+
const box = detailsRef.value;
|
|
277
|
+
if (!box) return;
|
|
278
|
+
|
|
279
|
+
const units = Array.from(box.querySelectorAll<HTMLElement>(FIT_SELECTOR));
|
|
280
|
+
box.style.minHeight = '';
|
|
281
|
+
|
|
282
|
+
if (isExpanded.value || !isChipsOverflowWidth()) {
|
|
283
|
+
units.forEach(el => el.removeAttribute('data-cut'));
|
|
284
|
+
hasCut.value = true;
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const { top } = box.getBoundingClientRect();
|
|
289
|
+
const limit = box.clientHeight + 0.5;
|
|
290
|
+
const bottoms = units.map(el => el.getBoundingClientRect().bottom - top);
|
|
291
|
+
const contentHeight = Math.max(0, ...bottoms);
|
|
292
|
+
|
|
293
|
+
const fullLimit = limit + getMoreRowHeight(box);
|
|
294
|
+
|
|
295
|
+
if (contentHeight <= fullLimit + FIT_TOLERANCE) {
|
|
296
|
+
if (contentHeight > fullLimit) box.style.minHeight = `${Math.ceil(contentHeight)}px`;
|
|
297
|
+
units.forEach(el => el.removeAttribute('data-cut'));
|
|
298
|
+
hasCut.value = false;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const visible: boolean[] = [];
|
|
303
|
+
let isOver = false;
|
|
304
|
+
|
|
305
|
+
bottoms.forEach((bottom, index) => {
|
|
306
|
+
isOver ||= bottom > limit;
|
|
307
|
+
visible[index] = !isOver;
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
for (let index = units.length - 1; index >= 0; index--) {
|
|
311
|
+
if (units[index].tagName === 'H3' && !(visible[index + 1] && units[index + 1].tagName !== 'H3')) {
|
|
312
|
+
visible[index] = false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
units.forEach((el, index) => el.toggleAttribute('data-cut', !visible[index]));
|
|
317
|
+
hasCut.value = visible.includes(false);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
useChipsOverflow(detailsRef, measureDetails);
|
|
321
|
+
|
|
322
|
+
watch([isExpanded, () => props.card], () => nextTick(measureDetails));
|
|
323
|
+
|
|
248
324
|
const isShareOpen = ref(false);
|
|
249
325
|
|
|
250
326
|
const { isAuthorized } = useUser(AuthorizationApiService);
|
|
@@ -308,15 +384,14 @@ const shareModelCard = computed<IModelCard>(() => ({
|
|
|
308
384
|
|
|
309
385
|
@include from-br(sm) {
|
|
310
386
|
grid-template-columns: 240px minmax(0, 1fr);
|
|
311
|
-
grid-template-rows: auto auto auto auto
|
|
387
|
+
grid-template-rows: auto auto auto auto 1fr auto;
|
|
312
388
|
grid-template-areas:
|
|
313
389
|
'aside header'
|
|
314
390
|
'aside born'
|
|
315
391
|
'aside description'
|
|
316
392
|
'aside summary'
|
|
317
393
|
'aside details'
|
|
318
|
-
'aside more'
|
|
319
|
-
'aside .';
|
|
394
|
+
'aside more';
|
|
320
395
|
}
|
|
321
396
|
}
|
|
322
397
|
|
|
@@ -543,14 +618,16 @@ const shareModelCard = computed<IModelCard>(() => ({
|
|
|
543
618
|
@include to-br(sm) {
|
|
544
619
|
display: none;
|
|
545
620
|
}
|
|
546
|
-
}
|
|
547
621
|
|
|
548
|
-
|
|
549
|
-
|
|
622
|
+
@include from-br(sm) {
|
|
623
|
+
align-content: start;
|
|
624
|
+
overflow: clip;
|
|
625
|
+
contain: size;
|
|
626
|
+
}
|
|
550
627
|
}
|
|
551
628
|
|
|
552
|
-
.info-model__details
|
|
553
|
-
|
|
629
|
+
.info-model__details [data-cut] {
|
|
630
|
+
visibility: hidden;
|
|
554
631
|
}
|
|
555
632
|
|
|
556
633
|
.info-model__about-title {
|
|
@@ -592,6 +669,12 @@ const shareModelCard = computed<IModelCard>(() => ({
|
|
|
592
669
|
}
|
|
593
670
|
}
|
|
594
671
|
|
|
672
|
+
.info-model__more.--fit {
|
|
673
|
+
@include from-br(sm) {
|
|
674
|
+
display: none;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
595
678
|
.info-model__more-icon {
|
|
596
679
|
transition: var(--transition) transform;
|
|
597
680
|
}
|
|
@@ -285,13 +285,14 @@ async function changeCountry(item: ISelectItem) {
|
|
|
285
285
|
@include font-sm;
|
|
286
286
|
|
|
287
287
|
display: grid;
|
|
288
|
-
grid-template-columns: 1fr auto;
|
|
288
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
289
289
|
margin-bottom: 4px;
|
|
290
290
|
column-gap: 12px;
|
|
291
291
|
align-items: center;
|
|
292
292
|
color: $language-item-text;
|
|
293
293
|
padding: 10px 8px;
|
|
294
294
|
text-align: start;
|
|
295
|
+
overflow-wrap: anywhere;
|
|
295
296
|
border-radius: $radius-lg;
|
|
296
297
|
|
|
297
298
|
@include hover(background-color) {
|
|
@@ -300,11 +301,11 @@ async function changeCountry(item: ISelectItem) {
|
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
.layout-language__details-item:has(img) {
|
|
303
|
-
grid-template-columns: 20px 1fr auto;
|
|
304
|
+
grid-template-columns: 20px minmax(0, 1fr) auto;
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
.layout-language__details-item:has(.layout-language__code) {
|
|
307
|
-
grid-template-columns: 32px 1fr auto;
|
|
308
|
+
grid-template-columns: 32px minmax(0, 1fr) auto;
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
.layout-language__check {
|
|
@@ -356,6 +357,7 @@ async function changeCountry(item: ISelectItem) {
|
|
|
356
357
|
|
|
357
358
|
.layout-language__buttons {
|
|
358
359
|
display: grid;
|
|
360
|
+
grid-template-columns: minmax(0, 1fr);
|
|
359
361
|
max-height: 192px;
|
|
360
362
|
overflow-y: auto;
|
|
361
363
|
scrollbar-width: none;
|
package/package.json
CHANGED
package/pages/user/profile.vue
CHANGED
|
@@ -182,6 +182,7 @@ watchEffect(() => {
|
|
|
182
182
|
|
|
183
183
|
.profile__header-wrapper {
|
|
184
184
|
display: grid;
|
|
185
|
+
grid-template-columns: minmax(0, 1fr);
|
|
185
186
|
row-gap: 1px;
|
|
186
187
|
}
|
|
187
188
|
|
|
@@ -191,7 +192,7 @@ watchEffect(() => {
|
|
|
191
192
|
display: grid;
|
|
192
193
|
column-gap: 8px;
|
|
193
194
|
align-items: center;
|
|
194
|
-
grid-template-columns: auto 1fr;
|
|
195
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
195
196
|
color: $profile-member-text;
|
|
196
197
|
margin-top: 4px;
|
|
197
198
|
}
|
|
@@ -245,7 +246,7 @@ watchEffect(() => {
|
|
|
245
246
|
|
|
246
247
|
.profile__header {
|
|
247
248
|
display: grid;
|
|
248
|
-
grid-template-columns: auto 1fr;
|
|
249
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
249
250
|
align-items: center;
|
|
250
251
|
column-gap: 20px;
|
|
251
252
|
}
|
|
@@ -253,6 +254,10 @@ watchEffect(() => {
|
|
|
253
254
|
.profile__edit {
|
|
254
255
|
@include button-variant(profile-edit);
|
|
255
256
|
|
|
257
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
258
|
+
max-width: 100%;
|
|
256
259
|
margin-top: 12px;
|
|
260
|
+
white-space: normal;
|
|
261
|
+
text-align: start;
|
|
257
262
|
}
|
|
258
263
|
</style>
|