@kovalenko/material-carousel 0.0.0-stage → 22.0.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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Gabriel Sanches
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,120 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Material Carousel
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/menelai/material2-carousel)
|
|
4
|
+
|
|
5
|
+
## EXTRA NOTICE
|
|
6
|
+
This version has been upgraded to Angular 22 and rewritten with standalone components
|
|
7
|
+
and signal-based inputs/outputs.
|
|
8
|
+
|
|
9
|
+
## About
|
|
10
|
+
This package is a carousel component for Angular using Material Design.
|
|
11
|
+
|
|
12
|
+
### Installing
|
|
13
|
+
`npm install --save @kovalenko/material-carousel`
|
|
14
|
+
|
|
15
|
+
### Importing
|
|
16
|
+
The components are standalone, so import them directly into your component (or lazy
|
|
17
|
+
route/feature) instead of an `NgModule`:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Component } from '@angular/core';
|
|
21
|
+
import {
|
|
22
|
+
MatCarouselComponent,
|
|
23
|
+
MatCarouselSlideComponent,
|
|
24
|
+
} from '@kovalenko/material-carousel';
|
|
25
|
+
|
|
26
|
+
@Component({
|
|
27
|
+
selector: 'app-example',
|
|
28
|
+
standalone: true,
|
|
29
|
+
imports: [MatCarouselComponent, MatCarouselSlideComponent],
|
|
30
|
+
templateUrl: './example.component.html',
|
|
31
|
+
})
|
|
32
|
+
export class ExampleComponent {}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
### `MatCarouselComponent`
|
|
37
|
+
```typescript
|
|
38
|
+
import { MatCarouselComponent } from '@kovalenko/material-carousel';
|
|
39
|
+
```
|
|
40
|
+
```html
|
|
41
|
+
<mat-carousel>
|
|
42
|
+
...
|
|
43
|
+
</mat-carousel>
|
|
44
|
+
```
|
|
45
|
+
#### Attributes
|
|
46
|
+
| Input | Type | Description | Default value |
|
|
47
|
+
| --------------------- | ------------------ | -------------------------------------------------------------------------- | :---------------: |
|
|
48
|
+
| `timings` | `string` | Timings for slide animation. | `'250ms ease-in'` |
|
|
49
|
+
| `autoplay` | `boolean` | Enable automatic sliding. | `true` |
|
|
50
|
+
| `interval` | `number` | Autoplay's interval in milliseconds. | `5000` |
|
|
51
|
+
| `loop` | `boolean` | Enable loop through arrows. | `true` |
|
|
52
|
+
| `hideArrows` | `boolean` | Hide navigation arrows. | `true` |
|
|
53
|
+
| `hideIndicators` | `boolean` | Hide navigation indicators. | `true` |
|
|
54
|
+
| `color` | `ThemePalette` | Color palette from Material. | `'accent'` |
|
|
55
|
+
| `maxWidth` | `string` | Maximum width. | `'auto'` |
|
|
56
|
+
| `maintainAspectRatio` | `boolean` | If true, use `proportion` to determine height, else `slideHeight` is used. | `true` |
|
|
57
|
+
| `proportion` | `number` | Height proportion compared to width. | `25` |
|
|
58
|
+
| `slideHeight` | `string` | Explicit slide height. Used when maintainAspectRatio is false. | `'100%'` |
|
|
59
|
+
| `slides` | `number` | Maximum amount of displayed slides. | |
|
|
60
|
+
| `useKeyboard` | `boolean` | Enable keyboard navigation. | `false` |
|
|
61
|
+
| `useMouseWheel` | `boolean` | Enable navigation through mouse wheeling. | `false` |
|
|
62
|
+
| `orientation` | `Orientation` | Orientation of the sliding panel. | `'ltr'` |
|
|
63
|
+
| `svgIconOverrides` | `SvgIconOverrides` | Override default carousel icons with registered SVG icons. | |
|
|
64
|
+
| `pauseOnHover` | `boolean` | Override default pause on hover. | `true` |
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
| Output | Type | Description |
|
|
68
|
+
| --------------------- | ------------------ | -------------------------------------------------------------------------- |
|
|
69
|
+
| `animationStart` | `number` | It emits the currentIndex when animation starts |
|
|
70
|
+
| `change` | `number` | It emtis the currentIndex when animation ends |
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
#### Size Considerations and Recommendations
|
|
74
|
+
By default, `maintainAspectRatio` is true, which means height is controlled through `proportion`.
|
|
75
|
+
|
|
76
|
+
If you want to have a carousel with constant height (regardless of width), you must set `maintainAspectRatio` to false.
|
|
77
|
+
|
|
78
|
+
By default, `slideHeight` is set to `100%`, which will not work if the parent element height isn't defined (i.e. relative heights do not work if the parent height is `auto`). In that case you could pass a valid css string for `slideHeight`. You can use any valid css height string like `100px` or `25vh`.
|
|
79
|
+
|
|
80
|
+
Play around with the [demo](https://gabrielbusarello.github.io/material2-carousel/) to see how you can use this carousel with or without explicit parent height.
|
|
81
|
+
|
|
82
|
+
**With parent elements that have height:auto**
|
|
83
|
+
* use `proportion` if you want a carousel that resizes responsively (this is the default configuration).
|
|
84
|
+
* use `maintainAspectRatio="false"` and a non-percentage `slideHeight` if you want a fixed height carousel.
|
|
85
|
+
* **DO NOT** use relative (%) values for `slideHeight`; the carousel will not render.
|
|
86
|
+
|
|
87
|
+
**With parent elements that have a set height**
|
|
88
|
+
* use `maintainAspectRatio="false"` if you want a fixed height carousel that fills the parent element (`slideHeight` is `100%` by default).
|
|
89
|
+
* **DO NOT** use `maintainAspectRatio="false"` **and** `slideHeight` (unless `slideHeight="100%"`); the carousel will not render correctly because the buttons and indicators will be positioned with respect to the parent.
|
|
90
|
+
* **DO NOT** use `proportion`; this will lead to gaps or unwanted overflow.
|
|
91
|
+
|
|
92
|
+
### `MatCarouselSlideComponent`
|
|
93
|
+
```typescript
|
|
94
|
+
import { MatCarouselSlideComponent } from '@kovalenko/material-carousel';
|
|
95
|
+
```
|
|
96
|
+
```html
|
|
97
|
+
<mat-carousel>
|
|
98
|
+
<mat-carousel-slide>
|
|
99
|
+
...
|
|
100
|
+
</mat-carousel-slide>
|
|
101
|
+
</mat-carousel>
|
|
102
|
+
```
|
|
103
|
+
#### Attributes
|
|
104
|
+
| Input | Type | Description | Default value |
|
|
105
|
+
| -------------- | --------- | ----------------------------- | :-----------: |
|
|
106
|
+
| `image` | `string` | Image displayed in the slide. | |
|
|
107
|
+
| `overlayColor` | `string` | Color of the slide's overlay. | `'#00000040'` |
|
|
108
|
+
| `hideOverlay` | `boolean` | Toggle overlay on/off. | `false` |
|
|
109
|
+
| `disabled` | `boolean` | Skip slide when navigating. | `false` |
|
|
110
|
+
|
|
111
|
+
## Contributing
|
|
112
|
+
### How to help
|
|
113
|
+
- For bugs and opinions, please [open an issue](https://github.com/menelai/material2-carousel/issues/new)
|
|
114
|
+
- For pushing changes, please [open a pull request](https://github.com/menelai/material2-carousel/compare)
|
|
115
|
+
|
|
116
|
+
### How to develop and test
|
|
117
|
+
#### Testing
|
|
118
|
+
`ng test carousel --watch false`
|
|
119
|
+
#### Running the demo application
|
|
120
|
+
`ng serve demo --source-map`
|
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
import { ListKeyManager } from "@angular/cdk/a11y";
|
|
2
|
+
import { NgTemplateOutlet, isPlatformBrowser } from "@angular/common";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import { Component, DestroyRef, HostListener, Injector, PLATFORM_ID, Renderer2, TemplateRef, computed, contentChildren, effect, inject, input, model, output, signal, viewChild } from "@angular/core";
|
|
5
|
+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
6
|
+
import { MatIconButton, MatMiniFabButton } from "@angular/material/button";
|
|
7
|
+
import { MatIcon } from "@angular/material/icon";
|
|
8
|
+
import { Subject, interval } from "rxjs";
|
|
9
|
+
import { filter, takeUntil } from "rxjs/operators";
|
|
10
|
+
import { DomSanitizer } from "@angular/platform-browser";
|
|
11
|
+
var MatCarouselSlideComponent = class MatCarouselSlideComponent {
|
|
12
|
+
image = input(...ngDevMode ? [void 0, { debugName: "image" }] : /* istanbul ignore next */ []);
|
|
13
|
+
overlayColor = input("#00000040", ...ngDevMode ? [{ debugName: "overlayColor" }] : /* istanbul ignore next */ []);
|
|
14
|
+
hideOverlay = input(false, ...ngDevMode ? [{ debugName: "hideOverlay" }] : /* istanbul ignore next */ []);
|
|
15
|
+
disabledInput = model(false, {
|
|
16
|
+
...ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {},
|
|
17
|
+
alias: "disabled"
|
|
18
|
+
});
|
|
19
|
+
templateRef = viewChild.required(TemplateRef, ...ngDevMode ? [{ debugName: "templateRef" }] : /* istanbul ignore next */ []);
|
|
20
|
+
sanitizer = inject(DomSanitizer);
|
|
21
|
+
backgroundImage = computed(() => {
|
|
22
|
+
const image = this.image();
|
|
23
|
+
return image ? this.sanitizer.bypassSecurityTrustStyle(`url('${image}')`) : null;
|
|
24
|
+
}, ...ngDevMode ? [{ debugName: "backgroundImage" }] : /* istanbul ignore next */ []);
|
|
25
|
+
get disabled() {
|
|
26
|
+
return this.disabledInput();
|
|
27
|
+
}
|
|
28
|
+
set disabled(value) {
|
|
29
|
+
this.disabledInput.set(value);
|
|
30
|
+
}
|
|
31
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
32
|
+
minVersion: "12.0.0",
|
|
33
|
+
version: "22.2.2",
|
|
34
|
+
ngImport: i0,
|
|
35
|
+
type: MatCarouselSlideComponent,
|
|
36
|
+
deps: [],
|
|
37
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
38
|
+
});
|
|
39
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
40
|
+
minVersion: "17.0.0",
|
|
41
|
+
version: "22.2.2",
|
|
42
|
+
type: MatCarouselSlideComponent,
|
|
43
|
+
isStandalone: true,
|
|
44
|
+
selector: "mat-carousel-slide",
|
|
45
|
+
inputs: {
|
|
46
|
+
image: {
|
|
47
|
+
classPropertyName: "image",
|
|
48
|
+
publicName: "image",
|
|
49
|
+
isSignal: true,
|
|
50
|
+
isRequired: false,
|
|
51
|
+
transformFunction: null
|
|
52
|
+
},
|
|
53
|
+
overlayColor: {
|
|
54
|
+
classPropertyName: "overlayColor",
|
|
55
|
+
publicName: "overlayColor",
|
|
56
|
+
isSignal: true,
|
|
57
|
+
isRequired: false,
|
|
58
|
+
transformFunction: null
|
|
59
|
+
},
|
|
60
|
+
hideOverlay: {
|
|
61
|
+
classPropertyName: "hideOverlay",
|
|
62
|
+
publicName: "hideOverlay",
|
|
63
|
+
isSignal: true,
|
|
64
|
+
isRequired: false,
|
|
65
|
+
transformFunction: null
|
|
66
|
+
},
|
|
67
|
+
disabledInput: {
|
|
68
|
+
classPropertyName: "disabledInput",
|
|
69
|
+
publicName: "disabled",
|
|
70
|
+
isSignal: true,
|
|
71
|
+
isRequired: false,
|
|
72
|
+
transformFunction: null
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
outputs: { disabledInput: "disabledChange" },
|
|
76
|
+
viewQueries: [{
|
|
77
|
+
propertyName: "templateRef",
|
|
78
|
+
first: true,
|
|
79
|
+
predicate: TemplateRef,
|
|
80
|
+
descendants: true,
|
|
81
|
+
isSignal: true
|
|
82
|
+
}],
|
|
83
|
+
ngImport: i0,
|
|
84
|
+
template: "<ng-template>\n <div class=\"carousel-slide\" [style.background-image]=\"backgroundImage()\">\n <div class=\"carousel-slide-content\"><ng-content></ng-content></div>\n @if (!hideOverlay()) {\n <div\n class=\"carousel-slide-overlay\"\n [style.background-color]=\"overlayColor()\"\n ></div>\n }\n </div>\n</ng-template>\n",
|
|
85
|
+
styles: [".carousel-slide{width:100%;height:100%;position:absolute;z-index:auto;background-size:cover;background-repeat:no-repeat;background-position:center}.carousel-slide-overlay{width:100%;height:100%;position:absolute;z-index:auto}.carousel-slide-content{width:100%;height:100%;position:absolute;z-index:1}\n"]
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
89
|
+
minVersion: "12.0.0",
|
|
90
|
+
version: "22.2.2",
|
|
91
|
+
ngImport: i0,
|
|
92
|
+
type: MatCarouselSlideComponent,
|
|
93
|
+
decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{
|
|
96
|
+
selector: "mat-carousel-slide",
|
|
97
|
+
standalone: true,
|
|
98
|
+
template: "<ng-template>\n <div class=\"carousel-slide\" [style.background-image]=\"backgroundImage()\">\n <div class=\"carousel-slide-content\"><ng-content></ng-content></div>\n @if (!hideOverlay()) {\n <div\n class=\"carousel-slide-overlay\"\n [style.background-color]=\"overlayColor()\"\n ></div>\n }\n </div>\n</ng-template>\n",
|
|
99
|
+
styles: [".carousel-slide{width:100%;height:100%;position:absolute;z-index:auto;background-size:cover;background-repeat:no-repeat;background-position:center}.carousel-slide-overlay{width:100%;height:100%;position:absolute;z-index:auto}.carousel-slide-content{width:100%;height:100%;position:absolute;z-index:1}\n"]
|
|
100
|
+
}]
|
|
101
|
+
}],
|
|
102
|
+
propDecorators: {
|
|
103
|
+
image: [{
|
|
104
|
+
type: i0.Input,
|
|
105
|
+
args: [{
|
|
106
|
+
isSignal: true,
|
|
107
|
+
alias: "image",
|
|
108
|
+
required: false
|
|
109
|
+
}]
|
|
110
|
+
}],
|
|
111
|
+
overlayColor: [{
|
|
112
|
+
type: i0.Input,
|
|
113
|
+
args: [{
|
|
114
|
+
isSignal: true,
|
|
115
|
+
alias: "overlayColor",
|
|
116
|
+
required: false
|
|
117
|
+
}]
|
|
118
|
+
}],
|
|
119
|
+
hideOverlay: [{
|
|
120
|
+
type: i0.Input,
|
|
121
|
+
args: [{
|
|
122
|
+
isSignal: true,
|
|
123
|
+
alias: "hideOverlay",
|
|
124
|
+
required: false
|
|
125
|
+
}]
|
|
126
|
+
}],
|
|
127
|
+
disabledInput: [{
|
|
128
|
+
type: i0.Input,
|
|
129
|
+
args: [{
|
|
130
|
+
isSignal: true,
|
|
131
|
+
alias: "disabled",
|
|
132
|
+
required: false
|
|
133
|
+
}]
|
|
134
|
+
}, {
|
|
135
|
+
type: i0.Output,
|
|
136
|
+
args: ["disabledChange"]
|
|
137
|
+
}],
|
|
138
|
+
templateRef: [{
|
|
139
|
+
type: i0.ViewChild,
|
|
140
|
+
args: [i0.forwardRef(() => TemplateRef), { isSignal: true }]
|
|
141
|
+
}]
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
var Direction;
|
|
145
|
+
(function(Direction) {
|
|
146
|
+
Direction[Direction["Left"] = 0] = "Left";
|
|
147
|
+
Direction[Direction["Right"] = 1] = "Right";
|
|
148
|
+
Direction[Direction["Index"] = 2] = "Index";
|
|
149
|
+
})(Direction || (Direction = {}));
|
|
150
|
+
var MatCarouselComponent = class MatCarouselComponent {
|
|
151
|
+
timings = input("250ms ease-in", ...ngDevMode ? [{ debugName: "timings" }] : /* istanbul ignore next */ []);
|
|
152
|
+
svgIconOverrides = input(...ngDevMode ? [void 0, { debugName: "svgIconOverrides" }] : /* istanbul ignore next */ []);
|
|
153
|
+
autoplay = input(true, ...ngDevMode ? [{ debugName: "autoplay" }] : /* istanbul ignore next */ []);
|
|
154
|
+
interval = input(5e3, ...ngDevMode ? [{ debugName: "interval" }] : /* istanbul ignore next */ []);
|
|
155
|
+
loop = input(true, ...ngDevMode ? [{ debugName: "loop" }] : /* istanbul ignore next */ []);
|
|
156
|
+
hideArrows = input(true, ...ngDevMode ? [{ debugName: "hideArrows" }] : /* istanbul ignore next */ []);
|
|
157
|
+
hideIndicators = input(true, ...ngDevMode ? [{ debugName: "hideIndicators" }] : /* istanbul ignore next */ []);
|
|
158
|
+
pauseOnHover = input(true, ...ngDevMode ? [{ debugName: "pauseOnHover" }] : /* istanbul ignore next */ []);
|
|
159
|
+
color = input("accent", ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []);
|
|
160
|
+
maxWidth = input("auto", ...ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []);
|
|
161
|
+
maintainAspectRatio = input(true, ...ngDevMode ? [{ debugName: "maintainAspectRatio" }] : /* istanbul ignore next */ []);
|
|
162
|
+
proportion = input(25, ...ngDevMode ? [{ debugName: "proportion" }] : /* istanbul ignore next */ []);
|
|
163
|
+
slideHeight = input("100%", ...ngDevMode ? [{ debugName: "slideHeight" }] : /* istanbul ignore next */ []);
|
|
164
|
+
slides = input(...ngDevMode ? [void 0, { debugName: "slides" }] : /* istanbul ignore next */ []);
|
|
165
|
+
useKeyboard = input(false, ...ngDevMode ? [{ debugName: "useKeyboard" }] : /* istanbul ignore next */ []);
|
|
166
|
+
useMouseWheel = input(false, ...ngDevMode ? [{ debugName: "useMouseWheel" }] : /* istanbul ignore next */ []);
|
|
167
|
+
orientation = input("ltr", ...ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []);
|
|
168
|
+
animationStart = output();
|
|
169
|
+
change = output();
|
|
170
|
+
currentIndex = signal(0, ...ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []);
|
|
171
|
+
slidesList = contentChildren(MatCarouselSlideComponent, ...ngDevMode ? [{ debugName: "slidesList" }] : /* istanbul ignore next */ []);
|
|
172
|
+
visibleSlides = computed(() => {
|
|
173
|
+
const slides = this.slides();
|
|
174
|
+
const list = this.slidesList();
|
|
175
|
+
return slides != null && slides < list.length ? list.slice(0, slides) : list;
|
|
176
|
+
}, ...ngDevMode ? [{ debugName: "visibleSlides" }] : /* istanbul ignore next */ []);
|
|
177
|
+
carouselContainerRef = viewChild.required("carouselContainer", ...ngDevMode ? [{ debugName: "carouselContainerRef" }] : /* istanbul ignore next */ []);
|
|
178
|
+
carouselListRef = viewChild.required("carouselList", ...ngDevMode ? [{ debugName: "carouselListRef" }] : /* istanbul ignore next */ []);
|
|
179
|
+
translation = signal("translateX(0px)", ...ngDevMode ? [{ debugName: "translation" }] : /* istanbul ignore next */ []);
|
|
180
|
+
listKeyManager;
|
|
181
|
+
timer$;
|
|
182
|
+
timerStop$ = new Subject();
|
|
183
|
+
animationPending = false;
|
|
184
|
+
animationTimeout = null;
|
|
185
|
+
pressed = false;
|
|
186
|
+
dragging = false;
|
|
187
|
+
dragStartX = 0;
|
|
188
|
+
dragStartY = 0;
|
|
189
|
+
dragThreshold = 12;
|
|
190
|
+
renderer = inject(Renderer2);
|
|
191
|
+
platformId = inject(PLATFORM_ID);
|
|
192
|
+
destroyRef = inject(DestroyRef);
|
|
193
|
+
injector = inject(Injector);
|
|
194
|
+
get currentSlide() {
|
|
195
|
+
return this.listKeyManager?.activeItem ?? null;
|
|
196
|
+
}
|
|
197
|
+
constructor() {
|
|
198
|
+
effect(() => {
|
|
199
|
+
const loop = this.loop();
|
|
200
|
+
this.listKeyManager?.withWrap(loop);
|
|
201
|
+
});
|
|
202
|
+
effect(() => {
|
|
203
|
+
const orientation = this.orientation();
|
|
204
|
+
this.listKeyManager?.withHorizontalOrientation(orientation);
|
|
205
|
+
});
|
|
206
|
+
effect(() => {
|
|
207
|
+
this.maxWidth();
|
|
208
|
+
this.slideTo(0);
|
|
209
|
+
});
|
|
210
|
+
effect(() => {
|
|
211
|
+
this.interval();
|
|
212
|
+
this.autoplay();
|
|
213
|
+
this.stopTimer();
|
|
214
|
+
this.startTimer();
|
|
215
|
+
});
|
|
216
|
+
this.destroyRef.onDestroy(() => {
|
|
217
|
+
this.clearAnimationTimeout();
|
|
218
|
+
this.listKeyManager?.destroy();
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
ngAfterContentInit() {
|
|
222
|
+
this.listKeyManager = new ListKeyManager(this.visibleSlides, this.injector).withVerticalOrientation(false).withHorizontalOrientation(this.orientation()).withWrap(this.loop());
|
|
223
|
+
this.listKeyManager.updateActiveItem(0);
|
|
224
|
+
this.listKeyManager.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((index) => {
|
|
225
|
+
this.currentIndex.set(index);
|
|
226
|
+
this.playAnimation();
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
next() {
|
|
230
|
+
this.goto(Direction.Right);
|
|
231
|
+
}
|
|
232
|
+
previous() {
|
|
233
|
+
this.goto(Direction.Left);
|
|
234
|
+
}
|
|
235
|
+
slideTo(index) {
|
|
236
|
+
this.goto(Direction.Index, index);
|
|
237
|
+
}
|
|
238
|
+
onKeyUp(event) {
|
|
239
|
+
if (this.useKeyboard()) this.listKeyManager?.onKeydown(event);
|
|
240
|
+
}
|
|
241
|
+
onMouseEnter() {
|
|
242
|
+
if (this.pauseOnHover()) this.stopTimer();
|
|
243
|
+
}
|
|
244
|
+
onMouseLeave() {
|
|
245
|
+
if (this.pauseOnHover()) this.startTimer();
|
|
246
|
+
}
|
|
247
|
+
onMouseWheel(event) {
|
|
248
|
+
if (this.useMouseWheel()) {
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
const delta = Math.sign(event.deltaY);
|
|
251
|
+
if (delta > 0) this.next();
|
|
252
|
+
else if (delta < 0) this.previous();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
onResize() {
|
|
256
|
+
this.slideTo(0);
|
|
257
|
+
}
|
|
258
|
+
onTransitionEnd(event) {
|
|
259
|
+
if (event.target === this.carouselListRef().nativeElement && event.propertyName === "transform") this.finishAnimation();
|
|
260
|
+
}
|
|
261
|
+
onDragStart(event) {
|
|
262
|
+
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
263
|
+
this.pressed = true;
|
|
264
|
+
this.dragging = false;
|
|
265
|
+
this.dragStartX = event.clientX;
|
|
266
|
+
this.dragStartY = event.clientY;
|
|
267
|
+
}
|
|
268
|
+
onDrag(event, slideElem) {
|
|
269
|
+
if (!this.pressed) return;
|
|
270
|
+
const deltaX = event.clientX - this.dragStartX;
|
|
271
|
+
const deltaY = event.clientY - this.dragStartY;
|
|
272
|
+
if (!this.dragging) {
|
|
273
|
+
if (!(Math.abs(deltaX) > this.dragThreshold && Math.abs(deltaX) > Math.abs(deltaY))) return;
|
|
274
|
+
this.dragging = true;
|
|
275
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
276
|
+
}
|
|
277
|
+
if (Math.abs(deltaY) > Math.abs(deltaX)) return;
|
|
278
|
+
let adjustedDelta = deltaX;
|
|
279
|
+
if (this.isOutOfBounds()) adjustedDelta *= .2;
|
|
280
|
+
this.renderer.setStyle(slideElem, "cursor", "grabbing");
|
|
281
|
+
this.translation.set(this.getTranslation(this.getOffset() + adjustedDelta));
|
|
282
|
+
}
|
|
283
|
+
onDragEnd(event, slideElem) {
|
|
284
|
+
this.pressed = false;
|
|
285
|
+
if (!this.dragging) return;
|
|
286
|
+
this.dragging = false;
|
|
287
|
+
this.renderer.removeStyle(slideElem, "cursor");
|
|
288
|
+
const deltaX = event.clientX - this.dragStartX;
|
|
289
|
+
if (!this.isOutOfBounds() && Math.abs(deltaX) > this.getWidth() * .25) {
|
|
290
|
+
if (deltaX <= 0) {
|
|
291
|
+
this.next();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
this.previous();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
this.playAnimation();
|
|
298
|
+
}
|
|
299
|
+
isOutOfBounds() {
|
|
300
|
+
const sign = this.orientation() === "rtl" ? -1 : 1;
|
|
301
|
+
const listEl = this.carouselListRef().nativeElement;
|
|
302
|
+
const offsetParent = listEl.offsetParent;
|
|
303
|
+
const parentLeft = offsetParent ? offsetParent.getBoundingClientRect().left : 0;
|
|
304
|
+
const left = sign * (listEl.getBoundingClientRect().left - parentLeft);
|
|
305
|
+
const lastIndex = this.visibleSlides().length - 1;
|
|
306
|
+
const width = -this.getWidth() * lastIndex;
|
|
307
|
+
return this.listKeyManager.activeItemIndex === 0 && left >= 0 || this.listKeyManager.activeItemIndex === lastIndex && left <= width;
|
|
308
|
+
}
|
|
309
|
+
isVisible() {
|
|
310
|
+
if (!isPlatformBrowser(this.platformId)) return false;
|
|
311
|
+
const container = this.carouselContainerRef();
|
|
312
|
+
if (!container) return false;
|
|
313
|
+
const elem = container.nativeElement;
|
|
314
|
+
const docViewTop = window.pageYOffset;
|
|
315
|
+
const docViewBottom = docViewTop + window.innerHeight;
|
|
316
|
+
const elemOffset = elem.getBoundingClientRect();
|
|
317
|
+
const elemTop = docViewTop + elemOffset.top;
|
|
318
|
+
return elemTop + elemOffset.height <= docViewBottom || elemTop >= docViewTop;
|
|
319
|
+
}
|
|
320
|
+
getOffset() {
|
|
321
|
+
const offset = this.currentIndex() * this.getWidth();
|
|
322
|
+
return (this.orientation() === "rtl" ? 1 : -1) * offset;
|
|
323
|
+
}
|
|
324
|
+
getTranslation(offset) {
|
|
325
|
+
return `translateX(${offset}px)`;
|
|
326
|
+
}
|
|
327
|
+
getWidth() {
|
|
328
|
+
return this.carouselContainerRef().nativeElement.clientWidth;
|
|
329
|
+
}
|
|
330
|
+
goto(direction, index) {
|
|
331
|
+
if (!this.listKeyManager) return;
|
|
332
|
+
const rtl = this.orientation() === "rtl";
|
|
333
|
+
switch (direction) {
|
|
334
|
+
case Direction.Left: return rtl ? this.listKeyManager.setNextItemActive() : this.listKeyManager.setPreviousItemActive();
|
|
335
|
+
case Direction.Right: return rtl ? this.listKeyManager.setPreviousItemActive() : this.listKeyManager.setNextItemActive();
|
|
336
|
+
case Direction.Index: return this.listKeyManager.setActiveItem(index);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
playAnimation() {
|
|
340
|
+
this.translation.set(this.getTranslation(this.getOffset()));
|
|
341
|
+
this.animationStart.emit(this.currentIndex());
|
|
342
|
+
this.scheduleAnimationEnd();
|
|
343
|
+
}
|
|
344
|
+
scheduleAnimationEnd() {
|
|
345
|
+
this.clearAnimationTimeout();
|
|
346
|
+
this.animationPending = true;
|
|
347
|
+
const duration = this.getTransitionDuration(this.timings());
|
|
348
|
+
this.animationTimeout = setTimeout(() => this.finishAnimation(), duration + 16);
|
|
349
|
+
}
|
|
350
|
+
finishAnimation() {
|
|
351
|
+
if (!this.animationPending) return;
|
|
352
|
+
this.animationPending = false;
|
|
353
|
+
this.clearAnimationTimeout();
|
|
354
|
+
this.change.emit(this.currentIndex());
|
|
355
|
+
}
|
|
356
|
+
getTransitionDuration(timings) {
|
|
357
|
+
const match = timings.match(/(\d+(?:\.\d+)?)(ms|s)/);
|
|
358
|
+
if (!match) return 250;
|
|
359
|
+
const value = parseFloat(match[1]);
|
|
360
|
+
return match[2] === "s" ? value * 1e3 : value;
|
|
361
|
+
}
|
|
362
|
+
clearAnimationTimeout() {
|
|
363
|
+
if (this.animationTimeout != null) {
|
|
364
|
+
clearTimeout(this.animationTimeout);
|
|
365
|
+
this.animationTimeout = null;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
resetTimer() {
|
|
369
|
+
this.timer$ = interval(this.interval());
|
|
370
|
+
}
|
|
371
|
+
startTimer() {
|
|
372
|
+
if (!this.autoplay()) return;
|
|
373
|
+
this.resetTimer();
|
|
374
|
+
this.timer$.pipe(takeUntil(this.timerStop$), takeUntilDestroyed(this.destroyRef), filter(() => this.isVisible())).subscribe(() => {
|
|
375
|
+
this.listKeyManager?.withWrap(true).setNextItemActive();
|
|
376
|
+
this.listKeyManager?.withWrap(this.loop());
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
stopTimer() {
|
|
380
|
+
this.timerStop$.next(void 0);
|
|
381
|
+
}
|
|
382
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
383
|
+
minVersion: "12.0.0",
|
|
384
|
+
version: "22.2.2",
|
|
385
|
+
ngImport: i0,
|
|
386
|
+
type: MatCarouselComponent,
|
|
387
|
+
deps: [],
|
|
388
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
389
|
+
});
|
|
390
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
391
|
+
minVersion: "17.0.0",
|
|
392
|
+
version: "22.2.2",
|
|
393
|
+
type: MatCarouselComponent,
|
|
394
|
+
isStandalone: true,
|
|
395
|
+
selector: "mat-carousel",
|
|
396
|
+
inputs: {
|
|
397
|
+
timings: {
|
|
398
|
+
classPropertyName: "timings",
|
|
399
|
+
publicName: "timings",
|
|
400
|
+
isSignal: true,
|
|
401
|
+
isRequired: false,
|
|
402
|
+
transformFunction: null
|
|
403
|
+
},
|
|
404
|
+
svgIconOverrides: {
|
|
405
|
+
classPropertyName: "svgIconOverrides",
|
|
406
|
+
publicName: "svgIconOverrides",
|
|
407
|
+
isSignal: true,
|
|
408
|
+
isRequired: false,
|
|
409
|
+
transformFunction: null
|
|
410
|
+
},
|
|
411
|
+
autoplay: {
|
|
412
|
+
classPropertyName: "autoplay",
|
|
413
|
+
publicName: "autoplay",
|
|
414
|
+
isSignal: true,
|
|
415
|
+
isRequired: false,
|
|
416
|
+
transformFunction: null
|
|
417
|
+
},
|
|
418
|
+
interval: {
|
|
419
|
+
classPropertyName: "interval",
|
|
420
|
+
publicName: "interval",
|
|
421
|
+
isSignal: true,
|
|
422
|
+
isRequired: false,
|
|
423
|
+
transformFunction: null
|
|
424
|
+
},
|
|
425
|
+
loop: {
|
|
426
|
+
classPropertyName: "loop",
|
|
427
|
+
publicName: "loop",
|
|
428
|
+
isSignal: true,
|
|
429
|
+
isRequired: false,
|
|
430
|
+
transformFunction: null
|
|
431
|
+
},
|
|
432
|
+
hideArrows: {
|
|
433
|
+
classPropertyName: "hideArrows",
|
|
434
|
+
publicName: "hideArrows",
|
|
435
|
+
isSignal: true,
|
|
436
|
+
isRequired: false,
|
|
437
|
+
transformFunction: null
|
|
438
|
+
},
|
|
439
|
+
hideIndicators: {
|
|
440
|
+
classPropertyName: "hideIndicators",
|
|
441
|
+
publicName: "hideIndicators",
|
|
442
|
+
isSignal: true,
|
|
443
|
+
isRequired: false,
|
|
444
|
+
transformFunction: null
|
|
445
|
+
},
|
|
446
|
+
pauseOnHover: {
|
|
447
|
+
classPropertyName: "pauseOnHover",
|
|
448
|
+
publicName: "pauseOnHover",
|
|
449
|
+
isSignal: true,
|
|
450
|
+
isRequired: false,
|
|
451
|
+
transformFunction: null
|
|
452
|
+
},
|
|
453
|
+
color: {
|
|
454
|
+
classPropertyName: "color",
|
|
455
|
+
publicName: "color",
|
|
456
|
+
isSignal: true,
|
|
457
|
+
isRequired: false,
|
|
458
|
+
transformFunction: null
|
|
459
|
+
},
|
|
460
|
+
maxWidth: {
|
|
461
|
+
classPropertyName: "maxWidth",
|
|
462
|
+
publicName: "maxWidth",
|
|
463
|
+
isSignal: true,
|
|
464
|
+
isRequired: false,
|
|
465
|
+
transformFunction: null
|
|
466
|
+
},
|
|
467
|
+
maintainAspectRatio: {
|
|
468
|
+
classPropertyName: "maintainAspectRatio",
|
|
469
|
+
publicName: "maintainAspectRatio",
|
|
470
|
+
isSignal: true,
|
|
471
|
+
isRequired: false,
|
|
472
|
+
transformFunction: null
|
|
473
|
+
},
|
|
474
|
+
proportion: {
|
|
475
|
+
classPropertyName: "proportion",
|
|
476
|
+
publicName: "proportion",
|
|
477
|
+
isSignal: true,
|
|
478
|
+
isRequired: false,
|
|
479
|
+
transformFunction: null
|
|
480
|
+
},
|
|
481
|
+
slideHeight: {
|
|
482
|
+
classPropertyName: "slideHeight",
|
|
483
|
+
publicName: "slideHeight",
|
|
484
|
+
isSignal: true,
|
|
485
|
+
isRequired: false,
|
|
486
|
+
transformFunction: null
|
|
487
|
+
},
|
|
488
|
+
slides: {
|
|
489
|
+
classPropertyName: "slides",
|
|
490
|
+
publicName: "slides",
|
|
491
|
+
isSignal: true,
|
|
492
|
+
isRequired: false,
|
|
493
|
+
transformFunction: null
|
|
494
|
+
},
|
|
495
|
+
useKeyboard: {
|
|
496
|
+
classPropertyName: "useKeyboard",
|
|
497
|
+
publicName: "useKeyboard",
|
|
498
|
+
isSignal: true,
|
|
499
|
+
isRequired: false,
|
|
500
|
+
transformFunction: null
|
|
501
|
+
},
|
|
502
|
+
useMouseWheel: {
|
|
503
|
+
classPropertyName: "useMouseWheel",
|
|
504
|
+
publicName: "useMouseWheel",
|
|
505
|
+
isSignal: true,
|
|
506
|
+
isRequired: false,
|
|
507
|
+
transformFunction: null
|
|
508
|
+
},
|
|
509
|
+
orientation: {
|
|
510
|
+
classPropertyName: "orientation",
|
|
511
|
+
publicName: "orientation",
|
|
512
|
+
isSignal: true,
|
|
513
|
+
isRequired: false,
|
|
514
|
+
transformFunction: null
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
outputs: {
|
|
518
|
+
animationStart: "animationStart",
|
|
519
|
+
change: "change"
|
|
520
|
+
},
|
|
521
|
+
host: { listeners: {
|
|
522
|
+
"keyup": "onKeyUp($event)",
|
|
523
|
+
"mouseenter": "onMouseEnter()",
|
|
524
|
+
"mouseleave": "onMouseLeave()",
|
|
525
|
+
"mousewheel": "onMouseWheel($event)",
|
|
526
|
+
"window:resize": "onResize()",
|
|
527
|
+
"transitionend": "onTransitionEnd($event)"
|
|
528
|
+
} },
|
|
529
|
+
queries: [{
|
|
530
|
+
propertyName: "slidesList",
|
|
531
|
+
predicate: MatCarouselSlideComponent,
|
|
532
|
+
isSignal: true
|
|
533
|
+
}],
|
|
534
|
+
viewQueries: [{
|
|
535
|
+
propertyName: "carouselContainerRef",
|
|
536
|
+
first: true,
|
|
537
|
+
predicate: ["carouselContainer"],
|
|
538
|
+
descendants: true,
|
|
539
|
+
isSignal: true
|
|
540
|
+
}, {
|
|
541
|
+
propertyName: "carouselListRef",
|
|
542
|
+
first: true,
|
|
543
|
+
predicate: ["carouselList"],
|
|
544
|
+
descendants: true,
|
|
545
|
+
isSignal: true
|
|
546
|
+
}],
|
|
547
|
+
ngImport: i0,
|
|
548
|
+
template: "<div\n #carouselContainer\n class=\"carousel\"\n tabindex=\"0\"\n [style.max-width]=\"maxWidth()\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n>\n <ul\n #carouselList\n class=\"carousel-list\"\n role=\"listbox\"\n [style.transform]=\"translation()\"\n [style.transition]=\"timings()\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n >\n @for (slide of visibleSlides(); track slide) {\n <li\n #carouselSlide\n class=\"carousel-slide\"\n role=\"option\"\n [style.padding-bottom]=\"maintainAspectRatio() && proportion() ? proportion() + '%' : '0px'\"\n [style.height]=\"!maintainAspectRatio() && slideHeight() ? slideHeight() : '0px'\"\n (pointerdown)=\"onDragStart($event)\"\n (pointermove)=\"onDrag($event, carouselSlide)\"\n (pointerup)=\"onDragEnd($event, carouselSlide)\"\n (pointercancel)=\"onDragEnd($event, carouselSlide)\"\n >\n <ng-container [ngTemplateOutlet]=\"slide.templateRef()\"></ng-container>\n </li>\n }\n </ul>\n\n @if (!hideArrows()) {\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === 0\"\n (click)=\"previous()\"\n >\n @if (svgIconOverrides()?.arrowBack; as arrowBack) {\n <mat-icon [svgIcon]=\"arrowBack\"></mat-icon>\n } @else {\n <mat-icon>arrow_back</mat-icon>\n }\n </button>\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === visibleSlides().length - 1\"\n (click)=\"next()\"\n >\n @if (svgIconOverrides()?.arrowForward; as arrowForward) {\n <mat-icon [svgIcon]=\"arrowForward\"></mat-icon>\n } @else {\n <mat-icon>arrow_forward</mat-icon>\n }\n </button>\n }\n\n @if (!hideIndicators()) {\n <div\n class=\"carousel-indicators\"\n tabindex=\"-1\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n >\n @for (slide of visibleSlides(); track slide; let i = $index) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n mat-mini-fab\n [color]=\"color()\"\n [disabled]=\"i === currentIndex()\"\n (click)=\"slideTo(i)\"\n (focus)=\"carouselContainer.focus()\"\n ></button>\n }\n </div>\n }\n</div>\n",
|
|
549
|
+
styles: [".carousel{width:100%;position:relative;overflow:hidden;outline:none}.carousel>button{position:absolute;z-index:1;top:50%;transform:translateY(-50%)}.carousel>button:first-of-type{left:30px}.carousel>button:last-of-type{right:30px}.carousel-list{width:100%;margin:0;padding:0;list-style:none;display:flex;position:relative}.carousel-slide{width:100%;height:0;display:flex;flex-shrink:0;position:relative}.carousel-slide:hover{cursor:grab}.carousel-indicators{display:flex;position:absolute;bottom:15px;z-index:1;left:50%;transform:translate(-50%);outline:none}.carousel-indicators>button{width:10px;height:10px;margin:7.5px}\n"],
|
|
550
|
+
dependencies: [
|
|
551
|
+
{
|
|
552
|
+
kind: "component",
|
|
553
|
+
type: MatIconButton,
|
|
554
|
+
selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]",
|
|
555
|
+
exportAs: ["matButton", "matAnchor"]
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
kind: "component",
|
|
559
|
+
type: MatMiniFabButton,
|
|
560
|
+
selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]",
|
|
561
|
+
exportAs: ["matButton", "matAnchor"]
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
kind: "component",
|
|
565
|
+
type: MatIcon,
|
|
566
|
+
selector: "mat-icon",
|
|
567
|
+
inputs: [
|
|
568
|
+
"color",
|
|
569
|
+
"inline",
|
|
570
|
+
"svgIcon",
|
|
571
|
+
"fontSet",
|
|
572
|
+
"fontIcon"
|
|
573
|
+
],
|
|
574
|
+
exportAs: ["matIcon"]
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
kind: "directive",
|
|
578
|
+
type: NgTemplateOutlet,
|
|
579
|
+
selector: "[ngTemplateOutlet]",
|
|
580
|
+
inputs: [
|
|
581
|
+
"ngTemplateOutletContext",
|
|
582
|
+
"ngTemplateOutlet",
|
|
583
|
+
"ngTemplateOutletInjector"
|
|
584
|
+
]
|
|
585
|
+
}
|
|
586
|
+
]
|
|
587
|
+
});
|
|
588
|
+
};
|
|
589
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
590
|
+
minVersion: "12.0.0",
|
|
591
|
+
version: "22.2.2",
|
|
592
|
+
ngImport: i0,
|
|
593
|
+
type: MatCarouselComponent,
|
|
594
|
+
decorators: [{
|
|
595
|
+
type: Component,
|
|
596
|
+
args: [{
|
|
597
|
+
selector: "mat-carousel",
|
|
598
|
+
standalone: true,
|
|
599
|
+
imports: [
|
|
600
|
+
MatIconButton,
|
|
601
|
+
MatMiniFabButton,
|
|
602
|
+
MatIcon,
|
|
603
|
+
NgTemplateOutlet
|
|
604
|
+
],
|
|
605
|
+
template: "<div\n #carouselContainer\n class=\"carousel\"\n tabindex=\"0\"\n [style.max-width]=\"maxWidth()\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n>\n <ul\n #carouselList\n class=\"carousel-list\"\n role=\"listbox\"\n [style.transform]=\"translation()\"\n [style.transition]=\"timings()\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n >\n @for (slide of visibleSlides(); track slide) {\n <li\n #carouselSlide\n class=\"carousel-slide\"\n role=\"option\"\n [style.padding-bottom]=\"maintainAspectRatio() && proportion() ? proportion() + '%' : '0px'\"\n [style.height]=\"!maintainAspectRatio() && slideHeight() ? slideHeight() : '0px'\"\n (pointerdown)=\"onDragStart($event)\"\n (pointermove)=\"onDrag($event, carouselSlide)\"\n (pointerup)=\"onDragEnd($event, carouselSlide)\"\n (pointercancel)=\"onDragEnd($event, carouselSlide)\"\n >\n <ng-container [ngTemplateOutlet]=\"slide.templateRef()\"></ng-container>\n </li>\n }\n </ul>\n\n @if (!hideArrows()) {\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === 0\"\n (click)=\"previous()\"\n >\n @if (svgIconOverrides()?.arrowBack; as arrowBack) {\n <mat-icon [svgIcon]=\"arrowBack\"></mat-icon>\n } @else {\n <mat-icon>arrow_back</mat-icon>\n }\n </button>\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === visibleSlides().length - 1\"\n (click)=\"next()\"\n >\n @if (svgIconOverrides()?.arrowForward; as arrowForward) {\n <mat-icon [svgIcon]=\"arrowForward\"></mat-icon>\n } @else {\n <mat-icon>arrow_forward</mat-icon>\n }\n </button>\n }\n\n @if (!hideIndicators()) {\n <div\n class=\"carousel-indicators\"\n tabindex=\"-1\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n >\n @for (slide of visibleSlides(); track slide; let i = $index) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n mat-mini-fab\n [color]=\"color()\"\n [disabled]=\"i === currentIndex()\"\n (click)=\"slideTo(i)\"\n (focus)=\"carouselContainer.focus()\"\n ></button>\n }\n </div>\n }\n</div>\n",
|
|
606
|
+
styles: [".carousel{width:100%;position:relative;overflow:hidden;outline:none}.carousel>button{position:absolute;z-index:1;top:50%;transform:translateY(-50%)}.carousel>button:first-of-type{left:30px}.carousel>button:last-of-type{right:30px}.carousel-list{width:100%;margin:0;padding:0;list-style:none;display:flex;position:relative}.carousel-slide{width:100%;height:0;display:flex;flex-shrink:0;position:relative}.carousel-slide:hover{cursor:grab}.carousel-indicators{display:flex;position:absolute;bottom:15px;z-index:1;left:50%;transform:translate(-50%);outline:none}.carousel-indicators>button{width:10px;height:10px;margin:7.5px}\n"]
|
|
607
|
+
}]
|
|
608
|
+
}],
|
|
609
|
+
ctorParameters: () => [],
|
|
610
|
+
propDecorators: {
|
|
611
|
+
timings: [{
|
|
612
|
+
type: i0.Input,
|
|
613
|
+
args: [{
|
|
614
|
+
isSignal: true,
|
|
615
|
+
alias: "timings",
|
|
616
|
+
required: false
|
|
617
|
+
}]
|
|
618
|
+
}],
|
|
619
|
+
svgIconOverrides: [{
|
|
620
|
+
type: i0.Input,
|
|
621
|
+
args: [{
|
|
622
|
+
isSignal: true,
|
|
623
|
+
alias: "svgIconOverrides",
|
|
624
|
+
required: false
|
|
625
|
+
}]
|
|
626
|
+
}],
|
|
627
|
+
autoplay: [{
|
|
628
|
+
type: i0.Input,
|
|
629
|
+
args: [{
|
|
630
|
+
isSignal: true,
|
|
631
|
+
alias: "autoplay",
|
|
632
|
+
required: false
|
|
633
|
+
}]
|
|
634
|
+
}],
|
|
635
|
+
interval: [{
|
|
636
|
+
type: i0.Input,
|
|
637
|
+
args: [{
|
|
638
|
+
isSignal: true,
|
|
639
|
+
alias: "interval",
|
|
640
|
+
required: false
|
|
641
|
+
}]
|
|
642
|
+
}],
|
|
643
|
+
loop: [{
|
|
644
|
+
type: i0.Input,
|
|
645
|
+
args: [{
|
|
646
|
+
isSignal: true,
|
|
647
|
+
alias: "loop",
|
|
648
|
+
required: false
|
|
649
|
+
}]
|
|
650
|
+
}],
|
|
651
|
+
hideArrows: [{
|
|
652
|
+
type: i0.Input,
|
|
653
|
+
args: [{
|
|
654
|
+
isSignal: true,
|
|
655
|
+
alias: "hideArrows",
|
|
656
|
+
required: false
|
|
657
|
+
}]
|
|
658
|
+
}],
|
|
659
|
+
hideIndicators: [{
|
|
660
|
+
type: i0.Input,
|
|
661
|
+
args: [{
|
|
662
|
+
isSignal: true,
|
|
663
|
+
alias: "hideIndicators",
|
|
664
|
+
required: false
|
|
665
|
+
}]
|
|
666
|
+
}],
|
|
667
|
+
pauseOnHover: [{
|
|
668
|
+
type: i0.Input,
|
|
669
|
+
args: [{
|
|
670
|
+
isSignal: true,
|
|
671
|
+
alias: "pauseOnHover",
|
|
672
|
+
required: false
|
|
673
|
+
}]
|
|
674
|
+
}],
|
|
675
|
+
color: [{
|
|
676
|
+
type: i0.Input,
|
|
677
|
+
args: [{
|
|
678
|
+
isSignal: true,
|
|
679
|
+
alias: "color",
|
|
680
|
+
required: false
|
|
681
|
+
}]
|
|
682
|
+
}],
|
|
683
|
+
maxWidth: [{
|
|
684
|
+
type: i0.Input,
|
|
685
|
+
args: [{
|
|
686
|
+
isSignal: true,
|
|
687
|
+
alias: "maxWidth",
|
|
688
|
+
required: false
|
|
689
|
+
}]
|
|
690
|
+
}],
|
|
691
|
+
maintainAspectRatio: [{
|
|
692
|
+
type: i0.Input,
|
|
693
|
+
args: [{
|
|
694
|
+
isSignal: true,
|
|
695
|
+
alias: "maintainAspectRatio",
|
|
696
|
+
required: false
|
|
697
|
+
}]
|
|
698
|
+
}],
|
|
699
|
+
proportion: [{
|
|
700
|
+
type: i0.Input,
|
|
701
|
+
args: [{
|
|
702
|
+
isSignal: true,
|
|
703
|
+
alias: "proportion",
|
|
704
|
+
required: false
|
|
705
|
+
}]
|
|
706
|
+
}],
|
|
707
|
+
slideHeight: [{
|
|
708
|
+
type: i0.Input,
|
|
709
|
+
args: [{
|
|
710
|
+
isSignal: true,
|
|
711
|
+
alias: "slideHeight",
|
|
712
|
+
required: false
|
|
713
|
+
}]
|
|
714
|
+
}],
|
|
715
|
+
slides: [{
|
|
716
|
+
type: i0.Input,
|
|
717
|
+
args: [{
|
|
718
|
+
isSignal: true,
|
|
719
|
+
alias: "slides",
|
|
720
|
+
required: false
|
|
721
|
+
}]
|
|
722
|
+
}],
|
|
723
|
+
useKeyboard: [{
|
|
724
|
+
type: i0.Input,
|
|
725
|
+
args: [{
|
|
726
|
+
isSignal: true,
|
|
727
|
+
alias: "useKeyboard",
|
|
728
|
+
required: false
|
|
729
|
+
}]
|
|
730
|
+
}],
|
|
731
|
+
useMouseWheel: [{
|
|
732
|
+
type: i0.Input,
|
|
733
|
+
args: [{
|
|
734
|
+
isSignal: true,
|
|
735
|
+
alias: "useMouseWheel",
|
|
736
|
+
required: false
|
|
737
|
+
}]
|
|
738
|
+
}],
|
|
739
|
+
orientation: [{
|
|
740
|
+
type: i0.Input,
|
|
741
|
+
args: [{
|
|
742
|
+
isSignal: true,
|
|
743
|
+
alias: "orientation",
|
|
744
|
+
required: false
|
|
745
|
+
}]
|
|
746
|
+
}],
|
|
747
|
+
animationStart: [{
|
|
748
|
+
type: i0.Output,
|
|
749
|
+
args: ["animationStart"]
|
|
750
|
+
}],
|
|
751
|
+
change: [{
|
|
752
|
+
type: i0.Output,
|
|
753
|
+
args: ["change"]
|
|
754
|
+
}],
|
|
755
|
+
slidesList: [{
|
|
756
|
+
type: i0.ContentChildren,
|
|
757
|
+
args: [i0.forwardRef(() => MatCarouselSlideComponent), { isSignal: true }]
|
|
758
|
+
}],
|
|
759
|
+
carouselContainerRef: [{
|
|
760
|
+
type: i0.ViewChild,
|
|
761
|
+
args: ["carouselContainer", { isSignal: true }]
|
|
762
|
+
}],
|
|
763
|
+
carouselListRef: [{
|
|
764
|
+
type: i0.ViewChild,
|
|
765
|
+
args: ["carouselList", { isSignal: true }]
|
|
766
|
+
}],
|
|
767
|
+
onKeyUp: [{
|
|
768
|
+
type: HostListener,
|
|
769
|
+
args: ["keyup", ["$event"]]
|
|
770
|
+
}],
|
|
771
|
+
onMouseEnter: [{
|
|
772
|
+
type: HostListener,
|
|
773
|
+
args: ["mouseenter"]
|
|
774
|
+
}],
|
|
775
|
+
onMouseLeave: [{
|
|
776
|
+
type: HostListener,
|
|
777
|
+
args: ["mouseleave"]
|
|
778
|
+
}],
|
|
779
|
+
onMouseWheel: [{
|
|
780
|
+
type: HostListener,
|
|
781
|
+
args: ["mousewheel", ["$event"]]
|
|
782
|
+
}],
|
|
783
|
+
onResize: [{
|
|
784
|
+
type: HostListener,
|
|
785
|
+
args: ["window:resize"]
|
|
786
|
+
}],
|
|
787
|
+
onTransitionEnd: [{
|
|
788
|
+
type: HostListener,
|
|
789
|
+
args: ["transitionend", ["$event"]]
|
|
790
|
+
}]
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
export { MatCarouselComponent, MatCarouselSlideComponent };
|
|
794
|
+
|
|
795
|
+
//# sourceMappingURL=kovalenko-material-carousel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kovalenko-material-carousel.mjs","names":[],"sources":["../../../projects/carousel/src/lib/carousel-slide/carousel-slide.component.ts","../../../projects/carousel/src/lib/carousel-slide/carousel-slide.component.html","../../../projects/carousel/src/lib/carousel.component.ts","../../../projects/carousel/src/lib/carousel.component.html"],"sourcesContent":["import { ListKeyManagerOption } from '@angular/cdk/a11y';\nimport {\n Component,\n computed,\n inject,\n input,\n model,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport { DomSanitizer, SafeStyle } from '@angular/platform-browser';\n\n@Component({\n selector: 'mat-carousel-slide',\n templateUrl: './carousel-slide.component.html',\n styleUrls: ['./carousel-slide.component.scss'],\n standalone: true,\n})\nexport class MatCarouselSlideComponent implements ListKeyManagerOption {\n readonly image = input<string>();\n\n readonly overlayColor = input('#00000040');\n\n readonly hideOverlay = input(false);\n\n readonly disabledInput = model(false, { alias: 'disabled' });\n\n readonly templateRef = viewChild.required(TemplateRef);\n\n private readonly sanitizer = inject(DomSanitizer);\n\n readonly backgroundImage = computed<SafeStyle | null>(() => {\n const image = this.image();\n return image ? this.sanitizer.bypassSecurityTrustStyle(`url('${image}')`) : null;\n });\n\n get disabled(): boolean {\n return this.disabledInput();\n }\n\n set disabled(value: boolean) {\n this.disabledInput.set(value);\n }\n}\n","<ng-template>\n <div class=\"carousel-slide\" [style.background-image]=\"backgroundImage()\">\n <div class=\"carousel-slide-content\"><ng-content></ng-content></div>\n @if (!hideOverlay()) {\n <div\n class=\"carousel-slide-overlay\"\n [style.background-color]=\"overlayColor()\"\n ></div>\n }\n </div>\n</ng-template>\n","import { ListKeyManager } from '@angular/cdk/a11y';\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport {\n AfterContentInit,\n Component,\n computed,\n contentChildren,\n DestroyRef,\n effect,\n ElementRef,\n HostListener,\n inject,\n Injector,\n input,\n output,\n PLATFORM_ID,\n Renderer2,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatIconButton, MatMiniFabButton } from '@angular/material/button';\nimport { ThemePalette } from '@angular/material/core';\nimport { MatIcon } from '@angular/material/icon';\nimport { interval, Observable, Subject } from 'rxjs';\nimport { filter, takeUntil } from 'rxjs/operators';\n\nimport { Orientation, SvgIconOverrides } from './carousel';\nimport { MatCarouselSlideComponent } from './carousel-slide/carousel-slide.component';\n\nenum Direction {\n Left,\n Right,\n Index,\n}\n\n@Component({\n selector: 'mat-carousel',\n templateUrl: './carousel.component.html',\n styleUrls: ['./carousel.component.scss'],\n standalone: true,\n imports: [MatIconButton, MatMiniFabButton, MatIcon, NgTemplateOutlet],\n})\nexport class MatCarouselComponent implements AfterContentInit {\n // Animations.\n readonly timings = input('250ms ease-in');\n readonly svgIconOverrides = input<SvgIconOverrides>();\n\n // Navigation.\n readonly autoplay = input(true);\n readonly interval = input(5000);\n readonly loop = input(true);\n readonly hideArrows = input(true);\n readonly hideIndicators = input(true);\n readonly pauseOnHover = input(true);\n\n // Appearance.\n readonly color = input<ThemePalette>('accent');\n readonly maxWidth = input('auto');\n readonly maintainAspectRatio = input(true);\n readonly proportion = input(25);\n readonly slideHeight = input('100%');\n readonly slides = input<number>();\n\n // Accessibility.\n readonly useKeyboard = input(false);\n readonly useMouseWheel = input(false);\n readonly orientation = input<Orientation>('ltr');\n\n readonly animationStart = output<number>();\n readonly change = output<number>();\n\n readonly currentIndex = signal(0);\n\n readonly slidesList = contentChildren(MatCarouselSlideComponent);\n\n readonly visibleSlides = computed(() => {\n const slides = this.slides();\n const list = this.slidesList();\n return slides != null && slides < list.length ? list.slice(0, slides) : list;\n });\n\n readonly carouselContainerRef = viewChild.required<ElementRef<HTMLDivElement>>(\n 'carouselContainer'\n );\n readonly carouselListRef = viewChild.required<ElementRef<HTMLElement>>('carouselList');\n\n readonly translation = signal('translateX(0px)');\n\n private listKeyManager!: ListKeyManager<MatCarouselSlideComponent>;\n private timer$!: Observable<number>;\n private readonly timerStop$ = new Subject<void>();\n private animationPending = false;\n private animationTimeout: ReturnType<typeof setTimeout> | null = null;\n private pressed = false;\n private dragging = false;\n private dragStartX = 0;\n private dragStartY = 0;\n private readonly dragThreshold = 12;\n\n private readonly renderer = inject(Renderer2);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly destroyRef = inject(DestroyRef);\n private readonly injector = inject(Injector);\n\n get currentSlide(): MatCarouselSlideComponent | null {\n return this.listKeyManager?.activeItem ?? null;\n }\n\n constructor() {\n effect(() => {\n const loop = this.loop();\n this.listKeyManager?.withWrap(loop);\n });\n\n effect(() => {\n const orientation = this.orientation();\n this.listKeyManager?.withHorizontalOrientation(orientation);\n });\n\n effect(() => {\n this.maxWidth();\n this.slideTo(0);\n });\n\n effect(() => {\n this.interval();\n this.autoplay();\n this.stopTimer();\n this.startTimer();\n });\n\n this.destroyRef.onDestroy(() => {\n this.clearAnimationTimeout();\n this.listKeyManager?.destroy();\n });\n }\n\n ngAfterContentInit(): void {\n this.listKeyManager = new ListKeyManager(this.visibleSlides, this.injector)\n .withVerticalOrientation(false)\n .withHorizontalOrientation(this.orientation())\n .withWrap(this.loop());\n\n this.listKeyManager.updateActiveItem(0);\n\n this.listKeyManager.change\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(index => {\n this.currentIndex.set(index);\n this.playAnimation();\n });\n }\n\n next(): void {\n this.goto(Direction.Right);\n }\n\n previous(): void {\n this.goto(Direction.Left);\n }\n\n slideTo(index: number): void {\n this.goto(Direction.Index, index);\n }\n\n @HostListener('keyup', ['$event'])\n onKeyUp(event: KeyboardEvent): void {\n if (this.useKeyboard()) {\n this.listKeyManager?.onKeydown(event);\n }\n }\n\n @HostListener('mouseenter')\n onMouseEnter(): void {\n if (this.pauseOnHover()) {\n this.stopTimer();\n }\n }\n\n @HostListener('mouseleave')\n onMouseLeave(): void {\n if (this.pauseOnHover()) {\n this.startTimer();\n }\n }\n\n @HostListener('mousewheel', ['$event'])\n onMouseWheel(event: Event): void {\n if (this.useMouseWheel()) {\n event.preventDefault(); // prevent window to scroll\n const delta = Math.sign((event as WheelEvent).deltaY);\n\n if (delta > 0) {\n this.next();\n } else if (delta < 0) {\n this.previous();\n }\n }\n }\n\n @HostListener('window:resize')\n onResize(): void {\n // Reset carousel when window is resized\n // in order to avoid major glitches.\n this.slideTo(0);\n }\n\n @HostListener('transitionend', ['$event'])\n onTransitionEnd(event: TransitionEvent): void {\n if (\n event.target === this.carouselListRef().nativeElement &&\n event.propertyName === 'transform'\n ) {\n this.finishAnimation();\n }\n }\n\n onDragStart(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) {\n return; // only react to the primary button\n }\n this.pressed = true;\n this.dragging = false;\n this.dragStartX = event.clientX;\n this.dragStartY = event.clientY;\n }\n\n onDrag(event: PointerEvent, slideElem: HTMLElement): void {\n if (!this.pressed) {\n return;\n }\n\n const deltaX = event.clientX - this.dragStartX;\n const deltaY = event.clientY - this.dragStartY;\n\n // Begin the drag (and capture the pointer) only once the pointer has moved\n // beyond the threshold, otherwise pointerdown/up on nested elements would\n // swallow their click events.\n if (!this.dragging) {\n const isHorizontalDrag =\n Math.abs(deltaX) > this.dragThreshold && Math.abs(deltaX) > Math.abs(deltaY);\n if (!isHorizontalDrag) {\n return;\n }\n this.dragging = true;\n (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);\n }\n\n // If the vertical drag is greater, it's a drag up/down, so ignore.\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n return;\n }\n\n let adjustedDelta = deltaX;\n if (this.isOutOfBounds()) {\n adjustedDelta *= 0.2; // decelerate movement;\n }\n\n this.renderer.setStyle(slideElem, 'cursor', 'grabbing');\n this.translation.set(this.getTranslation(this.getOffset() + adjustedDelta));\n }\n\n onDragEnd(event: PointerEvent, slideElem: HTMLElement): void {\n this.pressed = false;\n if (!this.dragging) {\n return;\n }\n this.dragging = false;\n this.renderer.removeStyle(slideElem, 'cursor');\n\n const deltaX = event.clientX - this.dragStartX;\n\n if (!this.isOutOfBounds() && Math.abs(deltaX) > this.getWidth() * 0.25) {\n if (deltaX <= 0) {\n this.next();\n return;\n }\n this.previous();\n return;\n }\n this.playAnimation(); // slide back, don't change current index\n }\n\n private isOutOfBounds(): boolean {\n const sign = this.orientation() === 'rtl' ? -1 : 1;\n const listEl = this.carouselListRef().nativeElement;\n const offsetParent = listEl.offsetParent;\n const parentLeft = offsetParent ? offsetParent.getBoundingClientRect().left : 0;\n const left = sign * (listEl.getBoundingClientRect().left - parentLeft);\n const lastIndex = this.visibleSlides().length - 1;\n const width = -this.getWidth() * lastIndex;\n\n return (\n (this.listKeyManager.activeItemIndex === 0 && left >= 0) ||\n (this.listKeyManager.activeItemIndex === lastIndex && left <= width)\n );\n }\n\n private isVisible(): boolean {\n if (!isPlatformBrowser(this.platformId)) {\n return false;\n }\n\n const container = this.carouselContainerRef();\n if (!container) {\n return false;\n }\n\n const elem = container.nativeElement;\n const docViewTop = window.pageYOffset;\n const docViewBottom = docViewTop + window.innerHeight;\n const elemOffset = elem.getBoundingClientRect();\n const elemTop = docViewTop + elemOffset.top;\n const elemBottom = elemTop + elemOffset.height;\n\n return elemBottom <= docViewBottom || elemTop >= docViewTop;\n }\n\n private getOffset(): number {\n const offset = this.currentIndex() * this.getWidth();\n const sign = this.orientation() === 'rtl' ? 1 : -1;\n return sign * offset;\n }\n\n private getTranslation(offset: number): string {\n return `translateX(${offset}px)`;\n }\n\n private getWidth(): number {\n return this.carouselContainerRef().nativeElement.clientWidth;\n }\n\n private goto(direction: Direction, index?: number): void {\n if (!this.listKeyManager) {\n return;\n }\n const rtl = this.orientation() === 'rtl';\n\n switch (direction) {\n case Direction.Left:\n return rtl\n ? this.listKeyManager.setNextItemActive()\n : this.listKeyManager.setPreviousItemActive();\n case Direction.Right:\n return rtl\n ? this.listKeyManager.setPreviousItemActive()\n : this.listKeyManager.setNextItemActive();\n case Direction.Index:\n return this.listKeyManager.setActiveItem(index as number);\n }\n }\n\n private playAnimation(): void {\n this.translation.set(this.getTranslation(this.getOffset()));\n this.animationStart.emit(this.currentIndex());\n this.scheduleAnimationEnd();\n }\n\n private scheduleAnimationEnd(): void {\n this.clearAnimationTimeout();\n this.animationPending = true;\n const duration = this.getTransitionDuration(this.timings());\n this.animationTimeout = setTimeout(() => this.finishAnimation(), duration + 16);\n }\n\n private finishAnimation(): void {\n if (!this.animationPending) {\n return;\n }\n this.animationPending = false;\n this.clearAnimationTimeout();\n this.change.emit(this.currentIndex());\n }\n\n private getTransitionDuration(timings: string): number {\n const match = timings.match(/(\\d+(?:\\.\\d+)?)(ms|s)/);\n if (!match) {\n return 250;\n }\n const value = parseFloat(match[1]);\n return match[2] === 's' ? value * 1000 : value;\n }\n\n private clearAnimationTimeout(): void {\n if (this.animationTimeout != null) {\n clearTimeout(this.animationTimeout);\n this.animationTimeout = null;\n }\n }\n\n private resetTimer(): void {\n this.timer$ = interval(this.interval());\n }\n\n private startTimer(): void {\n if (!this.autoplay()) {\n return;\n }\n\n this.resetTimer();\n this.timer$\n .pipe(\n takeUntil(this.timerStop$),\n takeUntilDestroyed(this.destroyRef),\n filter(() => this.isVisible())\n )\n .subscribe(() => {\n this.listKeyManager?.withWrap(true).setNextItemActive();\n this.listKeyManager?.withWrap(this.loop());\n });\n }\n\n private stopTimer(): void {\n this.timerStop$.next(undefined);\n }\n}\n","<div\n #carouselContainer\n class=\"carousel\"\n tabindex=\"0\"\n [style.max-width]=\"maxWidth()\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n>\n <ul\n #carouselList\n class=\"carousel-list\"\n role=\"listbox\"\n [style.transform]=\"translation()\"\n [style.transition]=\"timings()\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n [style.height]=\"!maintainAspectRatio() ? '100%' : 'auto'\"\n >\n @for (slide of visibleSlides(); track slide) {\n <li\n #carouselSlide\n class=\"carousel-slide\"\n role=\"option\"\n [style.padding-bottom]=\"maintainAspectRatio() && proportion() ? proportion() + '%' : '0px'\"\n [style.height]=\"!maintainAspectRatio() && slideHeight() ? slideHeight() : '0px'\"\n (pointerdown)=\"onDragStart($event)\"\n (pointermove)=\"onDrag($event, carouselSlide)\"\n (pointerup)=\"onDragEnd($event, carouselSlide)\"\n (pointercancel)=\"onDragEnd($event, carouselSlide)\"\n >\n <ng-container [ngTemplateOutlet]=\"slide.templateRef()\"></ng-container>\n </li>\n }\n </ul>\n\n @if (!hideArrows()) {\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === 0\"\n (click)=\"previous()\"\n >\n @if (svgIconOverrides()?.arrowBack; as arrowBack) {\n <mat-icon [svgIcon]=\"arrowBack\"></mat-icon>\n } @else {\n <mat-icon>arrow_back</mat-icon>\n }\n </button>\n <button\n mat-icon-button\n type=\"button\"\n tabindex=\"-1\"\n [color]=\"color()\"\n [disabled]=\"!loop() && currentIndex() === visibleSlides().length - 1\"\n (click)=\"next()\"\n >\n @if (svgIconOverrides()?.arrowForward; as arrowForward) {\n <mat-icon [svgIcon]=\"arrowForward\"></mat-icon>\n } @else {\n <mat-icon>arrow_forward</mat-icon>\n }\n </button>\n }\n\n @if (!hideIndicators()) {\n <div\n class=\"carousel-indicators\"\n tabindex=\"-1\"\n [style.flex-direction]=\"orientation() === 'rtl' ? 'row-reverse' : 'row'\"\n >\n @for (slide of visibleSlides(); track slide; let i = $index) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n mat-mini-fab\n [color]=\"color()\"\n [disabled]=\"i === currentIndex()\"\n (click)=\"slideTo(i)\"\n (focus)=\"carouselContainer.focus()\"\n ></button>\n }\n </div>\n }\n</div>\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kovalenko/material-carousel",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"description": "Carousel component for Angular 22 using Angular Material. Standalone components and signals.",
|
|
4
|
+
"version": "22.0.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/menelai/material2-carousel.git"
|
|
8
|
+
},
|
|
9
|
+
"author": "Kovalenko",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/menelai/material2-carousel",
|
|
12
|
+
"bugs": "https://github.com/menelai/material2-carousel/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"angular",
|
|
15
|
+
"material",
|
|
16
|
+
"carousel",
|
|
17
|
+
"component",
|
|
18
|
+
"standalone",
|
|
19
|
+
"signals"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@angular/cdk": "^22.0.0",
|
|
26
|
+
"@angular/common": "^22.0.0",
|
|
27
|
+
"@angular/core": "^22.0.0",
|
|
28
|
+
"@angular/material": "^22.0.0",
|
|
29
|
+
"@angular/platform-browser": "^22.0.0",
|
|
30
|
+
"rxjs": "^7.8.1"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"tslib": "^2.8.0"
|
|
34
|
+
},
|
|
35
|
+
"module": "fesm2022/kovalenko-material-carousel.mjs",
|
|
36
|
+
"typings": "types/kovalenko-material-carousel.d.ts",
|
|
37
|
+
"exports": {
|
|
38
|
+
"./package.json": {
|
|
39
|
+
"default": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
".": {
|
|
42
|
+
"types": "./types/kovalenko-material-carousel.d.ts",
|
|
43
|
+
"default": "./fesm2022/kovalenko-material-carousel.mjs"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"type": "module"
|
|
6
48
|
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { AfterContentInit, ElementRef, TemplateRef } from "@angular/core";
|
|
3
|
+
import { ThemePalette } from "@angular/material/core";
|
|
4
|
+
import { ListKeyManagerOption } from "@angular/cdk/a11y";
|
|
5
|
+
import { SafeStyle } from "@angular/platform-browser";
|
|
6
|
+
export type Orientation = 'ltr' | 'rtl';
|
|
7
|
+
export interface SvgIconOverrides {
|
|
8
|
+
arrowBack: string;
|
|
9
|
+
arrowForward: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class MatCarouselSlideComponent implements ListKeyManagerOption {
|
|
12
|
+
readonly image: import("@angular/core").InputSignal<string | undefined>;
|
|
13
|
+
readonly overlayColor: import("@angular/core").InputSignal<string>;
|
|
14
|
+
readonly hideOverlay: import("@angular/core").InputSignal<boolean>;
|
|
15
|
+
readonly disabledInput: import("@angular/core").ModelSignal<boolean>;
|
|
16
|
+
readonly templateRef: import("@angular/core").Signal<TemplateRef<any>>;
|
|
17
|
+
private readonly sanitizer;
|
|
18
|
+
readonly backgroundImage: import("@angular/core").Signal<SafeStyle | null>;
|
|
19
|
+
get disabled(): boolean;
|
|
20
|
+
set disabled(value: boolean);
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MatCarouselSlideComponent, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MatCarouselSlideComponent, "mat-carousel-slide", never, {
|
|
23
|
+
"image": {
|
|
24
|
+
"alias": "image";
|
|
25
|
+
"required": false;
|
|
26
|
+
"isSignal": true;
|
|
27
|
+
};
|
|
28
|
+
"overlayColor": {
|
|
29
|
+
"alias": "overlayColor";
|
|
30
|
+
"required": false;
|
|
31
|
+
"isSignal": true;
|
|
32
|
+
};
|
|
33
|
+
"hideOverlay": {
|
|
34
|
+
"alias": "hideOverlay";
|
|
35
|
+
"required": false;
|
|
36
|
+
"isSignal": true;
|
|
37
|
+
};
|
|
38
|
+
"disabledInput": {
|
|
39
|
+
"alias": "disabled";
|
|
40
|
+
"required": false;
|
|
41
|
+
"isSignal": true;
|
|
42
|
+
};
|
|
43
|
+
}, {
|
|
44
|
+
"disabledInput": "disabledChange";
|
|
45
|
+
}, never, ["*"], true, never>;
|
|
46
|
+
}
|
|
47
|
+
export declare class MatCarouselComponent implements AfterContentInit {
|
|
48
|
+
readonly timings: import("@angular/core").InputSignal<string>;
|
|
49
|
+
readonly svgIconOverrides: import("@angular/core").InputSignal<SvgIconOverrides | undefined>;
|
|
50
|
+
readonly autoplay: import("@angular/core").InputSignal<boolean>;
|
|
51
|
+
readonly interval: import("@angular/core").InputSignal<number>;
|
|
52
|
+
readonly loop: import("@angular/core").InputSignal<boolean>;
|
|
53
|
+
readonly hideArrows: import("@angular/core").InputSignal<boolean>;
|
|
54
|
+
readonly hideIndicators: import("@angular/core").InputSignal<boolean>;
|
|
55
|
+
readonly pauseOnHover: import("@angular/core").InputSignal<boolean>;
|
|
56
|
+
readonly color: import("@angular/core").InputSignal<ThemePalette>;
|
|
57
|
+
readonly maxWidth: import("@angular/core").InputSignal<string>;
|
|
58
|
+
readonly maintainAspectRatio: import("@angular/core").InputSignal<boolean>;
|
|
59
|
+
readonly proportion: import("@angular/core").InputSignal<number>;
|
|
60
|
+
readonly slideHeight: import("@angular/core").InputSignal<string>;
|
|
61
|
+
readonly slides: import("@angular/core").InputSignal<number | undefined>;
|
|
62
|
+
readonly useKeyboard: import("@angular/core").InputSignal<boolean>;
|
|
63
|
+
readonly useMouseWheel: import("@angular/core").InputSignal<boolean>;
|
|
64
|
+
readonly orientation: import("@angular/core").InputSignal<Orientation>;
|
|
65
|
+
readonly animationStart: import("@angular/core").OutputEmitterRef<number>;
|
|
66
|
+
readonly change: import("@angular/core").OutputEmitterRef<number>;
|
|
67
|
+
readonly currentIndex: import("@angular/core").WritableSignal<number>;
|
|
68
|
+
readonly slidesList: import("@angular/core").Signal<readonly MatCarouselSlideComponent[]>;
|
|
69
|
+
readonly visibleSlides: import("@angular/core").Signal<readonly MatCarouselSlideComponent[]>;
|
|
70
|
+
readonly carouselContainerRef: import("@angular/core").Signal<ElementRef<HTMLDivElement>>;
|
|
71
|
+
readonly carouselListRef: import("@angular/core").Signal<ElementRef<HTMLElement>>;
|
|
72
|
+
readonly translation: import("@angular/core").WritableSignal<string>;
|
|
73
|
+
private listKeyManager;
|
|
74
|
+
private timer$;
|
|
75
|
+
private readonly timerStop$;
|
|
76
|
+
private animationPending;
|
|
77
|
+
private animationTimeout;
|
|
78
|
+
private pressed;
|
|
79
|
+
private dragging;
|
|
80
|
+
private dragStartX;
|
|
81
|
+
private dragStartY;
|
|
82
|
+
private readonly dragThreshold;
|
|
83
|
+
private readonly renderer;
|
|
84
|
+
private readonly platformId;
|
|
85
|
+
private readonly destroyRef;
|
|
86
|
+
private readonly injector;
|
|
87
|
+
get currentSlide(): MatCarouselSlideComponent | null;
|
|
88
|
+
constructor();
|
|
89
|
+
ngAfterContentInit(): void;
|
|
90
|
+
next(): void;
|
|
91
|
+
previous(): void;
|
|
92
|
+
slideTo(index: number): void;
|
|
93
|
+
onKeyUp(event: KeyboardEvent): void;
|
|
94
|
+
onMouseEnter(): void;
|
|
95
|
+
onMouseLeave(): void;
|
|
96
|
+
onMouseWheel(event: Event): void;
|
|
97
|
+
onResize(): void;
|
|
98
|
+
onTransitionEnd(event: TransitionEvent): void;
|
|
99
|
+
onDragStart(event: PointerEvent): void;
|
|
100
|
+
onDrag(event: PointerEvent, slideElem: HTMLElement): void;
|
|
101
|
+
onDragEnd(event: PointerEvent, slideElem: HTMLElement): void;
|
|
102
|
+
private isOutOfBounds;
|
|
103
|
+
private isVisible;
|
|
104
|
+
private getOffset;
|
|
105
|
+
private getTranslation;
|
|
106
|
+
private getWidth;
|
|
107
|
+
private goto;
|
|
108
|
+
private playAnimation;
|
|
109
|
+
private scheduleAnimationEnd;
|
|
110
|
+
private finishAnimation;
|
|
111
|
+
private getTransitionDuration;
|
|
112
|
+
private clearAnimationTimeout;
|
|
113
|
+
private resetTimer;
|
|
114
|
+
private startTimer;
|
|
115
|
+
private stopTimer;
|
|
116
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MatCarouselComponent, never>;
|
|
117
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MatCarouselComponent, "mat-carousel", never, {
|
|
118
|
+
"timings": {
|
|
119
|
+
"alias": "timings";
|
|
120
|
+
"required": false;
|
|
121
|
+
"isSignal": true;
|
|
122
|
+
};
|
|
123
|
+
"svgIconOverrides": {
|
|
124
|
+
"alias": "svgIconOverrides";
|
|
125
|
+
"required": false;
|
|
126
|
+
"isSignal": true;
|
|
127
|
+
};
|
|
128
|
+
"autoplay": {
|
|
129
|
+
"alias": "autoplay";
|
|
130
|
+
"required": false;
|
|
131
|
+
"isSignal": true;
|
|
132
|
+
};
|
|
133
|
+
"interval": {
|
|
134
|
+
"alias": "interval";
|
|
135
|
+
"required": false;
|
|
136
|
+
"isSignal": true;
|
|
137
|
+
};
|
|
138
|
+
"loop": {
|
|
139
|
+
"alias": "loop";
|
|
140
|
+
"required": false;
|
|
141
|
+
"isSignal": true;
|
|
142
|
+
};
|
|
143
|
+
"hideArrows": {
|
|
144
|
+
"alias": "hideArrows";
|
|
145
|
+
"required": false;
|
|
146
|
+
"isSignal": true;
|
|
147
|
+
};
|
|
148
|
+
"hideIndicators": {
|
|
149
|
+
"alias": "hideIndicators";
|
|
150
|
+
"required": false;
|
|
151
|
+
"isSignal": true;
|
|
152
|
+
};
|
|
153
|
+
"pauseOnHover": {
|
|
154
|
+
"alias": "pauseOnHover";
|
|
155
|
+
"required": false;
|
|
156
|
+
"isSignal": true;
|
|
157
|
+
};
|
|
158
|
+
"color": {
|
|
159
|
+
"alias": "color";
|
|
160
|
+
"required": false;
|
|
161
|
+
"isSignal": true;
|
|
162
|
+
};
|
|
163
|
+
"maxWidth": {
|
|
164
|
+
"alias": "maxWidth";
|
|
165
|
+
"required": false;
|
|
166
|
+
"isSignal": true;
|
|
167
|
+
};
|
|
168
|
+
"maintainAspectRatio": {
|
|
169
|
+
"alias": "maintainAspectRatio";
|
|
170
|
+
"required": false;
|
|
171
|
+
"isSignal": true;
|
|
172
|
+
};
|
|
173
|
+
"proportion": {
|
|
174
|
+
"alias": "proportion";
|
|
175
|
+
"required": false;
|
|
176
|
+
"isSignal": true;
|
|
177
|
+
};
|
|
178
|
+
"slideHeight": {
|
|
179
|
+
"alias": "slideHeight";
|
|
180
|
+
"required": false;
|
|
181
|
+
"isSignal": true;
|
|
182
|
+
};
|
|
183
|
+
"slides": {
|
|
184
|
+
"alias": "slides";
|
|
185
|
+
"required": false;
|
|
186
|
+
"isSignal": true;
|
|
187
|
+
};
|
|
188
|
+
"useKeyboard": {
|
|
189
|
+
"alias": "useKeyboard";
|
|
190
|
+
"required": false;
|
|
191
|
+
"isSignal": true;
|
|
192
|
+
};
|
|
193
|
+
"useMouseWheel": {
|
|
194
|
+
"alias": "useMouseWheel";
|
|
195
|
+
"required": false;
|
|
196
|
+
"isSignal": true;
|
|
197
|
+
};
|
|
198
|
+
"orientation": {
|
|
199
|
+
"alias": "orientation";
|
|
200
|
+
"required": false;
|
|
201
|
+
"isSignal": true;
|
|
202
|
+
};
|
|
203
|
+
}, {
|
|
204
|
+
"animationStart": "animationStart";
|
|
205
|
+
"change": "change";
|
|
206
|
+
}, ["slidesList"], never, true, never>;
|
|
207
|
+
}
|