@snabcentr/client-ui 3.32.3 → 3.33.0
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/banner/sc-banner.module.d.ts +2 -1
- package/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.d.ts +1 -1
- package/cart/index.d.ts +1 -1
- package/cart/{sc-car-add-products-from-csv-dialog/sc-car-add-products-from-csv-dialog.component.d.ts → sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.d.ts} +3 -3
- package/catalog/category-card/sc-category-card.component.d.ts +0 -6
- package/catalog/hover-image-carousel/{hover-image-carousel.component.d.ts → sc-hover-image-carousel.component.d.ts} +16 -7
- package/catalog/index.d.ts +1 -0
- package/catalog/sc-catalog.module.d.ts +3 -2
- package/directives/abstract-price-card/abstract-sc-price-card.directive.d.ts +4 -4
- package/esm2022/banner/sc-banner.component.mjs +3 -3
- package/esm2022/banner/sc-banner.module.mjs +4 -3
- package/esm2022/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.mjs +6 -6
- package/esm2022/cart/cart-item/sc-cart-item.component.mjs +4 -4
- package/esm2022/cart/index.mjs +2 -2
- package/esm2022/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.mjs +110 -0
- package/esm2022/catalog/category-card/sc-category-card.component.mjs +4 -11
- package/esm2022/catalog/hover-image-carousel/sc-hover-image-carousel.component.mjs +76 -0
- package/esm2022/catalog/index.mjs +2 -1
- package/esm2022/catalog/price-card/sc-price-card.component.mjs +2 -2
- package/esm2022/catalog/price-card-inline/sc-price-card-inline.component.mjs +4 -4
- package/esm2022/catalog/sc-catalog.module.mjs +8 -5
- package/esm2022/directives/abstract-price-card/abstract-sc-price-card.directive.mjs +5 -6
- package/esm2022/news/news-card/sc-news-card.component.mjs +4 -8
- package/esm2022/news/sc-news.module.mjs +4 -3
- package/esm2022/order/order-item-mobile/sc-order-item-mobile.component.mjs +12 -20
- package/fesm2022/snabcentr-client-ui.mjs +67 -86
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/news/news-card/sc-news-card.component.d.ts +1 -5
- package/news/sc-news.module.d.ts +2 -1
- package/order/order-item-mobile/sc-order-item-mobile.component.d.ts +8 -14
- package/package.json +2 -2
- package/release_notes.tmp +5 -9
- package/styles/tailwind/tailwind.scss +0 -4
- package/esm2022/cart/sc-car-add-products-from-csv-dialog/sc-car-add-products-from-csv-dialog.component.mjs +0 -110
- package/esm2022/catalog/hover-image-carousel/hover-image-carousel.component.mjs +0 -76
@@ -1,5 +1,5 @@
|
|
1
1
|
import { InputSignal } from '@angular/core';
|
2
|
-
import {
|
2
|
+
import { ScNewsTile } from '@snabcentr/client-core';
|
3
3
|
import * as i0 from "@angular/core";
|
4
4
|
/**
|
5
5
|
* Компонент карточки новости.
|
@@ -17,10 +17,6 @@ export declare class ScNewsCardComponent {
|
|
17
17
|
* Признак того, что этот компонент отображается на мобильном устройстве.
|
18
18
|
*/
|
19
19
|
readonly isMobile: boolean;
|
20
|
-
/**
|
21
|
-
* Класс с вспомогательными методами для работы с изображениями.
|
22
|
-
*/
|
23
|
-
protected readonly imageHelper: ScImageHelper;
|
24
20
|
static ɵfac: i0.ɵɵFactoryDeclaration<ScNewsCardComponent, never>;
|
25
21
|
static ɵcmp: i0.ɵɵComponentDeclaration<ScNewsCardComponent, "sc-news-card", never, { "news": { "alias": "news"; "required": true; "isSignal": true; }; "href": { "alias": "href"; "required": true; "isSignal": true; }; }, {}, never, never, false, never>;
|
26
22
|
}
|
package/news/sc-news.module.d.ts
CHANGED
@@ -5,11 +5,12 @@ import * as i3 from "@angular/common";
|
|
5
5
|
import * as i4 from "@angular/router";
|
6
6
|
import * as i5 from "../share-button/sc-share-button.module";
|
7
7
|
import * as i6 from "../pipes/sc-format-date";
|
8
|
+
import * as i7 from "@snabcentr/client-core";
|
8
9
|
/**
|
9
10
|
* Модуль работы с новостями.
|
10
11
|
*/
|
11
12
|
export declare class ScNewsModule {
|
12
13
|
static ɵfac: i0.ɵɵFactoryDeclaration<ScNewsModule, never>;
|
13
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<ScNewsModule, [typeof i1.ScNewsCardComponent, typeof i2.ScNewsCardSkeletonComponent], [typeof i3.CommonModule, typeof i4.RouterModule, typeof i5.ScShareButtonModule, typeof i6.ScFormatDatePipe], [typeof i1.ScNewsCardComponent, typeof i2.ScNewsCardSkeletonComponent]>;
|
14
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<ScNewsModule, [typeof i1.ScNewsCardComponent, typeof i2.ScNewsCardSkeletonComponent], [typeof i3.CommonModule, typeof i4.RouterModule, typeof i5.ScShareButtonModule, typeof i6.ScFormatDatePipe, typeof i7.ScMediaImageTransformerPipe], [typeof i1.ScNewsCardComponent, typeof i2.ScNewsCardSkeletonComponent]>;
|
14
15
|
static ɵinj: i0.ɵɵInjectorDeclaration<ScNewsModule>;
|
15
16
|
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { EventEmitter } from '@angular/core';
|
2
|
-
import { ScCartItem,
|
1
|
+
import { EventEmitter, InputSignal, Signal } from '@angular/core';
|
2
|
+
import { ScCartItem, ScIImage } from '@snabcentr/client-core';
|
3
3
|
import { TuiPreviewDialogService } from '@taiga-ui/kit';
|
4
4
|
import { AbstractScPriceCard } from '../../directives';
|
5
5
|
import * as i0 from "@angular/core";
|
@@ -15,31 +15,25 @@ export declare class ScOrderItemMobileComponent extends AbstractScPriceCard {
|
|
15
15
|
/**
|
16
16
|
* Элемент заказа.
|
17
17
|
*/
|
18
|
-
orderItem
|
18
|
+
readonly orderItem: InputSignal<ScCartItem>;
|
19
19
|
/**
|
20
20
|
* Событие нажатия на дополнительные действия.
|
21
21
|
*/
|
22
22
|
clickActionsEvent: EventEmitter<void>;
|
23
|
+
/**
|
24
|
+
* Изображение товара в заказе.
|
25
|
+
*/
|
26
|
+
readonly cartImage: Signal<ScIImage>;
|
23
27
|
/**
|
24
28
|
* Инициирует экземпляр класса {@link ScOrderItemMobileComponent}.
|
25
29
|
*
|
26
30
|
* @param previewDialogService Сервис диалогового окна предварительного просмотра.
|
27
31
|
*/
|
28
32
|
constructor(previewDialogService: TuiPreviewDialogService);
|
29
|
-
/**
|
30
|
-
* Продукт элемента заказа.
|
31
|
-
*/
|
32
|
-
get product(): ScProduct | undefined;
|
33
33
|
/**
|
34
34
|
* Отобразить спецификацию.
|
35
35
|
*/
|
36
36
|
showSpecification(): void;
|
37
|
-
/**
|
38
|
-
* Возвращает ссылку на изображение карточки товара.
|
39
|
-
*
|
40
|
-
* @param product Позиция товара/услуги.
|
41
|
-
*/
|
42
|
-
getCardImage(product: ScProduct): string;
|
43
37
|
static ɵfac: i0.ɵɵFactoryDeclaration<ScOrderItemMobileComponent, never>;
|
44
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemMobileComponent, "sc-order-item-mobile", never, { "orderItem": { "alias": "orderItem"; "required":
|
38
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemMobileComponent, "sc-order-item-mobile", never, { "orderItem": { "alias": "orderItem"; "required": true; "isSignal": true; }; }, { "clickActionsEvent": "clickActionsEvent"; }, never, never, false, never>;
|
45
39
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@snabcentr/client-ui",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.33.0",
|
4
4
|
"author": "Snabcentr Ltd.",
|
5
5
|
"repository": "https://gitlab.snabcentr.met/web/angular/snabcentr-client-ui-lib",
|
6
6
|
"license": "Commercial",
|
@@ -15,7 +15,7 @@
|
|
15
15
|
"@maskito/core": "^3.2.0",
|
16
16
|
"@ng-web-apis/intersection-observer": "^4.11.1",
|
17
17
|
"@ng-web-apis/common": "^4.11.1",
|
18
|
-
"@snabcentr/client-core": "^2.
|
18
|
+
"@snabcentr/client-core": "^2.54.0",
|
19
19
|
"@taiga-ui/addon-charts": "^4.41.0",
|
20
20
|
"@taiga-ui/addon-commerce": "^4.41.0",
|
21
21
|
"@taiga-ui/cdk": "^4.41.0",
|
package/release_notes.tmp
CHANGED
@@ -1,14 +1,10 @@
|
|
1
|
-
## 3.
|
1
|
+
## 3.33.0 (2025-07-03)
|
2
2
|
|
3
|
-
###
|
4
|
-
|
5
|
-
- [#11858: Исправлена ошибка на форме добавления товара в корзину](web_soft/libs/angular/snabcentr-client-ui-lib@847c2a675ffd9e8b80d47dc6927ff6e1dbe2f3c5) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!292))
|
3
|
+
### added (1 change)
|
6
4
|
|
7
|
-
|
5
|
+
- [#11909: Добавлена поддержка WebP изображений в компонентах товаров, новостей, баннеров и категорий](web_soft/libs/angular/snabcentr-client-ui-lib@973979a00de3a2b1509dee5343ebc97abdc1220c) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!295))
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
### changed (1 change)
|
7
|
+
### fixed (1 change)
|
12
8
|
|
13
|
-
- [#
|
9
|
+
- [#11775: Исправлена ошибка добавления измеряемого товара в корзину.](web_soft/libs/angular/snabcentr-client-ui-lib@2e94b690a62736a481c061745ead0eebb6cacc2d) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!294))
|
14
10
|
|
@@ -1,110 +0,0 @@
|
|
1
|
-
import { NgIf } from '@angular/common';
|
2
|
-
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
3
|
-
import { toSignal } from '@angular/core/rxjs-interop';
|
4
|
-
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
5
|
-
import { WA_WINDOW } from '@ng-web-apis/common';
|
6
|
-
import { ScCartService, ScUploadedFile } from '@snabcentr/client-core';
|
7
|
-
import { tuiIsPresent } from '@taiga-ui/cdk';
|
8
|
-
import { TuiButton, TuiLink, TuiLoader } from '@taiga-ui/core';
|
9
|
-
import { TuiButtonLoading, TuiFiles } from '@taiga-ui/kit';
|
10
|
-
import { POLYMORPHEUS_CONTEXT } from '@taiga-ui/polymorpheus';
|
11
|
-
import { filter, map, Observable, share, startWith, Subject, switchMap, tap } from 'rxjs';
|
12
|
-
import * as i0 from "@angular/core";
|
13
|
-
import * as i1 from "@taiga-ui/kit";
|
14
|
-
import * as i2 from "@angular/forms";
|
15
|
-
/**
|
16
|
-
* Компонент диалога для добавления товаров в корзину из CSV файла.
|
17
|
-
*/
|
18
|
-
export class ScCarAddProductsFromCsvDialogComponent {
|
19
|
-
constructor() {
|
20
|
-
/**
|
21
|
-
* Контекст диалогового окна, в котором открыт компонент.
|
22
|
-
*/
|
23
|
-
this.context = inject(POLYMORPHEUS_CONTEXT);
|
24
|
-
/**
|
25
|
-
* Сервис для работы с корзиной.
|
26
|
-
*/
|
27
|
-
this.cartService = inject(ScCartService);
|
28
|
-
/**
|
29
|
-
* Объект окна.
|
30
|
-
*/
|
31
|
-
this.window = inject(WA_WINDOW);
|
32
|
-
/**
|
33
|
-
* {@link Subject} события скачивания цен каталога.
|
34
|
-
*/
|
35
|
-
this.onDownloadClick = new Subject();
|
36
|
-
/**
|
37
|
-
* {@link Observable} запроса на скачивание цен каталога.
|
38
|
-
*/
|
39
|
-
this.downloadRequest$ = this.onDownloadClick.pipe(switchMap(() => this.cartService.getCartCsvExample$().pipe(tap((blob) => {
|
40
|
-
this.downloadExampleFile(blob);
|
41
|
-
}), startWith(null))), share(),
|
42
|
-
// eslint-disable-next-line unicorn/no-useless-undefined
|
43
|
-
startWith(undefined));
|
44
|
-
/**
|
45
|
-
* Признак того, что запрос выполняется.
|
46
|
-
*/
|
47
|
-
this.isDownloadLoading = toSignal(this.downloadRequest$.pipe(map((value) => value === null)), {
|
48
|
-
initialValue: false,
|
49
|
-
});
|
50
|
-
/**
|
51
|
-
* {@link Subject} события отправки формы.
|
52
|
-
*/
|
53
|
-
this.onSubmit$ = new Subject();
|
54
|
-
/**
|
55
|
-
* {@link Observable} запроса на добавление товаров из CSV файла.
|
56
|
-
*/
|
57
|
-
this.submitRequest$ = this.onSubmit$.pipe(map(() => this.control.value), filter(tuiIsPresent), switchMap((file) => new Observable((observer) => {
|
58
|
-
const reader = new FileReader();
|
59
|
-
reader.addEventListener('load', () => {
|
60
|
-
observer.next(new ScUploadedFile(file.name, reader.result));
|
61
|
-
});
|
62
|
-
reader.addEventListener('error', (e) => {
|
63
|
-
observer.error(e);
|
64
|
-
});
|
65
|
-
reader.readAsDataURL(file);
|
66
|
-
return () => {
|
67
|
-
reader.abort();
|
68
|
-
};
|
69
|
-
})), switchMap((file) => this.cartService.addProductsFromCsv$(file).pipe(tap(() => {
|
70
|
-
this.context.$implicit.complete();
|
71
|
-
}), startWith(null))));
|
72
|
-
/**
|
73
|
-
* Признак того, что запрос на добавление товаров выполняется.
|
74
|
-
*/
|
75
|
-
this.isSubmitLoading = toSignal(this.submitRequest$.pipe(map((value) => value === null)), {
|
76
|
-
initialValue: false,
|
77
|
-
});
|
78
|
-
/**
|
79
|
-
* Поле для загрузки файла.
|
80
|
-
*/
|
81
|
-
this.control = new FormControl(null);
|
82
|
-
}
|
83
|
-
/**
|
84
|
-
* Метод для удаления загруженного файла.
|
85
|
-
*/
|
86
|
-
removeFile() {
|
87
|
-
this.control.setValue(null);
|
88
|
-
}
|
89
|
-
/**
|
90
|
-
* Метод для скачивания примера файла.
|
91
|
-
*
|
92
|
-
* @param blob Бинарный объект.
|
93
|
-
*/
|
94
|
-
downloadExampleFile(blob) {
|
95
|
-
const url = this.window.URL.createObjectURL(blob);
|
96
|
-
// используем ссылку и download, чтобы указать название файла.
|
97
|
-
const a = this.window.document.createElement('a');
|
98
|
-
a.href = url;
|
99
|
-
a.download = 'Пример файла добавления товаров в корзину.csv';
|
100
|
-
a.click();
|
101
|
-
this.window.URL.revokeObjectURL(url);
|
102
|
-
}
|
103
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScCarAddProductsFromCsvDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
104
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ScCarAddProductsFromCsvDialogComponent, isStandalone: true, selector: "sc-car-add-products-from-csv-dialog", ngImport: i0, template: "<div class=\"flex flex-col items-center gap-8\">\n <tui-loader\n [overlay]=\"true\"\n [showLoader]=\"isDownloadLoading()\"\n size=\"s\"\n class=\"mt-8\"\n >\n <button\n tuiLink\n [pseudo]=\"true\"\n type=\"button\"\n (click)=\"onDownloadClick.next()\"\n >\n \u041F\u0440\u0438\u043C\u0435\u0440 .csv \u0444\u0430\u0439\u043B\u0430\n </button>\n </tui-loader>\n\n <div class=\"flex w-full flex-col gap-1\">\n <label\n tuiInputFiles\n class=\"w-full\"\n >\n <input\n accept=\"text/csv\"\n tuiInputFiles\n [formControl]=\"control\"\n />\n </label>\n\n <tui-files class=\"tui-space_top-1\">\n <tui-file\n *ngIf=\"control.value as file\"\n [file]=\"file\"\n (remove)=\"removeFile()\"\n />\n </tui-files>\n </div>\n <div class=\"flex gap-2\">\n <button\n tuiButton\n [disabled]=\"!control.value\"\n [loading]=\"isSubmitLoading()\"\n iconStart=\"@tui.sc.send\"\n class=\"self-center\"\n (click)=\"onSubmit$.next()\"\n >\n \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\n </button>\n <button\n tuiButton\n (click)=\"context.$implicit.complete()\"\n type=\"button\"\n appearance=\"secondary\"\n >\n \u041E\u0442\u043C\u0435\u043D\u0430\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: i1.TuiFile, selector: "tui-file,a[tuiFile],button[tuiFile]", inputs: ["file", "state", "size", "showDelete", "showSize", "leftContent"], outputs: ["remove"] }, { kind: "component", type: i1.TuiInputFiles, selector: "label[tuiInputFiles]" }, { kind: "component", type: i1.TuiFilesComponent, selector: "tui-files", inputs: ["max", "expanded"], outputs: ["expandedChange"] }, { kind: "directive", type: i1.TuiInputFilesDirective, selector: "input[tuiInputFiles]", outputs: ["reject"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
105
|
-
}
|
106
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScCarAddProductsFromCsvDialogComponent, decorators: [{
|
107
|
-
type: Component,
|
108
|
-
args: [{ standalone: true, selector: 'sc-car-add-products-from-csv-dialog', imports: [TuiLink, TuiLoader, TuiFiles, ReactiveFormsModule, NgIf, TuiButton, TuiButtonLoading], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col items-center gap-8\">\n <tui-loader\n [overlay]=\"true\"\n [showLoader]=\"isDownloadLoading()\"\n size=\"s\"\n class=\"mt-8\"\n >\n <button\n tuiLink\n [pseudo]=\"true\"\n type=\"button\"\n (click)=\"onDownloadClick.next()\"\n >\n \u041F\u0440\u0438\u043C\u0435\u0440 .csv \u0444\u0430\u0439\u043B\u0430\n </button>\n </tui-loader>\n\n <div class=\"flex w-full flex-col gap-1\">\n <label\n tuiInputFiles\n class=\"w-full\"\n >\n <input\n accept=\"text/csv\"\n tuiInputFiles\n [formControl]=\"control\"\n />\n </label>\n\n <tui-files class=\"tui-space_top-1\">\n <tui-file\n *ngIf=\"control.value as file\"\n [file]=\"file\"\n (remove)=\"removeFile()\"\n />\n </tui-files>\n </div>\n <div class=\"flex gap-2\">\n <button\n tuiButton\n [disabled]=\"!control.value\"\n [loading]=\"isSubmitLoading()\"\n iconStart=\"@tui.sc.send\"\n class=\"self-center\"\n (click)=\"onSubmit$.next()\"\n >\n \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\n </button>\n <button\n tuiButton\n (click)=\"context.$implicit.complete()\"\n type=\"button\"\n appearance=\"secondary\"\n >\n \u041E\u0442\u043C\u0435\u043D\u0430\n </button>\n </div>\n</div>\n" }]
|
109
|
-
}] });
|
110
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhcnQvc2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cvc2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhcnQvc2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cvc2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ25GLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3QyxPQUFPLEVBQUUsU0FBUyxFQUFvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsTUFBTSxF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QUFFLElBQUksRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsbUJBQzlFLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ0lmIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGluamVjdCwgU2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgV0FfV0lORE9XIH0gZnJvbSAnQG5nLXdlYi1hcGlzL2NvbW1vbic7XG5pbXBvcnQgeyBTY0NhcnRTZXJ2aWNlLCBTY1VwbG9hZGVkRmlsZSB9IGZyb20gJ0BzbmFiY2VudHIvY2xpZW50LWNvcmUnO1xuaW1wb3J0IHsgdHVpSXNQcmVzZW50IH0gZnJvbSAnQHRhaWdhLXVpL2Nkayc7XG5pbXBvcnQgeyBUdWlCdXR0b24sIFR1aURpYWxvZ0NvbnRleHQsIFR1aUxpbmssIFR1aUxvYWRlciB9IGZyb20gJ0B0YWlnYS11aS9jb3JlJztcbmltcG9ydCB7IFR1aUJ1dHRvbkxvYWRpbmcsIFR1aUZpbGVzIH0gZnJvbSAnQHRhaWdhLXVpL2tpdCc7XG5pbXBvcnQgeyBQT0xZTU9SUEhFVVNfQ09OVEVYVCB9IGZyb20gJ0B0YWlnYS11aS9wb2x5bW9ycGhldXMnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXAsIE9ic2VydmFibGUsIHNoYXJlLCBzdGFydFdpdGgsIFN1YmplY3QsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbi8qKlxuICog0JrQvtC80L/QvtC90LXQvdGCINC00LjQsNC70L7Qs9CwINC00LvRjyDQtNC+0LHQsNCy0LvQtdC90LjRjyDRgtC+0LLQsNGA0L7QsiDQsiDQutC+0YDQt9C40L3RgyDQuNC3IENTViDRhNCw0LnQu9CwLlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAnc2MtY2FyLWFkZC1wcm9kdWN0cy1mcm9tLWNzdi1kaWFsb2cnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zYy1jYXItYWRkLXByb2R1Y3RzLWZyb20tY3N2LWRpYWxvZy5jb21wb25lbnQuaHRtbCcsXG4gICAgaW1wb3J0czogW1R1aUxpbmssIFR1aUxvYWRlciwgVHVpRmlsZXMsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIE5nSWYsIFR1aUJ1dHRvbiwgVHVpQnV0dG9uTG9hZGluZ10sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNjQ2FyQWRkUHJvZHVjdHNGcm9tQ3N2RGlhbG9nQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiDQmtC+0L3RgtC10LrRgdGCINC00LjQsNC70L7Qs9C+0LLQvtCz0L4g0L7QutC90LAsINCyINC60L7RgtC+0YDQvtC8INC+0YLQutGA0YvRgiDQutC+0LzQv9C+0L3QtdC90YIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbnRleHQ6IFR1aURpYWxvZ0NvbnRleHQgPSBpbmplY3Q8VHVpRGlhbG9nQ29udGV4dD4oUE9MWU1PUlBIRVVTX0NPTlRFWFQpO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LvRjyDRgNCw0LHQvtGC0Ysg0YEg0LrQvtGA0LfQuNC90L7QuS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGNhcnRTZXJ2aWNlOiBTY0NhcnRTZXJ2aWNlID0gaW5qZWN0KFNjQ2FydFNlcnZpY2UpO1xuXG4gICAgLyoqXG4gICAgICog0J7QsdGK0LXQutGCINC+0LrQvdCwLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgd2luZG93OiBXaW5kb3cgJiB0eXBlb2YgZ2xvYmFsVGhpcyA9IGluamVjdDxXaW5kb3cgJiB0eXBlb2YgZ2xvYmFsVGhpcz4oV0FfV0lORE9XKTtcblxuICAgIC8qKlxuICAgICAqIHtAbGluayBTdWJqZWN0fSDRgdC+0LHRi9GC0LjRjyDRgdC60LDRh9C40LLQsNC90LjRjyDRhtC10L0g0LrQsNGC0LDQu9C+0LPQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb25Eb3dubG9hZENsaWNrOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKlxuICAgICAqIHtAbGluayBPYnNlcnZhYmxlfSDQt9Cw0L/RgNC+0YHQsCDQvdCwINGB0LrQsNGH0LjQstCw0L3QuNC1INGG0LXQvSDQutCw0YLQsNC70L7Qs9CwLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBkb3dubG9hZFJlcXVlc3QkID0gdGhpcy5vbkRvd25sb2FkQ2xpY2sucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+XG4gICAgICAgICAgICB0aGlzLmNhcnRTZXJ2aWNlLmdldENhcnRDc3ZFeGFtcGxlJCgpLnBpcGUoXG4gICAgICAgICAgICAgICAgdGFwKChibG9iOiBCbG9iKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG93bmxvYWRFeGFtcGxlRmlsZShibG9iKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBzdGFydFdpdGgobnVsbClcbiAgICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgc2hhcmUoKSxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbm8tdXNlbGVzcy11bmRlZmluZWRcbiAgICAgICAgc3RhcnRXaXRoKHVuZGVmaW5lZClcbiAgICApO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0Log0YLQvtCz0L4sINGH0YLQviDQt9Cw0L/RgNC+0YEg0LLRi9C/0L7Qu9C90Y/QtdGC0YHRjy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNEb3dubG9hZExvYWRpbmc6IFNpZ25hbDxib29sZWFuPiA9IHRvU2lnbmFsKHRoaXMuZG93bmxvYWRSZXF1ZXN0JC5waXBlKG1hcCgodmFsdWUpID0+IHZhbHVlID09PSBudWxsKSksIHtcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIHtAbGluayBTdWJqZWN0fSDRgdC+0LHRi9GC0LjRjyDQvtGC0L/RgNCw0LLQutC4INGE0L7RgNC80YsuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG9uU3VibWl0JDogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiB7QGxpbmsgT2JzZXJ2YWJsZX0g0LfQsNC/0YDQvtGB0LAg0L3QsCDQtNC+0LHQsNCy0LvQtdC90LjQtSDRgtC+0LLQsNGA0L7QsiDQuNC3IENTViDRhNCw0LnQu9CwLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBzdWJtaXRSZXF1ZXN0JCA9IHRoaXMub25TdWJtaXQkLnBpcGUoXG4gICAgICAgIG1hcCgoKSA9PiB0aGlzLmNvbnRyb2wudmFsdWUpLFxuICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgc3dpdGNoTWFwKFxuICAgICAgICAgICAgKGZpbGU6IEZpbGUpID0+XG4gICAgICAgICAgICAgICAgbmV3IE9ic2VydmFibGU8U2NVcGxvYWRlZEZpbGU+KChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChuZXcgU2NVcGxvYWRlZEZpbGUoZmlsZS5uYW1lLCByZWFkZXIucmVzdWx0IGFzIHN0cmluZykpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIuYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgICAgICBzd2l0Y2hNYXAoKGZpbGUpID0+XG4gICAgICAgICAgICB0aGlzLmNhcnRTZXJ2aWNlLmFkZFByb2R1Y3RzRnJvbUNzdiQoZmlsZSkucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuJGltcGxpY2l0LmNvbXBsZXRlKCk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgc3RhcnRXaXRoKG51bGwpXG4gICAgICAgICAgICApXG4gICAgICAgIClcbiAgICApO1xuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0Log0YLQvtCz0L4sINGH0YLQviDQt9Cw0L/RgNC+0YEg0L3QsCDQtNC+0LHQsNCy0LvQtdC90LjQtSDRgtC+0LLQsNGA0L7QsiDQstGL0L/QvtC70L3Rj9C10YLRgdGPLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBpc1N1Ym1pdExvYWRpbmc6IFNpZ25hbDxib29sZWFuPiA9IHRvU2lnbmFsKHRoaXMuc3VibWl0UmVxdWVzdCQucGlwZShtYXAoKHZhbHVlKSA9PiB2YWx1ZSA9PT0gbnVsbCkpLCB7XG4gICAgICAgIGluaXRpYWxWYWx1ZTogZmFsc2UsXG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiDQn9C+0LvQtSDQtNC70Y8g0LfQsNCz0YDRg9C30LrQuCDRhNCw0LnQu9CwLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBjb250cm9sOiBGb3JtQ29udHJvbDxGaWxlIHwgbnVsbD4gPSBuZXcgRm9ybUNvbnRyb2w8RmlsZSB8IG51bGw+KG51bGwpO1xuXG4gICAgLyoqXG4gICAgICog0JzQtdGC0L7QtCDQtNC70Y8g0YPQtNCw0LvQtdC90LjRjyDQt9Cw0LPRgNGD0LbQtdC90L3QvtCz0L4g0YTQsNC50LvQsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVtb3ZlRmlsZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jb250cm9sLnNldFZhbHVlKG51bGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCc0LXRgtC+0LQg0LTQu9GPINGB0LrQsNGH0LjQstCw0L3QuNGPINC/0YDQuNC80LXRgNCwINGE0LDQudC70LAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYmxvYiDQkdC40L3QsNGA0L3Ri9C5INC+0LHRitC10LrRgi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGRvd25sb2FkRXhhbXBsZUZpbGUoYmxvYjogQmxvYik6IHZvaWQge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLndpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAvLyDQuNGB0L/QvtC70YzQt9GD0LXQvCDRgdGB0YvQu9C60YMg0LggZG93bmxvYWQsINGH0YLQvtCx0Ysg0YPQutCw0LfQsNGC0Ywg0L3QsNC30LLQsNC90LjQtSDRhNCw0LnQu9CwLlxuICAgICAgICBjb25zdCBhID0gdGhpcy53aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXG4gICAgICAgIGEuaHJlZiA9IHVybDtcbiAgICAgICAgYS5kb3dubG9hZCA9ICfQn9GA0LjQvNC10YAg0YTQsNC50LvQsCDQtNC+0LHQsNCy0LvQtdC90LjRjyDRgtC+0LLQsNGA0L7QsiDQsiDQutC+0YDQt9C40L3Rgy5jc3YnO1xuICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgIHRoaXMud2luZG93LlVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIgZ2FwLThcIj5cbiAgICA8dHVpLWxvYWRlclxuICAgICAgICBbb3ZlcmxheV09XCJ0cnVlXCJcbiAgICAgICAgW3Nob3dMb2FkZXJdPVwiaXNEb3dubG9hZExvYWRpbmcoKVwiXG4gICAgICAgIHNpemU9XCJzXCJcbiAgICAgICAgY2xhc3M9XCJtdC04XCJcbiAgICA+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR1aUxpbmtcbiAgICAgICAgICAgIFtwc2V1ZG9dPVwidHJ1ZVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkRvd25sb2FkQ2xpY2submV4dCgpXCJcbiAgICAgICAgPlxuICAgICAgICAgICAg0J/RgNC40LzQtdGAIC5jc3Yg0YTQsNC50LvQsFxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L3R1aS1sb2FkZXI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCB3LWZ1bGwgZmxleC1jb2wgZ2FwLTFcIj5cbiAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICB0dWlJbnB1dEZpbGVzXG4gICAgICAgICAgICBjbGFzcz1cInctZnVsbFwiXG4gICAgICAgID5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgIGFjY2VwdD1cInRleHQvY3N2XCJcbiAgICAgICAgICAgICAgICB0dWlJbnB1dEZpbGVzXG4gICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImNvbnRyb2xcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICA8dHVpLWZpbGVzIGNsYXNzPVwidHVpLXNwYWNlX3RvcC0xXCI+XG4gICAgICAgICAgICA8dHVpLWZpbGVcbiAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRyb2wudmFsdWUgYXMgZmlsZVwiXG4gICAgICAgICAgICAgICAgW2ZpbGVdPVwiZmlsZVwiXG4gICAgICAgICAgICAgICAgKHJlbW92ZSk9XCJyZW1vdmVGaWxlKClcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC90dWktZmlsZXM+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTJcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHVpQnV0dG9uXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWNvbnRyb2wudmFsdWVcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwiaXNTdWJtaXRMb2FkaW5nKClcIlxuICAgICAgICAgICAgaWNvblN0YXJ0PVwiQHR1aS5zYy5zZW5kXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2VsZi1jZW50ZXJcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uU3VibWl0JC5uZXh0KClcIlxuICAgICAgICA+XG4gICAgICAgICAgICDQl9Cw0LPRgNGD0LfQuNGC0YxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR1aUJ1dHRvblxuICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRleHQuJGltcGxpY2l0LmNvbXBsZXRlKClcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBhcHBlYXJhbmNlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgPlxuICAgICAgICAgICAg0J7RgtC80LXQvdCwXG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|
@@ -1,76 +0,0 @@
|
|
1
|
-
import { ChangeDetectionStrategy, Component, HostListener, Input, signal } from '@angular/core';
|
2
|
-
import { TuiHovered, TuiRepeatTimes } from '@taiga-ui/cdk';
|
3
|
-
import { TuiButton } from '@taiga-ui/core';
|
4
|
-
import * as i0 from "@angular/core";
|
5
|
-
/**
|
6
|
-
* Компонент просмотра изображений через событие наведения.
|
7
|
-
*/
|
8
|
-
export class HoverImageCarouselComponent {
|
9
|
-
constructor() {
|
10
|
-
/**
|
11
|
-
* Массив изображений.
|
12
|
-
*/
|
13
|
-
this.images = [];
|
14
|
-
/**
|
15
|
-
* Признак что необходимо отобразить элементы управления.
|
16
|
-
*/
|
17
|
-
this.isShowActions = true;
|
18
|
-
/**
|
19
|
-
* {@link WritableSignal} для отслеживания текущего индекса изображения.
|
20
|
-
*/
|
21
|
-
this.currentIndex = signal(0);
|
22
|
-
}
|
23
|
-
/**
|
24
|
-
* Обработчик события `mousemove.silent`.
|
25
|
-
*
|
26
|
-
* @param offsetX Отступ курсора мыши по оси X от края {@link HTMLElement}.
|
27
|
-
* @param target Объект {@link HTMLElement} в котором лежат изображения
|
28
|
-
*/
|
29
|
-
onHover(offsetX, target) {
|
30
|
-
if (this.images.length <= 1 || offsetX < 0) {
|
31
|
-
return;
|
32
|
-
}
|
33
|
-
// new Event().preventDefault
|
34
|
-
const elementWidth = target.offsetWidth;
|
35
|
-
const hoverPercentage = offsetX / elementWidth;
|
36
|
-
const newIndex = Math.floor(hoverPercentage * this.images.length);
|
37
|
-
this.currentIndex.set(newIndex);
|
38
|
-
}
|
39
|
-
/**
|
40
|
-
* Обработчик события `mouseleave.silent`.
|
41
|
-
*/
|
42
|
-
onLeave() {
|
43
|
-
if (this.images.length <= 1) {
|
44
|
-
return;
|
45
|
-
}
|
46
|
-
this.currentIndex.set(0);
|
47
|
-
}
|
48
|
-
/**
|
49
|
-
* Обработчик события наведения указателя мыши на точку.
|
50
|
-
*
|
51
|
-
* @param hovered Признак что указатель мыши наведен на точку.
|
52
|
-
* @param index Индекс изображения, который соответствует точке.
|
53
|
-
*/
|
54
|
-
onDotHovered(hovered, index) {
|
55
|
-
if (hovered) {
|
56
|
-
this.currentIndex.set(index);
|
57
|
-
}
|
58
|
-
}
|
59
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HoverImageCarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
60
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: HoverImageCarouselComponent, isStandalone: true, selector: "sc-hover-image-carousel", inputs: { images: "images", isShowActions: "isShowActions" }, host: { listeners: { "mousemove.silent": "onHover($event.offsetX,$event.target)", "mouseleave.silent": "onLeave()" } }, ngImport: i0, template: "<div\n class=\"overflow-hidden rounded-xl\"\n [class.mb-2]=\"images.length <= 1 && isShowActions\"\n [style.aspect-ratio]=\"'20/19'\"\n>\n <img\n [src]=\"images[currentIndex()]\"\n class=\"size-full rounded-xl object-contain\"\n />\n</div>\n\n@if (images.length > 1 && isShowActions) {\n <div\n (mousemove.silent)=\"$event.stopPropagation()\"\n class=\"flex justify-center\"\n >\n <button\n *tuiRepeatTimes=\"let indexItem of images.length\"\n #element\n tuiButton\n type=\"button\"\n class=\"button button_small\"\n [appearance]=\"indexItem === currentIndex() ? 'primary' : 'secondary'\"\n (tuiHoveredChange)=\"onDotHovered($event, indexItem)\"\n ></button>\n </div>\n}\n", styles: [".button{flex-shrink:0}.button:first-child{margin-inline-start:0}.button:last-child{margin-inline-end:0}.button_small{inline-size:.5rem;block-size:.5rem;font-size:0;padding:0;margin:0}.button_small:not(:first-child){margin-left:.5rem}\n"], dependencies: [{ kind: "directive", type: TuiRepeatTimes, selector: "[tuiRepeatTimes][tuiRepeatTimesOf]", inputs: ["tuiRepeatTimesOf"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: TuiHovered, selector: "[tuiHoveredChange]", outputs: ["tuiHoveredChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
61
|
-
}
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: HoverImageCarouselComponent, decorators: [{
|
63
|
-
type: Component,
|
64
|
-
args: [{ standalone: true, selector: 'sc-hover-image-carousel', imports: [TuiRepeatTimes, TuiButton, TuiHovered], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"overflow-hidden rounded-xl\"\n [class.mb-2]=\"images.length <= 1 && isShowActions\"\n [style.aspect-ratio]=\"'20/19'\"\n>\n <img\n [src]=\"images[currentIndex()]\"\n class=\"size-full rounded-xl object-contain\"\n />\n</div>\n\n@if (images.length > 1 && isShowActions) {\n <div\n (mousemove.silent)=\"$event.stopPropagation()\"\n class=\"flex justify-center\"\n >\n <button\n *tuiRepeatTimes=\"let indexItem of images.length\"\n #element\n tuiButton\n type=\"button\"\n class=\"button button_small\"\n [appearance]=\"indexItem === currentIndex() ? 'primary' : 'secondary'\"\n (tuiHoveredChange)=\"onDotHovered($event, indexItem)\"\n ></button>\n </div>\n}\n", styles: [".button{flex-shrink:0}.button:first-child{margin-inline-start:0}.button:last-child{margin-inline-end:0}.button_small{inline-size:.5rem;block-size:.5rem;font-size:0;padding:0;margin:0}.button_small:not(:first-child){margin-left:.5rem}\n"] }]
|
65
|
-
}], propDecorators: { images: [{
|
66
|
-
type: Input
|
67
|
-
}], isShowActions: [{
|
68
|
-
type: Input
|
69
|
-
}], onHover: [{
|
70
|
-
type: HostListener,
|
71
|
-
args: ['mousemove.silent', ['$event.offsetX', '$event.target']]
|
72
|
-
}], onLeave: [{
|
73
|
-
type: HostListener,
|
74
|
-
args: ['mouseleave.silent']
|
75
|
-
}] } });
|
76
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG92ZXItaW1hZ2UtY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhdGFsb2cvaG92ZXItaW1hZ2UtY2Fyb3VzZWwvaG92ZXItaW1hZ2UtY2Fyb3VzZWwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhdGFsb2cvaG92ZXItaW1hZ2UtY2Fyb3VzZWwvaG92ZXItaW1hZ2UtY2Fyb3VzZWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBa0IsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQUUzQzs7R0FFRztBQVNILE1BQU0sT0FBTywyQkFBMkI7SUFSeEM7UUFTSTs7V0FFRztRQUVJLFdBQU0sR0FBYSxFQUFFLENBQUM7UUFFN0I7O1dBRUc7UUFFSSxrQkFBYSxHQUFZLElBQUksQ0FBQztRQUVyQzs7V0FFRztRQUNJLGlCQUFZLEdBQTJCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztLQTJDM0Q7SUF6Q0c7Ozs7O09BS0c7SUFFSyxPQUFPLENBQUMsT0FBZSxFQUFFLE1BQW1CO1FBQ2hELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6QyxPQUFPO1FBQ1gsQ0FBQztRQUNELDZCQUE2QjtRQUM3QixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBQ3hDLE1BQU0sZUFBZSxHQUFHLE9BQU8sR0FBRyxZQUFZLENBQUM7UUFDL0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFFSyxPQUFPO1FBQ1gsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxQixPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNPLFlBQVksQ0FBQyxPQUFnQixFQUFFLEtBQWE7UUFDbEQsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNWLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUM7SUFDTCxDQUFDOytHQTFEUSwyQkFBMkI7bUdBQTNCLDJCQUEyQix5UUNmeEMsaXpCQTJCQSxxU0RqQmMsY0FBYyw2R0FBRSxTQUFTLG9JQUFFLFVBQVU7OzRGQUt0QywyQkFBMkI7a0JBUnZDLFNBQVM7aUNBQ00sSUFBSSxZQUNOLHlCQUF5QixXQUMxQixDQUFDLGNBQWMsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLG1CQUcvQix1QkFBdUIsQ0FBQyxNQUFNOzhCQU94QyxNQUFNO3NCQURaLEtBQUs7Z0JBT0MsYUFBYTtzQkFEbkIsS0FBSztnQkFlRSxPQUFPO3NCQURkLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxlQUFlLENBQUM7Z0JBZ0I3RCxPQUFPO3NCQURkLFlBQVk7dUJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSG9zdExpc3RlbmVyLCBJbnB1dCwgc2lnbmFsLCBXcml0YWJsZVNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVHVpSG92ZXJlZCwgVHVpUmVwZWF0VGltZXMgfSBmcm9tICdAdGFpZ2EtdWkvY2RrJztcbmltcG9ydCB7IFR1aUJ1dHRvbiB9IGZyb20gJ0B0YWlnYS11aS9jb3JlJztcblxuLyoqXG4gKiDQmtC+0LzQv9C+0L3QtdC90YIg0L/RgNC+0YHQvNC+0YLRgNCwINC40LfQvtCx0YDQsNC20LXQvdC40Lkg0YfQtdGA0LXQtyDRgdC+0LHRi9GC0LjQtSDQvdCw0LLQtdC00LXQvdC40Y8uXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdzYy1ob3Zlci1pbWFnZS1jYXJvdXNlbCcsXG4gICAgaW1wb3J0czogW1R1aVJlcGVhdFRpbWVzLCBUdWlCdXR0b24sIFR1aUhvdmVyZWRdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9ob3Zlci1pbWFnZS1jYXJvdXNlbC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmw6ICcuL2hvdmVyLWltYWdlLWNhcm91c2VsLmNvbXBvbmVudC5zY3NzJyxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgSG92ZXJJbWFnZUNhcm91c2VsQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiDQnNCw0YHRgdC40LIg0LjQt9C+0LHRgNCw0LbQtdC90LjQuS5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpbWFnZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiDRh9GC0L4g0L3QtdC+0LHRhdC+0LTQuNC80L4g0L7RgtC+0LHRgNCw0LfQuNGC0Ywg0Y3Qu9C10LzQtdC90YLRiyDRg9C/0YDQsNCy0LvQtdC90LjRjy5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpc1Nob3dBY3Rpb25zOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKlxuICAgICAqIHtAbGluayBXcml0YWJsZVNpZ25hbH0g0LTQu9GPINC+0YLRgdC70LXQttC40LLQsNC90LjRjyDRgtC10LrRg9GJ0LXQs9C+INC40L3QtNC10LrRgdCwINC40LfQvtCx0YDQsNC20LXQvdC40Y8uXG4gICAgICovXG4gICAgcHVibGljIGN1cnJlbnRJbmRleDogV3JpdGFibGVTaWduYWw8bnVtYmVyPiA9IHNpZ25hbCgwKTtcblxuICAgIC8qKlxuICAgICAqINCe0LHRgNCw0LHQvtGC0YfQuNC6INGB0L7QsdGL0YLQuNGPIGBtb3VzZW1vdmUuc2lsZW50YC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvZmZzZXRYINCe0YLRgdGC0YPQvyDQutGD0YDRgdC+0YDQsCDQvNGL0YjQuCDQv9C+INC+0YHQuCBYINC+0YIg0LrRgNCw0Y8ge0BsaW5rIEhUTUxFbGVtZW50fS5cbiAgICAgKiBAcGFyYW0gdGFyZ2V0INCe0LHRitC10LrRgiB7QGxpbmsgSFRNTEVsZW1lbnR9INCyINC60L7RgtC+0YDQvtC8INC70LXQttCw0YIg0LjQt9C+0LHRgNCw0LbQtdC90LjRj1xuICAgICAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbW92ZS5zaWxlbnQnLCBbJyRldmVudC5vZmZzZXRYJywgJyRldmVudC50YXJnZXQnXSlcbiAgICBwcml2YXRlIG9uSG92ZXIob2Zmc2V0WDogbnVtYmVyLCB0YXJnZXQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmltYWdlcy5sZW5ndGggPD0gMSB8fCBvZmZzZXRYIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIG5ldyBFdmVudCgpLnByZXZlbnREZWZhdWx0XG4gICAgICAgIGNvbnN0IGVsZW1lbnRXaWR0aCA9IHRhcmdldC5vZmZzZXRXaWR0aDtcbiAgICAgICAgY29uc3QgaG92ZXJQZXJjZW50YWdlID0gb2Zmc2V0WCAvIGVsZW1lbnRXaWR0aDtcbiAgICAgICAgY29uc3QgbmV3SW5kZXggPSBNYXRoLmZsb29yKGhvdmVyUGVyY2VudGFnZSAqIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG4gICAgICAgIHRoaXMuY3VycmVudEluZGV4LnNldChuZXdJbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7QsdGA0LDQsdC+0YLRh9C40Log0YHQvtCx0YvRgtC40Y8gYG1vdXNlbGVhdmUuc2lsZW50YC5cbiAgICAgKi9cbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlLnNpbGVudCcpXG4gICAgcHJpdmF0ZSBvbkxlYXZlKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pbWFnZXMubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVudEluZGV4LnNldCgwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0YDQsNCx0L7RgtGH0LjQuiDRgdC+0LHRi9GC0LjRjyDQvdCw0LLQtdC00LXQvdC40Y8g0YPQutCw0LfQsNGC0LXQu9GPINC80YvRiNC4INC90LAg0YLQvtGH0LrRgy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBob3ZlcmVkINCf0YDQuNC30L3QsNC6INGH0YLQviDRg9C60LDQt9Cw0YLQtdC70Ywg0LzRi9GI0Lgg0L3QsNCy0LXQtNC10L0g0L3QsCDRgtC+0YfQutGDLlxuICAgICAqIEBwYXJhbSBpbmRleCDQmNC90LTQtdC60YEg0LjQt9C+0LHRgNCw0LbQtdC90LjRjywg0LrQvtGC0L7RgNGL0Lkg0YHQvtC+0YLQstC10YLRgdGC0LLRg9C10YIg0YLQvtGH0LrQtS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgb25Eb3RIb3ZlcmVkKGhvdmVyZWQ6IGJvb2xlYW4sIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKGhvdmVyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEluZGV4LnNldChpbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCI8ZGl2XG4gICAgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gcm91bmRlZC14bFwiXG4gICAgW2NsYXNzLm1iLTJdPVwiaW1hZ2VzLmxlbmd0aCA8PSAxICYmIGlzU2hvd0FjdGlvbnNcIlxuICAgIFtzdHlsZS5hc3BlY3QtcmF0aW9dPVwiJzIwLzE5J1wiXG4+XG4gICAgPGltZ1xuICAgICAgICBbc3JjXT1cImltYWdlc1tjdXJyZW50SW5kZXgoKV1cIlxuICAgICAgICBjbGFzcz1cInNpemUtZnVsbCByb3VuZGVkLXhsIG9iamVjdC1jb250YWluXCJcbiAgICAvPlxuPC9kaXY+XG5cbkBpZiAoaW1hZ2VzLmxlbmd0aCA+IDEgJiYgaXNTaG93QWN0aW9ucykge1xuICAgIDxkaXZcbiAgICAgICAgKG1vdXNlbW92ZS5zaWxlbnQpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGp1c3RpZnktY2VudGVyXCJcbiAgICA+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICp0dWlSZXBlYXRUaW1lcz1cImxldCBpbmRleEl0ZW0gb2YgaW1hZ2VzLmxlbmd0aFwiXG4gICAgICAgICAgICAjZWxlbWVudFxuICAgICAgICAgICAgdHVpQnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYnV0dG9uIGJ1dHRvbl9zbWFsbFwiXG4gICAgICAgICAgICBbYXBwZWFyYW5jZV09XCJpbmRleEl0ZW0gPT09IGN1cnJlbnRJbmRleCgpID8gJ3ByaW1hcnknIDogJ3NlY29uZGFyeSdcIlxuICAgICAgICAgICAgKHR1aUhvdmVyZWRDaGFuZ2UpPVwib25Eb3RIb3ZlcmVkKCRldmVudCwgaW5kZXhJdGVtKVwiXG4gICAgICAgID48L2J1dHRvbj5cbiAgICA8L2Rpdj5cbn1cbiJdfQ==
|