wally-ui 1.5.2 → 1.7.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/public/sitemap.xml +8 -0
- package/playground/showcase/src/app/app.routes.server.ts +4 -0
- package/playground/showcase/src/app/components/button/button.html +9 -1
- package/playground/showcase/src/app/components/button/button.ts +5 -0
- package/playground/showcase/src/app/components/carousel/carousel.html +39 -0
- package/playground/showcase/src/app/components/carousel/carousel.ts +37 -0
- package/playground/showcase/src/app/pages/documentation/components/button-docs/button-docs.examples.ts +20 -0
- package/playground/showcase/src/app/pages/documentation/components/button-docs/button-docs.html +72 -10
- package/playground/showcase/src/app/pages/documentation/components/button-docs/button-docs.ts +9 -0
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.css +0 -0
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.examples.ts +17 -0
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.html +180 -0
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.spec.ts +23 -0
- package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.ts +44 -0
- package/playground/showcase/src/app/pages/documentation/components/components.html +13 -0
- package/playground/showcase/src/app/pages/documentation/components/components.routes.ts +4 -0
- package/playground/showcase/src/app/pages/home/home.html +1 -0
- package/playground/showcase/src/app/pages/home/home.ts +2 -1
package/package.json
CHANGED
|
@@ -44,4 +44,12 @@
|
|
|
44
44
|
<priority>0.8</priority>
|
|
45
45
|
</url>
|
|
46
46
|
|
|
47
|
+
<!-- Carousel Documentation -->
|
|
48
|
+
<url>
|
|
49
|
+
<loc>https://wally-ui.com/documentation/components/carousel</loc>
|
|
50
|
+
<lastmod>2025-09-27</lastmod>
|
|
51
|
+
<changefreq>monthly</changefreq>
|
|
52
|
+
<priority>0.8</priority>
|
|
53
|
+
</url>
|
|
54
|
+
|
|
47
55
|
</urlset>
|
|
@@ -21,6 +21,10 @@ export const serverRoutes: ServerRoute[] = [
|
|
|
21
21
|
path: 'documentation/components/breadcrumb',
|
|
22
22
|
renderMode: RenderMode.Prerender,
|
|
23
23
|
},
|
|
24
|
+
{
|
|
25
|
+
path: 'documentation/components/carousel',
|
|
26
|
+
renderMode: RenderMode.Prerender,
|
|
27
|
+
},
|
|
24
28
|
{
|
|
25
29
|
path: 'components',
|
|
26
30
|
renderMode: RenderMode.Prerender,
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
<button
|
|
1
|
+
<button
|
|
2
|
+
[type]="type()"
|
|
3
|
+
[disabled]="disabled() || loading()"
|
|
4
|
+
[attr.aria-label]="ariaLabel() || null"
|
|
5
|
+
[attr.aria-describedby]="ariaDescribedBy() || null"
|
|
6
|
+
[attr.aria-pressed]="ariaPressed()"
|
|
7
|
+
[attr.aria-busy]="loading()"
|
|
8
|
+
(click)="handleClick()"
|
|
9
|
+
class="
|
|
2
10
|
group
|
|
3
11
|
relative
|
|
4
12
|
w-full
|
|
@@ -15,6 +15,11 @@ export class Button {
|
|
|
15
15
|
loading: InputSignal<boolean> = input<boolean>(false);
|
|
16
16
|
showNotification: InputSignal<boolean> = input<boolean>(false);
|
|
17
17
|
|
|
18
|
+
// Accessibility properties
|
|
19
|
+
ariaLabel: InputSignal<string> = input<string>('');
|
|
20
|
+
ariaDescribedBy: InputSignal<string> = input<string>('');
|
|
21
|
+
ariaPressed: InputSignal<boolean | undefined> = input<boolean | undefined>(undefined);
|
|
22
|
+
|
|
18
23
|
click: OutputEmitterRef<void> = output<void>();
|
|
19
24
|
|
|
20
25
|
handleClick(): void {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<div class="w-full flex flex-col items-center gap-4">
|
|
2
|
+
<div class="relative w-64 h-40 overflow-hidden rounded-lg shadow">
|
|
3
|
+
@for (item of items; track item; let i = $index) {
|
|
4
|
+
<div class="absolute inset-0 flex items-center justify-center bg-blue-500 text-white text-2xl
|
|
5
|
+
transition-all duration-700 ease-in-out"
|
|
6
|
+
[ngClass]="{
|
|
7
|
+
'translate-x-0 opacity-100': i === itemVisible(),
|
|
8
|
+
'translate-x-full opacity-0': i > itemVisible(),
|
|
9
|
+
'-translate-x-full opacity-0': i < itemVisible()
|
|
10
|
+
}">
|
|
11
|
+
{{ item }}
|
|
12
|
+
</div>
|
|
13
|
+
}
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="flex gap-2">
|
|
17
|
+
@for (item of items; track item; let i = $index) {
|
|
18
|
+
<button
|
|
19
|
+
class="w-2 h-2 rounded-full transition-all duration-300"
|
|
20
|
+
[ngClass]="{
|
|
21
|
+
'bg-blue-500 scale-125': i === itemVisible(),
|
|
22
|
+
'bg-gray-300 hover:bg-gray-400': i !== itemVisible()
|
|
23
|
+
}"
|
|
24
|
+
(click)="goToSlide(i)">
|
|
25
|
+
</button>
|
|
26
|
+
}
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="flex gap-4">
|
|
30
|
+
<button class="px-4 py-2 bg-gray-700 text-white rounded hover:bg-gray-600 transition-colors duration-200"
|
|
31
|
+
(click)="goPrevios()">
|
|
32
|
+
Previos
|
|
33
|
+
</button>
|
|
34
|
+
<button class="px-4 py-2 bg-gray-700 text-white rounded hover:bg-gray-600 transition-colors duration-200"
|
|
35
|
+
(click)="goNext()">
|
|
36
|
+
Next
|
|
37
|
+
</button>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Component, input, OnInit, signal } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'wally-carousel',
|
|
6
|
+
imports: [CommonModule],
|
|
7
|
+
templateUrl: './carousel.html',
|
|
8
|
+
})
|
|
9
|
+
export class Carousel implements OnInit {
|
|
10
|
+
items = [1, 2, 3, 4];
|
|
11
|
+
itemVisible = signal<number>(0);
|
|
12
|
+
|
|
13
|
+
ngOnInit(): void {
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// test - algorithm Circular Buffer:
|
|
17
|
+
nextIndex(currentIndex: number): number {
|
|
18
|
+
return (currentIndex + 1) % this.items.length;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
previosIndex(currentIndex: number): number {
|
|
22
|
+
return (currentIndex - 1 + this.items.length) % this.items.length;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
goNext(): void {
|
|
26
|
+
this.itemVisible.set(this.nextIndex(this.itemVisible()));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
goPrevios(): void {
|
|
30
|
+
this.itemVisible.set(this.previosIndex(this.itemVisible()));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
goToSlide(index: number): void {
|
|
34
|
+
this.itemVisible.set(index);
|
|
35
|
+
}
|
|
36
|
+
// end test Circular Buffer ---
|
|
37
|
+
}
|
|
@@ -47,9 +47,29 @@ export const ButtonCodeExamples = {
|
|
|
47
47
|
</svg>
|
|
48
48
|
</wally-button>`,
|
|
49
49
|
|
|
50
|
+
// Accessibility
|
|
51
|
+
ariaLabel: `<wally-button ariaLabel="Save document">
|
|
52
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
53
|
+
stroke-width="1.5" stroke="currentColor" class="size-5">
|
|
54
|
+
<path stroke-linecap="round" stroke-linejoin="round"
|
|
55
|
+
d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" />
|
|
56
|
+
</svg>
|
|
57
|
+
</wally-button>`,
|
|
58
|
+
|
|
59
|
+
ariaPressed: `<wally-button [ariaPressed]="isToggled">
|
|
60
|
+
Toggle Setting
|
|
61
|
+
</wally-button>`,
|
|
62
|
+
|
|
63
|
+
ariaBusy: `<wally-button [loading]="true">
|
|
64
|
+
Processing...
|
|
65
|
+
</wally-button>`,
|
|
66
|
+
|
|
50
67
|
// Properties
|
|
51
68
|
propertyType: `type: string = 'button';`,
|
|
52
69
|
propertyDisabled: `disabled: boolean = false;`,
|
|
53
70
|
propertyLoading: `loading: boolean = false;`,
|
|
54
71
|
propertyShowNotification: `showNotification: boolean = false;`,
|
|
72
|
+
propertyAriaLabel: `ariaLabel: string = '';`,
|
|
73
|
+
propertyAriaPressed: `ariaPressed: boolean | undefined = undefined;`,
|
|
74
|
+
propertyAriaDescribedBy: `ariaDescribedBy: string = '';`,
|
|
55
75
|
};
|
package/playground/showcase/src/app/pages/documentation/components/button-docs/button-docs.html
CHANGED
|
@@ -274,6 +274,57 @@
|
|
|
274
274
|
</div>
|
|
275
275
|
</section>
|
|
276
276
|
|
|
277
|
+
<!-- Accessibility -->
|
|
278
|
+
<section class="mb-8">
|
|
279
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Accessibility</h2>
|
|
280
|
+
|
|
281
|
+
<div class="space-y-8">
|
|
282
|
+
<!-- ARIA Label -->
|
|
283
|
+
<div>
|
|
284
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">ARIA Label for Icon-Only Buttons</h3>
|
|
285
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
286
|
+
<pre><code [innerHTML]="ariaLabelCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
289
|
+
<wally-button ariaLabel="Save document">
|
|
290
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
|
291
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" />
|
|
292
|
+
</svg>
|
|
293
|
+
</wally-button>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
<!-- Toggle Button -->
|
|
298
|
+
<div>
|
|
299
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Toggle Button with ARIA Pressed</h3>
|
|
300
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
301
|
+
<pre><code [innerHTML]="ariaPressedCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
304
|
+
<wally-button [ariaPressed]="toggleState()">
|
|
305
|
+
Toggle Setting
|
|
306
|
+
</wally-button>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<!-- Loading State -->
|
|
311
|
+
<div>
|
|
312
|
+
<h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Loading State with ARIA Busy</h3>
|
|
313
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
314
|
+
<pre><code [innerHTML]="ariaBusyCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
315
|
+
</div>
|
|
316
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
317
|
+
<wally-button [loading]="true">
|
|
318
|
+
Processing...
|
|
319
|
+
</wally-button>
|
|
320
|
+
</div>
|
|
321
|
+
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2">
|
|
322
|
+
Automatically sets <code class="bg-gray-200 dark:bg-[#121212] px-1 py-0.5 rounded text-xs">aria-busy="true"</code> when loading
|
|
323
|
+
</p>
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
</section>
|
|
327
|
+
|
|
277
328
|
<!-- Properties -->
|
|
278
329
|
<section class="mb-8">
|
|
279
330
|
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Properties</h2>
|
|
@@ -306,6 +357,27 @@
|
|
|
306
357
|
</div>
|
|
307
358
|
<p class="text-sm text-gray-700 dark:text-gray-400">Shows notification badge when true</p>
|
|
308
359
|
</div>
|
|
360
|
+
|
|
361
|
+
<div class="space-y-2">
|
|
362
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
363
|
+
<pre><code [innerHTML]="propertyAriaLabelCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
364
|
+
</div>
|
|
365
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Accessible label for screen readers (essential for icon-only buttons)</p>
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<div class="space-y-2">
|
|
369
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
370
|
+
<pre><code [innerHTML]="propertyAriaPressedCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
371
|
+
</div>
|
|
372
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">Indicates pressed state for toggle buttons</p>
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<div class="space-y-2">
|
|
376
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
377
|
+
<pre><code [innerHTML]="propertyAriaDescribedByCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
378
|
+
</div>
|
|
379
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">References element(s) that describe the button</p>
|
|
380
|
+
</div>
|
|
309
381
|
</div>
|
|
310
382
|
</section>
|
|
311
383
|
|
|
@@ -324,16 +396,6 @@
|
|
|
324
396
|
</p>
|
|
325
397
|
</div>
|
|
326
398
|
|
|
327
|
-
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
328
|
-
<div class="flex items-center gap-2 mb-2">
|
|
329
|
-
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Accessibility</h3>
|
|
330
|
-
<span class="text-xs bg-yellow-500 text-black px-2 py-1 rounded">Under Construction</span>
|
|
331
|
-
</div>
|
|
332
|
-
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
333
|
-
ARIA labels, keyboard navigation, and screen reader support for better accessibility.
|
|
334
|
-
</p>
|
|
335
|
-
</div>
|
|
336
|
-
|
|
337
399
|
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
338
400
|
<div class="flex items-center gap-2 mb-2">
|
|
339
401
|
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Ripple Effect</h3>
|
package/playground/showcase/src/app/pages/documentation/components/button-docs/button-docs.ts
CHANGED
|
@@ -38,13 +38,22 @@ export class ButtonDocs {
|
|
|
38
38
|
iconCode = getFormattedCode(ButtonCodeExamples.iconWithText, 'html');
|
|
39
39
|
iconNotificationCode = getFormattedCode(ButtonCodeExamples.iconOnly, 'html');
|
|
40
40
|
|
|
41
|
+
// Accessibility
|
|
42
|
+
ariaLabelCode = getFormattedCode(ButtonCodeExamples.ariaLabel, 'html');
|
|
43
|
+
ariaPressedCode = getFormattedCode(ButtonCodeExamples.ariaPressed, 'html');
|
|
44
|
+
ariaBusyCode = getFormattedCode(ButtonCodeExamples.ariaBusy, 'html');
|
|
45
|
+
|
|
41
46
|
// Properties
|
|
42
47
|
propertyTypeCode = getFormattedCode(ButtonCodeExamples.propertyType, 'typescript');
|
|
43
48
|
propertyDisabledCode = getFormattedCode(ButtonCodeExamples.propertyDisabled, 'typescript');
|
|
44
49
|
propertyLoadingCode = getFormattedCode(ButtonCodeExamples.propertyLoading, 'typescript');
|
|
45
50
|
propertyShowNotificationCode = getFormattedCode(ButtonCodeExamples.propertyShowNotification, 'typescript');
|
|
51
|
+
propertyAriaLabelCode = getFormattedCode(ButtonCodeExamples.propertyAriaLabel, 'typescript');
|
|
52
|
+
propertyAriaPressedCode = getFormattedCode(ButtonCodeExamples.propertyAriaPressed, 'typescript');
|
|
53
|
+
propertyAriaDescribedByCode = getFormattedCode(ButtonCodeExamples.propertyAriaDescribedBy, 'typescript');
|
|
46
54
|
|
|
47
55
|
clickMessage: WritableSignal<string> = signal<string>('');
|
|
56
|
+
toggleState: WritableSignal<boolean> = signal<boolean>(false);
|
|
48
57
|
|
|
49
58
|
constructor(
|
|
50
59
|
private aiPromptService: AiPromptService
|
package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.css
ADDED
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Carousel documentation code examples
|
|
2
|
+
export const CarouselCodeExamples = {
|
|
3
|
+
// Installation
|
|
4
|
+
installation: `npx wally-ui add carousel`,
|
|
5
|
+
|
|
6
|
+
// Import examples
|
|
7
|
+
import: `import { Carousel } from './components/wally-ui/carousel/carousel';`,
|
|
8
|
+
componentImport: `@Component({
|
|
9
|
+
selector: 'app-example',
|
|
10
|
+
imports: [Carousel],
|
|
11
|
+
templateUrl: './example.html',
|
|
12
|
+
styleUrl: './example.css'
|
|
13
|
+
})`,
|
|
14
|
+
|
|
15
|
+
// Basic usage
|
|
16
|
+
basicUsage: `<wally-carousel></wally-carousel>`,
|
|
17
|
+
};
|
package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.html
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<div class="font-mono">
|
|
2
|
+
<div class="max-w-4xl mx-auto p-6">
|
|
3
|
+
<div class="mb-4">
|
|
4
|
+
<wally-breadcrumb [items]="breadcrumbItems"></wally-breadcrumb>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<h1 class="text-2xl font-bold mb-4 text-[#0a0a0a] dark:text-white">
|
|
8
|
+
Carousel
|
|
9
|
+
</h1>
|
|
10
|
+
<p class="text-gray-700 dark:text-gray-400 mb-4">
|
|
11
|
+
A smooth carousel component with navigation controls, dot indicators, and elegant transitions.
|
|
12
|
+
</p>
|
|
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. Features like auto-play, touch gestures, and customization options are coming soon!
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<!-- AI Prompts -->
|
|
23
|
+
<div class="flex flex-wrap gap-2 mb-6">
|
|
24
|
+
<a [href]="claudeUrl" target="_blank"
|
|
25
|
+
class="inline-flex items-center gap-2 px-3 py-1.5 text-xs bg-gray-200 dark:bg-[#121212] text-gray-600 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-[#1a1a1a] hover:text-[#0a0a0a] dark:hover:text-white transition-colors">
|
|
26
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="size-6" viewBox="0 0 24 24">
|
|
27
|
+
<path fill="currentColor"
|
|
28
|
+
d="m4.714 15.956l4.718-2.648l.079-.23l-.08-.128h-.23l-.79-.048l-2.695-.073l-2.337-.097l-2.265-.122l-.57-.121l-.535-.704l.055-.353l.48-.321l.685.06l1.518.104l2.277.157l1.651.098l2.447.255h.389l.054-.158l-.133-.097l-.103-.098l-2.356-1.596l-2.55-1.688l-1.336-.972l-.722-.491L2 6.223l-.158-1.008l.656-.722l.88.06l.224.061l.893.686l1.906 1.476l2.49 1.833l.364.304l.146-.104l.018-.072l-.164-.274l-1.354-2.446l-1.445-2.49l-.644-1.032l-.17-.619a3 3 0 0 1-.103-.729L6.287.133L6.7 0l.995.134l.42.364l.619 1.415L9.735 4.14l1.555 3.03l.455.898l.243.832l.09.255h.159V9.01l.127-1.706l.237-2.095l.23-2.695l.08-.76l.376-.91l.747-.492l.583.28l.48.685l-.067.444l-.286 1.851l-.558 2.903l-.365 1.942h.213l.243-.242l.983-1.306l1.652-2.064l.728-.82l.85-.904l.547-.431h1.032l.759 1.129l-.34 1.166l-1.063 1.347l-.88 1.142l-1.263 1.7l-.79 1.36l.074.11l.188-.02l2.853-.606l1.542-.28l1.84-.315l.832.388l.09.395l-.327.807l-1.967.486l-2.307.462l-3.436.813l-.043.03l.049.061l1.548.146l.662.036h1.62l3.018.225l.79.522l.473.638l-.08.485l-1.213.62l-1.64-.389l-3.825-.91l-1.31-.329h-.183v.11l1.093 1.068l2.003 1.81l2.508 2.33l.127.578l-.321.455l-.34-.049l-2.204-1.657l-.85-.747l-1.925-1.62h-.127v.17l.443.649l2.343 3.521l.122 1.08l-.17.353l-.607.213l-.668-.122l-1.372-1.924l-1.415-2.168l-1.141-1.943l-.14.08l-.674 7.254l-.316.37l-.728.28l-.607-.461l-.322-.747l.322-1.476l.388-1.924l.316-1.53l.285-1.9l.17-.632l-.012-.042l-.14.018l-1.432 1.967l-2.18 2.945l-1.724 1.845l-.413.164l-.716-.37l.066-.662l.401-.589l2.386-3.036l1.439-1.882l.929-1.086l-.006-.158h-.055L4.138 18.56l-1.13.146l-.485-.456l.06-.746l.231-.243l1.907-1.312Z" />
|
|
29
|
+
</svg>
|
|
30
|
+
Open in Claude
|
|
31
|
+
</a>
|
|
32
|
+
|
|
33
|
+
<a [href]="chatGptUrl" target="_blank"
|
|
34
|
+
class="inline-flex items-center gap-2 px-3 py-1.5 text-xs bg-gray-200 dark:bg-[#121212] text-gray-600 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-[#1a1a1a] hover:text-[#0a0a0a] dark:hover:text-white transition-colors">
|
|
35
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="size-6" viewBox="0 0 48 48">
|
|
36
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
37
|
+
d="M18.38 27.94v-14.4l11.19-6.46c6.2-3.58 17.3 5.25 12.64 13.33" />
|
|
38
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
39
|
+
d="m18.38 20.94l12.47-7.2l11.19 6.46c6.2 3.58 4.1 17.61-5.23 17.61" />
|
|
40
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
41
|
+
d="m24.44 17.44l12.47 7.2v12.93c0 7.16-13.2 12.36-17.86 4.28" />
|
|
42
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
43
|
+
d="M30.5 21.2v14.14L19.31 41.8c-6.2 3.58-17.3-5.25-12.64-13.33" />
|
|
44
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
45
|
+
d="m30.5 27.94l-12.47 7.2l-11.19-6.46c-6.21-3.59-4.11-17.61 5.22-17.61" />
|
|
46
|
+
<path fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round"
|
|
47
|
+
d="m24.44 31.44l-12.47-7.2V11.31c0-7.16 13.2-12.36 17.86-4.28" />
|
|
48
|
+
</svg>
|
|
49
|
+
Open in ChatGPT
|
|
50
|
+
</a>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<!-- Installation -->
|
|
54
|
+
<section class="mb-8">
|
|
55
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Installation</h2>
|
|
56
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
57
|
+
<pre><code [innerHTML]="installationCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
58
|
+
</div>
|
|
59
|
+
</section>
|
|
60
|
+
|
|
61
|
+
<!-- Preview -->
|
|
62
|
+
<section class="mb-8">
|
|
63
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Preview</h2>
|
|
64
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
65
|
+
<div class="flex justify-center">
|
|
66
|
+
<wally-carousel></wally-carousel>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</section>
|
|
70
|
+
|
|
71
|
+
<!-- Import -->
|
|
72
|
+
<section class="mb-8">
|
|
73
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Import</h2>
|
|
74
|
+
<div class="space-y-4">
|
|
75
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
76
|
+
<pre><code [innerHTML]="importCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
80
|
+
<pre><code [innerHTML]="componentImportCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
|
|
85
|
+
<!-- Basic Usage -->
|
|
86
|
+
<section class="mb-8">
|
|
87
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Basic Usage</h2>
|
|
88
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
|
|
89
|
+
<pre><code [innerHTML]="basicUsageCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
|
|
92
|
+
<div class="flex justify-center">
|
|
93
|
+
<wally-carousel></wally-carousel>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<!-- Current Features -->
|
|
99
|
+
<section class="mb-8">
|
|
100
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Current Features</h2>
|
|
101
|
+
|
|
102
|
+
<div class="space-y-4">
|
|
103
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
104
|
+
<div class="flex items-center gap-2 mb-2">
|
|
105
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Circular Buffer Algorithm</h3>
|
|
106
|
+
</div>
|
|
107
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
108
|
+
Infinite navigation using circular buffer data structure for seamless looping.
|
|
109
|
+
</p>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
113
|
+
<div class="flex items-center gap-2 mb-2">
|
|
114
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Smooth Transitions</h3>
|
|
115
|
+
</div>
|
|
116
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
117
|
+
Tailwind CSS v4 powered transitions with transform and opacity animations.
|
|
118
|
+
</p>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
122
|
+
<div class="flex items-center gap-2 mb-2">
|
|
123
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Navigation Controls</h3>
|
|
124
|
+
</div>
|
|
125
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
126
|
+
Previous/Next buttons and dot indicators for direct slide navigation.
|
|
127
|
+
</p>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</section>
|
|
131
|
+
|
|
132
|
+
<!-- Future Features -->
|
|
133
|
+
<section class="mb-8">
|
|
134
|
+
<h2 class="text-lg font-semibold mb-4 text-[#0a0a0a] dark:text-white">Future Features</h2>
|
|
135
|
+
|
|
136
|
+
<div class="space-y-4">
|
|
137
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
138
|
+
<div class="flex items-center gap-2 mb-2">
|
|
139
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Auto-play</h3>
|
|
140
|
+
<span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
|
|
141
|
+
</div>
|
|
142
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
143
|
+
Automatic slide progression with configurable intervals and pause on hover.
|
|
144
|
+
</p>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
148
|
+
<div class="flex items-center gap-2 mb-2">
|
|
149
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Touch Gestures</h3>
|
|
150
|
+
<span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
|
|
151
|
+
</div>
|
|
152
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
153
|
+
Swipe support for mobile devices with momentum scrolling and gesture recognition.
|
|
154
|
+
</p>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
158
|
+
<div class="flex items-center gap-2 mb-2">
|
|
159
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Accessibility</h3>
|
|
160
|
+
<span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
|
|
161
|
+
</div>
|
|
162
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
163
|
+
ARIA labels, keyboard navigation, and screen reader support for better accessibility.
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
|
|
168
|
+
<div class="flex items-center gap-2 mb-2">
|
|
169
|
+
<h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Custom Content</h3>
|
|
170
|
+
<span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
|
|
171
|
+
</div>
|
|
172
|
+
<p class="text-sm text-gray-700 dark:text-gray-400">
|
|
173
|
+
Support for custom slide content through content projection and templates.
|
|
174
|
+
</p>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</section>
|
|
178
|
+
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { CarouselDocs } from './carousel-docs';
|
|
4
|
+
|
|
5
|
+
describe('CarouselDocs', () => {
|
|
6
|
+
let component: CarouselDocs;
|
|
7
|
+
let fixture: ComponentFixture<CarouselDocs>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
imports: [CarouselDocs]
|
|
12
|
+
})
|
|
13
|
+
.compileComponents();
|
|
14
|
+
|
|
15
|
+
fixture = TestBed.createComponent(CarouselDocs);
|
|
16
|
+
component = fixture.componentInstance;
|
|
17
|
+
fixture.detectChanges();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should create', () => {
|
|
21
|
+
expect(component).toBeTruthy();
|
|
22
|
+
});
|
|
23
|
+
});
|
package/playground/showcase/src/app/pages/documentation/components/carousel-docs/carousel-docs.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
import { Breadcrumb, BreadcrumbItem } from '../../../../components/breadcrumb/breadcrumb';
|
|
4
|
+
import { Carousel } from '../../../../components/carousel/carousel';
|
|
5
|
+
|
|
6
|
+
import { AiPromptService } from '../../../../core/services/ai-prompt.service';
|
|
7
|
+
import { CarouselCodeExamples } from './carousel-docs.examples';
|
|
8
|
+
import { getFormattedCode } from '../../../../core/utils/prism';
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'wally-carousel-docs',
|
|
12
|
+
imports: [
|
|
13
|
+
Carousel,
|
|
14
|
+
Breadcrumb
|
|
15
|
+
],
|
|
16
|
+
templateUrl: './carousel-docs.html',
|
|
17
|
+
styleUrl: './carousel-docs.css'
|
|
18
|
+
})
|
|
19
|
+
export class CarouselDocs {
|
|
20
|
+
breadcrumbItems: BreadcrumbItem[] = [
|
|
21
|
+
{ label: 'Home', url: '/' },
|
|
22
|
+
{ label: 'Documentation', url: '/documentation' },
|
|
23
|
+
{ label: 'Components', url: '/documentation/components' },
|
|
24
|
+
{ label: 'Carousel' }
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// Code examples with highlighting
|
|
28
|
+
installationCode = getFormattedCode(CarouselCodeExamples.installation, 'bash');
|
|
29
|
+
importCode = getFormattedCode(CarouselCodeExamples.import, 'typescript');
|
|
30
|
+
componentImportCode = getFormattedCode(CarouselCodeExamples.componentImport, 'typescript');
|
|
31
|
+
basicUsageCode = getFormattedCode(CarouselCodeExamples.basicUsage, 'html');
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
private aiPromptService: AiPromptService
|
|
35
|
+
) { }
|
|
36
|
+
|
|
37
|
+
get claudeUrl(): string {
|
|
38
|
+
return this.aiPromptService.generateClaudeUrl();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get chatGptUrl(): string {
|
|
42
|
+
return this.aiPromptService.generateChatGptUrl();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -60,6 +60,19 @@
|
|
|
60
60
|
</a>
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
|
+
<div class="bg-gray-200 dark:bg-[#121212] rounded-lg p-4">
|
|
64
|
+
<div class="flex items-center gap-2 mb-2">
|
|
65
|
+
<h4 class="text-md font-semibold text-[#0a0a0a] dark:text-white">Carousel</h4>
|
|
66
|
+
<span class="text-xs bg-yellow-500 text-black px-2 py-1 rounded">Under Construction</span>
|
|
67
|
+
</div>
|
|
68
|
+
<p class="text-sm text-gray-700 dark:text-gray-400 mb-3">
|
|
69
|
+
A smooth carousel component with navigation controls, dot indicators, and elegant transitions using circular buffer algorithm.
|
|
70
|
+
</p>
|
|
71
|
+
<a href="/documentation/components/carousel" class="text-blue-500 underline hover:text-blue-700 text-sm">
|
|
72
|
+
View Documentation
|
|
73
|
+
</a>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
63
76
|
<div class="w-auto h-auto">
|
|
64
77
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4944285767597175"
|
|
65
78
|
crossorigin="anonymous"></script>
|
|
@@ -16,5 +16,9 @@ export const componentsRoutes: Routes = [
|
|
|
16
16
|
{
|
|
17
17
|
path: 'input',
|
|
18
18
|
loadComponent: () => import('./input-docs/input-docs').then(m => m.InputDocs)
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
path: 'carousel',
|
|
22
|
+
loadComponent: () => import('./carousel-docs/carousel-docs').then(m => m.CarouselDocs)
|
|
19
23
|
}
|
|
20
24
|
];
|