@tekus/design-system 5.34.0 → 5.35.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/fesm2022/tekus-design-system-components-action-group.mjs +1 -1
- package/fesm2022/tekus-design-system-components-action-group.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-button.mjs +24 -3
- package/fesm2022/tekus-design-system-components-button.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-card.mjs +1 -1
- package/fesm2022/tekus-design-system-components-card.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-carousel.mjs +209 -0
- package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-color-picker.mjs +1 -1
- package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-drawer.mjs +1 -1
- package/fesm2022/tekus-design-system-components-drawer.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-dropdown.mjs +1 -1
- package/fesm2022/tekus-design-system-components-dropdown.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-icon.mjs +2 -2
- package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-modal.mjs +2 -2
- package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-process-steps.mjs +111 -0
- package/fesm2022/tekus-design-system-components-process-steps.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs +1 -1
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-stepper.mjs +1 -1
- package/fesm2022/tekus-design-system-components-stepper.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-table.mjs +1 -1
- package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toast.mjs +1 -1
- package/fesm2022/tekus-design-system-components-toast.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs.map +1 -1
- package/package.json +9 -1
- package/types/tekus-design-system-components-button.d.ts +20 -1
- package/types/tekus-design-system-components-carousel.d.ts +196 -0
- package/types/tekus-design-system-components-modal.d.ts +1 -1
- package/types/tekus-design-system-components-process-steps.d.ts +57 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, computed, ChangeDetectionStrategy, Component, viewChild, signal } from '@angular/core';
|
|
3
|
+
import * as i1 from 'primeng/carousel';
|
|
4
|
+
import { Carousel, CarouselModule } from 'primeng/carousel';
|
|
5
|
+
import { IconComponent } from '@tekus/design-system/components/icon';
|
|
6
|
+
import { ButtonComponent } from '@tekus/design-system/components/button';
|
|
7
|
+
import { FallbackViewComponent } from '@tekus/design-system/components/fallback-view';
|
|
8
|
+
import { TagComponent } from '@tekus/design-system/components/tag';
|
|
9
|
+
import * as i2 from 'primeng/api';
|
|
10
|
+
|
|
11
|
+
/** Autoplay interval, in milliseconds, applied by the autoplay variant. */
|
|
12
|
+
const AUTOPLAY_INTERVAL_MS = 7000;
|
|
13
|
+
/** Maximum number of tags rendered per slide. */
|
|
14
|
+
const MAX_VISIBLE_TAGS = 2;
|
|
15
|
+
/** Maximum number of characters of the slide title before truncation. */
|
|
16
|
+
const MAX_TITLE_LENGTH = 50;
|
|
17
|
+
/** Maximum number of characters of the slide description before truncation. */
|
|
18
|
+
const MAX_DESCRIPTION_LENGTH = 140;
|
|
19
|
+
/** Maximum number of characters per tag before truncation. */
|
|
20
|
+
const MAX_TAG_LENGTH = 20;
|
|
21
|
+
|
|
22
|
+
const truncateWithEllipsis = (text, maxLength) => text.length > maxLength ? text.substring(0, maxLength) + '…' : text;
|
|
23
|
+
/**
|
|
24
|
+
* @component CarouselItemComponent
|
|
25
|
+
* @description
|
|
26
|
+
* Internal slide renderer for `tk-carousel`. It is not part of the public API
|
|
27
|
+
* of the design system and must only be used by `CarouselComponent`.
|
|
28
|
+
*
|
|
29
|
+
* Renders one of two views depending on the slide state:
|
|
30
|
+
* - `default`: background image with a bottom gradient overlay, up to two
|
|
31
|
+
* tags, a title, a description, and an optional call-to-action button.
|
|
32
|
+
* - `error`: `tk-fallback-view` with an illustration and error messages.
|
|
33
|
+
* Also used when the background image fails to load.
|
|
34
|
+
*/
|
|
35
|
+
class CarouselItemComponent {
|
|
36
|
+
constructor() {
|
|
37
|
+
/** Slide data to render. */
|
|
38
|
+
this.slide = input.required(...(ngDevMode ? [{ debugName: "slide" }] : /* istanbul ignore next */ []));
|
|
39
|
+
/** Whether the slide image failed to load and the error view must be shown. */
|
|
40
|
+
this.hasError = input(false, ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** Emits when the call-to-action button is clicked. */
|
|
42
|
+
this.actionClick = output();
|
|
43
|
+
/** Emits when the background image fails to load. */
|
|
44
|
+
this.imageError = output();
|
|
45
|
+
/** Effective presentation state, combining the slide state and image load failures. */
|
|
46
|
+
this.state = computed(() => this.hasError() || this.slide().state === 'error' ? 'error' : 'default', ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
47
|
+
/** Tags normalized to `CarouselSlideTag` and limited to the maximum allowed by the design. */
|
|
48
|
+
this.visibleTags = computed(() => {
|
|
49
|
+
const tags = this.slide().tags ?? [];
|
|
50
|
+
return tags
|
|
51
|
+
.slice(0, MAX_VISIBLE_TAGS)
|
|
52
|
+
.map((tag) => (typeof tag === 'string' ? { value: tag } : tag));
|
|
53
|
+
}, ...(ngDevMode ? [{ debugName: "visibleTags" }] : /* istanbul ignore next */ []));
|
|
54
|
+
/** Alternative text for the background image, falling back to the title. */
|
|
55
|
+
this.altText = computed(() => this.slide().imageAlt ?? this.slide().title, ...(ngDevMode ? [{ debugName: "altText" }] : /* istanbul ignore next */ []));
|
|
56
|
+
/** Title truncated with an ellipsis when it exceeds the maximum length. */
|
|
57
|
+
this.displayTitle = computed(() => truncateWithEllipsis(this.slide().title, MAX_TITLE_LENGTH), ...(ngDevMode ? [{ debugName: "displayTitle" }] : /* istanbul ignore next */ []));
|
|
58
|
+
/** Description truncated with an ellipsis when it exceeds the maximum length. */
|
|
59
|
+
this.displayDescription = computed(() => truncateWithEllipsis(this.slide().description ?? '', MAX_DESCRIPTION_LENGTH), ...(ngDevMode ? [{ debugName: "displayDescription" }] : /* istanbul ignore next */ []));
|
|
60
|
+
/** Error title truncated with an ellipsis, using the same limit as the title. */
|
|
61
|
+
this.displayErrorTitle = computed(() => truncateWithEllipsis(this.slide().errorTitle ?? '', MAX_TITLE_LENGTH), ...(ngDevMode ? [{ debugName: "displayErrorTitle" }] : /* istanbul ignore next */ []));
|
|
62
|
+
/** Error message truncated with an ellipsis, using the same limit as the description. */
|
|
63
|
+
this.displayErrorDescription = computed(() => truncateWithEllipsis(this.slide().errorDescription ?? '', MAX_DESCRIPTION_LENGTH), ...(ngDevMode ? [{ debugName: "displayErrorDescription" }] : /* istanbul ignore next */ []));
|
|
64
|
+
/** Maximum characters per tag, forwarded to `tk-tag`. */
|
|
65
|
+
this.tagTruncationLimit = MAX_TAG_LENGTH;
|
|
66
|
+
}
|
|
67
|
+
onImageError() {
|
|
68
|
+
this.imageError.emit();
|
|
69
|
+
}
|
|
70
|
+
onActionClick() {
|
|
71
|
+
this.actionClick.emit();
|
|
72
|
+
}
|
|
73
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CarouselItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
74
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: CarouselItemComponent, isStandalone: true, selector: "tk-carousel-item", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: true, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick", imageError: "imageError" }, ngImport: i0, template: "<div\n class=\"carousel-item\"\n [class.carousel-item--error]=\"state() === 'error'\"\n [class.carousel-item--plain]=\"state() === 'default' && !slide().imageSrc\">\n @switch (state()) {\n @case ('error') {\n <output class=\"carousel-item__status\" [title]=\"slide().errorDescription ?? ''\">\n <tk-fallback-view\n [imageSrc]=\"slide().errorImageSrc ?? ''\"\n [illustrationAlt]=\"slide().errorTitle ?? ''\"\n [title]=\"displayErrorTitle()\"\n [message]=\"displayErrorDescription()\">\n </tk-fallback-view>\n </output>\n }\n @default {\n @if (slide().imageSrc) {\n <img\n class=\"carousel-item__image\"\n [src]=\"slide().imageSrc\"\n [alt]=\"altText()\"\n (error)=\"onImageError()\" />\n <div class=\"carousel-item__overlay\" aria-hidden=\"true\"></div>\n }\n <div class=\"carousel-item__content\">\n @if (visibleTags().length > 0) {\n <div class=\"carousel-item__tags\">\n @for (tag of visibleTags(); track tag.value) {\n <tk-tag\n [value]=\"tag.value\"\n [severity]=\"tag.severity ?? 'primary'\"\n [truncationLimit]=\"tagTruncationLimit\">\n </tk-tag>\n }\n </div>\n }\n <div class=\"carousel-item__text\">\n <h2 class=\"carousel-item__title\" [title]=\"slide().title\">{{ displayTitle() }}</h2>\n @if (slide().description) {\n <p class=\"carousel-item__description\" [title]=\"slide().description\">\n {{ displayDescription() }}\n </p>\n }\n </div>\n @if (slide().actionLabel) {\n <div class=\"carousel-item__action\">\n <tk-button\n [label]=\"slide().actionLabel\"\n severity=\"primary\"\n [icon]=\"slide().actionIcon\"\n iconPosition=\"right\"\n [full]=\"true\"\n (clicked)=\"onActionClick()\">\n </tk-button>\n </div>\n }\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;height:100%}.carousel-item{position:relative;display:flex;flex-direction:column;justify-content:flex-end;width:100%;height:var(--tk-carousel-height, 28.125rem);padding:var(--tk-spacing-padding-xl, 1.5rem);overflow:hidden;box-sizing:border-box}.carousel-item__image{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.carousel-item__overlay{position:absolute;right:0;bottom:0;left:0;height:50%;background:linear-gradient(180deg,#191a1b00,#191a1ba3)}.carousel-item__content{position:relative;display:flex;flex-direction:column;align-items:flex-start;width:100%}.carousel-item__tags{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.carousel-item__text{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem);width:100%}.carousel-item__title{max-width:100%;margin:0;overflow:hidden;color:var(--tk-color-text-inverse, #ffffff);font-size:var(--tk-font-size-headers-l, 2rem);font-weight:var(--tk-font-weight-600, 600);line-height:normal;white-space:nowrap;text-overflow:ellipsis}.carousel-item__description{display:-webkit-box;max-width:100%;margin:0;overflow:hidden;color:var(--tk-color-text-inverse, #ffffff);font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);line-height:normal;overflow-wrap:break-word;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.carousel-item__action{width:100%;margin-top:var(--tk-spacing-gap-s, .5rem)}.carousel-item__status{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--tk-spacing-gap-s, .5rem);width:100%;text-align:center}.carousel-item--plain{background:var(--tk-color-background-inverse, #191a1b)}.carousel-item--error{align-items:center;justify-content:center;background:var(--tk-color-feedback-danger-muted, #ffddd4)}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: FallbackViewComponent, selector: "tk-fallback-view", inputs: ["type", "imageSrc", "illustrationAlt", "title", "message", "buttonLabel", "linkLabel", "buttonDisabled"], outputs: ["buttonAction", "linkAction"] }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
75
|
+
}
|
|
76
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CarouselItemComponent, decorators: [{
|
|
77
|
+
type: Component,
|
|
78
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'tk-carousel-item', imports: [ButtonComponent, FallbackViewComponent, TagComponent], template: "<div\n class=\"carousel-item\"\n [class.carousel-item--error]=\"state() === 'error'\"\n [class.carousel-item--plain]=\"state() === 'default' && !slide().imageSrc\">\n @switch (state()) {\n @case ('error') {\n <output class=\"carousel-item__status\" [title]=\"slide().errorDescription ?? ''\">\n <tk-fallback-view\n [imageSrc]=\"slide().errorImageSrc ?? ''\"\n [illustrationAlt]=\"slide().errorTitle ?? ''\"\n [title]=\"displayErrorTitle()\"\n [message]=\"displayErrorDescription()\">\n </tk-fallback-view>\n </output>\n }\n @default {\n @if (slide().imageSrc) {\n <img\n class=\"carousel-item__image\"\n [src]=\"slide().imageSrc\"\n [alt]=\"altText()\"\n (error)=\"onImageError()\" />\n <div class=\"carousel-item__overlay\" aria-hidden=\"true\"></div>\n }\n <div class=\"carousel-item__content\">\n @if (visibleTags().length > 0) {\n <div class=\"carousel-item__tags\">\n @for (tag of visibleTags(); track tag.value) {\n <tk-tag\n [value]=\"tag.value\"\n [severity]=\"tag.severity ?? 'primary'\"\n [truncationLimit]=\"tagTruncationLimit\">\n </tk-tag>\n }\n </div>\n }\n <div class=\"carousel-item__text\">\n <h2 class=\"carousel-item__title\" [title]=\"slide().title\">{{ displayTitle() }}</h2>\n @if (slide().description) {\n <p class=\"carousel-item__description\" [title]=\"slide().description\">\n {{ displayDescription() }}\n </p>\n }\n </div>\n @if (slide().actionLabel) {\n <div class=\"carousel-item__action\">\n <tk-button\n [label]=\"slide().actionLabel\"\n severity=\"primary\"\n [icon]=\"slide().actionIcon\"\n iconPosition=\"right\"\n [full]=\"true\"\n (clicked)=\"onActionClick()\">\n </tk-button>\n </div>\n }\n </div>\n }\n }\n</div>\n", styles: [":host{display:block;height:100%}.carousel-item{position:relative;display:flex;flex-direction:column;justify-content:flex-end;width:100%;height:var(--tk-carousel-height, 28.125rem);padding:var(--tk-spacing-padding-xl, 1.5rem);overflow:hidden;box-sizing:border-box}.carousel-item__image{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.carousel-item__overlay{position:absolute;right:0;bottom:0;left:0;height:50%;background:linear-gradient(180deg,#191a1b00,#191a1ba3)}.carousel-item__content{position:relative;display:flex;flex-direction:column;align-items:flex-start;width:100%}.carousel-item__tags{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.carousel-item__text{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem);width:100%}.carousel-item__title{max-width:100%;margin:0;overflow:hidden;color:var(--tk-color-text-inverse, #ffffff);font-size:var(--tk-font-size-headers-l, 2rem);font-weight:var(--tk-font-weight-600, 600);line-height:normal;white-space:nowrap;text-overflow:ellipsis}.carousel-item__description{display:-webkit-box;max-width:100%;margin:0;overflow:hidden;color:var(--tk-color-text-inverse, #ffffff);font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);line-height:normal;overflow-wrap:break-word;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.carousel-item__action{width:100%;margin-top:var(--tk-spacing-gap-s, .5rem)}.carousel-item__status{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--tk-spacing-gap-s, .5rem);width:100%;text-align:center}.carousel-item--plain{background:var(--tk-color-background-inverse, #191a1b)}.carousel-item--error{align-items:center;justify-content:center;background:var(--tk-color-feedback-danger-muted, #ffddd4)}\n"] }]
|
|
79
|
+
}], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: true }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], imageError: [{ type: i0.Output, args: ["imageError"] }] } });
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @component CarouselComponent
|
|
83
|
+
* @description
|
|
84
|
+
* Adaptive carousel that displays a sequence of slides one at a time, each
|
|
85
|
+
* with a background image, up to two tags, a title, a description, and an
|
|
86
|
+
* optional call-to-action button. It wraps PrimeNG's `p-carousel` with the
|
|
87
|
+
* Tekus design system look.
|
|
88
|
+
*
|
|
89
|
+
* The rotation is always an infinite loop: after the last slide, next returns
|
|
90
|
+
* to the first one.
|
|
91
|
+
*
|
|
92
|
+
* Variants (`variant` input):
|
|
93
|
+
* - `'manual'` (default): the user navigates with arrows and indicator; if a
|
|
94
|
+
* slide image fails to load, an error fallback is shown in its place.
|
|
95
|
+
* - `'autoplay'`: the rotation advances automatically every 7 seconds with
|
|
96
|
+
* swipe gestures enabled; slides whose image fails to load are removed
|
|
97
|
+
* from the rotation silently (unattended usage).
|
|
98
|
+
*
|
|
99
|
+
* Indicators (`indicator` input):
|
|
100
|
+
* - `'dots'` (default): dot indicators overlaid at the bottom of the slide.
|
|
101
|
+
* - `'thumbnails'`: clickable image thumbnails rendered below the slide.
|
|
102
|
+
*
|
|
103
|
+
* The slide height can be customized with the `--tk-carousel-height` CSS
|
|
104
|
+
* variable (defaults to `28.125rem`).
|
|
105
|
+
*
|
|
106
|
+
* @usage
|
|
107
|
+
* ### Manual navigation (default)
|
|
108
|
+
* ```html
|
|
109
|
+
* <tk-carousel
|
|
110
|
+
* [slides]="slides"
|
|
111
|
+
* (slideChange)="onSlideChange($event)"
|
|
112
|
+
* (actionClick)="onActionClick($event)">
|
|
113
|
+
* </tk-carousel>
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* ### Autoplay with thumbnails
|
|
117
|
+
* ```html
|
|
118
|
+
* <tk-carousel
|
|
119
|
+
* [slides]="slides"
|
|
120
|
+
* variant="autoplay"
|
|
121
|
+
* indicator="thumbnails">
|
|
122
|
+
* </tk-carousel>
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
class CarouselComponent {
|
|
126
|
+
constructor() {
|
|
127
|
+
/** Slides to display. Each slide must have a stable unique `id`. */
|
|
128
|
+
this.slides = input.required(...(ngDevMode ? [{ debugName: "slides" }] : /* istanbul ignore next */ []));
|
|
129
|
+
/**
|
|
130
|
+
* Behavioral preset of the carousel.
|
|
131
|
+
* @default 'manual'
|
|
132
|
+
*/
|
|
133
|
+
this.variant = input('manual', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
134
|
+
/**
|
|
135
|
+
* Type of position indicator.
|
|
136
|
+
* @default 'dots'
|
|
137
|
+
*/
|
|
138
|
+
this.indicator = input('dots', ...(ngDevMode ? [{ debugName: "indicator" }] : /* istanbul ignore next */ []));
|
|
139
|
+
/** Emits when the active slide changes, via arrows, indicator, swipe, or autoplay. */
|
|
140
|
+
this.slideChange = output();
|
|
141
|
+
/** Emits the slide whose call-to-action button was clicked. */
|
|
142
|
+
this.actionClick = output();
|
|
143
|
+
/** Reference to the underlying PrimeNG carousel, used for thumbnail navigation. */
|
|
144
|
+
this.primeCarousel = viewChild(Carousel, ...(ngDevMode ? [{ debugName: "primeCarousel" }] : /* istanbul ignore next */ []));
|
|
145
|
+
/** Zero-based index of the active slide within the visible slides. */
|
|
146
|
+
this.currentIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
|
|
147
|
+
/** Ids of the slides whose image failed to load. */
|
|
148
|
+
this.failedSlideIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "failedSlideIds" }] : /* istanbul ignore next */ []));
|
|
149
|
+
/** Whether the autoplay preset is active. */
|
|
150
|
+
this.isAutoplay = computed(() => this.variant() === 'autoplay', ...(ngDevMode ? [{ debugName: "isAutoplay" }] : /* istanbul ignore next */ []));
|
|
151
|
+
/** Autoplay interval mapped from the variant preset. `0` disables autoplay. */
|
|
152
|
+
this.autoplayInterval = computed(() => this.isAutoplay() ? AUTOPLAY_INTERVAL_MS : 0, ...(ngDevMode ? [{ debugName: "autoplayInterval" }] : /* istanbul ignore next */ []));
|
|
153
|
+
/**
|
|
154
|
+
* Slides currently part of the rotation. The autoplay variant excludes
|
|
155
|
+
* slides whose image failed to load; the manual variant keeps them and
|
|
156
|
+
* shows an error fallback instead.
|
|
157
|
+
*/
|
|
158
|
+
this.visibleSlides = computed(() => {
|
|
159
|
+
const failed = this.failedSlideIds();
|
|
160
|
+
const slides = this.slides();
|
|
161
|
+
if (!this.isAutoplay() || failed.size === 0) {
|
|
162
|
+
return slides;
|
|
163
|
+
}
|
|
164
|
+
return slides.filter((slide) => !failed.has(slide.id));
|
|
165
|
+
}, ...(ngDevMode ? [{ debugName: "visibleSlides" }] : /* istanbul ignore next */ []));
|
|
166
|
+
/**
|
|
167
|
+
* Whether the navigation controls (arrows and indicators) are rendered.
|
|
168
|
+
* With a single visible slide there is nowhere to navigate, so they are hidden.
|
|
169
|
+
*/
|
|
170
|
+
this.showNavigation = computed(() => this.visibleSlides().length > 1, ...(ngDevMode ? [{ debugName: "showNavigation" }] : /* istanbul ignore next */ []));
|
|
171
|
+
/** Whether the dot indicator is rendered. */
|
|
172
|
+
this.showDots = computed(() => this.indicator() === 'dots' && this.showNavigation(), ...(ngDevMode ? [{ debugName: "showDots" }] : /* istanbul ignore next */ []));
|
|
173
|
+
/** Whether the thumbnail indicator is rendered. */
|
|
174
|
+
this.showThumbnails = computed(() => this.indicator() === 'thumbnails' && this.showNavigation(), ...(ngDevMode ? [{ debugName: "showThumbnails" }] : /* istanbul ignore next */ []));
|
|
175
|
+
}
|
|
176
|
+
onPage(event) {
|
|
177
|
+
const index = event.page ?? 0;
|
|
178
|
+
this.currentIndex.set(index);
|
|
179
|
+
const slide = this.visibleSlides()[index];
|
|
180
|
+
if (slide) {
|
|
181
|
+
this.slideChange.emit({ index, slide });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
onThumbnailClick(event, index) {
|
|
185
|
+
this.primeCarousel()?.onDotClick(event, index);
|
|
186
|
+
}
|
|
187
|
+
onImageError(slide) {
|
|
188
|
+
this.failedSlideIds.update((failed) => new Set(failed).add(slide.id));
|
|
189
|
+
}
|
|
190
|
+
onActionClick(slide) {
|
|
191
|
+
this.actionClick.emit(slide);
|
|
192
|
+
}
|
|
193
|
+
hasSlideError(slide) {
|
|
194
|
+
return slide.state === 'error' || this.failedSlideIds().has(slide.id);
|
|
195
|
+
}
|
|
196
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
197
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: CarouselComponent, isStandalone: true, selector: "tk-carousel", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, indicator: { classPropertyName: "indicator", publicName: "indicator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { slideChange: "slideChange", actionClick: "actionClick" }, viewQueries: [{ propertyName: "primeCarousel", first: true, predicate: Carousel, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"carousel\">\n <p-carousel\n [value]=\"visibleSlides()\"\n [numVisible]=\"1\"\n [numScroll]=\"1\"\n [circular]=\"showNavigation()\"\n [autoplayInterval]=\"autoplayInterval()\"\n [showIndicators]=\"showDots()\"\n [showNavigators]=\"showNavigation()\"\n (onPage)=\"onPage($event)\">\n <ng-template pTemplate=\"item\" let-slide>\n <tk-carousel-item\n [slide]=\"slide\"\n [hasError]=\"failedSlideIds().has(slide.id)\"\n (imageError)=\"onImageError(slide)\"\n (actionClick)=\"onActionClick(slide)\">\n </tk-carousel-item>\n </ng-template>\n <ng-template pTemplate=\"previousicon\">\n <tk-icon icon=\"angle-left\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n <ng-template pTemplate=\"nexticon\">\n <tk-icon icon=\"angle-right\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n </p-carousel>\n\n @if (showThumbnails()) {\n <div class=\"carousel__thumbnails\" role=\"tablist\">\n @for (slide of visibleSlides(); track slide.id) {\n <button\n type=\"button\"\n class=\"carousel__thumbnail\"\n [class.carousel__thumbnail--active]=\"currentIndex() === $index\"\n role=\"tab\"\n [attr.aria-selected]=\"currentIndex() === $index\"\n [attr.aria-label]=\"slide.title\"\n (click)=\"onThumbnailClick($event, $index)\">\n @if (hasSlideError(slide)) {\n <span class=\"carousel__thumbnail-placeholder carousel__thumbnail-placeholder--error\">\n <tk-icon icon=\"triangle-exclamation\" styleIcon=\"regular\"></tk-icon>\n </span>\n } @else if (!slide.imageSrc) {\n <span class=\"carousel__thumbnail-placeholder\"></span>\n } @else {\n <img class=\"carousel__thumbnail-image\" [src]=\"slide.imageSrc\" alt=\"\" />\n }\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block}.carousel{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-s, .5rem);width:100%}.carousel__thumbnails{display:flex;gap:var(--tk-spacing-gap-xs, .25rem);width:100%;overflow-x:auto}.carousel__thumbnail{flex-shrink:0;width:3.75rem;height:2.5rem;padding:0;border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:transparent;overflow:hidden;cursor:pointer}.carousel__thumbnail--active{outline:2px solid var(--tk-color-primary-default, #16006f);outline-offset:-2px}.carousel__thumbnail:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:-2px}.carousel__thumbnail-image{display:block;width:100%;height:100%;object-fit:cover;border-radius:var(--tk-borderRadius-xs, .25rem)}.carousel__thumbnail-placeholder{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-background-medium, #d2d2d2)}.carousel__thumbnail-placeholder--error{background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-default, #dc362e)}:host ::ng-deep .carousel .p-carousel{width:100%}:host ::ng-deep .carousel .p-carousel-content-container{position:relative;border-radius:var(--tk-borderRadius-m, 1rem) var(--tk-borderRadius-m, 1rem) 0 0;overflow:hidden}:host ::ng-deep .carousel .p-carousel-content{position:relative;gap:0}:host ::ng-deep .carousel .p-carousel-viewport{width:100%}:host ::ng-deep .carousel .p-carousel-prev-button,:host ::ng-deep .carousel .p-carousel-next-button{position:absolute;top:50%;z-index:1;width:2.5rem;height:2.5rem;transform:translateY(-50%);border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:#f2f1f166;color:var(--tk-color-text-default, #191a1b)}:host ::ng-deep .carousel .p-carousel-prev-button tk-icon,:host ::ng-deep .carousel .p-carousel-prev-button svg,:host ::ng-deep .carousel .p-carousel-next-button tk-icon,:host ::ng-deep .carousel .p-carousel-next-button svg{color:var(--tk-color-text-default, #191a1b)}:host ::ng-deep .carousel .p-carousel-prev-button .p-button,:host ::ng-deep .carousel .p-carousel-next-button .p-button{width:100%;height:100%;padding:0;border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:transparent;color:inherit;box-shadow:none}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:not(:disabled):hover,:host ::ng-deep .carousel .p-carousel-prev-button .p-button:not(:disabled):active,:host ::ng-deep .carousel .p-carousel-next-button .p-button:not(:disabled):hover,:host ::ng-deep .carousel .p-carousel-next-button .p-button:not(:disabled):active{border:none;background:transparent;color:inherit}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus,:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus-visible,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus-visible{border:none;box-shadow:none;outline:none}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus-visible,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:2px}:host ::ng-deep .carousel .p-carousel-prev-button:hover,:host ::ng-deep .carousel .p-carousel-next-button:hover{background:#f2f1f199}:host ::ng-deep .carousel .p-carousel-prev-button.p-disabled,:host ::ng-deep .carousel .p-carousel-next-button.p-disabled{opacity:.4}:host ::ng-deep .carousel .p-carousel-prev-button{left:var(--tk-spacing-padding-m, 1rem)}:host ::ng-deep .carousel .p-carousel-next-button{right:var(--tk-spacing-padding-m, 1rem)}:host ::ng-deep .carousel .p-carousel-indicator-list{position:absolute;right:0;bottom:var(--tk-spacing-padding-s, .5rem);left:0;z-index:1;display:flex;align-items:center;justify-content:center;gap:var(--tk-spacing-gap-xs, .25rem);margin:0;padding:0}:host ::ng-deep .carousel .p-carousel-indicator-button{width:.5rem;height:.5rem;border-radius:var(--tk-borderRadius-full, 62.4375rem);background:var(--tk-color-background-medium, #d2d2d2);transition:width .2s ease,background .2s ease}:host ::ng-deep .carousel .p-carousel-indicator-button:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:2px}:host ::ng-deep .carousel .p-carousel-indicator-active .p-carousel-indicator-button{width:1rem;background:var(--tk-color-background-strong, #8a8a8b)}\n"], dependencies: [{ kind: "ngmodule", type: CarouselModule }, { kind: "component", type: i1.Carousel, selector: "p-carousel", inputs: ["page", "numVisible", "numScroll", "responsiveOptions", "orientation", "verticalViewPortHeight", "contentClass", "indicatorsContentClass", "indicatorsContentStyle", "indicatorStyleClass", "indicatorStyle", "value", "circular", "showIndicators", "showNavigators", "autoplayInterval", "styleClass", "prevButtonProps", "nextButtonProps"], outputs: ["onPage"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: CarouselItemComponent, selector: "tk-carousel-item", inputs: ["slide", "hasError"], outputs: ["actionClick", "imageError"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
198
|
+
}
|
|
199
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: CarouselComponent, decorators: [{
|
|
200
|
+
type: Component,
|
|
201
|
+
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'tk-carousel', imports: [CarouselModule, CarouselItemComponent, IconComponent], template: "<div class=\"carousel\">\n <p-carousel\n [value]=\"visibleSlides()\"\n [numVisible]=\"1\"\n [numScroll]=\"1\"\n [circular]=\"showNavigation()\"\n [autoplayInterval]=\"autoplayInterval()\"\n [showIndicators]=\"showDots()\"\n [showNavigators]=\"showNavigation()\"\n (onPage)=\"onPage($event)\">\n <ng-template pTemplate=\"item\" let-slide>\n <tk-carousel-item\n [slide]=\"slide\"\n [hasError]=\"failedSlideIds().has(slide.id)\"\n (imageError)=\"onImageError(slide)\"\n (actionClick)=\"onActionClick(slide)\">\n </tk-carousel-item>\n </ng-template>\n <ng-template pTemplate=\"previousicon\">\n <tk-icon icon=\"angle-left\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n <ng-template pTemplate=\"nexticon\">\n <tk-icon icon=\"angle-right\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n </p-carousel>\n\n @if (showThumbnails()) {\n <div class=\"carousel__thumbnails\" role=\"tablist\">\n @for (slide of visibleSlides(); track slide.id) {\n <button\n type=\"button\"\n class=\"carousel__thumbnail\"\n [class.carousel__thumbnail--active]=\"currentIndex() === $index\"\n role=\"tab\"\n [attr.aria-selected]=\"currentIndex() === $index\"\n [attr.aria-label]=\"slide.title\"\n (click)=\"onThumbnailClick($event, $index)\">\n @if (hasSlideError(slide)) {\n <span class=\"carousel__thumbnail-placeholder carousel__thumbnail-placeholder--error\">\n <tk-icon icon=\"triangle-exclamation\" styleIcon=\"regular\"></tk-icon>\n </span>\n } @else if (!slide.imageSrc) {\n <span class=\"carousel__thumbnail-placeholder\"></span>\n } @else {\n <img class=\"carousel__thumbnail-image\" [src]=\"slide.imageSrc\" alt=\"\" />\n }\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block}.carousel{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-s, .5rem);width:100%}.carousel__thumbnails{display:flex;gap:var(--tk-spacing-gap-xs, .25rem);width:100%;overflow-x:auto}.carousel__thumbnail{flex-shrink:0;width:3.75rem;height:2.5rem;padding:0;border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:transparent;overflow:hidden;cursor:pointer}.carousel__thumbnail--active{outline:2px solid var(--tk-color-primary-default, #16006f);outline-offset:-2px}.carousel__thumbnail:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:-2px}.carousel__thumbnail-image{display:block;width:100%;height:100%;object-fit:cover;border-radius:var(--tk-borderRadius-xs, .25rem)}.carousel__thumbnail-placeholder{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-background-medium, #d2d2d2)}.carousel__thumbnail-placeholder--error{background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-default, #dc362e)}:host ::ng-deep .carousel .p-carousel{width:100%}:host ::ng-deep .carousel .p-carousel-content-container{position:relative;border-radius:var(--tk-borderRadius-m, 1rem) var(--tk-borderRadius-m, 1rem) 0 0;overflow:hidden}:host ::ng-deep .carousel .p-carousel-content{position:relative;gap:0}:host ::ng-deep .carousel .p-carousel-viewport{width:100%}:host ::ng-deep .carousel .p-carousel-prev-button,:host ::ng-deep .carousel .p-carousel-next-button{position:absolute;top:50%;z-index:1;width:2.5rem;height:2.5rem;transform:translateY(-50%);border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:#f2f1f166;color:var(--tk-color-text-default, #191a1b)}:host ::ng-deep .carousel .p-carousel-prev-button tk-icon,:host ::ng-deep .carousel .p-carousel-prev-button svg,:host ::ng-deep .carousel .p-carousel-next-button tk-icon,:host ::ng-deep .carousel .p-carousel-next-button svg{color:var(--tk-color-text-default, #191a1b)}:host ::ng-deep .carousel .p-carousel-prev-button .p-button,:host ::ng-deep .carousel .p-carousel-next-button .p-button{width:100%;height:100%;padding:0;border:none;border-radius:var(--tk-borderRadius-xs, .25rem);background:transparent;color:inherit;box-shadow:none}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:not(:disabled):hover,:host ::ng-deep .carousel .p-carousel-prev-button .p-button:not(:disabled):active,:host ::ng-deep .carousel .p-carousel-next-button .p-button:not(:disabled):hover,:host ::ng-deep .carousel .p-carousel-next-button .p-button:not(:disabled):active{border:none;background:transparent;color:inherit}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus,:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus-visible,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus-visible{border:none;box-shadow:none;outline:none}:host ::ng-deep .carousel .p-carousel-prev-button .p-button:focus-visible,:host ::ng-deep .carousel .p-carousel-next-button .p-button:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:2px}:host ::ng-deep .carousel .p-carousel-prev-button:hover,:host ::ng-deep .carousel .p-carousel-next-button:hover{background:#f2f1f199}:host ::ng-deep .carousel .p-carousel-prev-button.p-disabled,:host ::ng-deep .carousel .p-carousel-next-button.p-disabled{opacity:.4}:host ::ng-deep .carousel .p-carousel-prev-button{left:var(--tk-spacing-padding-m, 1rem)}:host ::ng-deep .carousel .p-carousel-next-button{right:var(--tk-spacing-padding-m, 1rem)}:host ::ng-deep .carousel .p-carousel-indicator-list{position:absolute;right:0;bottom:var(--tk-spacing-padding-s, .5rem);left:0;z-index:1;display:flex;align-items:center;justify-content:center;gap:var(--tk-spacing-gap-xs, .25rem);margin:0;padding:0}:host ::ng-deep .carousel .p-carousel-indicator-button{width:.5rem;height:.5rem;border-radius:var(--tk-borderRadius-full, 62.4375rem);background:var(--tk-color-background-medium, #d2d2d2);transition:width .2s ease,background .2s ease}:host ::ng-deep .carousel .p-carousel-indicator-button:focus-visible{outline:2px solid var(--tk-color-border-focus, #6ad0bc);outline-offset:2px}:host ::ng-deep .carousel .p-carousel-indicator-active .p-carousel-indicator-button{width:1rem;background:var(--tk-color-background-strong, #8a8a8b)}\n"] }]
|
|
202
|
+
}], propDecorators: { slides: [{ type: i0.Input, args: [{ isSignal: true, alias: "slides", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], indicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "indicator", required: false }] }], slideChange: [{ type: i0.Output, args: ["slideChange"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], primeCarousel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Carousel), { isSignal: true }] }] } });
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Generated bundle index. Do not edit.
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
export { AUTOPLAY_INTERVAL_MS, CarouselComponent, MAX_DESCRIPTION_LENGTH, MAX_TAG_LENGTH, MAX_TITLE_LENGTH, MAX_VISIBLE_TAGS };
|
|
209
|
+
//# sourceMappingURL=tekus-design-system-components-carousel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-carousel.mjs","sources":["../../../projects/design-system/components/carousel/src/carousel.types.ts","../../../projects/design-system/components/carousel/src/carousel-item.component.ts","../../../projects/design-system/components/carousel/src/carousel-item.component.html","../../../projects/design-system/components/carousel/src/carousel.component.ts","../../../projects/design-system/components/carousel/src/carousel.component.html","../../../projects/design-system/components/carousel/tekus-design-system-components-carousel.ts"],"sourcesContent":["import { TagSeverity } from '@tekus/design-system/components/tag';\n\n/**\n * Behavioral preset of the carousel. The rotation is always an infinite\n * loop: after the last slide, next returns to the first one.\n * - `'manual'`: the user navigates with arrows and indicator; failed slide\n * images show an error fallback in place.\n * - `'autoplay'`: the rotation advances automatically every 7 seconds with\n * swipe gestures enabled; failed slide images remove the slide from the\n * rotation without any error message (unattended usage).\n */\nexport type CarouselVariant = 'manual' | 'autoplay';\n\n/**\n * Type of position indicator rendered by the carousel.\n * - `'dots'`: dot indicators overlaid at the bottom of the slide.\n * - `'thumbnails'`: clickable image thumbnails rendered below the slide.\n */\nexport type CarouselIndicatorType = 'dots' | 'thumbnails';\n\n/**\n * Presentation state of a slide.\n * - `'default'`: regular slide with image and content.\n * - `'error'`: error view rendered with `tk-fallback-view`.\n *\n * Independently of this consumer-driven state, a slide whose image fails to\n * load is switched to the error view automatically.\n */\nexport type CarouselSlideState = 'default' | 'error';\n\n/**\n * Tag displayed over a slide, with an optional color scheme.\n * The severity accepts the same values as `tk-tag`\n * (`'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'danger' | 'contrast'`).\n */\nexport interface CarouselSlideTag {\n /** Text of the tag. */\n value: string;\n /**\n * Color scheme of the tag, forwarded to `tk-tag`.\n * @default 'primary'\n */\n severity?: TagSeverity;\n}\n\n/**\n * Data contract for a single carousel slide.\n */\nexport interface CarouselSlide {\n /** Stable unique identifier, used for tracking and error handling. */\n id: string | number;\n /** URL of the slide background image. When omitted, the content is rendered over a dark background. */\n imageSrc?: string;\n /** Alternative text for the background image. Falls back to `title`. */\n imageAlt?: string;\n /** Main heading displayed over the image. */\n title: string;\n /** Supporting text displayed below the title. */\n description?: string;\n /**\n * Short labels displayed above the title. Only the first two are rendered.\n * Plain strings render with the default color scheme; use `CarouselSlideTag`\n * objects to set a severity per tag.\n */\n tags?: (string | CarouselSlideTag)[];\n /** Label of the call-to-action button. When omitted, no button is rendered. */\n actionLabel?: string;\n /** Icon name (from the design system IconCatalog) shown in the action button. */\n actionIcon?: string;\n /**\n * Consumer-driven presentation state of the slide.\n * @default 'default'\n */\n state?: CarouselSlideState;\n /** Illustration URL for the error view, forwarded to `tk-fallback-view`. */\n errorImageSrc?: string;\n /** Title of the error view (manual variant only). */\n errorTitle?: string;\n /** Message of the error view (manual variant only). */\n errorDescription?: string;\n}\n\n/**\n * Payload emitted when the active slide changes.\n */\nexport interface CarouselSlideChangeEvent {\n /** Zero-based index of the active slide within the visible slides. */\n index: number;\n /** The slide that became active. */\n slide: CarouselSlide;\n}\n\n/** Autoplay interval, in milliseconds, applied by the autoplay variant. */\nexport const AUTOPLAY_INTERVAL_MS = 7000;\n\n/** Maximum number of tags rendered per slide. */\nexport const MAX_VISIBLE_TAGS = 2;\n\n/** Maximum number of characters of the slide title before truncation. */\nexport const MAX_TITLE_LENGTH = 50;\n\n/** Maximum number of characters of the slide description before truncation. */\nexport const MAX_DESCRIPTION_LENGTH = 140;\n\n/** Maximum number of characters per tag before truncation. */\nexport const MAX_TAG_LENGTH = 20;\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output,\n} from '@angular/core';\n\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { FallbackViewComponent } from '@tekus/design-system/components/fallback-view';\nimport { TagComponent } from '@tekus/design-system/components/tag';\n\nimport {\n CarouselSlide,\n CarouselSlideState,\n CarouselSlideTag,\n MAX_DESCRIPTION_LENGTH,\n MAX_TAG_LENGTH,\n MAX_TITLE_LENGTH,\n MAX_VISIBLE_TAGS,\n} from './carousel.types';\n\nconst truncateWithEllipsis = (text: string, maxLength: number): string =>\n text.length > maxLength ? text.substring(0, maxLength) + '…' : text;\n\n/**\n * @component CarouselItemComponent\n * @description\n * Internal slide renderer for `tk-carousel`. It is not part of the public API\n * of the design system and must only be used by `CarouselComponent`.\n *\n * Renders one of two views depending on the slide state:\n * - `default`: background image with a bottom gradient overlay, up to two\n * tags, a title, a description, and an optional call-to-action button.\n * - `error`: `tk-fallback-view` with an illustration and error messages.\n * Also used when the background image fails to load.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-carousel-item',\n imports: [ButtonComponent, FallbackViewComponent, TagComponent],\n templateUrl: './carousel-item.component.html',\n styleUrl: './carousel-item.component.scss',\n})\nexport class CarouselItemComponent {\n /** Slide data to render. */\n slide = input.required<CarouselSlide>();\n\n /** Whether the slide image failed to load and the error view must be shown. */\n hasError = input<boolean>(false);\n\n /** Emits when the call-to-action button is clicked. */\n actionClick = output<void>();\n\n /** Emits when the background image fails to load. */\n imageError = output<void>();\n\n /** Effective presentation state, combining the slide state and image load failures. */\n state = computed<CarouselSlideState>(() =>\n this.hasError() || this.slide().state === 'error' ? 'error' : 'default'\n );\n\n /** Tags normalized to `CarouselSlideTag` and limited to the maximum allowed by the design. */\n visibleTags = computed<CarouselSlideTag[]>(() => {\n const tags = this.slide().tags ?? [];\n return tags\n .slice(0, MAX_VISIBLE_TAGS)\n .map((tag) => (typeof tag === 'string' ? { value: tag } : tag));\n });\n\n /** Alternative text for the background image, falling back to the title. */\n altText = computed(() => this.slide().imageAlt ?? this.slide().title);\n\n /** Title truncated with an ellipsis when it exceeds the maximum length. */\n displayTitle = computed(() =>\n truncateWithEllipsis(this.slide().title, MAX_TITLE_LENGTH)\n );\n\n /** Description truncated with an ellipsis when it exceeds the maximum length. */\n displayDescription = computed(() =>\n truncateWithEllipsis(this.slide().description ?? '', MAX_DESCRIPTION_LENGTH)\n );\n\n /** Error title truncated with an ellipsis, using the same limit as the title. */\n displayErrorTitle = computed(() =>\n truncateWithEllipsis(this.slide().errorTitle ?? '', MAX_TITLE_LENGTH)\n );\n\n /** Error message truncated with an ellipsis, using the same limit as the description. */\n displayErrorDescription = computed(() =>\n truncateWithEllipsis(this.slide().errorDescription ?? '', MAX_DESCRIPTION_LENGTH)\n );\n\n /** Maximum characters per tag, forwarded to `tk-tag`. */\n readonly tagTruncationLimit = MAX_TAG_LENGTH;\n\n onImageError(): void {\n this.imageError.emit();\n }\n\n onActionClick(): void {\n this.actionClick.emit();\n }\n}\n","<div\n class=\"carousel-item\"\n [class.carousel-item--error]=\"state() === 'error'\"\n [class.carousel-item--plain]=\"state() === 'default' && !slide().imageSrc\">\n @switch (state()) {\n @case ('error') {\n <output class=\"carousel-item__status\" [title]=\"slide().errorDescription ?? ''\">\n <tk-fallback-view\n [imageSrc]=\"slide().errorImageSrc ?? ''\"\n [illustrationAlt]=\"slide().errorTitle ?? ''\"\n [title]=\"displayErrorTitle()\"\n [message]=\"displayErrorDescription()\">\n </tk-fallback-view>\n </output>\n }\n @default {\n @if (slide().imageSrc) {\n <img\n class=\"carousel-item__image\"\n [src]=\"slide().imageSrc\"\n [alt]=\"altText()\"\n (error)=\"onImageError()\" />\n <div class=\"carousel-item__overlay\" aria-hidden=\"true\"></div>\n }\n <div class=\"carousel-item__content\">\n @if (visibleTags().length > 0) {\n <div class=\"carousel-item__tags\">\n @for (tag of visibleTags(); track tag.value) {\n <tk-tag\n [value]=\"tag.value\"\n [severity]=\"tag.severity ?? 'primary'\"\n [truncationLimit]=\"tagTruncationLimit\">\n </tk-tag>\n }\n </div>\n }\n <div class=\"carousel-item__text\">\n <h2 class=\"carousel-item__title\" [title]=\"slide().title\">{{ displayTitle() }}</h2>\n @if (slide().description) {\n <p class=\"carousel-item__description\" [title]=\"slide().description\">\n {{ displayDescription() }}\n </p>\n }\n </div>\n @if (slide().actionLabel) {\n <div class=\"carousel-item__action\">\n <tk-button\n [label]=\"slide().actionLabel\"\n severity=\"primary\"\n [icon]=\"slide().actionIcon\"\n iconPosition=\"right\"\n [full]=\"true\"\n (clicked)=\"onActionClick()\">\n </tk-button>\n </div>\n }\n </div>\n }\n }\n</div>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\n\nimport { Carousel, CarouselModule, CarouselPageEvent } from 'primeng/carousel';\nimport { IconComponent } from '@tekus/design-system/components/icon';\n\nimport { CarouselItemComponent } from './carousel-item.component';\nimport {\n AUTOPLAY_INTERVAL_MS,\n CarouselIndicatorType,\n CarouselSlide,\n CarouselSlideChangeEvent,\n CarouselVariant,\n} from './carousel.types';\n\n/**\n * @component CarouselComponent\n * @description\n * Adaptive carousel that displays a sequence of slides one at a time, each\n * with a background image, up to two tags, a title, a description, and an\n * optional call-to-action button. It wraps PrimeNG's `p-carousel` with the\n * Tekus design system look.\n *\n * The rotation is always an infinite loop: after the last slide, next returns\n * to the first one.\n *\n * Variants (`variant` input):\n * - `'manual'` (default): the user navigates with arrows and indicator; if a\n * slide image fails to load, an error fallback is shown in its place.\n * - `'autoplay'`: the rotation advances automatically every 7 seconds with\n * swipe gestures enabled; slides whose image fails to load are removed\n * from the rotation silently (unattended usage).\n *\n * Indicators (`indicator` input):\n * - `'dots'` (default): dot indicators overlaid at the bottom of the slide.\n * - `'thumbnails'`: clickable image thumbnails rendered below the slide.\n *\n * The slide height can be customized with the `--tk-carousel-height` CSS\n * variable (defaults to `28.125rem`).\n *\n * @usage\n * ### Manual navigation (default)\n * ```html\n * <tk-carousel\n * [slides]=\"slides\"\n * (slideChange)=\"onSlideChange($event)\"\n * (actionClick)=\"onActionClick($event)\">\n * </tk-carousel>\n * ```\n *\n * ### Autoplay with thumbnails\n * ```html\n * <tk-carousel\n * [slides]=\"slides\"\n * variant=\"autoplay\"\n * indicator=\"thumbnails\">\n * </tk-carousel>\n * ```\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-carousel',\n imports: [CarouselModule, CarouselItemComponent, IconComponent],\n templateUrl: './carousel.component.html',\n styleUrl: './carousel.component.scss',\n})\nexport class CarouselComponent {\n /** Slides to display. Each slide must have a stable unique `id`. */\n slides = input.required<CarouselSlide[]>();\n\n /**\n * Behavioral preset of the carousel.\n * @default 'manual'\n */\n variant = input<CarouselVariant>('manual');\n\n /**\n * Type of position indicator.\n * @default 'dots'\n */\n indicator = input<CarouselIndicatorType>('dots');\n\n /** Emits when the active slide changes, via arrows, indicator, swipe, or autoplay. */\n slideChange = output<CarouselSlideChangeEvent>();\n\n /** Emits the slide whose call-to-action button was clicked. */\n actionClick = output<CarouselSlide>();\n\n /** Reference to the underlying PrimeNG carousel, used for thumbnail navigation. */\n primeCarousel = viewChild(Carousel);\n\n /** Zero-based index of the active slide within the visible slides. */\n currentIndex = signal(0);\n\n /** Ids of the slides whose image failed to load. */\n failedSlideIds = signal<ReadonlySet<CarouselSlide['id']>>(new Set());\n\n /** Whether the autoplay preset is active. */\n isAutoplay = computed(() => this.variant() === 'autoplay');\n\n /** Autoplay interval mapped from the variant preset. `0` disables autoplay. */\n autoplayInterval = computed(() =>\n this.isAutoplay() ? AUTOPLAY_INTERVAL_MS : 0\n );\n\n /**\n * Slides currently part of the rotation. The autoplay variant excludes\n * slides whose image failed to load; the manual variant keeps them and\n * shows an error fallback instead.\n */\n visibleSlides = computed(() => {\n const failed = this.failedSlideIds();\n const slides = this.slides();\n if (!this.isAutoplay() || failed.size === 0) {\n return slides;\n }\n return slides.filter((slide) => !failed.has(slide.id));\n });\n\n /**\n * Whether the navigation controls (arrows and indicators) are rendered.\n * With a single visible slide there is nowhere to navigate, so they are hidden.\n */\n showNavigation = computed(() => this.visibleSlides().length > 1);\n\n /** Whether the dot indicator is rendered. */\n showDots = computed(() => this.indicator() === 'dots' && this.showNavigation());\n\n /** Whether the thumbnail indicator is rendered. */\n showThumbnails = computed(\n () => this.indicator() === 'thumbnails' && this.showNavigation()\n );\n\n onPage(event: CarouselPageEvent): void {\n const index = event.page ?? 0;\n this.currentIndex.set(index);\n const slide = this.visibleSlides()[index];\n if (slide) {\n this.slideChange.emit({ index, slide });\n }\n }\n\n onThumbnailClick(event: MouseEvent, index: number): void {\n this.primeCarousel()?.onDotClick(event, index);\n }\n\n onImageError(slide: CarouselSlide): void {\n this.failedSlideIds.update((failed) => new Set(failed).add(slide.id));\n }\n\n onActionClick(slide: CarouselSlide): void {\n this.actionClick.emit(slide);\n }\n\n hasSlideError(slide: CarouselSlide): boolean {\n return slide.state === 'error' || this.failedSlideIds().has(slide.id);\n }\n}\n","<div class=\"carousel\">\n <p-carousel\n [value]=\"visibleSlides()\"\n [numVisible]=\"1\"\n [numScroll]=\"1\"\n [circular]=\"showNavigation()\"\n [autoplayInterval]=\"autoplayInterval()\"\n [showIndicators]=\"showDots()\"\n [showNavigators]=\"showNavigation()\"\n (onPage)=\"onPage($event)\">\n <ng-template pTemplate=\"item\" let-slide>\n <tk-carousel-item\n [slide]=\"slide\"\n [hasError]=\"failedSlideIds().has(slide.id)\"\n (imageError)=\"onImageError(slide)\"\n (actionClick)=\"onActionClick(slide)\">\n </tk-carousel-item>\n </ng-template>\n <ng-template pTemplate=\"previousicon\">\n <tk-icon icon=\"angle-left\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n <ng-template pTemplate=\"nexticon\">\n <tk-icon icon=\"angle-right\" styleIcon=\"solid\"></tk-icon>\n </ng-template>\n </p-carousel>\n\n @if (showThumbnails()) {\n <div class=\"carousel__thumbnails\" role=\"tablist\">\n @for (slide of visibleSlides(); track slide.id) {\n <button\n type=\"button\"\n class=\"carousel__thumbnail\"\n [class.carousel__thumbnail--active]=\"currentIndex() === $index\"\n role=\"tab\"\n [attr.aria-selected]=\"currentIndex() === $index\"\n [attr.aria-label]=\"slide.title\"\n (click)=\"onThumbnailClick($event, $index)\">\n @if (hasSlideError(slide)) {\n <span class=\"carousel__thumbnail-placeholder carousel__thumbnail-placeholder--error\">\n <tk-icon icon=\"triangle-exclamation\" styleIcon=\"regular\"></tk-icon>\n </span>\n } @else if (!slide.imageSrc) {\n <span class=\"carousel__thumbnail-placeholder\"></span>\n } @else {\n <img class=\"carousel__thumbnail-image\" [src]=\"slide.imageSrc\" alt=\"\" />\n }\n </button>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1003,7 +1003,7 @@ class ColorPickerComponent {
|
|
|
1003
1003
|
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
1004
1004
|
}
|
|
1005
1005
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1006
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ColorPickerComponent, isStandalone: true, selector: "tk-color-picker", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, presetColors: { classPropertyName: "presetColors", publicName: "presetColors", isSignal: true, isRequired: false, transformFunction: null }, contrastColor: { classPropertyName: "contrastColor", publicName: "contrastColor", isSignal: true, isRequired: false, transformFunction: null }, maxCustomColors: { classPropertyName: "maxCustomColors", publicName: "maxCustomColors", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, customColors: { classPropertyName: "customColors", publicName: "customColors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", customColors: "customColorsChange", colorChange: "colorChange", textColorChange: "textColorChange", validChange: "validChange", opened: "opened", closed: "closed" }, viewQueries: [{ propertyName: "popover", first: true, predicate: ["op"], descendants: true, isSignal: true }, { propertyName: "swatchBtnRef", first: true, predicate: ["swatchBtn"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "inputTriggerRef", first: true, predicate: ["inputTrigger"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "panelHexInput", first: true, predicate: ["panelHexInput"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div\n class=\"tk-color-picker\"\n [class.tk-color-picker--disabled]=\"isDisabled()\"\n [class.tk-color-picker--open]=\"isOpen()\"\n [class.tk-color-picker--invalid]=\"!isValid()\">\n @if (variant() === 'swatch') {\n @if (label()) {\n <span class=\"tk-color-picker__label\">{{ label() }}</span>\n }\n <button\n #swatchBtn\n type=\"button\"\n class=\"tk-color-picker__trigger tk-color-picker__trigger--swatch\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-label]=\"t().openPickerLabel + (label() ? ': ' + label() : '')\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onTriggerClick($event)\">\n <span\n class=\"tk-color-picker__swatch\"\n [class.tk-color-picker__swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor()\"\n aria-hidden=\"true\"></span>\n <tk-icon\n class=\"tk-color-picker__chevron\"\n [class.tk-color-picker__chevron--open]=\"isOpen()\"\n icon=\"chevron-down\"\n styleIcon=\"regular\"\n size=\"xs\"></tk-icon>\n </button>\n } @else {\n <div\n #inputTrigger\n class=\"tk-color-picker__trigger-input\"\n [class.tk-color-picker__trigger-input--invalid]=\"!isValid()\">\n @if (label()) {\n <label\n class=\"tk-color-picker__input-label\"\n [for]=\"fieldId\"\n [title]=\"label()\"\n >{{ label() }}</label\n >\n }\n <div class=\"tk-color-picker__input-wrap\">\n <button\n type=\"button\"\n class=\"tk-color-picker__input-swatch\"\n [class.tk-color-picker__input-swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"t().openPickerLabel\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onTriggerClick($event)\"></button>\n <span class=\"tk-color-picker__input-prefix\" aria-hidden=\"true\">#</span>\n <input\n pInputText\n [id]=\"fieldId\"\n [value]=\"displayHexNoHash()\"\n [disabled]=\"isDisabled()\"\n [class.ng-invalid]=\"triggerControl.invalid\"\n [class.ng-dirty]=\"triggerControl.dirty\"\n [class.ng-touched]=\"triggerControl.touched\"\n [attr.aria-describedby]=\"!isValid() ? errorId : null\"\n [attr.aria-invalid]=\"!isValid()\"\n autocomplete=\"off\"\n (input)=\"onHexNativeInput($event)\"\n (keydown)=\"onHexKeydown($event)\"\n (paste)=\"onHexPaste($event)\"\n (blur)=\"onHexBlur()\" />\n </div>\n <div class=\"tk-color-picker__input-bottom\">\n @if (!isValid()) {\n <p-message\n severity=\"error\"\n size=\"small\"\n variant=\"simple\"\n [id]=\"errorId\"\n >{{ errorText() }}</p-message\n >\n } @else if (hint()) {\n <p-message severity=\"secondary\" size=\"small\" variant=\"simple\">{{\n hint()\n }}</p-message>\n }\n </div>\n </div>\n }\n\n @if (variant() === 'swatch') {\n @if (!isValid()) {\n <span\n [id]=\"errorId\"\n class=\"tk-color-picker__error\"\n role=\"alert\"\n aria-live=\"polite\">\n {{ errorText() }}\n </span>\n } @else if (hint()) {\n <span class=\"tk-color-picker__hint\">{{ hint() }}</span>\n }\n }\n</div>\n\n<p-popover\n #op\n [styleClass]=\"\n 'tk-color-picker-popover' +\n (variant() === 'input' ? ' tk-color-picker-popover--input' : '')\n \"\n position=\"bottom\"\n appendTo=\"body\"\n (onShow)=\"onPopoverShow()\"\n (onHide)=\"onPopoverHide()\">\n <div\n class=\"tk-color-picker__panel\"\n role=\"group\"\n [attr.aria-label]=\"t().dialogLabel\"\n tabindex=\"-1\"\n autofocus\n (keydown.enter)=\"onPanelEnter($event)\">\n @if (resolvedSections().swatches && presetColors().length) {\n <section class=\"tk-color-picker__section\">\n <span class=\"tk-color-picker__section-label\">{{\n t().swatchesLabel\n }}</span>\n <tk-color-picker-swatch-grid\n [colors]=\"presetColors()\"\n [selected]=\"draftHex()\"\n [ariaLabel]=\"t().swatchesLabel\"\n (picked)=\"onSwatchPick($event)\" />\n </section>\n }\n\n @if (resolvedSections().customColors) {\n <section class=\"tk-color-picker__section\">\n <span class=\"tk-color-picker__section-label\">{{\n t().customColorsLabel\n }}</span>\n <tk-color-picker-swatch-grid\n [colors]=\"customColors()\"\n [selected]=\"draftHex()\"\n [ariaLabel]=\"t().customColorsLabel\"\n (picked)=\"onSwatchPick($event)\">\n @if (canAddCustom()) {\n <button\n type=\"button\"\n class=\"tk-color-picker__add-custom\"\n [attr.aria-label]=\"t().addCustomColorLabel\"\n (click)=\"addCustomColor()\">\n <tk-icon icon=\"plus\" styleIcon=\"regular\" size=\"xs\"></tk-icon>\n </button>\n }\n @if (isCustomColorSelected()) {\n <button\n type=\"button\"\n class=\"tk-color-picker__remove-custom\"\n [attr.aria-label]=\"t().removeCustomColorLabel\"\n (click)=\"removeCustomColor()\">\n \u2212\n </button>\n }\n </tk-color-picker-swatch-grid>\n </section>\n }\n\n @if (\n resolvedSections().customColors &&\n (resolvedSections().spectrum ||\n resolvedSections().hue ||\n resolvedSections().hex)\n ) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (resolvedSections().spectrum) {\n <tk-color-picker-spectrum\n [hue]=\"hue()\"\n [saturation]=\"saturation()\"\n [brightness]=\"brightness()\"\n [color]=\"swatchColor() ?? ''\"\n [ariaLabel]=\"t().spectrumLabel\"\n (changed)=\"onSpectrumChange($event)\" />\n }\n\n @if (resolvedSections().hue) {\n <input\n class=\"tk-color-picker__hue\"\n type=\"range\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n [attr.aria-label]=\"t().hueLabel\"\n (input)=\"onHueChange($event)\" />\n }\n\n @if (\n (resolvedSections().spectrum || resolvedSections().hue) &&\n resolvedSections().hex\n ) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (resolvedSections().hex) {\n <section class=\"tk-color-picker__section tk-color-picker__hex-row\">\n <span\n class=\"tk-color-picker__swatch tk-color-picker__swatch--large\"\n [class.tk-color-picker__swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor()\"\n aria-hidden=\"true\"></span>\n <tk-input-text\n #panelHexInput\n class=\"tk-color-picker__panel-hex\"\n [class.tk-color-picker__trigger-input--invalid]=\"!isValid()\"\n [label]=\"t().hexLabel\"\n [id]=\"panelFieldId\"\n [value]=\"displayHexNoHash()\"\n prefixText=\"#\"\n (input)=\"onHexNativeInput($event)\"\n (keydown)=\"onHexKeydown($event)\"\n (paste)=\"onHexPaste($event)\"\n (focusout)=\"onHexBlur()\" />\n @if (showEyedropper()) {\n <tk-button\n class=\"tk-color-picker__eyedropper\"\n tabindex=\"-1\"\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"eye-dropper\"\n styleIcon=\"regular\"\n [attr.aria-label]=\"t().eyedropperLabel\"\n (clicked)=\"openEyeDropper()\">\n </tk-button>\n }\n </section>\n }\n\n @if (resolvedSections().hex && showContrast()) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (showContrast()) {\n <section class=\"tk-color-picker__section tk-color-picker__contrast\">\n <span class=\"tk-color-picker__section-label\">{{\n t().contrastLabel\n }}</span>\n <div class=\"tk-color-picker__contrast-row\">\n <span\n class=\"tk-color-picker__contrast-pill\"\n [style.background-color]=\"draftHex()\"\n [attr.aria-label]=\"t().contrastSampleLabel\">\n <span\n class=\"tk-color-picker__contrast-sample\"\n [style.color]=\"contrastTextColor()\">\n {{ t().contrastSampleText }}\n </span>\n </span>\n <div class=\"tk-color-picker__contrast-info\">\n <span class=\"tk-color-picker__contrast-label\">{{\n t().contrastSampleLabel\n }}</span>\n <span class=\"tk-color-picker__contrast-ratio\"\n >{{ contrastResult()!.ratio }}:1</span\n >\n </div>\n @switch (contrastResult()!.level) {\n @case ('AAA') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--aaa\"\n >AAA</span\n >\n }\n @case ('AA') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--aa\"\n >AA</span\n >\n }\n @case ('fail') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--fail\">\n {{ t().contrastLowLabel }}\n </span>\n }\n }\n </div>\n </section>\n }\n </div>\n</p-popover>\n", styles: [":host{display:inline-block;font-family:var(--tk-font-family, sans-serif)}.tk-color-picker{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-color-picker__label{font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-950, #191a1b);margin-bottom:.25rem}.tk-color-picker__trigger{display:flex;align-items:center;gap:var(--tk-spacing-gap-s, .5rem);padding:var(--tk-spacing-padding-xs, .25rem) var(--tk-spacing-padding-s, .5rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);border-radius:var(--tk-borderRadius-s, .25rem);background:var(--tk-color-background-default, #ffffff);cursor:pointer;transition:border-color .14s ease,background .14s ease}.tk-color-picker__trigger:hover{border-color:var(--tk-color-border-default, #cecdcd)}.tk-color-picker__trigger:focus-within{border-color:var(--tk-color-border-focus, #16006f)}.tk-color-picker__trigger--swatch{appearance:none;width:fit-content;font:inherit;-webkit-user-select:none;user-select:none}.tk-color-picker__trigger--swatch>*{pointer-events:none}.tk-color-picker__trigger--swatch:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__trigger--swatch:disabled{cursor:not-allowed}.tk-color-picker__trigger-input{display:flex;flex-direction:column;position:relative}.tk-color-picker__input-label{position:absolute;left:var(--tk-spacing-base-300, 3rem);top:.75rem;font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-500, #8a8a8b);background:var(--tk-color-background-default, #ffffff);padding:0 .25rem;transition:top .2s ease,left .2s ease,color .2s ease;pointer-events:none;z-index:1;max-width:calc(100% - 4rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tk-color-picker--disabled .tk-color-picker__input-label{display:none}.tk-color-picker--invalid .tk-color-picker__input-label{color:var(--tk-color-base-red-700, #cf2604)}.tk-color-picker__input-wrap{position:relative;display:flex;align-items:center;width:100%}.tk-color-picker__input-wrap input.p-inputtext{width:100%;flex:1;border:none;border-bottom:.0625rem solid var(--tk-color-base-surface-300, #d2d2d2);border-radius:0;padding:var(--tk-spacing-base-75, .75rem);padding-left:var(--tk-spacing-base-300, 3rem);color:var(--tk-color-base-surface-950, #191a1b);background-color:transparent;outline:none}.tk-color-picker__input-wrap input.p-inputtext:focus{border-color:var(--tk-color-base-primary-600, #140065);box-shadow:none}.tk-color-picker__input-wrap input.p-inputtext.ng-invalid.ng-dirty,.tk-color-picker__input-wrap input.p-inputtext.ng-invalid.ng-touched{border-color:var(--tk-color-base-red-700, #cf2604)}.tk-color-picker__input-wrap input.p-inputtext:disabled{background-color:var(--tk-color-base-surface-200, #e4e4e4);color:var(--tk-color-base-surface-500, #8a8a8b);opacity:1}.tk-color-picker__input-swatch{appearance:none;padding:0;position:absolute;left:var(--tk-spacing-base-25, .25rem);top:50%;transform:translateY(-50%);width:1.25rem;height:1.25rem;border-radius:var(--tk-borderRadius-xs, .125rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0;cursor:pointer;z-index:1;-webkit-user-select:none;user-select:none;background:transparent}.tk-color-picker__input-swatch--fallback{background:var(--tk-color-base-surface-400, #cecdcd)}.tk-color-picker__input-swatch:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__input-swatch:disabled{cursor:not-allowed;opacity:.5}.tk-color-picker__input-prefix{position:absolute;left:calc(var(--tk-spacing-base-25, .25rem) + 1.25rem + .25rem);top:50%;transform:translateY(-50%);color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-s, .875rem);line-height:1;pointer-events:none;z-index:1}.tk-color-picker__input-bottom{display:flex;margin-top:.25rem;min-height:1.25rem}.tk-color-picker--open .tk-color-picker__trigger{border-color:var(--tk-color-border-strong, #424243)}.tk-color-picker--invalid .tk-color-picker__trigger{border-color:var(--tk-color-feedback-danger-default, #ff6640)}.tk-color-picker--disabled .tk-color-picker__trigger{opacity:.55;cursor:not-allowed;pointer-events:none;background:var(--tk-color-background-soft, #f2f1f1)}.tk-color-picker__swatch{flex-shrink:0;width:1.25rem;height:1.25rem;border-radius:var(--tk-borderRadius-xs, .125rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4)}.tk-color-picker__swatch--fallback{background:var(--tk-color-base-surface-400, #cecdcd)}.tk-color-picker__swatch--large{width:2rem;height:2rem;border-radius:var(--tk-borderRadius-s, .25rem)}.tk-color-picker__chevron{transition:transform .2s ease}.tk-color-picker__chevron--open{transform:rotate(180deg)}.tk-color-picker__error{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-feedback-danger-default, #ff6640)}.tk-color-picker__hint{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-text-muted, #8a8a8b)}.tk-color-picker__panel{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-m, .75rem);width:16rem;padding:var(--tk-spacing-padding-m, 1rem);box-sizing:border-box}.tk-color-picker__panel:focus,.tk-color-picker__panel:focus-visible{outline:none}.tk-color-picker__section{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-color-picker__section-label{font-size:var(--tk-font-size-legal-m, .75rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-subtle, #5d5d5e)}.tk-color-picker__add-custom{appearance:none;padding:0;width:100%;aspect-ratio:1;border:1px dashed var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-xs, .125rem);background:var(--tk-color-background-default, #ffffff);color:var(--tk-color-text-muted, #8a8a8b);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color .12s ease,color .12s ease}.tk-color-picker__add-custom:hover{border-color:var(--tk-color-accent-default, #6ad0bc);color:var(--tk-color-accent-default, #6ad0bc)}.tk-color-picker__add-custom:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__remove-custom{appearance:none;padding:0;width:100%;aspect-ratio:1;border:1px dashed var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-xs, .125rem);background:var(--tk-color-background-default, #ffffff);color:var(--tk-color-text-muted, #8a8a8b);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color .12s ease,color .12s ease}.tk-color-picker__remove-custom:hover{border-color:var(--tk-color-accent-default, #6ad0bc);color:var(--tk-color-accent-default, #6ad0bc)}.tk-color-picker__remove-custom:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__hue{appearance:none;width:100%;height:.625rem;border-radius:var(--tk-borderRadius-full, 9999px);outline:none;cursor:pointer;background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.tk-color-picker__hue::-webkit-slider-thumb{appearance:none;width:1.125rem;height:1.125rem;border-radius:var(--tk-borderRadius-full, 50%);background:var(--tk-color-background-default, #ffffff);border:1px solid var(--tk-color-border-default, #cecdcd);cursor:grab}.tk-color-picker__hue::-moz-range-thumb{width:1.125rem;height:1.125rem;border-radius:var(--tk-borderRadius-full, 50%);background:var(--tk-color-background-default, #ffffff);border:1px solid var(--tk-color-border-default, #cecdcd);cursor:grab}.tk-color-picker__hue:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:2px}.tk-color-picker__divider{width:100%;height:1px;background:var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0}.tk-color-picker__hex-row{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-gap-s, .5rem);margin-top:var(--tk-spacing-gap-s, .5rem)}.tk-color-picker__hex-row>span{flex-shrink:0}.tk-color-picker__hex-row tk-button{flex-shrink:0;min-width:2.5rem;min-height:2.5rem}.tk-color-picker__eyedropper{margin-top:-12px}.tk-color-picker__eyedropper:focus,.tk-color-picker__eyedropper:focus-visible{outline:none;box-shadow:none}.tk-color-picker__panel-hex{flex:1;min-width:0}.tk-color-picker__contrast-row{display:flex;align-items:center;gap:var(--tk-spacing-gap-s, .5rem)}.tk-color-picker__contrast-pill{flex-shrink:0;width:2.5rem;height:2rem;border-radius:var(--tk-borderRadius-s, .25rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);display:inline-flex;align-items:center;justify-content:center}.tk-color-picker__contrast-sample{font-size:var(--tk-font-size-paragraph-s, .875rem);font-weight:var(--tk-font-weight-600, 600);line-height:1}.tk-color-picker__contrast-info{flex:1;min-width:0;display:flex;flex-direction:column}.tk-color-picker__contrast-label{font-size:var(--tk-font-size-legal-m, .75rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-default, #222324)}.tk-color-picker__contrast-ratio{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-text-muted, #8a8a8b)}.tk-color-picker__contrast-badge{flex-shrink:0;font-size:var(--tk-font-size-legal-s, .625rem);font-weight:var(--tk-font-weight-600, 600);padding:var(--tk-spacing-padding-xs, .25rem) var(--tk-spacing-padding-s, .5rem);border-radius:var(--tk-borderRadius-full, 9999px)}.tk-color-picker__contrast-badge--aaa,.tk-color-picker__contrast-badge--aa{background:var(--tk-color-feedback-success-muted, #d1fadf);color:var(--tk-color-feedback-success-strong, #114a3f)}.tk-color-picker__contrast-badge--fail{background:var(--tk-color-feedback-danger-muted, #feede8);color:var(--tk-color-feedback-danger-strong, #7f1d1d)}::ng-deep .tk-color-picker-popover{margin:0!important}::ng-deep .tk-color-picker-popover:before,::ng-deep .tk-color-picker-popover:after{display:none!important}::ng-deep .tk-color-picker-popover--input{margin-top:-22px!important}:host ::ng-deep .tk-color-picker__trigger-input--invalid input.p-inputtext{border-color:var(--tk-color-feedback-danger-default, #ff6640)}:host ::ng-deep .tk-color-picker__trigger-input:has(input:focus) .tk-color-picker__input-label{top:-.75rem;left:0;font-size:var(--tk-font-size-legal-m, .75rem);color:var(--tk-color-base-primary-600, #140065);max-width:none;overflow:visible;text-overflow:clip}:host ::ng-deep .tk-color-picker__trigger-input:has(input.p-filled) .tk-color-picker__input-label{top:-.75rem;left:0;font-size:var(--tk-font-size-legal-m, .75rem);color:var(--tk-color-base-surface-950, #191a1b);max-width:none;overflow:visible;text-overflow:clip}:host ::ng-deep .tk-color-picker__trigger-input:has(input.ng-invalid.ng-dirty) .tk-color-picker__input-label,:host ::ng-deep .tk-color-picker__trigger-input:has(input.ng-invalid.ng-touched) .tk-color-picker__input-label{color:var(--tk-color-base-red-700, #cf2604)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i2.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "size"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: InputTextComponent, selector: "tk-input-text", inputs: ["value", "control", "label", "type", "id", "icon", "clearable", "errorMessage", "hint", "maxLength"], outputs: ["valueChange"] }, { kind: "component", type: ColorPickerSpectrumComponent, selector: "tk-color-picker-spectrum", inputs: ["hue", "saturation", "brightness", "color", "ariaLabel"], outputs: ["changed"] }, { kind: "component", type: ColorPickerSwatchGridComponent, selector: "tk-color-picker-swatch-grid", inputs: ["colors", "selected", "ariaLabel"], outputs: ["picked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1006
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: ColorPickerComponent, isStandalone: true, selector: "tk-color-picker", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null }, presetColors: { classPropertyName: "presetColors", publicName: "presetColors", isSignal: true, isRequired: false, transformFunction: null }, contrastColor: { classPropertyName: "contrastColor", publicName: "contrastColor", isSignal: true, isRequired: false, transformFunction: null }, maxCustomColors: { classPropertyName: "maxCustomColors", publicName: "maxCustomColors", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, texts: { classPropertyName: "texts", publicName: "texts", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, customColors: { classPropertyName: "customColors", publicName: "customColors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", customColors: "customColorsChange", colorChange: "colorChange", textColorChange: "textColorChange", validChange: "validChange", opened: "opened", closed: "closed" }, viewQueries: [{ propertyName: "popover", first: true, predicate: ["op"], descendants: true, isSignal: true }, { propertyName: "swatchBtnRef", first: true, predicate: ["swatchBtn"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "inputTriggerRef", first: true, predicate: ["inputTrigger"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "panelHexInput", first: true, predicate: ["panelHexInput"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div\n class=\"tk-color-picker\"\n [class.tk-color-picker--disabled]=\"isDisabled()\"\n [class.tk-color-picker--open]=\"isOpen()\"\n [class.tk-color-picker--invalid]=\"!isValid()\">\n @if (variant() === 'swatch') {\n @if (label()) {\n <span class=\"tk-color-picker__label\">{{ label() }}</span>\n }\n <button\n #swatchBtn\n type=\"button\"\n class=\"tk-color-picker__trigger tk-color-picker__trigger--swatch\"\n [disabled]=\"isDisabled()\"\n aria-haspopup=\"dialog\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-label]=\"t().openPickerLabel + (label() ? ': ' + label() : '')\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onTriggerClick($event)\">\n <span\n class=\"tk-color-picker__swatch\"\n [class.tk-color-picker__swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor()\"\n aria-hidden=\"true\"></span>\n <tk-icon\n class=\"tk-color-picker__chevron\"\n [class.tk-color-picker__chevron--open]=\"isOpen()\"\n icon=\"chevron-down\"\n styleIcon=\"regular\"\n size=\"xs\"></tk-icon>\n </button>\n } @else {\n <div\n #inputTrigger\n class=\"tk-color-picker__trigger-input\"\n [class.tk-color-picker__trigger-input--invalid]=\"!isValid()\">\n @if (label()) {\n <label\n class=\"tk-color-picker__input-label\"\n [for]=\"fieldId\"\n [title]=\"label()\"\n >{{ label() }}</label\n >\n }\n <div class=\"tk-color-picker__input-wrap\">\n <button\n type=\"button\"\n class=\"tk-color-picker__input-swatch\"\n [class.tk-color-picker__input-swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"t().openPickerLabel\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"onTriggerClick($event)\"></button>\n <span class=\"tk-color-picker__input-prefix\" aria-hidden=\"true\">#</span>\n <input\n pInputText\n [id]=\"fieldId\"\n [value]=\"displayHexNoHash()\"\n [disabled]=\"isDisabled()\"\n [class.ng-invalid]=\"triggerControl.invalid\"\n [class.ng-dirty]=\"triggerControl.dirty\"\n [class.ng-touched]=\"triggerControl.touched\"\n [attr.aria-describedby]=\"!isValid() ? errorId : null\"\n [attr.aria-invalid]=\"!isValid()\"\n autocomplete=\"off\"\n (input)=\"onHexNativeInput($event)\"\n (keydown)=\"onHexKeydown($event)\"\n (paste)=\"onHexPaste($event)\"\n (blur)=\"onHexBlur()\" />\n </div>\n <div class=\"tk-color-picker__input-bottom\">\n @if (!isValid()) {\n <p-message\n severity=\"error\"\n size=\"small\"\n variant=\"simple\"\n [id]=\"errorId\"\n >{{ errorText() }}</p-message\n >\n } @else if (hint()) {\n <p-message severity=\"secondary\" size=\"small\" variant=\"simple\">{{\n hint()\n }}</p-message>\n }\n </div>\n </div>\n }\n\n @if (variant() === 'swatch') {\n @if (!isValid()) {\n <span\n [id]=\"errorId\"\n class=\"tk-color-picker__error\"\n role=\"alert\"\n aria-live=\"polite\">\n {{ errorText() }}\n </span>\n } @else if (hint()) {\n <span class=\"tk-color-picker__hint\">{{ hint() }}</span>\n }\n }\n</div>\n\n<p-popover\n #op\n [styleClass]=\"\n 'tk-color-picker-popover' +\n (variant() === 'input' ? ' tk-color-picker-popover--input' : '')\n \"\n position=\"bottom\"\n appendTo=\"body\"\n (onShow)=\"onPopoverShow()\"\n (onHide)=\"onPopoverHide()\">\n <div\n class=\"tk-color-picker__panel\"\n role=\"group\"\n [attr.aria-label]=\"t().dialogLabel\"\n tabindex=\"-1\"\n autofocus\n (keydown.enter)=\"onPanelEnter($event)\">\n @if (resolvedSections().swatches && presetColors().length) {\n <section class=\"tk-color-picker__section\">\n <span class=\"tk-color-picker__section-label\">{{\n t().swatchesLabel\n }}</span>\n <tk-color-picker-swatch-grid\n [colors]=\"presetColors()\"\n [selected]=\"draftHex()\"\n [ariaLabel]=\"t().swatchesLabel\"\n (picked)=\"onSwatchPick($event)\" />\n </section>\n }\n\n @if (resolvedSections().customColors) {\n <section class=\"tk-color-picker__section\">\n <span class=\"tk-color-picker__section-label\">{{\n t().customColorsLabel\n }}</span>\n <tk-color-picker-swatch-grid\n [colors]=\"customColors()\"\n [selected]=\"draftHex()\"\n [ariaLabel]=\"t().customColorsLabel\"\n (picked)=\"onSwatchPick($event)\">\n @if (canAddCustom()) {\n <button\n type=\"button\"\n class=\"tk-color-picker__add-custom\"\n [attr.aria-label]=\"t().addCustomColorLabel\"\n (click)=\"addCustomColor()\">\n <tk-icon icon=\"plus\" styleIcon=\"regular\" size=\"xs\"></tk-icon>\n </button>\n }\n @if (isCustomColorSelected()) {\n <button\n type=\"button\"\n class=\"tk-color-picker__remove-custom\"\n [attr.aria-label]=\"t().removeCustomColorLabel\"\n (click)=\"removeCustomColor()\">\n \u2212\n </button>\n }\n </tk-color-picker-swatch-grid>\n </section>\n }\n\n @if (\n resolvedSections().customColors &&\n (resolvedSections().spectrum ||\n resolvedSections().hue ||\n resolvedSections().hex)\n ) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (resolvedSections().spectrum) {\n <tk-color-picker-spectrum\n [hue]=\"hue()\"\n [saturation]=\"saturation()\"\n [brightness]=\"brightness()\"\n [color]=\"swatchColor() ?? ''\"\n [ariaLabel]=\"t().spectrumLabel\"\n (changed)=\"onSpectrumChange($event)\" />\n }\n\n @if (resolvedSections().hue) {\n <input\n class=\"tk-color-picker__hue\"\n type=\"range\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n [attr.aria-label]=\"t().hueLabel\"\n (input)=\"onHueChange($event)\" />\n }\n\n @if (\n (resolvedSections().spectrum || resolvedSections().hue) &&\n resolvedSections().hex\n ) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (resolvedSections().hex) {\n <section class=\"tk-color-picker__section tk-color-picker__hex-row\">\n <span\n class=\"tk-color-picker__swatch tk-color-picker__swatch--large\"\n [class.tk-color-picker__swatch--fallback]=\"!swatchColor()\"\n [style.background-color]=\"swatchColor()\"\n aria-hidden=\"true\"></span>\n <tk-input-text\n #panelHexInput\n class=\"tk-color-picker__panel-hex\"\n [class.tk-color-picker__trigger-input--invalid]=\"!isValid()\"\n [label]=\"t().hexLabel\"\n [id]=\"panelFieldId\"\n [value]=\"displayHexNoHash()\"\n prefixText=\"#\"\n (input)=\"onHexNativeInput($event)\"\n (keydown)=\"onHexKeydown($event)\"\n (paste)=\"onHexPaste($event)\"\n (focusout)=\"onHexBlur()\" />\n @if (showEyedropper()) {\n <tk-button\n class=\"tk-color-picker__eyedropper\"\n tabindex=\"-1\"\n severity=\"secondary\"\n variant=\"outlined\"\n icon=\"eye-dropper\"\n styleIcon=\"regular\"\n [attr.aria-label]=\"t().eyedropperLabel\"\n (clicked)=\"openEyeDropper()\">\n </tk-button>\n }\n </section>\n }\n\n @if (resolvedSections().hex && showContrast()) {\n <div class=\"tk-color-picker__divider\" role=\"separator\"></div>\n }\n\n @if (showContrast()) {\n <section class=\"tk-color-picker__section tk-color-picker__contrast\">\n <span class=\"tk-color-picker__section-label\">{{\n t().contrastLabel\n }}</span>\n <div class=\"tk-color-picker__contrast-row\">\n <span\n class=\"tk-color-picker__contrast-pill\"\n [style.background-color]=\"draftHex()\"\n [attr.aria-label]=\"t().contrastSampleLabel\">\n <span\n class=\"tk-color-picker__contrast-sample\"\n [style.color]=\"contrastTextColor()\">\n {{ t().contrastSampleText }}\n </span>\n </span>\n <div class=\"tk-color-picker__contrast-info\">\n <span class=\"tk-color-picker__contrast-label\">{{\n t().contrastSampleLabel\n }}</span>\n <span class=\"tk-color-picker__contrast-ratio\"\n >{{ contrastResult()!.ratio }}:1</span\n >\n </div>\n @switch (contrastResult()!.level) {\n @case ('AAA') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--aaa\"\n >AAA</span\n >\n }\n @case ('AA') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--aa\"\n >AA</span\n >\n }\n @case ('fail') {\n <span\n class=\"tk-color-picker__contrast-badge tk-color-picker__contrast-badge--fail\">\n {{ t().contrastLowLabel }}\n </span>\n }\n }\n </div>\n </section>\n }\n </div>\n</p-popover>\n", styles: [":host{display:inline-block;font-family:var(--tk-font-family, sans-serif)}.tk-color-picker{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-color-picker__label{font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-950, #191a1b);margin-bottom:.25rem}.tk-color-picker__trigger{display:flex;align-items:center;gap:var(--tk-spacing-gap-s, .5rem);padding:var(--tk-spacing-padding-xs, .25rem) var(--tk-spacing-padding-s, .5rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);border-radius:var(--tk-borderRadius-s, .25rem);background:var(--tk-color-background-default, #ffffff);cursor:pointer;transition:border-color .14s ease,background .14s ease}.tk-color-picker__trigger:hover{border-color:var(--tk-color-border-default, #cecdcd)}.tk-color-picker__trigger:focus-within{border-color:var(--tk-color-border-focus, #16006f)}.tk-color-picker__trigger--swatch{appearance:none;width:fit-content;font:inherit;-webkit-user-select:none;user-select:none}.tk-color-picker__trigger--swatch>*{pointer-events:none}.tk-color-picker__trigger--swatch:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__trigger--swatch:disabled{cursor:not-allowed}.tk-color-picker__trigger-input{display:flex;flex-direction:column;position:relative}.tk-color-picker__input-label{position:absolute;left:var(--tk-spacing-base-300, 3rem);top:.75rem;font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);color:var(--tk-color-base-surface-500, #8a8a8b);background:var(--tk-color-background-default, #ffffff);padding:0 .25rem;transition:top .2s ease,left .2s ease,color .2s ease;pointer-events:none;z-index:1;max-width:calc(100% - 4rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tk-color-picker--disabled .tk-color-picker__input-label{display:none}.tk-color-picker--invalid .tk-color-picker__input-label{color:var(--tk-color-base-red-700, #cf2604)}.tk-color-picker__input-wrap{position:relative;display:flex;align-items:center;width:100%}.tk-color-picker__input-wrap input.p-inputtext{width:100%;flex:1;border:none;border-bottom:.0625rem solid var(--tk-color-base-surface-300, #d2d2d2);border-radius:0;padding:var(--tk-spacing-base-75, .75rem);padding-left:var(--tk-spacing-base-300, 3rem);color:var(--tk-color-base-surface-950, #191a1b);background-color:transparent;outline:none}.tk-color-picker__input-wrap input.p-inputtext:focus{border-color:var(--tk-color-base-primary-600, #140065);box-shadow:none}.tk-color-picker__input-wrap input.p-inputtext.ng-invalid.ng-dirty,.tk-color-picker__input-wrap input.p-inputtext.ng-invalid.ng-touched{border-color:var(--tk-color-base-red-700, #cf2604)}.tk-color-picker__input-wrap input.p-inputtext:disabled{background-color:var(--tk-color-base-surface-200, #e4e4e4);color:var(--tk-color-base-surface-500, #8a8a8b);opacity:1}.tk-color-picker__input-swatch{appearance:none;padding:0;position:absolute;left:var(--tk-spacing-base-25, .25rem);top:50%;transform:translateY(-50%);width:1.25rem;height:1.25rem;border-radius:var(--tk-borderRadius-xs, .125rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0;cursor:pointer;z-index:1;-webkit-user-select:none;user-select:none;background:transparent}.tk-color-picker__input-swatch--fallback{background:var(--tk-color-base-surface-400, #cecdcd)}.tk-color-picker__input-swatch:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__input-swatch:disabled{cursor:not-allowed;opacity:.5}.tk-color-picker__input-prefix{position:absolute;left:calc(var(--tk-spacing-base-25, .25rem) + 1.25rem + .25rem);top:50%;transform:translateY(-50%);color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-s, .875rem);line-height:1;pointer-events:none;z-index:1}.tk-color-picker__input-bottom{display:flex;margin-top:.25rem;min-height:1.25rem}.tk-color-picker--open .tk-color-picker__trigger{border-color:var(--tk-color-border-strong, #424243)}.tk-color-picker--invalid .tk-color-picker__trigger{border-color:var(--tk-color-feedback-danger-default, #ff6640)}.tk-color-picker--disabled .tk-color-picker__trigger{opacity:.55;cursor:not-allowed;pointer-events:none;background:var(--tk-color-background-soft, #f2f1f1)}.tk-color-picker__swatch{flex-shrink:0;width:1.25rem;height:1.25rem;border-radius:var(--tk-borderRadius-xs, .125rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4)}.tk-color-picker__swatch--fallback{background:var(--tk-color-base-surface-400, #cecdcd)}.tk-color-picker__swatch--large{width:2rem;height:2rem;border-radius:var(--tk-borderRadius-s, .25rem)}.tk-color-picker__chevron{transition:transform .2s ease}.tk-color-picker__chevron--open{transform:rotate(180deg)}.tk-color-picker__error{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-feedback-danger-default, #ff6640)}.tk-color-picker__hint{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-text-muted, #8a8a8b)}.tk-color-picker__panel{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-m, .75rem);width:16rem;padding:var(--tk-spacing-padding-m, 1rem);box-sizing:border-box}.tk-color-picker__panel:focus,.tk-color-picker__panel:focus-visible{outline:none}.tk-color-picker__section{display:flex;flex-direction:column;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-color-picker__section-label{font-size:var(--tk-font-size-legal-m, .75rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-subtle, #5d5d5e)}.tk-color-picker__add-custom{appearance:none;padding:0;width:100%;aspect-ratio:1;border:1px dashed var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-xs, .125rem);background:var(--tk-color-background-default, #ffffff);color:var(--tk-color-text-muted, #8a8a8b);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color .12s ease,color .12s ease}.tk-color-picker__add-custom:hover{border-color:var(--tk-color-accent-default, #6ad0bc);color:var(--tk-color-accent-default, #6ad0bc)}.tk-color-picker__add-custom:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__remove-custom{appearance:none;padding:0;width:100%;aspect-ratio:1;border:1px dashed var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-xs, .125rem);background:var(--tk-color-background-default, #ffffff);color:var(--tk-color-text-muted, #8a8a8b);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color .12s ease,color .12s ease}.tk-color-picker__remove-custom:hover{border-color:var(--tk-color-accent-default, #6ad0bc);color:var(--tk-color-accent-default, #6ad0bc)}.tk-color-picker__remove-custom:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:1px}.tk-color-picker__hue{appearance:none;width:100%;height:.625rem;border-radius:var(--tk-borderRadius-full, 9999px);outline:none;cursor:pointer;background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.tk-color-picker__hue::-webkit-slider-thumb{appearance:none;width:1.125rem;height:1.125rem;border-radius:var(--tk-borderRadius-full, 50%);background:var(--tk-color-background-default, #ffffff);border:1px solid var(--tk-color-border-default, #cecdcd);cursor:grab}.tk-color-picker__hue::-moz-range-thumb{width:1.125rem;height:1.125rem;border-radius:var(--tk-borderRadius-full, 50%);background:var(--tk-color-background-default, #ffffff);border:1px solid var(--tk-color-border-default, #cecdcd);cursor:grab}.tk-color-picker__hue:focus-visible{outline:2px solid var(--tk-color-border-focus, #16006f);outline-offset:2px}.tk-color-picker__divider{width:100%;height:1px;background:var(--tk-color-border-subtle, #e4e4e4);flex-shrink:0}.tk-color-picker__hex-row{display:flex;flex-direction:row;align-items:center;gap:var(--tk-spacing-gap-s, .5rem);margin-top:var(--tk-spacing-gap-s, .5rem)}.tk-color-picker__hex-row>span{flex-shrink:0}.tk-color-picker__hex-row tk-button{flex-shrink:0;min-width:2.5rem;min-height:2.5rem}.tk-color-picker__eyedropper{margin-top:-12px}.tk-color-picker__eyedropper:focus,.tk-color-picker__eyedropper:focus-visible{outline:none;box-shadow:none}.tk-color-picker__panel-hex{flex:1;min-width:0}.tk-color-picker__contrast-row{display:flex;align-items:center;gap:var(--tk-spacing-gap-s, .5rem)}.tk-color-picker__contrast-pill{flex-shrink:0;width:2.5rem;height:2rem;border-radius:var(--tk-borderRadius-s, .25rem);border:1px solid var(--tk-color-border-subtle, #e4e4e4);display:inline-flex;align-items:center;justify-content:center}.tk-color-picker__contrast-sample{font-size:var(--tk-font-size-paragraph-s, .875rem);font-weight:var(--tk-font-weight-600, 600);line-height:1}.tk-color-picker__contrast-info{flex:1;min-width:0;display:flex;flex-direction:column}.tk-color-picker__contrast-label{font-size:var(--tk-font-size-legal-m, .75rem);font-weight:var(--tk-font-weight-600, 600);color:var(--tk-color-text-default, #222324)}.tk-color-picker__contrast-ratio{font-size:var(--tk-font-size-legal-s, .625rem);color:var(--tk-color-text-muted, #8a8a8b)}.tk-color-picker__contrast-badge{flex-shrink:0;font-size:var(--tk-font-size-legal-s, .625rem);font-weight:var(--tk-font-weight-600, 600);padding:var(--tk-spacing-padding-xs, .25rem) var(--tk-spacing-padding-s, .5rem);border-radius:var(--tk-borderRadius-full, 9999px)}.tk-color-picker__contrast-badge--aaa,.tk-color-picker__contrast-badge--aa{background:var(--tk-color-feedback-success-muted, #d1fadf);color:var(--tk-color-feedback-success-strong, #114a3f)}.tk-color-picker__contrast-badge--fail{background:var(--tk-color-feedback-danger-muted, #feede8);color:var(--tk-color-feedback-danger-strong, #7f1d1d)}::ng-deep .tk-color-picker-popover{margin:0!important}::ng-deep .tk-color-picker-popover:before,::ng-deep .tk-color-picker-popover:after{display:none!important}::ng-deep .tk-color-picker-popover--input{margin-top:-22px!important}:host ::ng-deep .tk-color-picker__trigger-input--invalid input.p-inputtext{border-color:var(--tk-color-feedback-danger-default, #ff6640)}:host ::ng-deep .tk-color-picker__trigger-input:has(input:focus) .tk-color-picker__input-label{top:-.75rem;left:0;font-size:var(--tk-font-size-legal-m, .75rem);color:var(--tk-color-base-primary-600, #140065);max-width:none;overflow:visible;text-overflow:clip}:host ::ng-deep .tk-color-picker__trigger-input:has(input.p-filled) .tk-color-picker__input-label{top:-.75rem;left:0;font-size:var(--tk-font-size-legal-m, .75rem);color:var(--tk-color-base-surface-950, #191a1b);max-width:none;overflow:visible;text-overflow:clip}:host ::ng-deep .tk-color-picker__trigger-input:has(input.ng-invalid.ng-dirty) .tk-color-picker__input-label,:host ::ng-deep .tk-color-picker__trigger-input:has(input.ng-invalid.ng-touched) .tk-color-picker__input-label{color:var(--tk-color-base-red-700, #cf2604)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i1.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i2.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: InputTextComponent, selector: "tk-input-text", inputs: ["value", "control", "label", "type", "id", "icon", "clearable", "errorMessage", "hint", "maxLength"], outputs: ["valueChange"] }, { kind: "component", type: ColorPickerSpectrumComponent, selector: "tk-color-picker-spectrum", inputs: ["hue", "saturation", "brightness", "color", "ariaLabel"], outputs: ["changed"] }, { kind: "component", type: ColorPickerSwatchGridComponent, selector: "tk-color-picker-swatch-grid", inputs: ["colors", "selected", "ariaLabel"], outputs: ["picked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1007
1007
|
}
|
|
1008
1008
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: ColorPickerComponent, decorators: [{
|
|
1009
1009
|
type: Component,
|