wally-ui 1.8.0 → 1.9.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/package.json +1 -1
- package/playground/showcase/src/app/components/carousel/carousel.html +39 -25
- package/playground/showcase/src/app/components/carousel/carousel.ts +80 -104
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.examples.ts +99 -15
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.html +475 -46
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.ts +13 -1
package/package.json
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
|
-
<div class="w-full flex flex-col items-center gap-4">
|
|
2
|
-
<div class="
|
|
3
|
-
<
|
|
4
|
-
|
|
1
|
+
<div class="w-full h-full flex flex-col items-center gap-4 p-2">
|
|
2
|
+
<div class="w-full h-full flex items-center gap-3">
|
|
3
|
+
<div>
|
|
4
|
+
<button type="button"
|
|
5
|
+
class="group hidden sm:block bg-neutral-100 hover:bg-neutral-200 border-2 border-neutral-200 hover:border-neutral-300 dark:bg-[#1b1b1b] dark:hover:bg-[#1d1d1d] dark:border-neutral-700 hover:dark:border-neutral-600 p-2 rounded-full cursor-pointer transition-all duration-500 ease-in-out"
|
|
6
|
+
(click)="navigateToPreviousItem()" aria-label="Go to previous slide">
|
|
7
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
class="size-5 text-neutral-500 dark:text-neutral-300 group-hover:dark:text-white transition-all duration-500 ease-in-out">
|
|
10
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
|
|
11
|
+
</svg>
|
|
12
|
+
</button>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="relative w-full h-full overflow-hidden p-2 shadow rounded-lg" #carouselContainer>
|
|
16
|
+
<ng-content></ng-content>
|
|
17
|
+
</div>
|
|
5
18
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
[attr.aria-label]="'Navigate to slide ' + (dotIndex + 1)">
|
|
19
|
+
<div>
|
|
20
|
+
<button type="button"
|
|
21
|
+
class="group hidden sm:block bg-neutral-100 hover:bg-neutral-200 border-2 border-neutral-200 hover:border-neutral-300 dark:bg-[#1b1b1b] dark:hover:bg-[#1d1d1d] dark:border-neutral-700 hover:dark:border-neutral-600 p-2 rounded-full cursor-pointer transition-all duration-500 ease-in-out"
|
|
22
|
+
(click)="navigateToNextItem()" aria-label="Go to next slide">
|
|
23
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
|
24
|
+
stroke="currentColor"
|
|
25
|
+
class="size-5 text-neutral-500 dark:text-neutral-300 group-hover:dark:text-white transition-all duration-500 ease-in-out">
|
|
26
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
|
|
27
|
+
</svg>
|
|
16
28
|
</button>
|
|
17
|
-
|
|
29
|
+
</div>
|
|
18
30
|
</div>
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
@if (isNavigationIndicator()) {
|
|
33
|
+
<div class="flex items-center gap-2">
|
|
34
|
+
@for (navigationIndicator of navigationIndicatorsArray; track $index; let indicatorIndex = $index) {
|
|
35
|
+
<button type="button"
|
|
36
|
+
class="w-3.5 h-1.5 rounded-sm transition-all duration-500 ease-in-out cursor-pointer focus:outline-none focus:ring-0 active:outline-none"
|
|
37
|
+
[ngClass]="{
|
|
38
|
+
'bg-blue-500': indicatorIndex === currentVisibleItemIndex(),
|
|
39
|
+
'bg-neutral-300 hover:bg-neutral-400 hover:scale-105 dark:bg-neutral-700': indicatorIndex !== currentVisibleItemIndex()
|
|
40
|
+
}" (click)="navigateToSpecificItem(indicatorIndex)"
|
|
41
|
+
[attr.aria-label]="'Navigate to slide ' + (indicatorIndex + 1)">
|
|
30
42
|
</button>
|
|
43
|
+
}
|
|
31
44
|
</div>
|
|
45
|
+
}
|
|
32
46
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component,
|
|
1
|
+
import { Component, signal, ViewChild, ElementRef, AfterViewInit, Renderer2, OnDestroy, HostListener, WritableSignal, input, InputSignal } from '@angular/core';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
|
|
4
4
|
@Component({
|
|
@@ -6,14 +6,14 @@ import { CommonModule } from '@angular/common';
|
|
|
6
6
|
imports: [CommonModule],
|
|
7
7
|
templateUrl: './carousel.html',
|
|
8
8
|
})
|
|
9
|
-
export class Carousel implements
|
|
9
|
+
export class Carousel implements AfterViewInit, OnDestroy {
|
|
10
10
|
@ViewChild('carouselContainer', { static: false }) carouselContainer!: ElementRef;
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
isNavigationIndicator: InputSignal<boolean> = input<boolean>(false);
|
|
13
|
+
totalItemsCount: WritableSignal<number> = signal<number>(0);
|
|
14
|
+
currentVisibleItemIndex: WritableSignal<number> = signal<number>(0);
|
|
14
15
|
carouselItemElements: HTMLElement[] = [];
|
|
15
16
|
|
|
16
|
-
// Touch and swipe gesture state
|
|
17
17
|
private gestureState = {
|
|
18
18
|
startPositionX: 0,
|
|
19
19
|
startPositionY: 0,
|
|
@@ -23,22 +23,19 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
23
23
|
gestureStartTime: 0
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
private readonly
|
|
28
|
-
private readonly
|
|
29
|
-
private readonly MAXIMUM_SWIPE_DURATION = 300; // maximum milliseconds for swipe gesture
|
|
26
|
+
private readonly MINIMUM_SWIPE_DISTANCE = 50;
|
|
27
|
+
private readonly MINIMUM_SWIPE_VELOCITY = 0.3;
|
|
28
|
+
private readonly MAXIMUM_SWIPE_DURATION = 300;
|
|
30
29
|
|
|
31
|
-
// Event listener cleanup functions
|
|
32
30
|
private eventListenerCleanupFunctions: (() => void)[] = [];
|
|
33
31
|
|
|
34
|
-
get
|
|
32
|
+
get navigationIndicatorsArray() {
|
|
35
33
|
return Array(this.totalItemsCount()).fill(0);
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
constructor(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
36
|
+
constructor(
|
|
37
|
+
private renderer: Renderer2
|
|
38
|
+
) { }
|
|
42
39
|
|
|
43
40
|
ngAfterViewInit(): void {
|
|
44
41
|
if (this.carouselContainer) {
|
|
@@ -49,16 +46,76 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
ngOnDestroy(): void {
|
|
52
|
-
// Clean up all event listeners to prevent memory leaks
|
|
53
49
|
this.eventListenerCleanupFunctions.forEach(cleanupFunction => cleanupFunction());
|
|
54
50
|
}
|
|
55
51
|
|
|
52
|
+
calculateNextItemIndex(currentItemIndex: number): number {
|
|
53
|
+
return (currentItemIndex + 1) % this.totalItemsCount();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
calculatePreviousItemIndex(currentItemIndex: number): number {
|
|
57
|
+
return (currentItemIndex - 1 + this.totalItemsCount()) % this.totalItemsCount();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
navigateToNextItem(): void {
|
|
61
|
+
this.currentVisibleItemIndex.set(this.calculateNextItemIndex(this.currentVisibleItemIndex()));
|
|
62
|
+
this.updateAllItemElementPositions();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
navigateToPreviousItem(): void {
|
|
66
|
+
this.currentVisibleItemIndex.set(this.calculatePreviousItemIndex(this.currentVisibleItemIndex()));
|
|
67
|
+
this.updateAllItemElementPositions();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
navigateToSpecificItem(targetItemIndex: number): void {
|
|
71
|
+
this.currentVisibleItemIndex.set(targetItemIndex);
|
|
72
|
+
this.updateAllItemElementPositions();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
updateItemElementPosition(carouselItemElement: HTMLElement, itemIndex: number): void {
|
|
76
|
+
const currentVisibleIndex = this.currentVisibleItemIndex();
|
|
77
|
+
|
|
78
|
+
if (itemIndex === currentVisibleIndex) {
|
|
79
|
+
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(0)');
|
|
80
|
+
} else if (itemIndex > currentVisibleIndex) {
|
|
81
|
+
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(110%)');
|
|
82
|
+
} else {
|
|
83
|
+
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(-110%)');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
updateAllItemElementPositions(): void {
|
|
88
|
+
this.carouselItemElements.forEach((itemElement, itemIndex) => {
|
|
89
|
+
this.updateItemElementPosition(itemElement, itemIndex);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@HostListener('keydown', ['$event'])
|
|
94
|
+
handleKeyboardNavigation(keyboardEvent: KeyboardEvent): void {
|
|
95
|
+
switch (keyboardEvent.key) {
|
|
96
|
+
case 'ArrowLeft':
|
|
97
|
+
keyboardEvent.preventDefault();
|
|
98
|
+
this.navigateToPreviousItem();
|
|
99
|
+
break;
|
|
100
|
+
case 'ArrowRight':
|
|
101
|
+
keyboardEvent.preventDefault();
|
|
102
|
+
this.navigateToNextItem();
|
|
103
|
+
break;
|
|
104
|
+
case 'Home':
|
|
105
|
+
keyboardEvent.preventDefault();
|
|
106
|
+
this.navigateToSpecificItem(0);
|
|
107
|
+
break;
|
|
108
|
+
case 'End':
|
|
109
|
+
keyboardEvent.preventDefault();
|
|
110
|
+
this.navigateToSpecificItem(this.totalItemsCount() - 1);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
56
115
|
private initializeCarouselItems(): void {
|
|
57
|
-
// Get all direct children elements of the carousel container
|
|
58
116
|
this.carouselItemElements = Array.from(this.carouselContainer.nativeElement.children);
|
|
59
117
|
this.totalItemsCount.set(this.carouselItemElements.length);
|
|
60
118
|
|
|
61
|
-
// Apply positioning and styling to each carousel item using Renderer2
|
|
62
119
|
this.carouselItemElements.forEach((itemElement, itemIndex) => {
|
|
63
120
|
this.renderer.setStyle(itemElement, 'position', 'absolute');
|
|
64
121
|
this.renderer.setStyle(itemElement, 'inset', '0');
|
|
@@ -73,18 +130,15 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
73
130
|
private setupTouchAndMouseEvents(): void {
|
|
74
131
|
const carouselContainerElement = this.carouselContainer.nativeElement;
|
|
75
132
|
|
|
76
|
-
// Touch events for mobile devices
|
|
77
133
|
const touchStartListener = this.renderer.listen(carouselContainerElement, 'touchstart', (event) => this.handleTouchStart(event));
|
|
78
134
|
const touchMoveListener = this.renderer.listen(carouselContainerElement, 'touchmove', (event) => this.handleTouchMove(event));
|
|
79
135
|
const touchEndListener = this.renderer.listen(carouselContainerElement, 'touchend', () => this.handleTouchEnd());
|
|
80
136
|
|
|
81
|
-
// Mouse events for desktop devices
|
|
82
137
|
const mouseDownListener = this.renderer.listen(carouselContainerElement, 'mousedown', (event) => this.handleMouseDown(event));
|
|
83
138
|
const mouseMoveListener = this.renderer.listen(carouselContainerElement, 'mousemove', (event) => this.handleMouseMove(event));
|
|
84
139
|
const mouseUpListener = this.renderer.listen(carouselContainerElement, 'mouseup', () => this.handleMouseUp());
|
|
85
140
|
const mouseLeaveListener = this.renderer.listen(carouselContainerElement, 'mouseleave', () => this.handleMouseUp());
|
|
86
141
|
|
|
87
|
-
// Store all cleanup functions for proper memory management
|
|
88
142
|
this.eventListenerCleanupFunctions.push(
|
|
89
143
|
touchStartListener,
|
|
90
144
|
touchMoveListener,
|
|
@@ -95,48 +149,24 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
95
149
|
mouseLeaveListener
|
|
96
150
|
);
|
|
97
151
|
|
|
98
|
-
// Optimize touch performance by restricting to horizontal panning only
|
|
99
152
|
this.renderer.setStyle(carouselContainerElement, 'touch-action', 'pan-x');
|
|
100
153
|
}
|
|
101
154
|
|
|
102
155
|
private setupAccessibilityAttributes(): void {
|
|
103
156
|
const carouselContainerElement = this.carouselContainer.nativeElement;
|
|
104
157
|
|
|
105
|
-
// Set ARIA attributes for screen readers and accessibility
|
|
106
158
|
this.renderer.setAttribute(carouselContainerElement, 'role', 'region');
|
|
107
159
|
this.renderer.setAttribute(carouselContainerElement, 'aria-label', 'Carousel');
|
|
108
160
|
this.renderer.setAttribute(carouselContainerElement, 'tabindex', '0');
|
|
109
161
|
}
|
|
110
162
|
|
|
111
|
-
updateItemElementPosition(carouselItemElement: HTMLElement, itemIndex: number): void {
|
|
112
|
-
const currentVisibleIndex = this.currentVisibleItemIndex();
|
|
113
|
-
|
|
114
|
-
if (itemIndex === currentVisibleIndex) {
|
|
115
|
-
// Position the currently visible item at center (0% translation)
|
|
116
|
-
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(0)');
|
|
117
|
-
} else if (itemIndex > currentVisibleIndex) {
|
|
118
|
-
// Position items to the right of current item (110% translation to the right)
|
|
119
|
-
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(110%)');
|
|
120
|
-
} else {
|
|
121
|
-
// Position items to the left of current item (110% translation to the left)
|
|
122
|
-
this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(-110%)');
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
updateAllItemElementPositions(): void {
|
|
127
|
-
this.carouselItemElements.forEach((itemElement, itemIndex) => {
|
|
128
|
-
this.updateItemElementPosition(itemElement, itemIndex);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Touch event handlers for mobile devices
|
|
133
163
|
private handleTouchStart(touchEvent: TouchEvent): void {
|
|
134
164
|
this.initializeGesture(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
private handleTouchMove(touchEvent: TouchEvent): void {
|
|
138
168
|
if (this.gestureState.isCurrentlyDragging) {
|
|
139
|
-
touchEvent.preventDefault();
|
|
169
|
+
touchEvent.preventDefault();
|
|
140
170
|
this.updateGesturePosition(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
|
|
141
171
|
}
|
|
142
172
|
}
|
|
@@ -145,14 +175,13 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
145
175
|
this.finalizeGestureAndNavigate();
|
|
146
176
|
}
|
|
147
177
|
|
|
148
|
-
// Mouse event handlers for desktop devices
|
|
149
178
|
private handleMouseDown(mouseEvent: MouseEvent): void {
|
|
150
179
|
this.initializeGesture(mouseEvent.clientX, mouseEvent.clientY);
|
|
151
180
|
}
|
|
152
181
|
|
|
153
182
|
private handleMouseMove(mouseEvent: MouseEvent): void {
|
|
154
183
|
if (this.gestureState.isCurrentlyDragging) {
|
|
155
|
-
mouseEvent.preventDefault();
|
|
184
|
+
mouseEvent.preventDefault();
|
|
156
185
|
this.updateGesturePosition(mouseEvent.clientX, mouseEvent.clientY);
|
|
157
186
|
}
|
|
158
187
|
}
|
|
@@ -161,7 +190,6 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
161
190
|
this.finalizeGestureAndNavigate();
|
|
162
191
|
}
|
|
163
192
|
|
|
164
|
-
// Unified gesture handling methods
|
|
165
193
|
private initializeGesture(xPosition: number, yPosition: number): void {
|
|
166
194
|
this.gestureState = {
|
|
167
195
|
startPositionX: xPosition,
|
|
@@ -188,70 +216,18 @@ export class Carousel implements OnInit, AfterViewInit, OnDestroy {
|
|
|
188
216
|
const gestureDuration = Date.now() - this.gestureState.gestureStartTime;
|
|
189
217
|
const gestureVelocity = Math.abs(horizontalDistanceMoved) / gestureDuration;
|
|
190
218
|
|
|
191
|
-
// Only process horizontal swipes (ignore vertical movements)
|
|
192
219
|
if (Math.abs(horizontalDistanceMoved) > Math.abs(verticalDistanceMoved)) {
|
|
193
|
-
// Check if gesture meets minimum requirements for navigation
|
|
194
220
|
const isValidSwipeGesture = Math.abs(horizontalDistanceMoved) > this.MINIMUM_SWIPE_DISTANCE ||
|
|
195
221
|
(gestureVelocity > this.MINIMUM_SWIPE_VELOCITY && gestureDuration < this.MAXIMUM_SWIPE_DURATION);
|
|
196
222
|
|
|
197
223
|
if (isValidSwipeGesture) {
|
|
198
224
|
if (horizontalDistanceMoved > 0) {
|
|
199
|
-
this.navigateToPreviousItem();
|
|
225
|
+
this.navigateToPreviousItem();
|
|
200
226
|
} else {
|
|
201
|
-
this.navigateToNextItem();
|
|
227
|
+
this.navigateToNextItem();
|
|
202
228
|
}
|
|
203
229
|
}
|
|
204
230
|
}
|
|
205
|
-
|
|
206
|
-
// Reset gesture state after processing
|
|
207
231
|
this.gestureState.isCurrentlyDragging = false;
|
|
208
232
|
}
|
|
209
|
-
|
|
210
|
-
// Keyboard navigation handler
|
|
211
|
-
@HostListener('keydown', ['$event'])
|
|
212
|
-
handleKeyboardNavigation(keyboardEvent: KeyboardEvent): void {
|
|
213
|
-
switch (keyboardEvent.key) {
|
|
214
|
-
case 'ArrowLeft':
|
|
215
|
-
keyboardEvent.preventDefault();
|
|
216
|
-
this.navigateToPreviousItem();
|
|
217
|
-
break;
|
|
218
|
-
case 'ArrowRight':
|
|
219
|
-
keyboardEvent.preventDefault();
|
|
220
|
-
this.navigateToNextItem();
|
|
221
|
-
break;
|
|
222
|
-
case 'Home':
|
|
223
|
-
keyboardEvent.preventDefault();
|
|
224
|
-
this.navigateToSpecificItem(0);
|
|
225
|
-
break;
|
|
226
|
-
case 'End':
|
|
227
|
-
keyboardEvent.preventDefault();
|
|
228
|
-
this.navigateToSpecificItem(this.totalItemsCount() - 1);
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Circular buffer algorithm implementation for infinite carousel navigation
|
|
234
|
-
calculateNextItemIndex(currentItemIndex: number): number {
|
|
235
|
-
return (currentItemIndex + 1) % this.totalItemsCount();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
calculatePreviousItemIndex(currentItemIndex: number): number {
|
|
239
|
-
return (currentItemIndex - 1 + this.totalItemsCount()) % this.totalItemsCount();
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
navigateToNextItem(): void {
|
|
243
|
-
this.currentVisibleItemIndex.set(this.calculateNextItemIndex(this.currentVisibleItemIndex()));
|
|
244
|
-
this.updateAllItemElementPositions();
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
navigateToPreviousItem(): void {
|
|
248
|
-
this.currentVisibleItemIndex.set(this.calculatePreviousItemIndex(this.currentVisibleItemIndex()));
|
|
249
|
-
this.updateAllItemElementPositions();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
navigateToSpecificItem(targetItemIndex: number): void {
|
|
253
|
-
this.currentVisibleItemIndex.set(targetItemIndex);
|
|
254
|
-
this.updateAllItemElementPositions();
|
|
255
|
-
}
|
|
256
|
-
// end test Circular Buffer ---
|
|
257
|
-
}
|
|
233
|
+
}
|
|
@@ -18,6 +18,45 @@ export const CarouselCodeExamples = {
|
|
|
18
18
|
<div>Item 2</div>
|
|
19
19
|
</wally-carousel>`,
|
|
20
20
|
|
|
21
|
+
// With navigation indicators
|
|
22
|
+
withNavigationIndicators: `<wally-carousel [isNavigationIndicator]="true">
|
|
23
|
+
<div>Item 1</div>
|
|
24
|
+
<div>Item 2</div>
|
|
25
|
+
</wally-carousel>`,
|
|
26
|
+
|
|
27
|
+
// Image carousel
|
|
28
|
+
imageCarousel: `<div class="w-full h-80">
|
|
29
|
+
<wally-carousel>
|
|
30
|
+
<div class="w-full h-full">
|
|
31
|
+
<img src="/api/placeholder/600/320" alt="Image 1" class="w-full h-full object-cover">
|
|
32
|
+
</div>
|
|
33
|
+
<div class="w-full h-full">
|
|
34
|
+
<img src="/api/placeholder/600/320" alt="Image 2" class="w-full h-full object-cover">
|
|
35
|
+
</div>
|
|
36
|
+
<div class="w-full h-full">
|
|
37
|
+
<img src="/api/placeholder/600/320" alt="Image 3" class="w-full h-full object-cover">
|
|
38
|
+
</div>
|
|
39
|
+
</wally-carousel>
|
|
40
|
+
</div>`,
|
|
41
|
+
|
|
42
|
+
// Product showcase
|
|
43
|
+
productShowcase: `<div class="w-full h-96">
|
|
44
|
+
<wally-carousel>
|
|
45
|
+
<div class="w-full h-full bg-white border-2 border-gray-200 rounded-lg p-6 flex flex-col items-center justify-center">
|
|
46
|
+
<div class="w-20 h-20 bg-blue-500 rounded-lg mb-4"></div>
|
|
47
|
+
<h3 class="text-lg font-semibold text-gray-900">Product A</h3>
|
|
48
|
+
<p class="text-gray-600 text-center">Amazing features and benefits</p>
|
|
49
|
+
<span class="text-xl font-bold text-blue-600 mt-2">$99</span>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="w-full h-full bg-white border-2 border-gray-200 rounded-lg p-6 flex flex-col items-center justify-center">
|
|
52
|
+
<div class="w-20 h-20 bg-green-500 rounded-lg mb-4"></div>
|
|
53
|
+
<h3 class="text-lg font-semibold text-gray-900">Product B</h3>
|
|
54
|
+
<p class="text-gray-600 text-center">Premium quality guaranteed</p>
|
|
55
|
+
<span class="text-xl font-bold text-green-600 mt-2">$149</span>
|
|
56
|
+
</div>
|
|
57
|
+
</wally-carousel>
|
|
58
|
+
</div>`,
|
|
59
|
+
|
|
21
60
|
// Custom content example
|
|
22
61
|
customContent: `<wally-carousel>
|
|
23
62
|
<div class="w-full h-full bg-gradient-to-r from-blue-500 to-purple-600 text-white flex flex-col items-center justify-center p-6">
|
|
@@ -30,19 +69,64 @@ export const CarouselCodeExamples = {
|
|
|
30
69
|
</div>
|
|
31
70
|
</wally-carousel>`,
|
|
32
71
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
72
|
+
// Responsive design example
|
|
73
|
+
responsiveExample: `<!-- Different sizes for different use cases -->
|
|
74
|
+
|
|
75
|
+
<!-- Hero carousel - full width, tall -->
|
|
76
|
+
<div class="w-full h-96">
|
|
77
|
+
<wally-carousel>
|
|
78
|
+
<div>Hero slide 1</div>
|
|
79
|
+
<div>Hero slide 2</div>
|
|
80
|
+
</wally-carousel>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<!-- Product gallery - square aspect ratio -->
|
|
84
|
+
<div class="w-full aspect-square max-w-md">
|
|
85
|
+
<wally-carousel>
|
|
86
|
+
<div>Product image 1</div>
|
|
87
|
+
<div>Product image 2</div>
|
|
88
|
+
</wally-carousel>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<!-- Mobile testimonials - compact -->
|
|
92
|
+
<div class="w-full h-48 sm:h-64">
|
|
93
|
+
<wally-carousel>
|
|
94
|
+
<div>Testimonial 1</div>
|
|
95
|
+
<div>Testimonial 2</div>
|
|
96
|
+
</wally-carousel>
|
|
97
|
+
</div>`,
|
|
98
|
+
|
|
99
|
+
// Individual properties
|
|
100
|
+
propertyIsNavigationIndicator: `isNavigationIndicator: InputSignal<boolean> = input<boolean>(false);`,
|
|
101
|
+
propertyTotalItemsCount: `totalItemsCount: number (read-only);`,
|
|
102
|
+
propertyCurrentVisibleItemIndex: `currentVisibleItemIndex: number (read-only);`,
|
|
103
|
+
propertyNavigationIndicatorsArray: `navigationIndicatorsArray: any[] (read-only);`,
|
|
104
|
+
|
|
105
|
+
// API Methods
|
|
106
|
+
apiMethods: `// Public navigation methods
|
|
107
|
+
navigateToNextItem(): void; // Go to next slide
|
|
108
|
+
navigateToPreviousItem(): void; // Go to previous slide
|
|
109
|
+
navigateToSpecificItem(index: number): void; // Jump to specific slide
|
|
110
|
+
|
|
111
|
+
// Public calculation methods
|
|
112
|
+
calculateNextItemIndex(current: number): number; // Get next index
|
|
113
|
+
calculatePreviousItemIndex(current: number): number; // Get previous index
|
|
114
|
+
|
|
115
|
+
// Public positioning methods
|
|
116
|
+
updateItemElementPosition(element: HTMLElement, index: number): void;
|
|
117
|
+
updateAllItemElementPositions(): void;`,
|
|
118
|
+
|
|
119
|
+
// Keyboard shortcuts
|
|
120
|
+
keyboardShortcuts: `// Keyboard navigation (when carousel is focused)
|
|
121
|
+
ArrowLeft → Previous slide
|
|
122
|
+
ArrowRight → Next slide
|
|
123
|
+
Home → First slide
|
|
124
|
+
End → Last slide`,
|
|
125
|
+
|
|
126
|
+
// Touch gestures
|
|
127
|
+
touchGestures: `// Touch and mouse gestures
|
|
128
|
+
Swipe Left → Next slide
|
|
129
|
+
Swipe Right → Previous slide
|
|
130
|
+
Click Dots → Jump to specific slide
|
|
131
|
+
Drag → Same as swipe (desktop)`
|
|
48
132
|
};
|
package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.html
CHANGED
|
@@ -7,18 +7,10 @@
|
|
|
7
7
|
<h1 class="text-2xl font-bold mb-4 text-[#0a0a0a] dark:text-white">
|
|
8
8
|
Carousel
|
|
9
9
|
</h1>
|
|
10
|
-
<p class="text-gray-700 dark:text-gray-400 mb-
|
|
11
|
-
A carousel component with navigation controls, touch gestures, and smooth transitions.
|
|
10
|
+
<p class="text-gray-700 dark:text-gray-400 mb-6">
|
|
11
|
+
A fully responsive carousel component with navigation controls, touch/swipe gestures, keyboard accessibility, and smooth transitions. Built with comprehensive accessibility features and optimized performance.
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
<!-- Under Construction Badge -->
|
|
15
|
-
<div class="mb-6">
|
|
16
|
-
<span class="text-xs bg-yellow-500 text-black px-3 py-1 rounded-full font-medium">Under Construction</span>
|
|
17
|
-
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2">
|
|
18
|
-
This component is actively being developed. Touch gestures, accessibility, and customization options are coming soon.
|
|
19
|
-
</p>
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
14
|
<!-- AI Prompts -->
|
|
23
15
|
<div class="flex flex-wrap gap-2 mb-6">
|
|
24
16
|
<a [href]="claudeUrl" target="_blank"
|
|
@@ -63,17 +55,20 @@
|
|
|
63
55
|
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Preview</h2>
|
|
64
56
|
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
65
57
|
<div class="flex justify-center">
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
58
|
+
<div class="w-96 h-96">
|
|
59
|
+
<wally-carousel>
|
|
60
|
+
<div class="w-full h-full bg-blue-500 text-white flex items-center justify-center text-lg font-semibold">
|
|
61
|
+
Slide 1
|
|
62
|
+
</div>
|
|
63
|
+
<div class="w-full h-full bg-green-500 text-white flex items-center justify-center text-lg font-semibold">
|
|
64
|
+
Slide 2
|
|
65
|
+
</div>
|
|
66
|
+
<div
|
|
67
|
+
class="w-full h-full bg-purple-500 text-white flex items-center justify-center text-lg font-semibold">
|
|
68
|
+
Slide 3
|
|
69
|
+
</div>
|
|
70
|
+
</wally-carousel>
|
|
71
|
+
</div>
|
|
77
72
|
</div>
|
|
78
73
|
</div>
|
|
79
74
|
</section>
|
|
@@ -95,23 +90,96 @@
|
|
|
95
90
|
<!-- Basic Usage -->
|
|
96
91
|
<section class="mb-8">
|
|
97
92
|
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Basic Usage</h2>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
</
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
93
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
94
|
+
Simple carousel setup - just wrap your content elements. No configuration required.
|
|
95
|
+
</p>
|
|
96
|
+
|
|
97
|
+
<!-- Simple Example -->
|
|
98
|
+
<div class="mb-8">
|
|
99
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Simple Carousel</h3>
|
|
100
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
101
|
+
<pre><code [innerHTML]="basicUsageCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
104
|
+
<div class="flex justify-center">
|
|
105
|
+
<div class="w-96 h-96">
|
|
106
|
+
<wally-carousel>
|
|
107
|
+
<div class="w-full h-full bg-blue-400 text-white flex items-center justify-center text-lg font-semibold">
|
|
108
|
+
Item 1
|
|
109
|
+
</div>
|
|
110
|
+
<div class="w-full h-full bg-green-400 text-white flex items-center justify-center text-lg font-semibold">
|
|
111
|
+
Item 2
|
|
112
|
+
</div>
|
|
113
|
+
</wally-carousel>
|
|
106
114
|
</div>
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<!-- With Navigation Indicators -->
|
|
120
|
+
<div class="mb-8">
|
|
121
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">With Navigation Indicators</h3>
|
|
122
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
123
|
+
<pre><code [innerHTML]="withNavigationIndicatorsCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
126
|
+
<div class="flex justify-center">
|
|
127
|
+
<div class="w-96 h-96">
|
|
128
|
+
<wally-carousel [isNavigationIndicator]="true">
|
|
129
|
+
<div class="w-full h-full bg-orange-400 text-white flex items-center justify-center text-lg font-semibold">
|
|
130
|
+
Item 1
|
|
131
|
+
</div>
|
|
132
|
+
<div class="w-full h-full bg-red-400 text-white flex items-center justify-center text-lg font-semibold">
|
|
133
|
+
Item 2
|
|
134
|
+
</div>
|
|
135
|
+
</wally-carousel>
|
|
109
136
|
</div>
|
|
110
|
-
</
|
|
137
|
+
</div>
|
|
111
138
|
</div>
|
|
112
139
|
</div>
|
|
140
|
+
|
|
141
|
+
<!-- Product Showcase -->
|
|
142
|
+
<div class="mb-8">
|
|
143
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Product Showcase</h3>
|
|
144
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
145
|
+
<pre><code [innerHTML]="productShowcaseCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
148
|
+
<div class="w-full h-96">
|
|
149
|
+
<wally-carousel>
|
|
150
|
+
<div class="w-full h-full bg-white dark:bg-[#1a1a1a] border border-gray-200 dark:border-gray-700 rounded-lg p-8 flex flex-col items-center justify-center">
|
|
151
|
+
<div class="w-24 h-24 bg-blue-500 rounded mb-6"></div>
|
|
152
|
+
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-2">MacBook Pro</h3>
|
|
153
|
+
<p class="text-gray-600 dark:text-gray-400 text-center mb-4">M3 chip, 16GB RAM, 512GB SSD</p>
|
|
154
|
+
<span class="text-2xl font-bold text-blue-600">$1,999</span>
|
|
155
|
+
</div>
|
|
156
|
+
<div class="w-full h-full bg-white dark:bg-[#1a1a1a] border border-gray-200 dark:border-gray-700 rounded-lg p-8 flex flex-col items-center justify-center">
|
|
157
|
+
<div class="w-24 h-24 bg-green-500 rounded mb-6"></div>
|
|
158
|
+
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-2">iPhone 15</h3>
|
|
159
|
+
<p class="text-gray-600 dark:text-gray-400 text-center mb-4">128GB, Dynamic Island, USB-C</p>
|
|
160
|
+
<span class="text-2xl font-bold text-green-600">$799</span>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="w-full h-full bg-white dark:bg-[#1a1a1a] border border-gray-200 dark:border-gray-700 rounded-lg p-8 flex flex-col items-center justify-center">
|
|
163
|
+
<div class="w-24 h-24 bg-purple-500 rounded mb-6"></div>
|
|
164
|
+
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-2">iPad Air</h3>
|
|
165
|
+
<p class="text-gray-600 dark:text-gray-400 text-center mb-4">10.9-inch, M2 chip, Wi-Fi</p>
|
|
166
|
+
<span class="text-2xl font-bold text-purple-600">$599</span>
|
|
167
|
+
</div>
|
|
168
|
+
</wally-carousel>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="mt-6 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg">
|
|
174
|
+
<h3 class="font-medium text-amber-900 dark:text-amber-100 mb-2">Tip</h3>
|
|
175
|
+
<p class="text-sm text-amber-800 dark:text-amber-200">
|
|
176
|
+
The carousel automatically detects child elements and creates navigation.
|
|
177
|
+
Try swiping on mobile or using keyboard arrows when focused!
|
|
178
|
+
</p>
|
|
179
|
+
</div>
|
|
113
180
|
</section>
|
|
114
181
|
|
|
182
|
+
|
|
115
183
|
<!-- Advanced Examples -->
|
|
116
184
|
<section class="mb-8">
|
|
117
185
|
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Advanced Examples</h2>
|
|
@@ -124,33 +192,394 @@
|
|
|
124
192
|
</div>
|
|
125
193
|
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
126
194
|
<div class="flex justify-center">
|
|
127
|
-
<
|
|
128
|
-
<
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<
|
|
195
|
+
<div class="w-96 h-96">
|
|
196
|
+
<wally-carousel>
|
|
197
|
+
<div
|
|
198
|
+
class="w-full h-full bg-gradient-to-r from-blue-500 to-purple-600 text-white flex flex-col items-center justify-center p-6">
|
|
199
|
+
<h3 class="text-xl font-bold mb-2">Feature 1</h3>
|
|
200
|
+
<p class="text-center text-sm">This is a custom slide with rich content</p>
|
|
201
|
+
</div>
|
|
202
|
+
<div
|
|
203
|
+
class="w-full h-full bg-gradient-to-r from-green-500 to-blue-500 text-white flex flex-col items-center justify-center p-6">
|
|
204
|
+
<h3 class="text-xl font-bold mb-2">Feature 2</h3>
|
|
205
|
+
<p class="text-center text-sm">Another slide with different styling</p>
|
|
206
|
+
</div>
|
|
207
|
+
<div
|
|
208
|
+
class="w-full h-full bg-gradient-to-r from-purple-500 to-pink-500 text-white flex flex-col items-center justify-center p-6">
|
|
209
|
+
<h3 class="text-xl font-bold mb-2">Feature 3</h3>
|
|
210
|
+
<p class="text-center text-sm">Beautiful gradients and typography</p>
|
|
211
|
+
</div>
|
|
212
|
+
</wally-carousel>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
</section>
|
|
218
|
+
|
|
219
|
+
<!-- Responsive Design -->
|
|
220
|
+
<section class="mb-8">
|
|
221
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Responsive Design</h2>
|
|
222
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
223
|
+
The carousel is 100% responsive and adapts to any container size. Simply set the parent container dimensions and
|
|
224
|
+
the carousel will fill it completely.
|
|
225
|
+
</p>
|
|
226
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
227
|
+
<pre><code [innerHTML]="responsiveExampleCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
<!-- Live Examples -->
|
|
231
|
+
<div class="space-y-6">
|
|
232
|
+
<!-- Hero style -->
|
|
233
|
+
<div>
|
|
234
|
+
<h3 class="text-md font-medium mb-2 text-[#0a0a0a] dark:text-white">Hero Carousel (w-full h-96)</h3>
|
|
235
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
236
|
+
<div class="w-full h-96">
|
|
237
|
+
<wally-carousel>
|
|
238
|
+
<div
|
|
239
|
+
class="w-full h-full bg-gradient-to-r from-indigo-500 to-purple-600 text-white flex flex-col items-center justify-center p-6">
|
|
240
|
+
<h3 class="text-2xl font-bold mb-2">Hero Slide 1</h3>
|
|
241
|
+
<p class="text-center">Perfect for landing page heroes</p>
|
|
242
|
+
</div>
|
|
243
|
+
<div
|
|
244
|
+
class="w-full h-full bg-gradient-to-r from-purple-600 to-pink-600 text-white flex flex-col items-center justify-center p-6">
|
|
245
|
+
<h3 class="text-2xl font-bold mb-2">Hero Slide 2</h3>
|
|
246
|
+
<p class="text-center">Responsive and touch-friendly</p>
|
|
247
|
+
</div>
|
|
248
|
+
</wally-carousel>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<!-- Compact style -->
|
|
254
|
+
<div>
|
|
255
|
+
<h3 class="text-md font-medium mb-2 text-[#0a0a0a] dark:text-white">Compact Carousel (w-full h-48)</h3>
|
|
256
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
257
|
+
<div class="w-full h-48">
|
|
258
|
+
<wally-carousel>
|
|
259
|
+
<div
|
|
260
|
+
class="w-full h-full bg-gradient-to-r from-emerald-500 to-teal-600 text-white flex items-center justify-center p-4">
|
|
261
|
+
<div class="text-center">
|
|
262
|
+
<h4 class="text-lg font-semibold mb-1">Compact Design</h4>
|
|
263
|
+
<p class="text-sm">Great for testimonials</p>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
<div
|
|
267
|
+
class="w-full h-full bg-gradient-to-r from-teal-600 to-cyan-600 text-white flex items-center justify-center p-4">
|
|
268
|
+
<div class="text-center">
|
|
269
|
+
<h4 class="text-lg font-semibold mb-1">Mobile Friendly</h4>
|
|
270
|
+
<p class="text-sm">Swipe gestures included</p>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
</wally-carousel>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
</section>
|
|
279
|
+
|
|
280
|
+
<!-- Accessibility -->
|
|
281
|
+
<section class="mb-8">
|
|
282
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Accessibility</h2>
|
|
283
|
+
<p class="text-gray-700 dark:text-gray-400 mb-6">
|
|
284
|
+
The carousel is built with comprehensive accessibility features and follows WCAG guidelines for inclusive design.
|
|
285
|
+
</p>
|
|
286
|
+
|
|
287
|
+
<div class="space-y-8">
|
|
288
|
+
<!-- ARIA Attributes -->
|
|
289
|
+
<div>
|
|
290
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">ARIA Attributes</h3>
|
|
291
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
292
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
293
|
+
<div class="space-y-3">
|
|
294
|
+
<div>
|
|
295
|
+
<code class="text-sm dark:text-white bg-gray-200 dark:bg-[#1a1a1a] px-2 py-1 rounded">role="region"</code>
|
|
296
|
+
<p class="text-xs text-gray-600 dark:text-gray-400 mt-1">Identifies the carousel as a landmark region</p>
|
|
297
|
+
</div>
|
|
298
|
+
<div>
|
|
299
|
+
<code class="text-sm dark:text-white bg-gray-200 dark:bg-[#1a1a1a] px-2 py-1 rounded">aria-label="Carousel"</code>
|
|
300
|
+
<p class="text-xs text-gray-600 dark:text-gray-400 mt-1">Provides accessible name for screen readers</p>
|
|
301
|
+
</div>
|
|
135
302
|
</div>
|
|
136
|
-
<div class="
|
|
137
|
-
<
|
|
138
|
-
|
|
303
|
+
<div class="space-y-3">
|
|
304
|
+
<div>
|
|
305
|
+
<code class="text-sm dark:text-white bg-gray-200 dark:bg-[#1a1a1a] px-2 py-1 rounded">tabindex="0"</code>
|
|
306
|
+
<p class="text-xs text-gray-600 dark:text-gray-400 mt-1">Makes carousel keyboard focusable</p>
|
|
307
|
+
</div>
|
|
308
|
+
<div>
|
|
309
|
+
<code class="text-sm dark:text-white bg-gray-200 dark:bg-[#1a1a1a] px-2 py-1 rounded">aria-label="Navigate to slide X"</code>
|
|
310
|
+
<p class="text-xs text-gray-600 dark:text-gray-400 mt-1">Descriptive labels for navigation indicators</p>
|
|
311
|
+
</div>
|
|
139
312
|
</div>
|
|
140
|
-
</
|
|
313
|
+
</div>
|
|
141
314
|
</div>
|
|
142
315
|
</div>
|
|
316
|
+
|
|
317
|
+
<!-- Keyboard Navigation -->
|
|
318
|
+
<div>
|
|
319
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Keyboard Navigation Example</h3>
|
|
320
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
321
|
+
<p class="text-sm text-gray-700 dark:text-gray-400 mb-4">
|
|
322
|
+
Click the carousel below to focus it, then use keyboard arrows to navigate:
|
|
323
|
+
</p>
|
|
324
|
+
<div class="w-full h-64">
|
|
325
|
+
<wally-carousel>
|
|
326
|
+
<div class="w-full h-full bg-gradient-to-r from-indigo-500 to-purple-600 text-white flex flex-col items-center justify-center p-6">
|
|
327
|
+
<h3 class="text-xl font-bold mb-2">Keyboard Accessible</h3>
|
|
328
|
+
<p class="text-center text-sm">Use ← → arrows when focused</p>
|
|
329
|
+
</div>
|
|
330
|
+
<div class="w-full h-full bg-gradient-to-r from-purple-600 to-pink-600 text-white flex flex-col items-center justify-center p-6">
|
|
331
|
+
<h3 class="text-xl font-bold mb-2">Screen Reader Friendly</h3>
|
|
332
|
+
<p class="text-center text-sm">Proper ARIA attributes included</p>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="w-full h-full bg-gradient-to-r from-pink-600 to-rose-600 text-white flex flex-col items-center justify-center p-6">
|
|
335
|
+
<h3 class="text-xl font-bold mb-2">WCAG Compliant</h3>
|
|
336
|
+
<p class="text-center text-sm">WCAG accessibility standards</p>
|
|
337
|
+
</div>
|
|
338
|
+
</wally-carousel>
|
|
339
|
+
</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
143
343
|
</div>
|
|
144
344
|
</section>
|
|
145
345
|
|
|
146
346
|
<!-- Properties -->
|
|
147
347
|
<section class="mb-8">
|
|
148
348
|
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Properties</h2>
|
|
349
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
350
|
+
The carousel component accepts one optional input property and automatically manages its internal state.
|
|
351
|
+
</p>
|
|
352
|
+
|
|
353
|
+
<div class="space-y-6">
|
|
354
|
+
<!-- Input Properties -->
|
|
355
|
+
<div>
|
|
356
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Input Properties</h3>
|
|
357
|
+
<div class="space-y-2">
|
|
358
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
359
|
+
<pre><code [innerHTML]="propertyIsNavigationIndicatorCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
360
|
+
</div>
|
|
361
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
362
|
+
Controls whether navigation indicators (dots) are displayed below the carousel.
|
|
363
|
+
</p>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<!-- Read-only Properties -->
|
|
368
|
+
<div>
|
|
369
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Read-only Properties</h3>
|
|
370
|
+
<div class="space-y-4">
|
|
371
|
+
<div class="space-y-2">
|
|
372
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
373
|
+
<pre><code [innerHTML]="propertyTotalItemsCountCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
374
|
+
</div>
|
|
375
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Automatically detected number of child elements in the carousel</p>
|
|
376
|
+
</div>
|
|
377
|
+
|
|
378
|
+
<div class="space-y-2">
|
|
379
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
380
|
+
<pre><code [innerHTML]="propertyCurrentVisibleItemIndexCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
381
|
+
</div>
|
|
382
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Zero-based index of the currently visible slide</p>
|
|
383
|
+
</div>
|
|
384
|
+
|
|
385
|
+
<div class="space-y-2">
|
|
386
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
387
|
+
<pre><code [innerHTML]="propertyNavigationIndicatorsArrayCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
388
|
+
</div>
|
|
389
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Auto-generated array used for rendering navigation indicators</p>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
393
|
+
</div>
|
|
394
|
+
</section>
|
|
395
|
+
|
|
396
|
+
<!-- API Methods -->
|
|
397
|
+
<section class="mb-8">
|
|
398
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">API Methods</h2>
|
|
399
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
400
|
+
Public methods available for programmatic control of the carousel. Access these methods through a template reference or ViewChild.
|
|
401
|
+
</p>
|
|
402
|
+
|
|
403
|
+
<div class="overflow-x-auto">
|
|
404
|
+
<table class="w-full border-collapse border border-gray-200 dark:border-gray-700 rounded-lg">
|
|
405
|
+
<thead>
|
|
406
|
+
<tr class="bg-gray-50 dark:bg-[#1a1a1a]">
|
|
407
|
+
<th class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-left text-sm font-semibold text-[#0a0a0a] dark:text-white">Method</th>
|
|
408
|
+
<th class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-left text-sm font-semibold text-[#0a0a0a] dark:text-white">Parameters</th>
|
|
409
|
+
<th class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-left text-sm font-semibold text-[#0a0a0a] dark:text-white">Return</th>
|
|
410
|
+
<th class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-left text-sm font-semibold text-[#0a0a0a] dark:text-white">Description</th>
|
|
411
|
+
</tr>
|
|
412
|
+
</thead>
|
|
413
|
+
<tbody>
|
|
414
|
+
<!-- Navigation Methods -->
|
|
415
|
+
<tr class="bg-blue-50 dark:bg-blue-900/20">
|
|
416
|
+
<td colspan="4" class="border border-gray-200 dark:border-gray-700 px-4 py-2 text-sm font-medium text-blue-900 dark:text-blue-100">Navigation Methods</td>
|
|
417
|
+
</tr>
|
|
418
|
+
<tr>
|
|
419
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
420
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">navigateToNextItem()</code>
|
|
421
|
+
</td>
|
|
422
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">None</td>
|
|
423
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">void</td>
|
|
424
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Navigate to the next slide with circular navigation</td>
|
|
425
|
+
</tr>
|
|
426
|
+
<tr>
|
|
427
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
428
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">navigateToPreviousItem()</code>
|
|
429
|
+
</td>
|
|
430
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">None</td>
|
|
431
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">void</td>
|
|
432
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Navigate to the previous slide with circular navigation</td>
|
|
433
|
+
</tr>
|
|
434
|
+
<tr>
|
|
435
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
436
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">navigateToSpecificItem()</code>
|
|
437
|
+
</td>
|
|
438
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">
|
|
439
|
+
<code class="text-xs">index: number</code>
|
|
440
|
+
</td>
|
|
441
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">void</td>
|
|
442
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Jump directly to a specific slide by index (0-based)</td>
|
|
443
|
+
</tr>
|
|
444
|
+
|
|
445
|
+
<!-- Calculation Methods -->
|
|
446
|
+
<tr class="bg-green-50 dark:bg-green-900/20">
|
|
447
|
+
<td colspan="4" class="border border-gray-200 dark:border-gray-700 px-4 py-2 text-sm font-medium text-green-900 dark:text-green-100">Calculation Methods</td>
|
|
448
|
+
</tr>
|
|
449
|
+
<tr>
|
|
450
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
451
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">calculateNextItemIndex()</code>
|
|
452
|
+
</td>
|
|
453
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">
|
|
454
|
+
<code class="text-xs">current: number</code>
|
|
455
|
+
</td>
|
|
456
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">number</td>
|
|
457
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Calculate the next index using circular buffer algorithm</td>
|
|
458
|
+
</tr>
|
|
459
|
+
<tr>
|
|
460
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
461
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">calculatePreviousItemIndex()</code>
|
|
462
|
+
</td>
|
|
463
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">
|
|
464
|
+
<code class="text-xs">current: number</code>
|
|
465
|
+
</td>
|
|
466
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">number</td>
|
|
467
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Calculate the previous index using circular buffer algorithm</td>
|
|
468
|
+
</tr>
|
|
469
|
+
|
|
470
|
+
<!-- Positioning Methods -->
|
|
471
|
+
<tr class="bg-purple-50 dark:bg-purple-900/20">
|
|
472
|
+
<td colspan="4" class="border border-gray-200 dark:border-gray-700 px-4 py-2 text-sm font-medium text-purple-900 dark:text-purple-100">Positioning Methods</td>
|
|
473
|
+
</tr>
|
|
474
|
+
<tr>
|
|
475
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
476
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">updateItemElementPosition()</code>
|
|
477
|
+
</td>
|
|
478
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">
|
|
479
|
+
<code class="text-xs">element: HTMLElement<br>index: number</code>
|
|
480
|
+
</td>
|
|
481
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">void</td>
|
|
482
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Update position of a specific carousel item element</td>
|
|
483
|
+
</tr>
|
|
484
|
+
<tr>
|
|
485
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm">
|
|
486
|
+
<code class="bg-gray-100 dark:bg-[#1a1a1a] dark:text-white px-2 py-1 rounded text-xs">updateAllItemElementPositions()</code>
|
|
487
|
+
</td>
|
|
488
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">None</td>
|
|
489
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-600 dark:text-gray-400">void</td>
|
|
490
|
+
<td class="border border-gray-200 dark:border-gray-700 px-4 py-3 text-sm text-gray-700 dark:text-gray-300">Update positions of all carousel item elements</td>
|
|
491
|
+
</tr>
|
|
492
|
+
</tbody>
|
|
493
|
+
</table>
|
|
494
|
+
</div>
|
|
495
|
+
</section>
|
|
496
|
+
|
|
497
|
+
<!-- Keyboard Navigation -->
|
|
498
|
+
<section class="mb-8">
|
|
499
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Keyboard Navigation</h2>
|
|
500
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
501
|
+
When the carousel has focus, users can navigate using these keyboard shortcuts.
|
|
502
|
+
</p>
|
|
149
503
|
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
150
|
-
<pre><code [innerHTML]="
|
|
504
|
+
<pre><code [innerHTML]="keyboardShortcutsCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
151
505
|
</div>
|
|
152
506
|
</section>
|
|
153
507
|
|
|
508
|
+
<!-- Touch Gestures -->
|
|
509
|
+
<section class="mb-8">
|
|
510
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Touch & Mouse Gestures</h2>
|
|
511
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
512
|
+
Interactive gestures supported on both mobile and desktop devices.
|
|
513
|
+
</p>
|
|
514
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
515
|
+
<pre><code [innerHTML]="touchGesturesCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
516
|
+
</div>
|
|
517
|
+
</section>
|
|
518
|
+
|
|
519
|
+
<!-- Features -->
|
|
520
|
+
<section class="mb-8">
|
|
521
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Features</h2>
|
|
522
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
523
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
524
|
+
<div class="flex items-center gap-3 mb-2">
|
|
525
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-blue-500">
|
|
526
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 0 0 6 3.75v16.5a2.25 2.25 0 0 0 2.25 2.25h7.5A2.25 2.25 0 0 0 18 20.25V3.75a2.25 2.25 0 0 0-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" />
|
|
527
|
+
</svg>
|
|
528
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">Touch & Swipe</h3>
|
|
529
|
+
</div>
|
|
530
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Full touch gesture support with configurable thresholds for distance and velocity detection.</p>
|
|
531
|
+
</div>
|
|
154
532
|
|
|
533
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
534
|
+
<div class="flex items-center gap-3 mb-2">
|
|
535
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-green-500">
|
|
536
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
|
537
|
+
</svg>
|
|
538
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">Accessibility</h3>
|
|
539
|
+
</div>
|
|
540
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">ARIA attributes, keyboard navigation (arrows, home, end), and screen reader support built-in.</p>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
544
|
+
<div class="flex items-center gap-3 mb-2">
|
|
545
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-purple-500">
|
|
546
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" />
|
|
547
|
+
</svg>
|
|
548
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">100% Responsive</h3>
|
|
549
|
+
</div>
|
|
550
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Adapts to any container size automatically. Set parent dimensions and carousel fills completely.</p>
|
|
551
|
+
</div>
|
|
552
|
+
|
|
553
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
554
|
+
<div class="flex items-center gap-3 mb-2">
|
|
555
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-orange-500">
|
|
556
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5 10 4.5m0 0L16.25 13.5M10 4.5V21" />
|
|
557
|
+
</svg>
|
|
558
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">Performance</h3>
|
|
559
|
+
</div>
|
|
560
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">GPU-accelerated animations, optimized event handling, and proper memory cleanup.</p>
|
|
561
|
+
</div>
|
|
562
|
+
|
|
563
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
564
|
+
<div class="flex items-center gap-3 mb-2">
|
|
565
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-indigo-500">
|
|
566
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
|
|
567
|
+
</svg>
|
|
568
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">Infinite Loop</h3>
|
|
569
|
+
</div>
|
|
570
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Circular buffer algorithm provides seamless infinite navigation between slides.</p>
|
|
571
|
+
</div>
|
|
572
|
+
|
|
573
|
+
<div class="p-4 border rounded-lg bg-white dark:bg-[#121212]">
|
|
574
|
+
<div class="flex items-center gap-3 mb-2">
|
|
575
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5 text-red-500">
|
|
576
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-6.364-.386 1.591-1.591M3 12h2.25m.386-6.364 1.591 1.591" />
|
|
577
|
+
</svg>
|
|
578
|
+
<h3 class="font-medium text-[#0a0a0a] dark:text-white">Zero Config</h3>
|
|
579
|
+
</div>
|
|
580
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">No configuration required. Just wrap your content and it works. Automatically detects child elements.</p>
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
583
|
+
</section>
|
|
155
584
|
</div>
|
|
156
|
-
</div>
|
|
585
|
+
</div>
|
package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.ts
CHANGED
|
@@ -29,8 +29,20 @@ export class CarouselDocs {
|
|
|
29
29
|
importCode = getFormattedCode(CarouselCodeExamples.import, 'typescript');
|
|
30
30
|
componentImportCode = getFormattedCode(CarouselCodeExamples.componentImport, 'typescript');
|
|
31
31
|
basicUsageCode = getFormattedCode(CarouselCodeExamples.basicUsage, 'html');
|
|
32
|
+
withNavigationIndicatorsCode = getFormattedCode(CarouselCodeExamples.withNavigationIndicators, 'html');
|
|
33
|
+
imageCarouselCode = getFormattedCode(CarouselCodeExamples.imageCarousel, 'html');
|
|
34
|
+
productShowcaseCode = getFormattedCode(CarouselCodeExamples.productShowcase, 'html');
|
|
32
35
|
customContentCode = getFormattedCode(CarouselCodeExamples.customContent, 'html');
|
|
33
|
-
|
|
36
|
+
responsiveExampleCode = getFormattedCode(CarouselCodeExamples.responsiveExample, 'html');
|
|
37
|
+
|
|
38
|
+
propertyIsNavigationIndicatorCode = getFormattedCode(CarouselCodeExamples.propertyIsNavigationIndicator, 'typescript');
|
|
39
|
+
propertyTotalItemsCountCode = getFormattedCode(CarouselCodeExamples.propertyTotalItemsCount, 'typescript');
|
|
40
|
+
propertyCurrentVisibleItemIndexCode = getFormattedCode(CarouselCodeExamples.propertyCurrentVisibleItemIndex, 'typescript');
|
|
41
|
+
propertyNavigationIndicatorsArrayCode = getFormattedCode(CarouselCodeExamples.propertyNavigationIndicatorsArray, 'typescript');
|
|
42
|
+
|
|
43
|
+
apiMethodsCode = getFormattedCode(CarouselCodeExamples.apiMethods, 'typescript');
|
|
44
|
+
keyboardShortcutsCode = getFormattedCode(CarouselCodeExamples.keyboardShortcuts, 'typescript');
|
|
45
|
+
touchGesturesCode = getFormattedCode(CarouselCodeExamples.touchGestures, 'typescript');
|
|
34
46
|
|
|
35
47
|
constructor(
|
|
36
48
|
private aiPromptService: AiPromptService
|