@lluc_llull/ui-lib 0.36.0 → 0.36.1

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.
@@ -1,7 +1,7 @@
1
1
  import { CommonModule, isPlatformBrowser } from "@angular/common";
2
2
  import * as i0 from "@angular/core";
3
3
  import { ChangeDetectionStrategy, Component, Inject, Input, PLATFORM_ID, signal } from "@angular/core";
4
- import { HighlightDirective, LinkTypeDirective, ScrollRevealDirective } from "@lluc_llull/ui-lib/directives";
4
+ import { LinkTypeDirective, ScrollRevealDirective } from "@lluc_llull/ui-lib/directives";
5
5
  import { UiImageComponent } from "@lluc_llull/ui-lib/shared";
6
6
  var SplitPreviewerComponent = class SplitPreviewerComponent {
7
7
  platformId;
@@ -54,8 +54,8 @@ var SplitPreviewerComponent = class SplitPreviewerComponent {
54
54
  },
55
55
  host: { styleAttribute: "display: contents" },
56
56
  ngImport: i0,
57
- template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
58
- styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:all .4s cubic-bezier(.25,.46,.45,.94);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);transition:color .3s ease}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border)}.split-previewer__item-link:hover .split-previewer__item{padding-left:1rem}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary)!important}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(hover:none)and (pointer:coarse){.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:0fr;margin-top:0;opacity:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"],
57
+ template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
58
+ styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:transform .22s cubic-bezier(.22,1,.36,1);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);background-image:linear-gradient(to bottom,transparent 65%,var(--highlight-color) 65%,var(--highlight-color) calc(65% + var(--highlight-thickness)),transparent calc(65% + var(--highlight-thickness)));background-repeat:no-repeat;background-size:0% 100%;transition:color .2s ease,background-size .22s cubic-bezier(.22,1,.36,1)}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{opacity:0;transform:translateY(.35rem);font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border);transition:opacity .16s ease-out,transform .22s cubic-bezier(.22,1,.36,1);transition-delay:calc((var(--tag-count) - var(--tag-index) - 1) * 18ms)}.split-previewer__item-link:focus-visible{outline:2px solid var(--color-secondary);outline-offset:.5rem}.split-previewer__item-link:focus-visible .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:focus-visible .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:focus-visible .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:focus-visible .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:focus-visible .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}@media(hover:hover)and (pointer:fine){.split-previewer__item-link:hover .split-previewer__item,.split-previewer__item-link:focus-within .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:hover .split-previewer__item-tags,.split-previewer__item-link:focus-within .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:focus-within .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:hover .split-previewer__item-text,.split-previewer__item-link:focus-within .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:hover .split-previewer__item-tag,.split-previewer__item-link:focus-within .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(prefers-reduced-motion:reduce){.split-previewer__item-title,.split-previewer__item-tags,.split-previewer__item-tag{transition-duration:1ms;transition-delay:0ms!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"],
59
59
  dependencies: [
60
60
  {
61
61
  kind: "ngmodule",
@@ -68,12 +68,6 @@ var SplitPreviewerComponent = class SplitPreviewerComponent {
68
68
  inputs: ["linkType", "href"],
69
69
  outputs: ["anchorClicked"]
70
70
  },
71
- {
72
- kind: "directive",
73
- type: HighlightDirective,
74
- selector: "[highlight]",
75
- inputs: ["highlight", "highlightThickness"]
76
- },
77
71
  {
78
72
  kind: "directive",
79
73
  type: ScrollRevealDirective,
@@ -116,14 +110,13 @@ i0.ɵɵngDeclareClassMetadata({
116
110
  imports: [
117
111
  CommonModule,
118
112
  LinkTypeDirective,
119
- HighlightDirective,
120
113
  ScrollRevealDirective,
121
114
  UiImageComponent
122
115
  ],
123
116
  changeDetection: ChangeDetectionStrategy.OnPush,
124
117
  host: { style: "display: contents" },
125
- template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
126
- styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:all .4s cubic-bezier(.25,.46,.45,.94);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);transition:color .3s ease}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border)}.split-previewer__item-link:hover .split-previewer__item{padding-left:1rem}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary)!important}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(hover:none)and (pointer:coarse){.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:0fr;margin-top:0;opacity:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"]
118
+ template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
119
+ styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:transform .22s cubic-bezier(.22,1,.36,1);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);background-image:linear-gradient(to bottom,transparent 65%,var(--highlight-color) 65%,var(--highlight-color) calc(65% + var(--highlight-thickness)),transparent calc(65% + var(--highlight-thickness)));background-repeat:no-repeat;background-size:0% 100%;transition:color .2s ease,background-size .22s cubic-bezier(.22,1,.36,1)}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{opacity:0;transform:translateY(.35rem);font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border);transition:opacity .16s ease-out,transform .22s cubic-bezier(.22,1,.36,1);transition-delay:calc((var(--tag-count) - var(--tag-index) - 1) * 18ms)}.split-previewer__item-link:focus-visible{outline:2px solid var(--color-secondary);outline-offset:.5rem}.split-previewer__item-link:focus-visible .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:focus-visible .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:focus-visible .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:focus-visible .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:focus-visible .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}@media(hover:hover)and (pointer:fine){.split-previewer__item-link:hover .split-previewer__item,.split-previewer__item-link:focus-within .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:hover .split-previewer__item-tags,.split-previewer__item-link:focus-within .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:focus-within .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:hover .split-previewer__item-text,.split-previewer__item-link:focus-within .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:hover .split-previewer__item-tag,.split-previewer__item-link:focus-within .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(prefers-reduced-motion:reduce){.split-previewer__item-title,.split-previewer__item-tags,.split-previewer__item-tag{transition-duration:1ms;transition-delay:0ms!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"]
127
120
  }]
128
121
  }],
129
122
  ctorParameters: () => [{
@@ -1 +1 @@
1
- {"version":3,"file":"lluc_llull-ui-lib-content-split-previewer.mjs","names":[],"sources":["../../../projects/ui-lib/content/split-previewer/split-previewer.component.ts","../../../projects/ui-lib/content/split-previewer/split-previewer.component.html"],"sourcesContent":["import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';\nimport {\n HighlightDirective,\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-previewer',\n imports: [CommonModule, LinkTypeDirective, HighlightDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './split-previewer.component.html',\n styleUrl: './split-previewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitPreviewerComponent implements OnInit {\n @Input() title?: string;\n @Input() items?: SplitPreviewerItemI[];\n @Input() imageDefault?: UiLibImageI;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n\n activeImage = signal<UiLibImageI | undefined>(undefined);\n\n get count(): number {\n return this.items?.length || 0;\n }\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {}\n\n ngOnInit() {\n if (!this.items) return;\n if (!isPlatformBrowser(this.platformId)) return;\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.items?.forEach((item) => {\n if (item.image?.url) {\n const img = new Image();\n img.src = item.image.url;\n }\n });\n });\n }\n }\n}\n\nexport interface SplitPreviewerItemI {\n title?: string;\n type?: string;\n description?: string;\n tags?: string[];\n link?: UiLibButtonI;\n image?: UiLibImageI;\n}\n","<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n"],"mappings":";;;;;AAoBA,IAAa,0BAAb,MAAa,wBAAuB;CAckB;CAbzC;CACA;CACA;CACA,YAA8B;CAC9B,iBAAiB;CACjB,qBAAqB;CAE9B,cAAc,OAAgC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAExD,IAAI,QAAK;EACL,OAAO,KAAK,OAAO,UAAU;CACjC;CAEA,YAAkD,YAAkB;EAAlB,KAAA,aAAA;CAAqB;CAEvE,WAAQ;EACJ,IAAI,CAAC,KAAK,OAAO;EACjB,IAAI,CAAC,kBAAkB,KAAK,UAAU,GAAG;EACzC,IAAI,yBAAyB,QACxB,OAAe,0BAAyB;GACrC,KAAK,OAAO,SAAS,SAAQ;IACzB,IAAI,KAAK,OAAO,KAAK;KACjB,MAAM,MAAM,IAAI,MAAK;KACrB,IAAI,MAAM,KAAK,MAAM;IACzB;GACJ,CAAC;EACL,CAAC;CAET;CA7BS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAuB,MAAA,CAAA,EAAA,OAcZ,YAAW,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAdtB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAuB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;GAAA,OAAA;GAAA,cAAA;GAAA,WAAA;GAAA,gBAAA;GAAA,oBAAA;EAAA;EAAA,MAAA,EAAA,gBAAA,oBAAA;EAAA,UAAA;EAAA,UCpBpC;EAiEA,QAAA,CAAA,g5GAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MDrDc;GAAY;GAAA;IAAA,MAAA;IAAA,MAAE;IAAiB,UAAA;IAAA,QAAA,CAAA,YAAA,MAAA;IAAA,SAAA,CAAA,eAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAkB,UAAA;IAAA,QAAA,CAAA,aAAA,oBAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAqB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAQ7F,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EAVnC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAqB,SACtB;IAAC;IAAc;IAAmB;IAAoB;IAAuB;GAAgB;GAAC,iBAGtF,wBAAwB;GAAM,MACzC,EACF,OAAO,oBACV;GAAA,UAAA;GAAA,QAAA,CAAA,g5GAAA;EAAA,CAAA;;;;;GAgBY,MAAA;GAAO,MAAA,CAAA,WAAW;;;;E,UAb9B,MAAA,M;E,UACA,MAAA,M;E,iBACA,MAAA,M;E,cACA,MAAA,M;E,mBACA,MAAA,M;E,uBACA,MAAA,M"}
1
+ {"version":3,"file":"lluc_llull-ui-lib-content-split-previewer.mjs","names":[],"sources":["../../../projects/ui-lib/content/split-previewer/split-previewer.component.ts","../../../projects/ui-lib/content/split-previewer/split-previewer.component.html"],"sourcesContent":["import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';\nimport {\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-previewer',\n imports: [CommonModule, LinkTypeDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './split-previewer.component.html',\n styleUrl: './split-previewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitPreviewerComponent implements OnInit {\n @Input() title?: string;\n @Input() items?: SplitPreviewerItemI[];\n @Input() imageDefault?: UiLibImageI;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n\n activeImage = signal<UiLibImageI | undefined>(undefined);\n\n get count(): number {\n return this.items?.length || 0;\n }\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {}\n\n ngOnInit() {\n if (!this.items) return;\n if (!isPlatformBrowser(this.platformId)) return;\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.items?.forEach((item) => {\n if (item.image?.url) {\n const img = new Image();\n img.src = item.image.url;\n }\n });\n });\n }\n }\n}\n\nexport interface SplitPreviewerItemI {\n title?: string;\n type?: string;\n description?: string;\n tags?: string[];\n link?: UiLibButtonI;\n image?: UiLibImageI;\n}\n","<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n"],"mappings":";;;;;AAmBA,IAAa,0BAAb,MAAa,wBAAuB;CAckB;CAbzC;CACA;CACA;CACA,YAA8B;CAC9B,iBAAiB;CACjB,qBAAqB;CAE9B,cAAc,OAAgC,QAAU,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAExD,IAAI,QAAK;EACL,OAAO,KAAK,OAAO,UAAU;CACjC;CAEA,YAAkD,YAAkB;EAAlB,KAAA,aAAA;CAAqB;CAEvE,WAAQ;EACJ,IAAI,CAAC,KAAK,OAAO;EACjB,IAAI,CAAC,kBAAkB,KAAK,UAAU,GAAG;EACzC,IAAI,yBAAyB,QACxB,OAAe,0BAAyB;GACrC,KAAK,OAAO,SAAS,SAAQ;IACzB,IAAI,KAAK,OAAO,KAAK;KACjB,MAAM,MAAM,IAAI,MAAK;KACrB,IAAI,MAAM,KAAK,MAAM;IACzB;GACJ,CAAC;EACL,CAAC;CAET;CA7BS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAuB,MAAA,CAAA,EAAA,OAcZ,YAAW,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAdtB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAuB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;GAAA,OAAA;GAAA,cAAA;GAAA,WAAA;GAAA,gBAAA;GAAA,oBAAA;EAAA;EAAA,MAAA,EAAA,gBAAA,oBAAA;EAAA,UAAA;EAAA,UCnBpC;EA6EA,QAAA,CAAA,mqJAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MDlEc;GAAY;GAAA;IAAA,MAAA;IAAA,MAAE;IAAiB,UAAA;IAAA,QAAA,CAAA,YAAA,MAAA;IAAA,SAAA,CAAA,eAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAqB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAQzE,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EAVnC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAqB,SACtB;IAAC;IAAc;IAAmB;IAAuB;GAAgB;GAAC,iBAGlE,wBAAwB;GAAM,MACzC,EACF,OAAO,oBACV;GAAA,UAAA;GAAA,QAAA,CAAA,mqJAAA;EAAA,CAAA;;;;;GAgBY,MAAA;GAAO,MAAA,CAAA,WAAW;;;;E,UAb9B,MAAA,M;E,UACA,MAAA,M;E,iBACA,MAAA,M;E,cACA,MAAA,M;E,mBACA,MAAA,M;E,uBACA,MAAA,M"}
@@ -368,8 +368,8 @@ var SplitPreviewerComponent = class SplitPreviewerComponent {
368
368
  },
369
369
  host: { styleAttribute: "display: contents" },
370
370
  ngImport: i0,
371
- template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
372
- styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:all .4s cubic-bezier(.25,.46,.45,.94);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);transition:color .3s ease}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border)}.split-previewer__item-link:hover .split-previewer__item{padding-left:1rem}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary)!important}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(hover:none)and (pointer:coarse){.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:0fr;margin-top:0;opacity:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"],
371
+ template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
372
+ styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:transform .22s cubic-bezier(.22,1,.36,1);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);background-image:linear-gradient(to bottom,transparent 65%,var(--highlight-color) 65%,var(--highlight-color) calc(65% + var(--highlight-thickness)),transparent calc(65% + var(--highlight-thickness)));background-repeat:no-repeat;background-size:0% 100%;transition:color .2s ease,background-size .22s cubic-bezier(.22,1,.36,1)}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{opacity:0;transform:translateY(.35rem);font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border);transition:opacity .16s ease-out,transform .22s cubic-bezier(.22,1,.36,1);transition-delay:calc((var(--tag-count) - var(--tag-index) - 1) * 18ms)}.split-previewer__item-link:focus-visible{outline:2px solid var(--color-secondary);outline-offset:.5rem}.split-previewer__item-link:focus-visible .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:focus-visible .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:focus-visible .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:focus-visible .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:focus-visible .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}@media(hover:hover)and (pointer:fine){.split-previewer__item-link:hover .split-previewer__item,.split-previewer__item-link:focus-within .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:hover .split-previewer__item-tags,.split-previewer__item-link:focus-within .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:focus-within .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:hover .split-previewer__item-text,.split-previewer__item-link:focus-within .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:hover .split-previewer__item-tag,.split-previewer__item-link:focus-within .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(prefers-reduced-motion:reduce){.split-previewer__item-title,.split-previewer__item-tags,.split-previewer__item-tag{transition-duration:1ms;transition-delay:0ms!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"],
373
373
  dependencies: [
374
374
  {
375
375
  kind: "ngmodule",
@@ -382,12 +382,6 @@ var SplitPreviewerComponent = class SplitPreviewerComponent {
382
382
  inputs: ["linkType", "href"],
383
383
  outputs: ["anchorClicked"]
384
384
  },
385
- {
386
- kind: "directive",
387
- type: HighlightDirective,
388
- selector: "[highlight]",
389
- inputs: ["highlight", "highlightThickness"]
390
- },
391
385
  {
392
386
  kind: "directive",
393
387
  type: ScrollRevealDirective,
@@ -430,14 +424,13 @@ i0.ɵɵngDeclareClassMetadata({
430
424
  imports: [
431
425
  CommonModule,
432
426
  LinkTypeDirective,
433
- HighlightDirective,
434
427
  ScrollRevealDirective,
435
428
  UiImageComponent
436
429
  ],
437
430
  changeDetection: ChangeDetectionStrategy.OnPush,
438
431
  host: { style: "display: contents" },
439
- template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
440
- styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:all .4s cubic-bezier(.25,.46,.45,.94);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);transition:color .3s ease}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border)}.split-previewer__item-link:hover .split-previewer__item{padding-left:1rem}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary)!important}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(hover:none)and (pointer:coarse){.split-previewer__item-link:hover .split-previewer__item{padding-left:0}.split-previewer__item-link:hover .split-previewer__item-tags{grid-template-rows:0fr;margin-top:0;opacity:0}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:hover .split-previewer__item-text{color:var(--text-primary-60)!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"]
432
+ template: "<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n",
433
+ styles: [".split-previewer{display:flex;gap:5rem;min-width:0;padding-bottom:5rem}.split-previewer--left{flex-direction:row-reverse}.split-previewer--right{flex-direction:row}.split-previewer__text-column{flex:1;display:flex;flex-direction:column;min-width:0}.split-previewer__header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;min-width:0}.split-previewer__header .title{margin:0 0 1rem;text-transform:uppercase;min-width:0}.split-previewer__header .count{font-family:var(--font-base);font-size:1rem;font-weight:500;flex-shrink:0}.split-previewer__items{display:flex;flex-direction:column;gap:2rem;min-width:0}.split-previewer__item-link{text-decoration:none;color:inherit;display:block;min-width:0}.split-previewer__item{transition:transform .22s cubic-bezier(.22,1,.36,1);min-width:0}.split-previewer__item-title{margin-bottom:.5rem;display:inline-block;min-width:0;color:var(--text-primary-60);background-image:linear-gradient(to bottom,transparent 65%,var(--highlight-color) 65%,var(--highlight-color) calc(65% + var(--highlight-thickness)),transparent calc(65% + var(--highlight-thickness)));background-repeat:no-repeat;background-size:0% 100%;transition:color .2s ease,background-size .22s cubic-bezier(.22,1,.36,1)}.split-previewer__item-text{line-height:1.6;max-width:min(1000px,100%);color:var(--text-primary-60);transition:color .3s ease;overflow-wrap:break-word;font-size:1.2rem}.split-previewer__item-tags{display:grid;grid-template-rows:0fr;margin-top:0;opacity:0;transition:grid-template-rows .45s ease,margin-top .45s ease,opacity .3s ease}.split-previewer__item-tags-inner{display:flex;flex-wrap:wrap;gap:1rem;min-height:0;overflow:hidden}.split-previewer__item-tag{opacity:0;transform:translateY(.35rem);font-size:1rem;font-weight:600;letter-spacing:.05em;padding:.3rem .8rem;background-color:var(--tag-bg);color:var(--tag-color);border:3px solid var(--tag-border);transition:opacity .16s ease-out,transform .22s cubic-bezier(.22,1,.36,1);transition-delay:calc((var(--tag-count) - var(--tag-index) - 1) * 18ms)}.split-previewer__item-link:focus-visible{outline:2px solid var(--color-secondary);outline-offset:.5rem}.split-previewer__item-link:focus-visible .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:focus-visible .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:focus-visible .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:focus-visible .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:focus-visible .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}@media(hover:hover)and (pointer:fine){.split-previewer__item-link:hover .split-previewer__item,.split-previewer__item-link:focus-within .split-previewer__item{transform:translate(1rem)}.split-previewer__item-link:hover .split-previewer__item-tags,.split-previewer__item-link:focus-within .split-previewer__item-tags{grid-template-rows:1fr;margin-top:1rem;opacity:1}.split-previewer__item-link:hover .split-previewer__item-title,.split-previewer__item-link:focus-within .split-previewer__item-title{color:var(--text-primary);background-size:100% 100%}.split-previewer__item-link:hover .split-previewer__item-text,.split-previewer__item-link:focus-within .split-previewer__item-text{color:var(--text-primary)}.split-previewer__item-link:hover .split-previewer__item-tag,.split-previewer__item-link:focus-within .split-previewer__item-tag{opacity:1;transform:translateY(0);transition-delay:calc(var(--tag-index) * 24ms)}}.split-previewer__media{flex:1;min-width:0;position:relative}.split-previewer__media-inner{position:sticky;top:4rem;height:fit-content;display:flex;justify-content:center;align-items:center}.split-previewer__media .preview-img{display:block;width:100%;aspect-ratio:5/4;max-width:100%;height:auto;object-fit:contain;animation:fadeInMedia .5s ease-out;filter:contrast(1.1) grayscale(.2)}@media(max-width:1280px){.split-previewer{gap:3rem}}@media(max-width:1024px){.split-previewer{display:block;width:100%;min-width:0}.split-previewer--left,.split-previewer--right{flex-direction:unset}.split-previewer__media{display:none}.split-previewer__header{display:block}.split-previewer__header .title{margin-bottom:.75rem}.split-previewer__header .count{display:inline-block}.split-previewer__item-text{max-width:100%}.split-previewer__item-tags{display:none}}@media(prefers-reduced-motion:reduce){.split-previewer__item-title,.split-previewer__item-tags,.split-previewer__item-tag{transition-duration:1ms;transition-delay:0ms!important}}@keyframes fadeInMedia{0%{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}\n"]
441
434
  }]
442
435
  }],
443
436
  ctorParameters: () => [{
@@ -1 +1 @@
1
- {"version":3,"file":"lluc_llull-ui-lib-content.mjs","names":[],"sources":["../../../projects/ui-lib/content/category-progress/category-progress.component.ts","../../../projects/ui-lib/content/category-progress/category-progress.component.html","../../../projects/ui-lib/content/hero-section/hero-section.component.ts","../../../projects/ui-lib/content/hero-section/hero-section.component.html","../../../projects/ui-lib/content/section-intro/section-intro.component.ts","../../../projects/ui-lib/content/section-intro/section-intro.component.html","../../../projects/ui-lib/content/split-previewer/split-previewer.component.ts","../../../projects/ui-lib/content/split-previewer/split-previewer.component.html","../../../projects/ui-lib/content/contact-minimal/contact-minimal.component.ts","../../../projects/ui-lib/content/contact-minimal/contact-minimal.component.html","../../../projects/ui-lib/content/media-split/media-split.component.ts","../../../projects/ui-lib/content/media-split/media-split.component.html","../../../projects/ui-lib/content/stacked-rows/stacked-rows.component.ts","../../../projects/ui-lib/content/stacked-rows/stacked-rows.component.html","../../../projects/ui-lib/content/mosaic-parallax/mosaic-parallax.component.ts","../../../projects/ui-lib/content/mosaic-parallax/mosaic-parallax.component.html","../../../projects/ui-lib/content/content-document/content-document.component.ts","../../../projects/ui-lib/content/content-document/content-document.component.html","../../../projects/ui-lib/content/split-showcase/split-showcase.component.ts","../../../projects/ui-lib/content/split-showcase/split-showcase.component.html","../../../projects/ui-lib/content/asymmetric-media/asymmetric-media.component.ts","../../../projects/ui-lib/content/asymmetric-media/asymmetric-media.component.html","../../../projects/ui-lib/content/media-intro/media-intro.component.ts","../../../projects/ui-lib/content/media-intro/media-intro.component.html","../../../projects/ui-lib/content/columns-media-stacked/columns-media-stacked.component.ts","../../../projects/ui-lib/content/columns-media-stacked/columns-media-stacked.component.html","../../../projects/ui-lib/content/mosaic-grid/mosaic-grid.component.ts","../../../projects/ui-lib/content/mosaic-grid/mosaic-grid.component.html"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { HighlightDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\n\n@Component({\n selector: 'lib-category-progress',\n standalone: true,\n imports: [CommonModule, HighlightDirective, ScrollRevealDirective],\n templateUrl: './category-progress.component.html',\n styleUrl: './category-progress.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class CategoryProgressComponent {\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() categories?: ProgressCategoryI[];\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n}\n\nexport interface ProgressItemI {\n label: string;\n value: number;\n}\n\nexport interface ProgressCategoryI {\n title: string;\n items: ProgressItemI[];\n}\n","<div class=\"category-progress col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n @if (pretitle) {\n <h3 class=\"pretitle\">{{ pretitle }}</h3>\n }\n @if (title) {\n <h2 class=\"title\">{{ title }}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ category.title }}</h3>\n\n @for (item of category.items; track $index) {\n <div class=\"item\">\n <div class=\"item-info\">\n <span class=\"label\">{{ item.label }}</span>\n <span class=\"value\">{{ item.value }}%</span>\n </div>\n\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n","import { CommonModule, DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n Inject,\n Input,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { LinkTypeDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent, UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-hero-section',\n standalone: true,\n imports: [CommonModule, LinkTypeDirective, UiIconComponent, UiImageComponent],\n templateUrl: './hero-section.component.html',\n styleUrl: './hero-section.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class HeroSectionComponent implements OnInit, OnDestroy {\n @Input() variant: 'text' | 'image' = 'text';\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() text?: string;\n @Input() buttons?: UiLibButtonI[];\n @Input() highlight?: string;\n @Input() image?: UiLibImageI;\n\n constructor(@Inject(DOCUMENT) private document: Document) {}\n\n ngOnInit(): void {\n if (this.variant === 'image') {\n this.document.body.classList.add('has-hero-image');\n }\n }\n\n ngOnDestroy(): void {\n this.document.body.classList.remove('has-hero-image');\n }\n}\n","<div\n class=\"hero-section col-span-full\"\n [class.hero-section--text]=\"variant === 'text'\"\n [class.hero-section--image]=\"variant === 'image'\"\n>\n @if (variant === 'image' && image) {\n <div class=\"hero-section__bg\">\n @if (image.publicId) {\n <ui-image \n [publicId]=\"image.publicId\" \n [eager]=\"true\"\n class=\"hero-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"image.url\"\n [alt]=\"image.alt\"\n class=\"hero-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n }\n\n <div class=\"hero-section__content col-span-full\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"btn-group--center\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n }\n </div>\n }\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { LinkTypeDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-section-intro',\n standalone: true,\n imports: [CommonModule, LinkTypeDirective, UiIconComponent, ScrollRevealDirective],\n templateUrl: './section-intro.component.html',\n styleUrl: './section-intro.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SectionIntroComponent {\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() text?: string;\n @Input() button?: UiLibButtonI;\n}\n","<div class=\"section-intro col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (button) {\n <div class=\"btn-group\">\n <a [href]=\"button.url\" [linkType]=\"button.linkType\" class=\"btn btn-link\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n </div>\n }\n</div>\n","import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';\nimport {\n HighlightDirective,\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-previewer',\n imports: [CommonModule, LinkTypeDirective, HighlightDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './split-previewer.component.html',\n styleUrl: './split-previewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitPreviewerComponent implements OnInit {\n @Input() title?: string;\n @Input() items?: SplitPreviewerItemI[];\n @Input() imageDefault?: UiLibImageI;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n\n activeImage = signal<UiLibImageI | undefined>(undefined);\n\n get count(): number {\n return this.items?.length || 0;\n }\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {}\n\n ngOnInit() {\n if (!this.items) return;\n if (!isPlatformBrowser(this.platformId)) return;\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.items?.forEach((item) => {\n if (item.image?.url) {\n const img = new Image();\n img.src = item.image.url;\n }\n });\n });\n }\n }\n}\n\nexport interface SplitPreviewerItemI {\n title?: string;\n type?: string;\n description?: string;\n tags?: string[];\n link?: UiLibButtonI;\n image?: UiLibImageI;\n}\n","<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2 class=\"split-previewer__item-title\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ item.title }}</h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div class=\"split-previewer__item-tags-inner\">\n @for (tag of item.tags; track tag) {\n <span class=\"split-previewer__item-tag\">{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport {\n HighlightDirective,\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-contact-minimal',\n imports: [CommonModule, HighlightDirective, LinkTypeDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './contact-minimal.component.html',\n styleUrl: './contact-minimal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ContactMinimalComponent {\n @Input() contactsTitle?: string;\n @Input() socialsTitle?: string;\n @Input() contacts?: UiLibButtonI[];\n @Input() socials?: UiLibButtonI[];\n @Input() img?: UiLibImageI;\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n}\n","<div class=\"contact-minimal main-grid col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n <div class=\"contact-minimal__content col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"contact-minimal__content--left col-span-6 col-start-1\">\n @if (contactsTitle) {\n <h2 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ contactsTitle }}</h2>\n }\n @if (contacts && contacts.length > 0) {\n <div class=\"btn-group\">\n @for (contact of contacts; track $index) {\n <a [href]=\"contact?.url\" [linkType]=\"contact?.linkType\" class=\"btn btn-link\">\n {{ contact?.label }}\n </a>\n }\n </div>\n }\n </div>\n <div class=\"contact-minimal__content--right col-span-6 col-start-7\">\n @if (socialsTitle) {\n <h2 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ socialsTitle }}</h2>\n }\n @if (socials && socials.length > 0) {\n <div class=\"btn-group\">\n @for (social of socials; track $index) {\n <a [href]=\"social?.url\" [linkType]=\"social?.linkType\" class=\"btn btn-link\">\n {{ social?.label }}\n </a>\n }\n </div>\n }\n </div>\n </div>\n @if (img) {\n <div class=\"contact-minimal__content--media col-span-full md:col-span-12 md:col-start-1\">\n @if (img.publicId) {\n <ui-image [publicId]=\"img.publicId\"></ui-image>\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </div>\n }\n</div>\n","import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n Inject,\n Input,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { ScrollTextRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-media-split',\n standalone: true,\n imports: [CommonModule, UiImageComponent, ScrollTextRevealDirective],\n templateUrl: './media-split.component.html',\n styleUrl: './media-split.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MediaSplitComponent {\n @Input() title?: string;\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n activeImageIndex = signal(0);\n imageLoaded = signal(false);\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {\n effect(() => {\n this.activeImageIndex();\n\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.imageLoaded.set(false);\n\n requestAnimationFrame(() => {\n this.imageLoaded.set(true);\n });\n });\n }\n\n currentImage = computed(() => {\n const imgs = this.images ?? [];\n return imgs[this.activeImageIndex()] ?? null;\n });\n\n updateActiveImage(index: number) {\n this.activeImageIndex.set(index);\n }\n\n resetImage() {\n this.activeImageIndex.set(0);\n }\n\n ngOnInit() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.preloadImages();\n });\n } else {\n setTimeout(() => this.preloadImages(), 2000);\n }\n }\n\n private preloadImages() {\n this.images?.slice(1).forEach((img) => {\n const i = new Image();\n i.src = img.url;\n });\n }\n}\n","<div class=\"media-split main-grid col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n <div class=\"media-split__visual col-span-full md:col-span-7 md:col-start-1\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n\n @if (images?.length) {\n <div class=\"image-stack\" (mouseleave)=\"resetImage()\">\n @if (currentImage().publicId) {\n <ui-image\n [publicId]=\"currentImage().publicId!\"\n [eager]=\"true\"\n class=\"img-responsive active-image\"\n [class.loaded]=\"imageLoaded()\"\n ></ui-image>\n } @else {\n <img\n [src]=\"currentImage().url\"\n [alt]=\"currentImage().alt\"\n class=\"img-responsive active-image\"\n [class.loaded]=\"imageLoaded()\"\n loading=\"eager\"\n fetchpriority=\"high\"\n />\n }\n\n <div class=\"hover-grid\">\n @for (image of images; track $index) {\n <div class=\"hover-zone\" (mouseenter)=\"updateActiveImage($index)\"></div>\n }\n </div>\n </div>\n }\n </div>\n\n <div class=\"media-split__info col-span-full md:col-span-5 md:col-start-8\">\n @if (text) {\n <p class=\"text\" scrollTextReveal [innerHTML]=\"text\"></p>\n }\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\n\n@Component({\n selector: 'lib-stacked-rows',\n imports: [CommonModule, ScrollRevealDirective],\n templateUrl: './stacked-rows.component.html',\n styleUrl: './stacked-rows.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class StackedRowsComponent {\n @Input() title?: string;\n @Input() text?: string;\n @Input() items?: StackedRowItemI[];\n}\n\nexport interface StackedRowItemI {\n title: string;\n text: string;\n}\n","<div class=\"stacked-rows main-grid col-span-full md:col-span-12 md:col-start-1\">\n <!-- INTRO -->\n <div class=\"stacked-rows__intro main-grid col-span-full\" scrollReveal from=\"bottom\">\n @if (title) {\n <h1 class=\"subtitle col-span-full md:col-span-3 md:col-start-1\">\n {{ title }}\n </h1>\n }\n\n @if (text) {\n <p class=\"text col-span-full md:col-span-9 md:col-start-4\">\n {{ text }}\n </p>\n }\n </div>\n\n <!-- ITEMS -->\n @if (items) {\n <div class=\"stacked-rows__items col-span-full\">\n @for (item of items; track $index) {\n <div class=\"stacked-rows__items--item main-grid\" scrollReveal from=\"bottom\">\n <h2 class=\"stacked-rows__items--item_title col-span-full md:col-span-3 md:col-start-1\">\n {{ item.title }}\n </h2>\n\n <p class=\"stacked-rows__items--item_text col-span-full md:col-span-7 md:col-start-6\">\n {{ item.text }}\n </p>\n </div>\n }\n </div>\n }\n</div>\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n Inject,\n Input,\n OnDestroy,\n PLATFORM_ID,\n signal,\n ViewChild,\n} from '@angular/core';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'app-mosaic-parallax',\n standalone: true,\n imports: [UiImageComponent],\n templateUrl: './mosaic-parallax.component.html',\n styleUrls: ['./mosaic-parallax.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MosaicParallaxComponent implements AfterViewInit, OnDestroy {\n @Input() title?: string;\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n @ViewChild('mosaicSection') mosaicSection!: ElementRef<HTMLElement>;\n\n isVisible = signal(false);\n private observer?: IntersectionObserver;\n private isBrowser: boolean;\n\n constructor(@Inject(PLATFORM_ID) platformId: object) {\n this.isBrowser = isPlatformBrowser(platformId);\n }\n\n ngAfterViewInit() {\n if (!this.isBrowser) return;\n\n this.observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !this.isVisible()) {\n this.isVisible.set(true);\n this.observer?.disconnect();\n }\n },\n { threshold: 0.1 },\n );\n\n this.observer.observe(this.mosaicSection.nativeElement);\n }\n\n ngOnDestroy() {\n this.observer?.disconnect();\n }\n}\n","<div class=\"mosaic-parallax main-grid col-span-full\" #mosaicSection>\n\n @if (title) {\n <h2 class=\"subtitle md:col-span-3 md:col-start-1\">{{ title }}</h2>\n }\n\n @if (text) {\n <p class=\"text col-span-full md:col-span-5 md:col-start-1\">\n {{ text }}\n </p>\n }\n\n @if (images && images.length > 0) {\n <div class=\"mosaic-parallax__track col-span-full md:col-span-10 md:col-start-2\">\n @for (item of images; track $index) {\n <article\n class=\"mosaic-item\"\n [class.mosaic-item--visible]=\"isVisible()\"\n [style.--item-index]=\"images.length - 1 - $index\"\n [style.--anim-delay]=\"(images.length - 1 - $index) * 250 + 'ms'\"\n >\n <div class=\"mosaic-item__media\">\n @if (item.publicId) {\n <ui-image [publicId]=\"item.publicId\"></ui-image>\n } @else {\n <img [src]=\"item.url\" [alt]=\"item.alt\" loading=\"lazy\" />\n }\n </div>\n @if (item.texts; as texts) {\n <div class=\"mosaic-item__content\">\n <p class=\"mosaic-item__description\">{{ texts.text }}</p>\n <div class=\"mosaic-item__meta\">\n <span class=\"mosaic-item__date\">{{ texts.title }}</span>\n <span class=\"mosaic-item__index\">\n {{ ($index + 1).toString().padStart(2, '0') }}\n </span>\n </div>\n </div>\n }\n </article>\n }\n </div>\n }\n\n</div>","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'lib-content-document',\n imports: [CommonModule],\n templateUrl: './content-document.component.html',\n styleUrl: './content-document.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ContentDocumentComponent {\n @Input() title?: string;\n @Input() items?: ContentDocumentItemI[];\n}\n\nexport interface ContentDocumentItemI {\n title: string;\n text: string;\n}\n","<div class=\"content-document main-grid col-span-full sm:col-span-12 sm:col-start-1\" scrollReveal>\n @if (title) {\n <div class=\"content-document__title main-grid col-span-full\">\n <h1 class=\"title col-span-full\">{{ title }}</h1>\n </div>\n }\n @if (items) {\n <div class=\"content-document__items col-span-full\">\n @for (item of items; track $index) {\n <div class=\"content-document__items--item main-grid\">\n <h2 class=\"content-document__items--item_title col-span-full sm:col-span-12 sm:col-start-1\">\n {{ item.title }}\n </h2>\n <p class=\"content-document__items--item_text col-span-full sm:col-span-4 sm:col-start-5\" [innerHTML]=\"item.text\"></p>\n </div>\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { LinkTypeDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-showcase',\n imports: [CommonModule, ScrollRevealDirective, LinkTypeDirective, UiIconComponent],\n templateUrl: './split-showcase.component.html',\n styleUrl: './split-showcase.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitShowcaseComponent {\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() description?: string;\n @Input() metas?: SplitShowcaseMetaItemI[];\n @Input() buttons?: UiLibButtonI[];\n}\n\nexport interface SplitShowcaseMetaItemI {\n label: string;\n value: string;\n}","<div class=\"split-showcase main-grid col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"split-showcase__metas col-span-full md:col-span-5 md:col-start-1\">\n <h2\n class=\"split-showcase__metas--title\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n >{{ title }}</h2>\n @if (buttons && buttons.length > 0) {\n <div class=\"btn-group\" scrollReveal from=\"left\" distance=\"48px\" duration=\"0.7s\" [delay]=\"200\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n }\n </div>\n }\n <div class=\"split-showcase__metas--items\">\n @for (meta of metas; track meta.label) {\n <div\n class=\"split-showcase__metas--item\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"200 + $index * 110\"\n >\n <span class=\"split-showcase__metas--item-label\">{{ meta.label }}: </span>\n <span class=\"split-showcase__metas--item-value\">{{ meta.value }}</span> \n </div>\n }\n </div>\n </div>\n\n <div class=\"split-showcase__content col-span-full md:col-span-5 md:col-start-8\">\n <h3\n class=\"split-showcase__content--subtitle\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n >{{ subtitle }}</h3>\n <p\n class=\"split-showcase__content--description\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"200\"\n >{{ description }}</p>\n </div>\n</div>","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-asymmetric-media',\n imports: [CommonModule, UiImageComponent, ScrollRevealDirective],\n templateUrl: './asymmetric-media.component.html',\n styleUrl: './asymmetric-media.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class AsymmetricMediaComponent {\n @Input() media?: UiLibImageI[];\n @Input() direction: 'left' | 'right' = 'right';\n}\n","<div class=\"asymmetric-media main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(media && media.length > 0) {\n <div class=\"asymmetric-media__items main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(direction === 'left') {\n <div\n class=\"asymmetric-media__items--small col-span-full md:col-span-4 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[0]!.publicId) {\n <ui-image [publicId]=\"media[0]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[0]!.url\" [alt]=\"media[0]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n <div\n class=\"asymmetric-media__items--big col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"top\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[1]!.publicId) {\n <ui-image [publicId]=\"media[1]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[1]!.url\" [alt]=\"media[1]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n }\n @if(direction === 'right') {\n <div\n class=\"asymmetric-media__items--small col-span-full md:col-span-8 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[0]!.publicId) {\n <ui-image [publicId]=\"media[0]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[0]!.url\" [alt]=\"media[0]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n <div\n class=\"asymmetric-media__items--big col-span-full md:col-span-4 md:col-start-9\"\n scrollReveal\n from=\"top\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[1]!.publicId) {\n <ui-image [publicId]=\"media[1]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[1]!.url\" [alt]=\"media[1]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n }\n </div>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({ \n selector: 'lib-media-intro',\n imports: [CommonModule, ScrollRevealDirective, UiImageComponent],\n templateUrl: './media-intro.component.html',\n styleUrl: './media-intro.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MediaIntroComponent {\n @Input() highlightedText?: string;\n @Input() secondaryText?: string;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() media?: UiLibImageI;\n}\n","<div class=\"media-intro main-grid col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"media-intro__content main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(highlightedText) {\n <div class=\"media-intro__content--left main-grid col-span-full\">\n <h2 class=\"media-intro__content--main-text col-span-full md:col-span-6\" \n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-7]=\"direction === 'right'\"\n [innerHTML]=\"highlightedText\"\n scrollReveal\n [from]=\"direction === 'left' ? 'left' : 'right'\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\">\n </h2>\n </div>\n }\n @if(secondaryText) {\n <div class=\"media-intro__content--right main-grid col-span-full\">\n <p class=\"media-intro__content--secondary-text col-span-full md:col-span-6\"\n [class.md:col-start-7]=\"direction === 'left'\"\n [class.md:col-start-1]=\"direction === 'right'\"\n [innerHTML]=\"secondaryText\"\n scrollReveal\n [from]=\"direction === 'left' ? 'right' : 'left'\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n ></p>\n </div>\n }\n </div>\n @if(media) {\n <div\n class=\"media-intro__media col-span-full md:col-span-12 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [delay]=\"180\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n >\n @if (media.publicId) {\n <ui-image [publicId]=\"media.publicId\" [eager]=\"true\" class=\"media-intro-img\"></ui-image>\n } @else {\n <img [src]=\"media.url\" [alt]=\"media.alt\" class=\"media-intro-img\" loading=\"eager\" />\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-columns-media-stacked',\n imports: [CommonModule, ScrollRevealDirective, UiImageComponent],\n templateUrl: './columns-media-stacked.component.html',\n styleUrl: './columns-media-stacked.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ColumnsMediaStackedComponent {\n @Input() leftColumn?: string;\n @Input() rightColumn?: string;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() image?: UiLibImageI;\n}\n","<div class=\"columns-media-stacked main-grid col-span-full\">\n <div class=\"columns-media-stacked__content main-grid col-span-full\">\n @if(leftColumn) {\n <p \n class=\"columns-media-stacked__content-column col-span-full md:col-span-4\"\n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-5]=\"direction === 'right'\"\n [innerHTML]=\"leftColumn\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n > \n </p>\n }\n @if(rightColumn) {\n <p \n class=\"columns-media-stacked__content-column col-span-full md:col-span-4\"\n [class.md:col-start-5]=\"direction === 'left'\"\n [class.md:col-start-9]=\"direction === 'right'\"\n [innerHTML]=\"rightColumn\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n > \n </p>\n }\n </div>\n @if(image) {\n <div \n class=\"columns-media-stacked__image col-span-full md:col-span-10\"\n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-3]=\"direction === 'right'\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [delay]=\"180\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n >\n @if (image.publicId) {\n <ui-image [publicId]=\"image.publicId\" [eager]=\"true\" class=\"media-intro-img\"></ui-image>\n } @else {\n <img [src]=\"image.url\" [alt]=\"image.alt\" class=\"media-intro-img\" loading=\"eager\" />\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-mosaic-grid',\n imports: [CommonModule, UiImageComponent, ScrollRevealDirective],\n templateUrl: './mosaic-grid.component.html',\n styleUrl: './mosaic-grid.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MosaicGridComponent implements OnInit{\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n imageGroups: { row1: UiLibImageI[], row2: UiLibImageI[] }[] = [];\n\n ngOnInit(): void {\n console.log('MosaicGridComponent initialized with images:', this.images);\n if (!this.images?.length) {\n this.imageGroups = [];\n return;\n }\n const groups = [];\n for (let i = 0; i < this.images.length; i += 5) {\n groups.push({\n row1: this.images.slice(i, i + 3),\n row2: this.images.slice(i + 3, i + 5)\n });\n }\n this.imageGroups = groups;\n }\n}","<div class=\"mosaic-grid main-grid\">\n @if (text) {\n <p\n class=\"mosaic-grid__text col-span-full md:col-span-6 md:col-start-7\"\n [innerHTML]=\"text\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n ></p>\n }\n\n @for (group of imageGroups; track $index) {\n\n <!-- row 1: 3 imágenes -->\n <div class=\"mosaic-grid__images main-grid col-span-full\">\n @for (img of group.row1; track $index) {\n @if (img.publicId) {\n <ui-image [publicId]=\"img.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-{{ $index * 4 + 1 }}\" [class.image-half-height]=\"$index === 2\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"$index * 90\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"img.url\" [alt]=\"img.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-{{ $index * 4 + 1 }}\" [class.image-half-height]=\"$index === 2\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"$index * 90\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n }\n </div>\n\n <!-- row 2: 1 pequeña + 1 grande -->\n @if (group.row2.length) {\n <div class=\"mosaic-grid__images main-grid col-span-full\">\n @if (group.row2[0]!.publicId) {\n <ui-image [publicId]=\"group.row2[0]!.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-1 image-half-height\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"group.row2[0]!.url\" [alt]=\"group.row2[0]!.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-1 image-half-height\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n\n @if (group.row2[1]) {\n @if (group.row2[1]!.publicId) {\n <ui-image [publicId]=\"group.row2[1]!.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"group.row2[1]!.url\" [alt]=\"group.row2[1]!.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n }\n </div>\n }\n\n }\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"lluc_llull-ui-lib-content.mjs","names":[],"sources":["../../../projects/ui-lib/content/category-progress/category-progress.component.ts","../../../projects/ui-lib/content/category-progress/category-progress.component.html","../../../projects/ui-lib/content/hero-section/hero-section.component.ts","../../../projects/ui-lib/content/hero-section/hero-section.component.html","../../../projects/ui-lib/content/section-intro/section-intro.component.ts","../../../projects/ui-lib/content/section-intro/section-intro.component.html","../../../projects/ui-lib/content/split-previewer/split-previewer.component.ts","../../../projects/ui-lib/content/split-previewer/split-previewer.component.html","../../../projects/ui-lib/content/contact-minimal/contact-minimal.component.ts","../../../projects/ui-lib/content/contact-minimal/contact-minimal.component.html","../../../projects/ui-lib/content/media-split/media-split.component.ts","../../../projects/ui-lib/content/media-split/media-split.component.html","../../../projects/ui-lib/content/stacked-rows/stacked-rows.component.ts","../../../projects/ui-lib/content/stacked-rows/stacked-rows.component.html","../../../projects/ui-lib/content/mosaic-parallax/mosaic-parallax.component.ts","../../../projects/ui-lib/content/mosaic-parallax/mosaic-parallax.component.html","../../../projects/ui-lib/content/content-document/content-document.component.ts","../../../projects/ui-lib/content/content-document/content-document.component.html","../../../projects/ui-lib/content/split-showcase/split-showcase.component.ts","../../../projects/ui-lib/content/split-showcase/split-showcase.component.html","../../../projects/ui-lib/content/asymmetric-media/asymmetric-media.component.ts","../../../projects/ui-lib/content/asymmetric-media/asymmetric-media.component.html","../../../projects/ui-lib/content/media-intro/media-intro.component.ts","../../../projects/ui-lib/content/media-intro/media-intro.component.html","../../../projects/ui-lib/content/columns-media-stacked/columns-media-stacked.component.ts","../../../projects/ui-lib/content/columns-media-stacked/columns-media-stacked.component.html","../../../projects/ui-lib/content/mosaic-grid/mosaic-grid.component.ts","../../../projects/ui-lib/content/mosaic-grid/mosaic-grid.component.html"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { HighlightDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\n\n@Component({\n selector: 'lib-category-progress',\n standalone: true,\n imports: [CommonModule, HighlightDirective, ScrollRevealDirective],\n templateUrl: './category-progress.component.html',\n styleUrl: './category-progress.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class CategoryProgressComponent {\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() categories?: ProgressCategoryI[];\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n}\n\nexport interface ProgressItemI {\n label: string;\n value: number;\n}\n\nexport interface ProgressCategoryI {\n title: string;\n items: ProgressItemI[];\n}\n","<div class=\"category-progress col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n @if (pretitle) {\n <h3 class=\"pretitle\">{{ pretitle }}</h3>\n }\n @if (title) {\n <h2 class=\"title\">{{ title }}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ category.title }}</h3>\n\n @for (item of category.items; track $index) {\n <div class=\"item\">\n <div class=\"item-info\">\n <span class=\"label\">{{ item.label }}</span>\n <span class=\"value\">{{ item.value }}%</span>\n </div>\n\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n</div>\n","import { CommonModule, DOCUMENT } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n Inject,\n Input,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { LinkTypeDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent, UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-hero-section',\n standalone: true,\n imports: [CommonModule, LinkTypeDirective, UiIconComponent, UiImageComponent],\n templateUrl: './hero-section.component.html',\n styleUrl: './hero-section.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class HeroSectionComponent implements OnInit, OnDestroy {\n @Input() variant: 'text' | 'image' = 'text';\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() text?: string;\n @Input() buttons?: UiLibButtonI[];\n @Input() highlight?: string;\n @Input() image?: UiLibImageI;\n\n constructor(@Inject(DOCUMENT) private document: Document) {}\n\n ngOnInit(): void {\n if (this.variant === 'image') {\n this.document.body.classList.add('has-hero-image');\n }\n }\n\n ngOnDestroy(): void {\n this.document.body.classList.remove('has-hero-image');\n }\n}\n","<div\n class=\"hero-section col-span-full\"\n [class.hero-section--text]=\"variant === 'text'\"\n [class.hero-section--image]=\"variant === 'image'\"\n>\n @if (variant === 'image' && image) {\n <div class=\"hero-section__bg\">\n @if (image.publicId) {\n <ui-image \n [publicId]=\"image.publicId\" \n [eager]=\"true\"\n class=\"hero-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"image.url\"\n [alt]=\"image.alt\"\n class=\"hero-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n }\n\n <div class=\"hero-section__content col-span-full\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"btn-group--center\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n }\n </div>\n }\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { LinkTypeDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-section-intro',\n standalone: true,\n imports: [CommonModule, LinkTypeDirective, UiIconComponent, ScrollRevealDirective],\n templateUrl: './section-intro.component.html',\n styleUrl: './section-intro.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SectionIntroComponent {\n @Input() pretitle?: string;\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() text?: string;\n @Input() button?: UiLibButtonI;\n}\n","<div class=\"section-intro col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (button) {\n <div class=\"btn-group\">\n <a [href]=\"button.url\" [linkType]=\"button.linkType\" class=\"btn btn-link\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n </div>\n }\n</div>\n","import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Inject, Input, OnInit, PLATFORM_ID, signal } from '@angular/core';\nimport {\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-previewer',\n imports: [CommonModule, LinkTypeDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './split-previewer.component.html',\n styleUrl: './split-previewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitPreviewerComponent implements OnInit {\n @Input() title?: string;\n @Input() items?: SplitPreviewerItemI[];\n @Input() imageDefault?: UiLibImageI;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n\n activeImage = signal<UiLibImageI | undefined>(undefined);\n\n get count(): number {\n return this.items?.length || 0;\n }\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {}\n\n ngOnInit() {\n if (!this.items) return;\n if (!isPlatformBrowser(this.platformId)) return;\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.items?.forEach((item) => {\n if (item.image?.url) {\n const img = new Image();\n img.src = item.image.url;\n }\n });\n });\n }\n }\n}\n\nexport interface SplitPreviewerItemI {\n title?: string;\n type?: string;\n description?: string;\n tags?: string[];\n link?: UiLibButtonI;\n image?: UiLibImageI;\n}\n","<div\n class=\"split-previewer col-span-full md:col-span-12 md:col-start-1\"\n [class]=\"'split-previewer--' + direction\"\n>\n <div class=\"split-previewer__text-column\">\n <div class=\"split-previewer__header\" scrollReveal from=\"left\" duration=\"1.2s\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n @if (count) {\n <span class=\"count\">{{ count }}</span>\n }\n </div>\n\n <div class=\"split-previewer__items\" (mouseleave)=\"activeImage.set(undefined)\">\n @for (item of items; track item.title) {\n <a\n [href]=\"item.link?.url\"\n [linkType]=\"item.link?.linkType\"\n (mouseenter)=\"activeImage.set(item.image)\"\n class=\"split-previewer__item-link\"\n scrollReveal\n from=\"left\"\n duration=\"1.2s\"\n [delay]=\"($index + 1) * 180\"\n >\n <div class=\"split-previewer__item\">\n <h2\n class=\"split-previewer__item-title\"\n [style.--highlight-color]=\"highlightColor\"\n [style.--highlight-thickness]=\"highlightThickness + '%'\"\n >\n {{ item.title }}\n </h2>\n <p class=\"split-previewer__item-text\">{{ item.description }}</p>\n @if (item.tags?.length) {\n <div class=\"split-previewer__item-tags\">\n <div\n class=\"split-previewer__item-tags-inner\"\n [style.--tag-count]=\"item.tags.length\"\n >\n @for (tag of item.tags; track tag) {\n <span\n class=\"split-previewer__item-tag\"\n [style.--tag-index]=\"$index\"\n >{{ tag }}</span>\n }\n </div>\n </div>\n }\n </div>\n </a>\n }\n </div>\n </div>\n\n <div class=\"split-previewer__media\">\n <div class=\"split-previewer__media-inner\">\n @if ((activeImage() || imageDefault)?.publicId) {\n <ui-image \n [publicId]=\"(activeImage() || imageDefault)!.publicId!\" \n [eager]=\"true\"\n class=\"preview-img\"\n ></ui-image>\n } @else {\n <img\n [src]=\"(activeImage() || imageDefault)?.url\"\n [alt]=\"(activeImage() || imageDefault)?.alt\"\n class=\"preview-img\"\n loading=\"eager\"\n fetchpriority=\"high\"\n decoding=\"async\"\n />\n }\n </div>\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport {\n HighlightDirective,\n LinkTypeDirective,\n ScrollRevealDirective,\n} from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI, UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-contact-minimal',\n imports: [CommonModule, HighlightDirective, LinkTypeDirective, ScrollRevealDirective, UiImageComponent],\n templateUrl: './contact-minimal.component.html',\n styleUrl: './contact-minimal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ContactMinimalComponent {\n @Input() contactsTitle?: string;\n @Input() socialsTitle?: string;\n @Input() contacts?: UiLibButtonI[];\n @Input() socials?: UiLibButtonI[];\n @Input() img?: UiLibImageI;\n @Input() highlightColor = 'var(--content-highlight)';\n @Input() highlightThickness = 30;\n}\n","<div class=\"contact-minimal main-grid col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n <div class=\"contact-minimal__content col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"contact-minimal__content--left col-span-6 col-start-1\">\n @if (contactsTitle) {\n <h2 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ contactsTitle }}</h2>\n }\n @if (contacts && contacts.length > 0) {\n <div class=\"btn-group\">\n @for (contact of contacts; track $index) {\n <a [href]=\"contact?.url\" [linkType]=\"contact?.linkType\" class=\"btn btn-link\">\n {{ contact?.label }}\n </a>\n }\n </div>\n }\n </div>\n <div class=\"contact-minimal__content--right col-span-6 col-start-7\">\n @if (socialsTitle) {\n <h2 class=\"subtitle\" [highlight]=\"highlightColor\" [highlightThickness]=\"highlightThickness\">{{ socialsTitle }}</h2>\n }\n @if (socials && socials.length > 0) {\n <div class=\"btn-group\">\n @for (social of socials; track $index) {\n <a [href]=\"social?.url\" [linkType]=\"social?.linkType\" class=\"btn btn-link\">\n {{ social?.label }}\n </a>\n }\n </div>\n }\n </div>\n </div>\n @if (img) {\n <div class=\"contact-minimal__content--media col-span-full md:col-span-12 md:col-start-1\">\n @if (img.publicId) {\n <ui-image [publicId]=\"img.publicId\"></ui-image>\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </div>\n }\n</div>\n","import { CommonModule, isPlatformBrowser } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n Inject,\n Input,\n PLATFORM_ID,\n signal,\n} from '@angular/core';\nimport { ScrollTextRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-media-split',\n standalone: true,\n imports: [CommonModule, UiImageComponent, ScrollTextRevealDirective],\n templateUrl: './media-split.component.html',\n styleUrl: './media-split.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MediaSplitComponent {\n @Input() title?: string;\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n activeImageIndex = signal(0);\n imageLoaded = signal(false);\n\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {\n effect(() => {\n this.activeImageIndex();\n\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.imageLoaded.set(false);\n\n requestAnimationFrame(() => {\n this.imageLoaded.set(true);\n });\n });\n }\n\n currentImage = computed(() => {\n const imgs = this.images ?? [];\n return imgs[this.activeImageIndex()] ?? null;\n });\n\n updateActiveImage(index: number) {\n this.activeImageIndex.set(index);\n }\n\n resetImage() {\n this.activeImageIndex.set(0);\n }\n\n ngOnInit() {\n if (!isPlatformBrowser(this.platformId)) return;\n\n if ('requestIdleCallback' in window) {\n (window as any).requestIdleCallback(() => {\n this.preloadImages();\n });\n } else {\n setTimeout(() => this.preloadImages(), 2000);\n }\n }\n\n private preloadImages() {\n this.images?.slice(1).forEach((img) => {\n const i = new Image();\n i.src = img.url;\n });\n }\n}\n","<div class=\"media-split main-grid col-span-full md:col-span-12 md:col-start-1\" scrollReveal>\n <div class=\"media-split__visual col-span-full md:col-span-7 md:col-start-1\">\n @if (title) {\n <h1 class=\"title\">{{ title }}</h1>\n }\n\n @if (images?.length) {\n <div class=\"image-stack\" (mouseleave)=\"resetImage()\">\n @if (currentImage().publicId) {\n <ui-image\n [publicId]=\"currentImage().publicId!\"\n [eager]=\"true\"\n class=\"img-responsive active-image\"\n [class.loaded]=\"imageLoaded()\"\n ></ui-image>\n } @else {\n <img\n [src]=\"currentImage().url\"\n [alt]=\"currentImage().alt\"\n class=\"img-responsive active-image\"\n [class.loaded]=\"imageLoaded()\"\n loading=\"eager\"\n fetchpriority=\"high\"\n />\n }\n\n <div class=\"hover-grid\">\n @for (image of images; track $index) {\n <div class=\"hover-zone\" (mouseenter)=\"updateActiveImage($index)\"></div>\n }\n </div>\n </div>\n }\n </div>\n\n <div class=\"media-split__info col-span-full md:col-span-5 md:col-start-8\">\n @if (text) {\n <p class=\"text\" scrollTextReveal [innerHTML]=\"text\"></p>\n }\n </div>\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\n\n@Component({\n selector: 'lib-stacked-rows',\n imports: [CommonModule, ScrollRevealDirective],\n templateUrl: './stacked-rows.component.html',\n styleUrl: './stacked-rows.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class StackedRowsComponent {\n @Input() title?: string;\n @Input() text?: string;\n @Input() items?: StackedRowItemI[];\n}\n\nexport interface StackedRowItemI {\n title: string;\n text: string;\n}\n","<div class=\"stacked-rows main-grid col-span-full md:col-span-12 md:col-start-1\">\n <!-- INTRO -->\n <div class=\"stacked-rows__intro main-grid col-span-full\" scrollReveal from=\"bottom\">\n @if (title) {\n <h1 class=\"subtitle col-span-full md:col-span-3 md:col-start-1\">\n {{ title }}\n </h1>\n }\n\n @if (text) {\n <p class=\"text col-span-full md:col-span-9 md:col-start-4\">\n {{ text }}\n </p>\n }\n </div>\n\n <!-- ITEMS -->\n @if (items) {\n <div class=\"stacked-rows__items col-span-full\">\n @for (item of items; track $index) {\n <div class=\"stacked-rows__items--item main-grid\" scrollReveal from=\"bottom\">\n <h2 class=\"stacked-rows__items--item_title col-span-full md:col-span-3 md:col-start-1\">\n {{ item.title }}\n </h2>\n\n <p class=\"stacked-rows__items--item_text col-span-full md:col-span-7 md:col-start-6\">\n {{ item.text }}\n </p>\n </div>\n }\n </div>\n }\n</div>\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n Inject,\n Input,\n OnDestroy,\n PLATFORM_ID,\n signal,\n ViewChild,\n} from '@angular/core';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'app-mosaic-parallax',\n standalone: true,\n imports: [UiImageComponent],\n templateUrl: './mosaic-parallax.component.html',\n styleUrls: ['./mosaic-parallax.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MosaicParallaxComponent implements AfterViewInit, OnDestroy {\n @Input() title?: string;\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n @ViewChild('mosaicSection') mosaicSection!: ElementRef<HTMLElement>;\n\n isVisible = signal(false);\n private observer?: IntersectionObserver;\n private isBrowser: boolean;\n\n constructor(@Inject(PLATFORM_ID) platformId: object) {\n this.isBrowser = isPlatformBrowser(platformId);\n }\n\n ngAfterViewInit() {\n if (!this.isBrowser) return;\n\n this.observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !this.isVisible()) {\n this.isVisible.set(true);\n this.observer?.disconnect();\n }\n },\n { threshold: 0.1 },\n );\n\n this.observer.observe(this.mosaicSection.nativeElement);\n }\n\n ngOnDestroy() {\n this.observer?.disconnect();\n }\n}\n","<div class=\"mosaic-parallax main-grid col-span-full\" #mosaicSection>\n\n @if (title) {\n <h2 class=\"subtitle md:col-span-3 md:col-start-1\">{{ title }}</h2>\n }\n\n @if (text) {\n <p class=\"text col-span-full md:col-span-5 md:col-start-1\">\n {{ text }}\n </p>\n }\n\n @if (images && images.length > 0) {\n <div class=\"mosaic-parallax__track col-span-full md:col-span-10 md:col-start-2\">\n @for (item of images; track $index) {\n <article\n class=\"mosaic-item\"\n [class.mosaic-item--visible]=\"isVisible()\"\n [style.--item-index]=\"images.length - 1 - $index\"\n [style.--anim-delay]=\"(images.length - 1 - $index) * 250 + 'ms'\"\n >\n <div class=\"mosaic-item__media\">\n @if (item.publicId) {\n <ui-image [publicId]=\"item.publicId\"></ui-image>\n } @else {\n <img [src]=\"item.url\" [alt]=\"item.alt\" loading=\"lazy\" />\n }\n </div>\n @if (item.texts; as texts) {\n <div class=\"mosaic-item__content\">\n <p class=\"mosaic-item__description\">{{ texts.text }}</p>\n <div class=\"mosaic-item__meta\">\n <span class=\"mosaic-item__date\">{{ texts.title }}</span>\n <span class=\"mosaic-item__index\">\n {{ ($index + 1).toString().padStart(2, '0') }}\n </span>\n </div>\n </div>\n }\n </article>\n }\n </div>\n }\n\n</div>","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'lib-content-document',\n imports: [CommonModule],\n templateUrl: './content-document.component.html',\n styleUrl: './content-document.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ContentDocumentComponent {\n @Input() title?: string;\n @Input() items?: ContentDocumentItemI[];\n}\n\nexport interface ContentDocumentItemI {\n title: string;\n text: string;\n}\n","<div class=\"content-document main-grid col-span-full sm:col-span-12 sm:col-start-1\" scrollReveal>\n @if (title) {\n <div class=\"content-document__title main-grid col-span-full\">\n <h1 class=\"title col-span-full\">{{ title }}</h1>\n </div>\n }\n @if (items) {\n <div class=\"content-document__items col-span-full\">\n @for (item of items; track $index) {\n <div class=\"content-document__items--item main-grid\">\n <h2 class=\"content-document__items--item_title col-span-full sm:col-span-12 sm:col-start-1\">\n {{ item.title }}\n </h2>\n <p class=\"content-document__items--item_text col-span-full sm:col-span-4 sm:col-start-5\" [innerHTML]=\"item.text\"></p>\n </div>\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { LinkTypeDirective, ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibButtonI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-split-showcase',\n imports: [CommonModule, ScrollRevealDirective, LinkTypeDirective, UiIconComponent],\n templateUrl: './split-showcase.component.html',\n styleUrl: './split-showcase.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class SplitShowcaseComponent {\n @Input() title?: string;\n @Input() subtitle?: string;\n @Input() description?: string;\n @Input() metas?: SplitShowcaseMetaItemI[];\n @Input() buttons?: UiLibButtonI[];\n}\n\nexport interface SplitShowcaseMetaItemI {\n label: string;\n value: string;\n}","<div class=\"split-showcase main-grid col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"split-showcase__metas col-span-full md:col-span-5 md:col-start-1\">\n <h2\n class=\"split-showcase__metas--title\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n >{{ title }}</h2>\n @if (buttons && buttons.length > 0) {\n <div class=\"btn-group\" scrollReveal from=\"left\" distance=\"48px\" duration=\"0.7s\" [delay]=\"200\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <ui-icon [name]=\"button.icon!\" [size]=\"17\" [color]=\"'var(--color-primary)'\"></ui-icon>\n {{ button.label }}\n </a>\n }\n </div>\n }\n <div class=\"split-showcase__metas--items\">\n @for (meta of metas; track meta.label) {\n <div\n class=\"split-showcase__metas--item\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"200 + $index * 110\"\n >\n <span class=\"split-showcase__metas--item-label\">{{ meta.label }}: </span>\n <span class=\"split-showcase__metas--item-value\">{{ meta.value }}</span> \n </div>\n }\n </div>\n </div>\n\n <div class=\"split-showcase__content col-span-full md:col-span-5 md:col-start-8\">\n <h3\n class=\"split-showcase__content--subtitle\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n >{{ subtitle }}</h3>\n <p\n class=\"split-showcase__content--description\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"200\"\n >{{ description }}</p>\n </div>\n</div>","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-asymmetric-media',\n imports: [CommonModule, UiImageComponent, ScrollRevealDirective],\n templateUrl: './asymmetric-media.component.html',\n styleUrl: './asymmetric-media.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class AsymmetricMediaComponent {\n @Input() media?: UiLibImageI[];\n @Input() direction: 'left' | 'right' = 'right';\n}\n","<div class=\"asymmetric-media main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(media && media.length > 0) {\n <div class=\"asymmetric-media__items main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(direction === 'left') {\n <div\n class=\"asymmetric-media__items--small col-span-full md:col-span-4 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[0]!.publicId) {\n <ui-image [publicId]=\"media[0]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[0]!.url\" [alt]=\"media[0]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n <div\n class=\"asymmetric-media__items--big col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"top\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[1]!.publicId) {\n <ui-image [publicId]=\"media[1]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[1]!.url\" [alt]=\"media[1]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n }\n @if(direction === 'right') {\n <div\n class=\"asymmetric-media__items--small col-span-full md:col-span-8 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[0]!.publicId) {\n <ui-image [publicId]=\"media[0]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[0]!.url\" [alt]=\"media[0]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n <div\n class=\"asymmetric-media__items--big col-span-full md:col-span-4 md:col-start-9\"\n scrollReveal\n from=\"top\"\n distance=\"64px\"\n duration=\"0.8s\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -25% 0px\"\n >\n @if (media[1]!.publicId) {\n <ui-image [publicId]=\"media[1]!.publicId!\" [eager]=\"true\" class=\"asymmetric-media-img\"></ui-image>\n } @else {\n <img [src]=\"media[1]!.url\" [alt]=\"media[1]!.alt\" class=\"asymmetric-media-img\" loading=\"eager\" />\n }\n </div>\n }\n </div>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({ \n selector: 'lib-media-intro',\n imports: [CommonModule, ScrollRevealDirective, UiImageComponent],\n templateUrl: './media-intro.component.html',\n styleUrl: './media-intro.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MediaIntroComponent {\n @Input() highlightedText?: string;\n @Input() secondaryText?: string;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() media?: UiLibImageI;\n}\n","<div class=\"media-intro main-grid col-span-full md:col-span-12 md:col-start-1\">\n <div class=\"media-intro__content main-grid col-span-full md:col-span-12 md:col-start-1\">\n @if(highlightedText) {\n <div class=\"media-intro__content--left main-grid col-span-full\">\n <h2 class=\"media-intro__content--main-text col-span-full md:col-span-6\" \n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-7]=\"direction === 'right'\"\n [innerHTML]=\"highlightedText\"\n scrollReveal\n [from]=\"direction === 'left' ? 'left' : 'right'\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\">\n </h2>\n </div>\n }\n @if(secondaryText) {\n <div class=\"media-intro__content--right main-grid col-span-full\">\n <p class=\"media-intro__content--secondary-text col-span-full md:col-span-6\"\n [class.md:col-start-7]=\"direction === 'left'\"\n [class.md:col-start-1]=\"direction === 'right'\"\n [innerHTML]=\"secondaryText\"\n scrollReveal\n [from]=\"direction === 'left' ? 'right' : 'left'\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n ></p>\n </div>\n }\n </div>\n @if(media) {\n <div\n class=\"media-intro__media col-span-full md:col-span-12 md:col-start-1\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [delay]=\"180\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n >\n @if (media.publicId) {\n <ui-image [publicId]=\"media.publicId\" [eager]=\"true\" class=\"media-intro-img\"></ui-image>\n } @else {\n <img [src]=\"media.url\" [alt]=\"media.alt\" class=\"media-intro-img\" loading=\"eager\" />\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-columns-media-stacked',\n imports: [CommonModule, ScrollRevealDirective, UiImageComponent],\n templateUrl: './columns-media-stacked.component.html',\n styleUrl: './columns-media-stacked.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class ColumnsMediaStackedComponent {\n @Input() leftColumn?: string;\n @Input() rightColumn?: string;\n @Input() direction: 'left' | 'right' = 'right';\n @Input() image?: UiLibImageI;\n}\n","<div class=\"columns-media-stacked main-grid col-span-full\">\n <div class=\"columns-media-stacked__content main-grid col-span-full\">\n @if(leftColumn) {\n <p \n class=\"columns-media-stacked__content-column col-span-full md:col-span-4\"\n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-5]=\"direction === 'right'\"\n [innerHTML]=\"leftColumn\"\n scrollReveal\n from=\"left\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n > \n </p>\n }\n @if(rightColumn) {\n <p \n class=\"columns-media-stacked__content-column col-span-full md:col-span-4\"\n [class.md:col-start-5]=\"direction === 'left'\"\n [class.md:col-start-9]=\"direction === 'right'\"\n [innerHTML]=\"rightColumn\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n > \n </p>\n }\n </div>\n @if(image) {\n <div \n class=\"columns-media-stacked__image col-span-full md:col-span-10\"\n [class.md:col-start-1]=\"direction === 'left'\"\n [class.md:col-start-3]=\"direction === 'right'\"\n scrollReveal\n from=\"bottom\"\n distance=\"64px\"\n duration=\"0.8s\"\n [delay]=\"180\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n >\n @if (image.publicId) {\n <ui-image [publicId]=\"image.publicId\" [eager]=\"true\" class=\"media-intro-img\"></ui-image>\n } @else {\n <img [src]=\"image.url\" [alt]=\"image.alt\" class=\"media-intro-img\" loading=\"eager\" />\n }\n </div>\n }\n</div>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';\nimport { ScrollRevealDirective } from '@lluc_llull/ui-lib/directives';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\n\n@Component({\n selector: 'lib-mosaic-grid',\n imports: [CommonModule, UiImageComponent, ScrollRevealDirective],\n templateUrl: './mosaic-grid.component.html',\n styleUrl: './mosaic-grid.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n style: 'display: contents',\n },\n})\nexport class MosaicGridComponent implements OnInit{\n @Input() text?: string;\n @Input() images?: UiLibImageI[];\n\n imageGroups: { row1: UiLibImageI[], row2: UiLibImageI[] }[] = [];\n\n ngOnInit(): void {\n console.log('MosaicGridComponent initialized with images:', this.images);\n if (!this.images?.length) {\n this.imageGroups = [];\n return;\n }\n const groups = [];\n for (let i = 0; i < this.images.length; i += 5) {\n groups.push({\n row1: this.images.slice(i, i + 3),\n row2: this.images.slice(i + 3, i + 5)\n });\n }\n this.imageGroups = groups;\n }\n}","<div class=\"mosaic-grid main-grid\">\n @if (text) {\n <p\n class=\"mosaic-grid__text col-span-full md:col-span-6 md:col-start-7\"\n [innerHTML]=\"text\"\n scrollReveal\n from=\"right\"\n distance=\"48px\"\n duration=\"0.7s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -20% 0px\"\n ></p>\n }\n\n @for (group of imageGroups; track $index) {\n\n <!-- row 1: 3 imágenes -->\n <div class=\"mosaic-grid__images main-grid col-span-full\">\n @for (img of group.row1; track $index) {\n @if (img.publicId) {\n <ui-image [publicId]=\"img.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-{{ $index * 4 + 1 }}\" [class.image-half-height]=\"$index === 2\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"$index * 90\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"img.url\" [alt]=\"img.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-{{ $index * 4 + 1 }}\" [class.image-half-height]=\"$index === 2\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"$index * 90\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n }\n </div>\n\n <!-- row 2: 1 pequeña + 1 grande -->\n @if (group.row2.length) {\n <div class=\"mosaic-grid__images main-grid col-span-full\">\n @if (group.row2[0]!.publicId) {\n <ui-image [publicId]=\"group.row2[0]!.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-1 image-half-height\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"group.row2[0]!.url\" [alt]=\"group.row2[0]!.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-4 md:col-start-1 image-half-height\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"0\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n\n @if (group.row2[1]) {\n @if (group.row2[1]!.publicId) {\n <ui-image [publicId]=\"group.row2[1]!.publicId\" [eager]=\"true\" class=\"mosaic-grid__images col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n ></ui-image>\n } @else {\n <img [src]=\"group.row2[1]!.url\" [alt]=\"group.row2[1]!.alt\" loading=\"eager\" class=\"mosaic-grid__images col-span-full md:col-span-8 md:col-start-5\"\n scrollReveal\n from=\"bottom\"\n distance=\"40px\"\n duration=\"0.6s\"\n [delay]=\"120\"\n [threshold]=\"0\"\n rootMargin=\"0px 0px -15% 0px\"\n />\n }\n }\n </div>\n }\n\n }\n</div>\n"],"mappings":"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"}
@@ -97,7 +97,7 @@ var ContactFormComponent = class ContactFormComponent {
97
97
  host: { styleAttribute: "display: contents" },
98
98
  ngImport: i0,
99
99
  template: "<section\n class=\"contact-form-section main-grid col-span-full md:col-span-12 md:col-start-1\"\n aria-labelledby=\"contact-form-title\"\n>\n <div class=\"contact-form-heading col-span-full md:col-span-12 md:col-start-1\">\n @if(texts.title) {\n <h2 class=\"title\" id=\"contact-form-title\">{{ texts.title }}</h2> \n }\n @if(texts.intro) {\n <p class=\"text\">{{ texts.intro }}</p>\n }\n </div>\n\n <form\n class=\"contact-form col-span-full\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submit()\"\n [attr.aria-busy]=\"status() === 'sending' ? 'true' : null\"\n novalidate\n >\n <p class=\"contact-form-required-hint col-span-full\">{{ texts.requiredHint }}</p>\n\n <div class=\"contact-form-body main-grid col-span-full\">\n <div class=\"contact-form-grid col-span-full md:col-span-6 md:col-start-1\">\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-name\"\n [label]=\"texts.name\"\n [required]=\"true\"\n [error]=\"getError('name')\"\n >\n <lib-form-input\n id=\"contact-name\"\n formControlName=\"name\"\n autocomplete=\"given-name\"\n [placeholder]=\"texts.namePlaceholder\"\n [describedBy]=\"getError('name') ? 'contact-name-error' : ''\"\n [invalid]=\"!!getError('name')\"\n [required]=\"true\"\n [maxLength]=\"80\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-surname\"\n [label]=\"texts.surname\"\n >\n <lib-form-input\n id=\"contact-surname\"\n formControlName=\"surname\"\n autocomplete=\"family-name\"\n [placeholder]=\"texts.surnamePlaceholder\"\n [maxLength]=\"100\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-email\"\n [label]=\"texts.email\"\n [required]=\"true\"\n [error]=\"getError('email')\"\n >\n <lib-form-input\n id=\"contact-email\"\n type=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n [placeholder]=\"texts.emailPlaceholder\"\n [describedBy]=\"getError('email') ? 'contact-email-error' : ''\"\n [invalid]=\"!!getError('email')\"\n [required]=\"true\"\n [maxLength]=\"254\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-phone\"\n [label]=\"texts.phone\"\n >\n <lib-form-input\n id=\"contact-phone\"\n type=\"tel\"\n formControlName=\"phone\"\n autocomplete=\"tel\"\n [placeholder]=\"texts.phonePlaceholder\"\n [maxLength]=\"40\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"contact-form-field--message col-span-full\"\n controlId=\"contact-message\"\n [label]=\"texts.message\"\n [required]=\"true\"\n [error]=\"getError('message')\"\n >\n <lib-form-textarea\n id=\"contact-message\"\n formControlName=\"message\"\n [placeholder]=\"texts.messagePlaceholder\"\n [describedBy]=\"getError('message') ? 'contact-message-error' : ''\"\n [invalid]=\"!!getError('message')\"\n [required]=\"true\"\n [maxLength]=\"5000\"\n [rows]=\"6\"\n [showCounter]=\"true\"\n />\n </lib-form-field>\n\n </div>\n\n @if (img) {\n <figure class=\"contact-form-image col-span-full md:col-span-6 md:col-start-7\">\n @if (img.publicId) {\n <ui-image\n [publicId]=\"img.publicId\"\n [width]=\"img.width\"\n [height]=\"img.height\"\n [eager]=\"true\"\n />\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </figure>\n }\n </div>\n\n <div class=\"contact-form-honeypot\" aria-hidden=\"true\">\n <label for=\"contact-website\">Website</label>\n <input\n id=\"contact-website\"\n type=\"text\"\n formControlName=\"website\"\n tabindex=\"-1\"\n autocomplete=\"off\"\n />\n </div>\n\n <div class=\"contact-form-footer col-span-full\">\n <p class=\"contact-form-privacy col-span-full md:col-span-8\">\n <strong>{{ texts.privacyTitle }}</strong>\n {{ texts.privacyResponsible }}\n {{ texts.privacyPurpose }}\n {{ texts.privacyLegalBasis }}\n {{ texts.privacyRecipients }}\n {{ texts.privacyRetention }}\n {{ texts.privacyRights }}\n {{ texts.privacyLinkLead }}\n <a class=\"contact-form-privacy__link\" [href]=\"privacyUrl\">{{ texts.privacyLink }}</a>\n {{ texts.privacyLinkTail }}\n </p>\n\n <button\n class=\"contact-form-submit col-span-full md:col-span-4\"\n type=\"submit\"\n [disabled]=\"status() === 'sending'\"\n >\n <span>{{ status() === 'sending' ? texts.sending : texts.send }}</span>\n <ui-icon name=\"arrow-up-right\" [size]=\"20\" color=\"currentColor\"></ui-icon>\n </button>\n </div>\n\n @if (status() !== 'idle') {\n <p\n class=\"contact-form-status col-span-full\"\n [class.contact-form-status--success]=\"status() === 'success'\"\n [class.contact-form-status--error]=\"status() === 'error'\"\n [attr.role]=\"status() === 'error' ? 'alert' : 'status'\"\n aria-live=\"polite\"\n >\n {{\n status() === 'sending'\n ? texts.sending\n : status() === 'success'\n ? texts.success\n : submissionError() || texts.error\n }}\n </p>\n }\n </form>\n</section>\n",
100
- styles: [":host{color:var(--text-primary)}.contact-form-section{padding-top:0!important}.title{text-transform:uppercase}.contact-form-required-hint{font-family:var(--font-base);text-transform:uppercase}.contact-form-body{padding-top:0!important}.contact-form-required-hint{margin:0;color:var(--text-primary-60);font-size:.8rem}.contact-form-image{min-width:0;min-height:100%;margin:0;overflow:hidden}.contact-form-image ui-image,.contact-form-image img{display:block;width:100%;min-height:20rem;object-fit:cover}@media(max-width:1024px){.contact-form-image{display:none}}.contact-form-honeypot{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.contact-form-privacy{margin:0;padding-bottom:2rem!important;color:var(--text-primary-60);font-family:var(--font-base);font-size:.82rem;line-height:1.65}.contact-form-privacy strong{color:var(--text-primary-80);font-weight:600}.contact-form-privacy a{color:var(--text-primary);background-image:linear-gradient(var(--text-primary-70),var(--text-primary-70));background-size:100% 1px;background-position:0% 100%;background-repeat:no-repeat;transition:background-size .3s ease-in-out,background-position .3s ease-in-out}.contact-form-privacy a:hover{background-size:0% 1px;background-position:100% 100%;animation:linkMove .4s forwards}@keyframes linkMove{0%{background-size:100% 1px;background-position:0% 100%}50%{background-size:0% 1px;background-position:100% 100%}51%{background-size:0% 1px;background-position:0% 100%}to{background-size:100% 1px;background-position:0% 100%}}.contact-form-footer button{padding-bottom:2rem;display:inline-flex;min-height:3.5rem;align-items:center;justify-content:space-between;gap:.5rem;border:4px solid var(--border-primary);border-radius:0;padding:.9rem 1.2rem;background:var(--button-primary-bg);color:var(--button-primary-text);cursor:pointer;font-family:var(--font-base);font-size:1rem;text-transform:uppercase;transition:background-color .16s ease,color .16s ease,transform .16s ease;justify-self:end}.contact-form-footer button:hover:not(:disabled){background:var(--button-primary-bg-hover);transform:translateY(-2px)}.contact-form-footer button:focus-visible{outline:2px solid var(--color-secondary);outline-offset:4px}.contact-form-footer button:disabled{cursor:wait;opacity:.65}.contact-form-arrow{font-size:1.2rem}.contact-form-status{margin:0;font-family:var(--font-base);line-height:1.5}.contact-form-status--success{color:#18794e}.contact-form-status--error{color:#b42318}.contact-form-submit{max-width:100%}@media(max-width:1024px){.contact-form-submit{width:100%}}@media(prefers-reduced-motion:reduce){.contact-form-footer button{transition:none}}\n"],
100
+ styles: [":host{color:var(--text-primary)}.contact-form-section{padding-top:0!important}.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{opacity:1;transform:translate(0);transition:opacity .36s ease-out,transform .52s cubic-bezier(.25,1,.5,1)}@starting-style{.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{opacity:0}}@starting-style{.contact-form-heading,.contact-form-grid,.contact-form-required-hint,.contact-form-footer{transform:translate(-2rem)}}.contact-form-heading{transition-delay:0ms}.contact-form-required-hint{transition-delay:70ms}.contact-form-grid{transition-delay:.12s}.contact-form-image{transition-delay:.17s}@starting-style{.contact-form-image{transform:translate(2rem)}}.contact-form-footer{transition-delay:.22s}.title{text-transform:uppercase}.contact-form-required-hint{font-family:var(--font-base);text-transform:uppercase}.contact-form-body{padding-top:0!important}.contact-form-required-hint{margin:0;color:var(--text-primary-60);font-size:.8rem}.contact-form-image{min-width:0;min-height:100%;margin:0;overflow:hidden}.contact-form-image ui-image,.contact-form-image img{display:block;width:100%;min-height:20rem;object-fit:cover;transform:scaleX(-1)}@media(max-width:1024px){.contact-form-image{display:none}}.contact-form-honeypot{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.contact-form-privacy{margin:0;padding-bottom:2rem!important;color:var(--text-primary-60);font-family:var(--font-base);font-size:.82rem;line-height:1.65}.contact-form-privacy strong{color:var(--text-primary-80);font-weight:600}.contact-form-privacy a{color:var(--text-primary);background-image:linear-gradient(var(--text-primary-70),var(--text-primary-70));background-size:100% 1px;background-position:0% 100%;background-repeat:no-repeat;transition:background-size .3s ease-in-out,background-position .3s ease-in-out}.contact-form-privacy a:hover{background-size:0% 1px;background-position:100% 100%;animation:linkMove .4s forwards}@keyframes linkMove{0%{background-size:100% 1px;background-position:0% 100%}50%{background-size:0% 1px;background-position:100% 100%}51%{background-size:0% 1px;background-position:0% 100%}to{background-size:100% 1px;background-position:0% 100%}}.contact-form-footer button{touch-action:manipulation;padding-bottom:2rem;display:inline-flex;min-height:3.5rem;align-items:center;justify-content:space-between;gap:.5rem;border:4px solid var(--border-primary);border-radius:0;padding:.9rem 1.2rem;background:var(--button-primary-bg);color:var(--button-primary-text);cursor:pointer;font-family:var(--font-base);font-size:1rem;text-transform:uppercase;transition:background-color .16s ease,color .16s ease,transform .16s ease;justify-self:end}.contact-form-footer button:hover:not(:disabled){background:var(--button-primary-bg-hover);transform:translateY(-2px)}.contact-form-footer button:active:not(:disabled){transform:translateY(0) scale(.98);transition-duration:.1s}.contact-form-footer button:focus-visible{outline:2px solid var(--color-secondary);outline-offset:4px}.contact-form-footer button:disabled{cursor:wait;opacity:.65}.contact-form-arrow{font-size:1.2rem}.contact-form-status{margin:0;font-family:var(--font-base);line-height:1.5;opacity:1;transform:translateY(0);transition:opacity .18s ease-out,transform .22s cubic-bezier(.22,1,.36,1)}@starting-style{.contact-form-status{opacity:0;transform:translateY(.4rem)}}.contact-form-status--success{color:#18794e}.contact-form-status--error{color:#b42318}.contact-form-submit{max-width:100%}@media(max-width:1024px){.contact-form-submit{width:100%}}@media(prefers-reduced-motion:reduce){.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{transform:none;transition:opacity .12s ease-out,transform .12s ease-out;transition-delay:0ms}@starting-style{.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{transform:none}}.contact-form-footer button{transition:none}.contact-form-footer button:active:not(:disabled){transform:none}.contact-form-status{transform:none;transition:opacity .12s ease-out}@starting-style{.contact-form-status{transform:none}}}\n"],
101
101
  dependencies: [
102
102
  {
103
103
  kind: "ngmodule",
@@ -236,7 +236,7 @@ i0.ɵɵngDeclareClassMetadata({
236
236
  ],
237
237
  host: { style: "display: contents" },
238
238
  template: "<section\n class=\"contact-form-section main-grid col-span-full md:col-span-12 md:col-start-1\"\n aria-labelledby=\"contact-form-title\"\n>\n <div class=\"contact-form-heading col-span-full md:col-span-12 md:col-start-1\">\n @if(texts.title) {\n <h2 class=\"title\" id=\"contact-form-title\">{{ texts.title }}</h2> \n }\n @if(texts.intro) {\n <p class=\"text\">{{ texts.intro }}</p>\n }\n </div>\n\n <form\n class=\"contact-form col-span-full\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submit()\"\n [attr.aria-busy]=\"status() === 'sending' ? 'true' : null\"\n novalidate\n >\n <p class=\"contact-form-required-hint col-span-full\">{{ texts.requiredHint }}</p>\n\n <div class=\"contact-form-body main-grid col-span-full\">\n <div class=\"contact-form-grid col-span-full md:col-span-6 md:col-start-1\">\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-name\"\n [label]=\"texts.name\"\n [required]=\"true\"\n [error]=\"getError('name')\"\n >\n <lib-form-input\n id=\"contact-name\"\n formControlName=\"name\"\n autocomplete=\"given-name\"\n [placeholder]=\"texts.namePlaceholder\"\n [describedBy]=\"getError('name') ? 'contact-name-error' : ''\"\n [invalid]=\"!!getError('name')\"\n [required]=\"true\"\n [maxLength]=\"80\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-surname\"\n [label]=\"texts.surname\"\n >\n <lib-form-input\n id=\"contact-surname\"\n formControlName=\"surname\"\n autocomplete=\"family-name\"\n [placeholder]=\"texts.surnamePlaceholder\"\n [maxLength]=\"100\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-email\"\n [label]=\"texts.email\"\n [required]=\"true\"\n [error]=\"getError('email')\"\n >\n <lib-form-input\n id=\"contact-email\"\n type=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n [placeholder]=\"texts.emailPlaceholder\"\n [describedBy]=\"getError('email') ? 'contact-email-error' : ''\"\n [invalid]=\"!!getError('email')\"\n [required]=\"true\"\n [maxLength]=\"254\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-phone\"\n [label]=\"texts.phone\"\n >\n <lib-form-input\n id=\"contact-phone\"\n type=\"tel\"\n formControlName=\"phone\"\n autocomplete=\"tel\"\n [placeholder]=\"texts.phonePlaceholder\"\n [maxLength]=\"40\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"contact-form-field--message col-span-full\"\n controlId=\"contact-message\"\n [label]=\"texts.message\"\n [required]=\"true\"\n [error]=\"getError('message')\"\n >\n <lib-form-textarea\n id=\"contact-message\"\n formControlName=\"message\"\n [placeholder]=\"texts.messagePlaceholder\"\n [describedBy]=\"getError('message') ? 'contact-message-error' : ''\"\n [invalid]=\"!!getError('message')\"\n [required]=\"true\"\n [maxLength]=\"5000\"\n [rows]=\"6\"\n [showCounter]=\"true\"\n />\n </lib-form-field>\n\n </div>\n\n @if (img) {\n <figure class=\"contact-form-image col-span-full md:col-span-6 md:col-start-7\">\n @if (img.publicId) {\n <ui-image\n [publicId]=\"img.publicId\"\n [width]=\"img.width\"\n [height]=\"img.height\"\n [eager]=\"true\"\n />\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </figure>\n }\n </div>\n\n <div class=\"contact-form-honeypot\" aria-hidden=\"true\">\n <label for=\"contact-website\">Website</label>\n <input\n id=\"contact-website\"\n type=\"text\"\n formControlName=\"website\"\n tabindex=\"-1\"\n autocomplete=\"off\"\n />\n </div>\n\n <div class=\"contact-form-footer col-span-full\">\n <p class=\"contact-form-privacy col-span-full md:col-span-8\">\n <strong>{{ texts.privacyTitle }}</strong>\n {{ texts.privacyResponsible }}\n {{ texts.privacyPurpose }}\n {{ texts.privacyLegalBasis }}\n {{ texts.privacyRecipients }}\n {{ texts.privacyRetention }}\n {{ texts.privacyRights }}\n {{ texts.privacyLinkLead }}\n <a class=\"contact-form-privacy__link\" [href]=\"privacyUrl\">{{ texts.privacyLink }}</a>\n {{ texts.privacyLinkTail }}\n </p>\n\n <button\n class=\"contact-form-submit col-span-full md:col-span-4\"\n type=\"submit\"\n [disabled]=\"status() === 'sending'\"\n >\n <span>{{ status() === 'sending' ? texts.sending : texts.send }}</span>\n <ui-icon name=\"arrow-up-right\" [size]=\"20\" color=\"currentColor\"></ui-icon>\n </button>\n </div>\n\n @if (status() !== 'idle') {\n <p\n class=\"contact-form-status col-span-full\"\n [class.contact-form-status--success]=\"status() === 'success'\"\n [class.contact-form-status--error]=\"status() === 'error'\"\n [attr.role]=\"status() === 'error' ? 'alert' : 'status'\"\n aria-live=\"polite\"\n >\n {{\n status() === 'sending'\n ? texts.sending\n : status() === 'success'\n ? texts.success\n : submissionError() || texts.error\n }}\n </p>\n }\n </form>\n</section>\n",
239
- styles: [":host{color:var(--text-primary)}.contact-form-section{padding-top:0!important}.title{text-transform:uppercase}.contact-form-required-hint{font-family:var(--font-base);text-transform:uppercase}.contact-form-body{padding-top:0!important}.contact-form-required-hint{margin:0;color:var(--text-primary-60);font-size:.8rem}.contact-form-image{min-width:0;min-height:100%;margin:0;overflow:hidden}.contact-form-image ui-image,.contact-form-image img{display:block;width:100%;min-height:20rem;object-fit:cover}@media(max-width:1024px){.contact-form-image{display:none}}.contact-form-honeypot{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.contact-form-privacy{margin:0;padding-bottom:2rem!important;color:var(--text-primary-60);font-family:var(--font-base);font-size:.82rem;line-height:1.65}.contact-form-privacy strong{color:var(--text-primary-80);font-weight:600}.contact-form-privacy a{color:var(--text-primary);background-image:linear-gradient(var(--text-primary-70),var(--text-primary-70));background-size:100% 1px;background-position:0% 100%;background-repeat:no-repeat;transition:background-size .3s ease-in-out,background-position .3s ease-in-out}.contact-form-privacy a:hover{background-size:0% 1px;background-position:100% 100%;animation:linkMove .4s forwards}@keyframes linkMove{0%{background-size:100% 1px;background-position:0% 100%}50%{background-size:0% 1px;background-position:100% 100%}51%{background-size:0% 1px;background-position:0% 100%}to{background-size:100% 1px;background-position:0% 100%}}.contact-form-footer button{padding-bottom:2rem;display:inline-flex;min-height:3.5rem;align-items:center;justify-content:space-between;gap:.5rem;border:4px solid var(--border-primary);border-radius:0;padding:.9rem 1.2rem;background:var(--button-primary-bg);color:var(--button-primary-text);cursor:pointer;font-family:var(--font-base);font-size:1rem;text-transform:uppercase;transition:background-color .16s ease,color .16s ease,transform .16s ease;justify-self:end}.contact-form-footer button:hover:not(:disabled){background:var(--button-primary-bg-hover);transform:translateY(-2px)}.contact-form-footer button:focus-visible{outline:2px solid var(--color-secondary);outline-offset:4px}.contact-form-footer button:disabled{cursor:wait;opacity:.65}.contact-form-arrow{font-size:1.2rem}.contact-form-status{margin:0;font-family:var(--font-base);line-height:1.5}.contact-form-status--success{color:#18794e}.contact-form-status--error{color:#b42318}.contact-form-submit{max-width:100%}@media(max-width:1024px){.contact-form-submit{width:100%}}@media(prefers-reduced-motion:reduce){.contact-form-footer button{transition:none}}\n"]
239
+ styles: [":host{color:var(--text-primary)}.contact-form-section{padding-top:0!important}.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{opacity:1;transform:translate(0);transition:opacity .36s ease-out,transform .52s cubic-bezier(.25,1,.5,1)}@starting-style{.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{opacity:0}}@starting-style{.contact-form-heading,.contact-form-grid,.contact-form-required-hint,.contact-form-footer{transform:translate(-2rem)}}.contact-form-heading{transition-delay:0ms}.contact-form-required-hint{transition-delay:70ms}.contact-form-grid{transition-delay:.12s}.contact-form-image{transition-delay:.17s}@starting-style{.contact-form-image{transform:translate(2rem)}}.contact-form-footer{transition-delay:.22s}.title{text-transform:uppercase}.contact-form-required-hint{font-family:var(--font-base);text-transform:uppercase}.contact-form-body{padding-top:0!important}.contact-form-required-hint{margin:0;color:var(--text-primary-60);font-size:.8rem}.contact-form-image{min-width:0;min-height:100%;margin:0;overflow:hidden}.contact-form-image ui-image,.contact-form-image img{display:block;width:100%;min-height:20rem;object-fit:cover;transform:scaleX(-1)}@media(max-width:1024px){.contact-form-image{display:none}}.contact-form-honeypot{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.contact-form-privacy{margin:0;padding-bottom:2rem!important;color:var(--text-primary-60);font-family:var(--font-base);font-size:.82rem;line-height:1.65}.contact-form-privacy strong{color:var(--text-primary-80);font-weight:600}.contact-form-privacy a{color:var(--text-primary);background-image:linear-gradient(var(--text-primary-70),var(--text-primary-70));background-size:100% 1px;background-position:0% 100%;background-repeat:no-repeat;transition:background-size .3s ease-in-out,background-position .3s ease-in-out}.contact-form-privacy a:hover{background-size:0% 1px;background-position:100% 100%;animation:linkMove .4s forwards}@keyframes linkMove{0%{background-size:100% 1px;background-position:0% 100%}50%{background-size:0% 1px;background-position:100% 100%}51%{background-size:0% 1px;background-position:0% 100%}to{background-size:100% 1px;background-position:0% 100%}}.contact-form-footer button{touch-action:manipulation;padding-bottom:2rem;display:inline-flex;min-height:3.5rem;align-items:center;justify-content:space-between;gap:.5rem;border:4px solid var(--border-primary);border-radius:0;padding:.9rem 1.2rem;background:var(--button-primary-bg);color:var(--button-primary-text);cursor:pointer;font-family:var(--font-base);font-size:1rem;text-transform:uppercase;transition:background-color .16s ease,color .16s ease,transform .16s ease;justify-self:end}.contact-form-footer button:hover:not(:disabled){background:var(--button-primary-bg-hover);transform:translateY(-2px)}.contact-form-footer button:active:not(:disabled){transform:translateY(0) scale(.98);transition-duration:.1s}.contact-form-footer button:focus-visible{outline:2px solid var(--color-secondary);outline-offset:4px}.contact-form-footer button:disabled{cursor:wait;opacity:.65}.contact-form-arrow{font-size:1.2rem}.contact-form-status{margin:0;font-family:var(--font-base);line-height:1.5;opacity:1;transform:translateY(0);transition:opacity .18s ease-out,transform .22s cubic-bezier(.22,1,.36,1)}@starting-style{.contact-form-status{opacity:0;transform:translateY(.4rem)}}.contact-form-status--success{color:#18794e}.contact-form-status--error{color:#b42318}.contact-form-submit{max-width:100%}@media(max-width:1024px){.contact-form-submit{width:100%}}@media(prefers-reduced-motion:reduce){.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{transform:none;transition:opacity .12s ease-out,transform .12s ease-out;transition-delay:0ms}@starting-style{.contact-form-heading,.contact-form-required-hint,.contact-form-grid,.contact-form-image,.contact-form-footer{transform:none}}.contact-form-footer button{transition:none}.contact-form-footer button:active:not(:disabled){transform:none}.contact-form-status{transform:none;transition:opacity .12s ease-out}@starting-style{.contact-form-status{transform:none}}}\n"]
240
240
  }]
241
241
  }],
242
242
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"lluc_llull-ui-lib-forms-contact-form.mjs","names":[],"sources":["../../../projects/ui-lib/forms/contact-form/contact-form.component.ts","../../../projects/ui-lib/forms/contact-form/contact-form.component.html"],"sourcesContent":["import { Component, EventEmitter, Input, Output, signal } from '@angular/core';\nimport { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport {\n FormFieldComponent,\n FormInputComponent,\n FormTextareaComponent,\n} from '@lluc_llull/ui-lib/forms';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\nimport { ContactFormSubmissionI, ContactFormTextsI } from './contact-form.interface';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\ntype ContactField = 'name' | 'email' | 'message';\ntype ContactFormStatus = 'idle' | 'sending' | 'success' | 'error';\n\n@Component({\n selector: 'lib-contact-form',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormFieldComponent,\n FormInputComponent,\n FormTextareaComponent,\n UiImageComponent,\n UiIconComponent\n ],\n templateUrl: './contact-form.component.html',\n styleUrl: './contact-form.component.scss',\n host: {\n style: 'display: contents',\n },\n})\nexport class ContactFormComponent {\n @Input({ required: true }) texts!: ContactFormTextsI;\n @Input() privacyUrl = '/es/privacy';\n @Input() img: UiLibImageI | null = null;\n @Output() readonly messageSubmitted = new EventEmitter<ContactFormSubmissionI>();\n\n readonly status = signal<ContactFormStatus>('idle');\n readonly submissionError = signal('');\n submitted = false;\n\n readonly form = new FormGroup({\n name: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.pattern(/\\S/), Validators.maxLength(80)],\n }),\n surname: new FormControl('', {\n nonNullable: true,\n validators: [Validators.maxLength(100)],\n }),\n email: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.email, Validators.maxLength(254)],\n }),\n phone: new FormControl('', {\n nonNullable: true,\n validators: [Validators.maxLength(40)],\n }),\n message: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.pattern(/\\S/), Validators.maxLength(5000)],\n }),\n website: new FormControl('', { nonNullable: true }),\n });\n\n getError(field: ContactField): string {\n const control = this.form.controls[field];\n if (!control.invalid || (!control.touched && !this.submitted)) return '';\n if (control.hasError('required') || control.hasError('pattern')) {\n return this.texts.requiredError;\n }\n if (control.hasError('email')) return this.texts.emailError;\n if (control.hasError('maxlength')) return this.texts.lengthError;\n return this.texts.invalidError;\n }\n\n submit(): void {\n if (this.status() === 'sending') return;\n\n this.submitted = true;\n this.status.set('idle');\n if (this.form.invalid) {\n this.form.markAllAsTouched();\n return;\n }\n\n this.status.set('sending');\n this.messageSubmitted.emit(this.form.getRawValue());\n }\n\n setSubmissionResult(success: boolean, errorMessage = this.texts.error): void {\n this.status.set(success ? 'success' : 'error');\n this.submissionError.set(success ? '' : errorMessage);\n if (success) {\n this.form.reset();\n this.submitted = false;\n }\n }\n}\n","<section\n class=\"contact-form-section main-grid col-span-full md:col-span-12 md:col-start-1\"\n aria-labelledby=\"contact-form-title\"\n>\n <div class=\"contact-form-heading col-span-full md:col-span-12 md:col-start-1\">\n @if(texts.title) {\n <h2 class=\"title\" id=\"contact-form-title\">{{ texts.title }}</h2> \n }\n @if(texts.intro) {\n <p class=\"text\">{{ texts.intro }}</p>\n }\n </div>\n\n <form\n class=\"contact-form col-span-full\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submit()\"\n [attr.aria-busy]=\"status() === 'sending' ? 'true' : null\"\n novalidate\n >\n <p class=\"contact-form-required-hint col-span-full\">{{ texts.requiredHint }}</p>\n\n <div class=\"contact-form-body main-grid col-span-full\">\n <div class=\"contact-form-grid col-span-full md:col-span-6 md:col-start-1\">\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-name\"\n [label]=\"texts.name\"\n [required]=\"true\"\n [error]=\"getError('name')\"\n >\n <lib-form-input\n id=\"contact-name\"\n formControlName=\"name\"\n autocomplete=\"given-name\"\n [placeholder]=\"texts.namePlaceholder\"\n [describedBy]=\"getError('name') ? 'contact-name-error' : ''\"\n [invalid]=\"!!getError('name')\"\n [required]=\"true\"\n [maxLength]=\"80\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-surname\"\n [label]=\"texts.surname\"\n >\n <lib-form-input\n id=\"contact-surname\"\n formControlName=\"surname\"\n autocomplete=\"family-name\"\n [placeholder]=\"texts.surnamePlaceholder\"\n [maxLength]=\"100\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-email\"\n [label]=\"texts.email\"\n [required]=\"true\"\n [error]=\"getError('email')\"\n >\n <lib-form-input\n id=\"contact-email\"\n type=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n [placeholder]=\"texts.emailPlaceholder\"\n [describedBy]=\"getError('email') ? 'contact-email-error' : ''\"\n [invalid]=\"!!getError('email')\"\n [required]=\"true\"\n [maxLength]=\"254\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-phone\"\n [label]=\"texts.phone\"\n >\n <lib-form-input\n id=\"contact-phone\"\n type=\"tel\"\n formControlName=\"phone\"\n autocomplete=\"tel\"\n [placeholder]=\"texts.phonePlaceholder\"\n [maxLength]=\"40\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"contact-form-field--message col-span-full\"\n controlId=\"contact-message\"\n [label]=\"texts.message\"\n [required]=\"true\"\n [error]=\"getError('message')\"\n >\n <lib-form-textarea\n id=\"contact-message\"\n formControlName=\"message\"\n [placeholder]=\"texts.messagePlaceholder\"\n [describedBy]=\"getError('message') ? 'contact-message-error' : ''\"\n [invalid]=\"!!getError('message')\"\n [required]=\"true\"\n [maxLength]=\"5000\"\n [rows]=\"6\"\n [showCounter]=\"true\"\n />\n </lib-form-field>\n\n </div>\n\n @if (img) {\n <figure class=\"contact-form-image col-span-full md:col-span-6 md:col-start-7\">\n @if (img.publicId) {\n <ui-image\n [publicId]=\"img.publicId\"\n [width]=\"img.width\"\n [height]=\"img.height\"\n [eager]=\"true\"\n />\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </figure>\n }\n </div>\n\n <div class=\"contact-form-honeypot\" aria-hidden=\"true\">\n <label for=\"contact-website\">Website</label>\n <input\n id=\"contact-website\"\n type=\"text\"\n formControlName=\"website\"\n tabindex=\"-1\"\n autocomplete=\"off\"\n />\n </div>\n\n <div class=\"contact-form-footer col-span-full\">\n <p class=\"contact-form-privacy col-span-full md:col-span-8\">\n <strong>{{ texts.privacyTitle }}</strong>\n {{ texts.privacyResponsible }}\n {{ texts.privacyPurpose }}\n {{ texts.privacyLegalBasis }}\n {{ texts.privacyRecipients }}\n {{ texts.privacyRetention }}\n {{ texts.privacyRights }}\n {{ texts.privacyLinkLead }}\n <a class=\"contact-form-privacy__link\" [href]=\"privacyUrl\">{{ texts.privacyLink }}</a>\n {{ texts.privacyLinkTail }}\n </p>\n\n <button\n class=\"contact-form-submit col-span-full md:col-span-4\"\n type=\"submit\"\n [disabled]=\"status() === 'sending'\"\n >\n <span>{{ status() === 'sending' ? texts.sending : texts.send }}</span>\n <ui-icon name=\"arrow-up-right\" [size]=\"20\" color=\"currentColor\"></ui-icon>\n </button>\n </div>\n\n @if (status() !== 'idle') {\n <p\n class=\"contact-form-status col-span-full\"\n [class.contact-form-status--success]=\"status() === 'success'\"\n [class.contact-form-status--error]=\"status() === 'error'\"\n [attr.role]=\"status() === 'error' ? 'alert' : 'status'\"\n aria-live=\"polite\"\n >\n {{\n status() === 'sending'\n ? texts.sending\n : status() === 'success'\n ? texts.success\n : submissionError() || texts.error\n }}\n </p>\n }\n </form>\n</section>\n"],"mappings":";;;;;;AAgCA,IAAa,uBAAb,MAAa,qBAAoB;CACF;CAClB,aAAa;CACb,MAA0B;CAChB,mBAAmB,IAAI,aAAY;CAE7C,SAAS,OAA0B,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAC1C,kBAAkB,OAAO,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;CACrC,YAAY;CAEH,OAAO,IAAI,UAAU;EAC1B,MAAM,IAAI,YAAY,IAAI;GACtB,aAAa;GACb,YAAY;IAAC,WAAW;IAAU,WAAW,QAAQ,IAAI;IAAG,WAAW,UAAU,EAAE;GAAC;EACvF,CAAA;EACD,SAAS,IAAI,YAAY,IAAI;GACzB,aAAa;GACb,YAAY,CAAC,WAAW,UAAU,GAAG,CAAC;EACzC,CAAA;EACD,OAAO,IAAI,YAAY,IAAI;GACvB,aAAa;GACb,YAAY;IAAC,WAAW;IAAU,WAAW;IAAO,WAAW,UAAU,GAAG;GAAC;EAChF,CAAA;EACD,OAAO,IAAI,YAAY,IAAI;GACvB,aAAa;GACb,YAAY,CAAC,WAAW,UAAU,EAAE,CAAC;EACxC,CAAA;EACD,SAAS,IAAI,YAAY,IAAI;GACzB,aAAa;GACb,YAAY;IAAC,WAAW;IAAU,WAAW,QAAQ,IAAI;IAAG,WAAW,UAAU,GAAI;GAAC;EACzF,CAAA;EACD,SAAS,IAAI,YAAY,IAAI,EAAE,aAAa,KAAI,CAAE;CACrD,CAAA;CAED,SAAS,OAAmB;EACxB,MAAM,UAAU,KAAK,KAAK,SAAS;EACnC,IAAI,CAAC,QAAQ,WAAY,CAAC,QAAQ,WAAW,CAAC,KAAK,WAAY,OAAO;EACtE,IAAI,QAAQ,SAAS,UAAU,KAAK,QAAQ,SAAS,SAAS,GAC1D,OAAO,KAAK,MAAM;EAEtB,IAAI,QAAQ,SAAS,OAAO,GAAG,OAAO,KAAK,MAAM;EACjD,IAAI,QAAQ,SAAS,WAAW,GAAG,OAAO,KAAK,MAAM;EACrD,OAAO,KAAK,MAAM;CACtB;CAEA,SAAM;EACF,IAAI,KAAK,OAAM,MAAO,WAAW;EAEjC,KAAK,YAAY;EACjB,KAAK,OAAO,IAAI,MAAM;EACtB,IAAI,KAAK,KAAK,SAAS;GACnB,KAAK,KAAK,iBAAgB;GAC1B;EACJ;EAEA,KAAK,OAAO,IAAI,SAAS;EACzB,KAAK,iBAAiB,KAAK,KAAK,KAAK,YAAW,CAAE;CACtD;CAEA,oBAAoB,SAAkB,eAAe,KAAK,MAAM,OAAK;EACjE,KAAK,OAAO,IAAI,UAAU,YAAY,OAAO;EAC7C,KAAK,gBAAgB,IAAI,UAAU,KAAK,YAAY;EACpD,IAAI,SAAS;GACT,KAAK,KAAK,MAAK;GACf,KAAK,YAAY;EACrB;CACJ;CAlES,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAoB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;GAAA,YAAA;GAAA,KAAA;EAAA;EAAA,SAAA,EAAA,kBAAA,mBAAA;EAAA,MAAA,EAAA,gBAAA,oBAAA;EAAA,UAAA;EAAA,UChCjC;EA+LA,QAAA,CAAA,unFAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MD5KQ;GAAmB;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA,CAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA,CAAA,WAAA;IAAA,SAAA,CAAA,UAAA;IAAA,UAAA,CAAA,QAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,eAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACnB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAqB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACrB;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;GAAA;EAAA;CAAA,CAAA;;AAQV,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA;EAjBhC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAkB,YAChB;GAAI,SACP;IACL;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MAGK,EACF,OAAO,oBACV;GAAA,UAAA;GAAA,QAAA,CAAA,unFAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,eACxB,MAAA,M;E,QACA,MAAA,M;E,qBACA,MAAA,O"}
1
+ {"version":3,"file":"lluc_llull-ui-lib-forms-contact-form.mjs","names":[],"sources":["../../../projects/ui-lib/forms/contact-form/contact-form.component.ts","../../../projects/ui-lib/forms/contact-form/contact-form.component.html"],"sourcesContent":["import { Component, EventEmitter, Input, Output, signal } from '@angular/core';\nimport { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport {\n FormFieldComponent,\n FormInputComponent,\n FormTextareaComponent,\n} from '@lluc_llull/ui-lib/forms';\nimport { UiLibImageI } from '@lluc_llull/ui-lib/interfaces';\nimport { UiImageComponent } from '@lluc_llull/ui-lib/shared';\nimport { ContactFormSubmissionI, ContactFormTextsI } from './contact-form.interface';\nimport { UiIconComponent } from '@lluc_llull/ui-lib/shared';\n\ntype ContactField = 'name' | 'email' | 'message';\ntype ContactFormStatus = 'idle' | 'sending' | 'success' | 'error';\n\n@Component({\n selector: 'lib-contact-form',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormFieldComponent,\n FormInputComponent,\n FormTextareaComponent,\n UiImageComponent,\n UiIconComponent\n ],\n templateUrl: './contact-form.component.html',\n styleUrl: './contact-form.component.scss',\n host: {\n style: 'display: contents',\n },\n})\nexport class ContactFormComponent {\n @Input({ required: true }) texts!: ContactFormTextsI;\n @Input() privacyUrl = '/es/privacy';\n @Input() img: UiLibImageI | null = null;\n @Output() readonly messageSubmitted = new EventEmitter<ContactFormSubmissionI>();\n\n readonly status = signal<ContactFormStatus>('idle');\n readonly submissionError = signal('');\n submitted = false;\n\n readonly form = new FormGroup({\n name: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.pattern(/\\S/), Validators.maxLength(80)],\n }),\n surname: new FormControl('', {\n nonNullable: true,\n validators: [Validators.maxLength(100)],\n }),\n email: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.email, Validators.maxLength(254)],\n }),\n phone: new FormControl('', {\n nonNullable: true,\n validators: [Validators.maxLength(40)],\n }),\n message: new FormControl('', {\n nonNullable: true,\n validators: [Validators.required, Validators.pattern(/\\S/), Validators.maxLength(5000)],\n }),\n website: new FormControl('', { nonNullable: true }),\n });\n\n getError(field: ContactField): string {\n const control = this.form.controls[field];\n if (!control.invalid || (!control.touched && !this.submitted)) return '';\n if (control.hasError('required') || control.hasError('pattern')) {\n return this.texts.requiredError;\n }\n if (control.hasError('email')) return this.texts.emailError;\n if (control.hasError('maxlength')) return this.texts.lengthError;\n return this.texts.invalidError;\n }\n\n submit(): void {\n if (this.status() === 'sending') return;\n\n this.submitted = true;\n this.status.set('idle');\n if (this.form.invalid) {\n this.form.markAllAsTouched();\n return;\n }\n\n this.status.set('sending');\n this.messageSubmitted.emit(this.form.getRawValue());\n }\n\n setSubmissionResult(success: boolean, errorMessage = this.texts.error): void {\n this.status.set(success ? 'success' : 'error');\n this.submissionError.set(success ? '' : errorMessage);\n if (success) {\n this.form.reset();\n this.submitted = false;\n }\n }\n}\n","<section\n class=\"contact-form-section main-grid col-span-full md:col-span-12 md:col-start-1\"\n aria-labelledby=\"contact-form-title\"\n>\n <div class=\"contact-form-heading col-span-full md:col-span-12 md:col-start-1\">\n @if(texts.title) {\n <h2 class=\"title\" id=\"contact-form-title\">{{ texts.title }}</h2> \n }\n @if(texts.intro) {\n <p class=\"text\">{{ texts.intro }}</p>\n }\n </div>\n\n <form\n class=\"contact-form col-span-full\"\n [formGroup]=\"form\"\n (ngSubmit)=\"submit()\"\n [attr.aria-busy]=\"status() === 'sending' ? 'true' : null\"\n novalidate\n >\n <p class=\"contact-form-required-hint col-span-full\">{{ texts.requiredHint }}</p>\n\n <div class=\"contact-form-body main-grid col-span-full\">\n <div class=\"contact-form-grid col-span-full md:col-span-6 md:col-start-1\">\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-name\"\n [label]=\"texts.name\"\n [required]=\"true\"\n [error]=\"getError('name')\"\n >\n <lib-form-input\n id=\"contact-name\"\n formControlName=\"name\"\n autocomplete=\"given-name\"\n [placeholder]=\"texts.namePlaceholder\"\n [describedBy]=\"getError('name') ? 'contact-name-error' : ''\"\n [invalid]=\"!!getError('name')\"\n [required]=\"true\"\n [maxLength]=\"80\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-surname\"\n [label]=\"texts.surname\"\n >\n <lib-form-input\n id=\"contact-surname\"\n formControlName=\"surname\"\n autocomplete=\"family-name\"\n [placeholder]=\"texts.surnamePlaceholder\"\n [maxLength]=\"100\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-email\"\n [label]=\"texts.email\"\n [required]=\"true\"\n [error]=\"getError('email')\"\n >\n <lib-form-input\n id=\"contact-email\"\n type=\"email\"\n formControlName=\"email\"\n autocomplete=\"email\"\n [placeholder]=\"texts.emailPlaceholder\"\n [describedBy]=\"getError('email') ? 'contact-email-error' : ''\"\n [invalid]=\"!!getError('email')\"\n [required]=\"true\"\n [maxLength]=\"254\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"col-span-full md:col-span-6\"\n controlId=\"contact-phone\"\n [label]=\"texts.phone\"\n >\n <lib-form-input\n id=\"contact-phone\"\n type=\"tel\"\n formControlName=\"phone\"\n autocomplete=\"tel\"\n [placeholder]=\"texts.phonePlaceholder\"\n [maxLength]=\"40\"\n />\n </lib-form-field>\n\n <lib-form-field\n class=\"contact-form-field--message col-span-full\"\n controlId=\"contact-message\"\n [label]=\"texts.message\"\n [required]=\"true\"\n [error]=\"getError('message')\"\n >\n <lib-form-textarea\n id=\"contact-message\"\n formControlName=\"message\"\n [placeholder]=\"texts.messagePlaceholder\"\n [describedBy]=\"getError('message') ? 'contact-message-error' : ''\"\n [invalid]=\"!!getError('message')\"\n [required]=\"true\"\n [maxLength]=\"5000\"\n [rows]=\"6\"\n [showCounter]=\"true\"\n />\n </lib-form-field>\n\n </div>\n\n @if (img) {\n <figure class=\"contact-form-image col-span-full md:col-span-6 md:col-start-7\">\n @if (img.publicId) {\n <ui-image\n [publicId]=\"img.publicId\"\n [width]=\"img.width\"\n [height]=\"img.height\"\n [eager]=\"true\"\n />\n } @else {\n <img\n [src]=\"img.url\"\n [alt]=\"img.alt\"\n loading=\"eager\"\n fetchpriority=\"high\"\n [attr.width]=\"img.width || 800\"\n [attr.height]=\"img.height || 600\"\n />\n }\n </figure>\n }\n </div>\n\n <div class=\"contact-form-honeypot\" aria-hidden=\"true\">\n <label for=\"contact-website\">Website</label>\n <input\n id=\"contact-website\"\n type=\"text\"\n formControlName=\"website\"\n tabindex=\"-1\"\n autocomplete=\"off\"\n />\n </div>\n\n <div class=\"contact-form-footer col-span-full\">\n <p class=\"contact-form-privacy col-span-full md:col-span-8\">\n <strong>{{ texts.privacyTitle }}</strong>\n {{ texts.privacyResponsible }}\n {{ texts.privacyPurpose }}\n {{ texts.privacyLegalBasis }}\n {{ texts.privacyRecipients }}\n {{ texts.privacyRetention }}\n {{ texts.privacyRights }}\n {{ texts.privacyLinkLead }}\n <a class=\"contact-form-privacy__link\" [href]=\"privacyUrl\">{{ texts.privacyLink }}</a>\n {{ texts.privacyLinkTail }}\n </p>\n\n <button\n class=\"contact-form-submit col-span-full md:col-span-4\"\n type=\"submit\"\n [disabled]=\"status() === 'sending'\"\n >\n <span>{{ status() === 'sending' ? texts.sending : texts.send }}</span>\n <ui-icon name=\"arrow-up-right\" [size]=\"20\" color=\"currentColor\"></ui-icon>\n </button>\n </div>\n\n @if (status() !== 'idle') {\n <p\n class=\"contact-form-status col-span-full\"\n [class.contact-form-status--success]=\"status() === 'success'\"\n [class.contact-form-status--error]=\"status() === 'error'\"\n [attr.role]=\"status() === 'error' ? 'alert' : 'status'\"\n aria-live=\"polite\"\n >\n {{\n status() === 'sending'\n ? texts.sending\n : status() === 'success'\n ? texts.success\n : submissionError() || texts.error\n }}\n </p>\n }\n </form>\n</section>\n"],"mappings":"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"}
@@ -37,7 +37,7 @@ var FormFieldComponent = class FormFieldComponent {
37
37
  host: { classAttribute: "form-field" },
38
38
  ngImport: i0,
39
39
  template: "@if (label) {\n <label [for]=\"controlId\">\n {{ label }}\n @if (required) {\n <span class=\"form-field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n}\n<ng-content />\n@if (hint && !error) {\n <span class=\"form-field-hint\" [id]=\"hintId\">{{ hint }}</span>\n}\n@if (error) {\n <span class=\"form-field-error\" [id]=\"errorId\" role=\"alert\">{{ error }}</span>\n}\n",
40
- styles: [":host{display:flex;min-width:0;flex-direction:column;gap:.65rem}:host>label{color:var(--text-primary);font-family:var(--font-base);font-size:.9rem;letter-spacing:.04em;text-transform:uppercase;padding-top:1rem}.form-field-required{color:var(--color-secondary)}.form-field-hint{color:var(--text-primary-60);font-size:.8rem;line-height:1.4}.form-field-error{color:#b42318;font-size:.875rem;line-height:1.4}\n"]
40
+ styles: [":host{display:flex;min-width:0;flex-direction:column;gap:.65rem}:host>label{color:var(--text-primary);font-family:var(--font-base);font-size:.9rem;letter-spacing:.04em;text-transform:uppercase;padding-top:1rem}.form-field-required{color:var(--color-secondary)}.form-field-hint{color:var(--text-primary-60);font-size:.8rem;line-height:1.4}.form-field-error{color:#b42318;font-size:.875rem;line-height:1.4;opacity:1;transform:translateY(0);transition:opacity .15s ease-out,transform .18s cubic-bezier(.22,1,.36,1)}@starting-style{.form-field-error{opacity:0;transform:translateY(-.25rem)}}@media(prefers-reduced-motion:reduce){.form-field-error{transform:none;transition:opacity .12s ease-out}@starting-style{.form-field-error{transform:none}}}\n"]
41
41
  });
42
42
  };
43
43
  i0.ɵɵngDeclareClassMetadata({
@@ -52,7 +52,7 @@ i0.ɵɵngDeclareClassMetadata({
52
52
  standalone: true,
53
53
  host: { class: "form-field" },
54
54
  template: "@if (label) {\n <label [for]=\"controlId\">\n {{ label }}\n @if (required) {\n <span class=\"form-field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n}\n<ng-content />\n@if (hint && !error) {\n <span class=\"form-field-hint\" [id]=\"hintId\">{{ hint }}</span>\n}\n@if (error) {\n <span class=\"form-field-error\" [id]=\"errorId\" role=\"alert\">{{ error }}</span>\n}\n",
55
- styles: [":host{display:flex;min-width:0;flex-direction:column;gap:.65rem}:host>label{color:var(--text-primary);font-family:var(--font-base);font-size:.9rem;letter-spacing:.04em;text-transform:uppercase;padding-top:1rem}.form-field-required{color:var(--color-secondary)}.form-field-hint{color:var(--text-primary-60);font-size:.8rem;line-height:1.4}.form-field-error{color:#b42318;font-size:.875rem;line-height:1.4}\n"]
55
+ styles: [":host{display:flex;min-width:0;flex-direction:column;gap:.65rem}:host>label{color:var(--text-primary);font-family:var(--font-base);font-size:.9rem;letter-spacing:.04em;text-transform:uppercase;padding-top:1rem}.form-field-required{color:var(--color-secondary)}.form-field-hint{color:var(--text-primary-60);font-size:.8rem;line-height:1.4}.form-field-error{color:#b42318;font-size:.875rem;line-height:1.4;opacity:1;transform:translateY(0);transition:opacity .15s ease-out,transform .18s cubic-bezier(.22,1,.36,1)}@starting-style{.form-field-error{opacity:0;transform:translateY(-.25rem)}}@media(prefers-reduced-motion:reduce){.form-field-error{transform:none;transition:opacity .12s ease-out}@starting-style{.form-field-error{transform:none}}}\n"]
56
56
  }]
57
57
  }],
58
58
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"lluc_llull-ui-lib-forms.mjs","names":[],"sources":["../../../projects/ui-lib/forms/form-field/form-field.component.ts","../../../projects/ui-lib/forms/form-field/form-field.component.html","../../../projects/ui-lib/forms/form-input/form-input.component.ts","../../../projects/ui-lib/forms/form-input/form-input.component.html","../../../projects/ui-lib/forms/form-select/form-select.component.ts","../../../projects/ui-lib/forms/form-select/form-select.component.html","../../../projects/ui-lib/forms/form-textarea/form-textarea.component.ts","../../../projects/ui-lib/forms/form-textarea/form-textarea.component.html","../../../projects/ui-lib/forms/form-toggle/form-toggle.component.ts","../../../projects/ui-lib/forms/form-toggle/form-toggle.component.html"],"sourcesContent":["import { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'lib-form-field',\n standalone: true,\n templateUrl: './form-field.component.html',\n styleUrl: './form-field.component.scss',\n host: {\n class: 'form-field',\n },\n})\nexport class FormFieldComponent {\n @Input({ required: true }) controlId = '';\n @Input() label = '';\n @Input() required = false;\n @Input() hint = '';\n @Input() error = '';\n\n get errorId(): string {\n return `${this.controlId}-error`;\n }\n\n get hintId(): string {\n return `${this.controlId}-hint`;\n }\n}\n","@if (label) {\n <label [for]=\"controlId\">\n {{ label }}\n @if (required) {\n <span class=\"form-field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n}\n<ng-content />\n@if (hint && !error) {\n <span class=\"form-field-hint\" [id]=\"hintId\">{{ hint }}</span>\n}\n@if (error) {\n <span class=\"form-field-error\" [id]=\"errorId\" role=\"alert\">{{ error }}</span>\n}\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport type UiLibInputType = 'text' | 'email' | 'tel' | 'url' | 'search' | 'password';\n\n@Component({\n selector: 'lib-form-input',\n standalone: true,\n templateUrl: './form-input.component.html',\n styleUrl: './form-input.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormInputComponent),\n multi: true,\n },\n ],\n})\nexport class FormInputComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() type: UiLibInputType = 'text';\n @Input() placeholder = '';\n @Input() autocomplete = '';\n @Input() describedBy = '';\n @Input() maxLength: number | null = null;\n @Input() required = false;\n @Input() invalid = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleInput(event: Event): void {\n this.value = (event.target as HTMLInputElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [attr.autocomplete]=\"autocomplete || null\"\n [attr.maxlength]=\"maxLength ?? null\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (input)=\"handleInput($event)\"\n (blur)=\"handleBlur()\"\n/>\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface UiLibSelectOptionI {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\n@Component({\n selector: 'lib-form-select',\n standalone: true,\n templateUrl: './form-select.component.html',\n styleUrl: './form-select.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormSelectComponent),\n multi: true,\n },\n ],\n})\nexport class FormSelectComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() options: UiLibSelectOptionI[] = [];\n @Input() placeholder = '';\n @Input() describedBy = '';\n @Input() required = false;\n @Input() invalid = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleChange(event: Event): void {\n this.value = (event.target as HTMLSelectElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<select\n [id]=\"id\"\n [value]=\"value\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (change)=\"handleChange($event)\"\n (blur)=\"handleBlur()\"\n>\n @if (placeholder) {\n <option value=\"\" disabled>{{ placeholder }}</option>\n }\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n {{ option.label }}\n </option>\n }\n</select>\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n@Component({\n selector: 'lib-form-textarea',\n standalone: true,\n templateUrl: './form-textarea.component.html',\n styleUrl: './form-textarea.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormTextareaComponent),\n multi: true,\n },\n ],\n})\nexport class FormTextareaComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() placeholder = '';\n @Input() describedBy = '';\n @Input() rows = 6;\n @Input() maxLength: number | null = null;\n @Input() required = false;\n @Input() invalid = false;\n @Input() showCounter = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleInput(event: Event): void {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<textarea\n [id]=\"id\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [rows]=\"rows\"\n [attr.maxlength]=\"maxLength ?? null\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (input)=\"handleInput($event)\"\n (blur)=\"handleBlur()\"\n></textarea>\n@if (showCounter && maxLength) {\n <span class=\"form-textarea-counter\" aria-live=\"polite\">\n {{ value.length }} / {{ maxLength }}\n </span>\n}\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n@Component({\n selector: 'lib-form-toggle',\n standalone: true,\n templateUrl: './form-toggle.component.html',\n styleUrl: './form-toggle.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormToggleComponent),\n multi: true,\n },\n ],\n})\nexport class FormToggleComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() describedBy = '';\n\n checked = false;\n disabled = false;\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: boolean | null): void {\n this.checked = value ?? false;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n this.onChange(this.checked);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<label class=\"form-toggle\" [for]=\"id\">\n <input\n [id]=\"id\"\n type=\"checkbox\"\n role=\"switch\"\n [checked]=\"checked\"\n [attr.aria-describedby]=\"describedBy || null\"\n [disabled]=\"disabled\"\n (change)=\"handleChange($event)\"\n (blur)=\"handleBlur()\"\n />\n <span class=\"form-toggle-track\" aria-hidden=\"true\"><span></span></span>\n <span class=\"form-toggle-label\"><ng-content /></span>\n</label>\n"],"mappings":";;;AAWA,IAAa,qBAAb,MAAa,mBAAkB;CACA,YAAY;CAC9B,QAAQ;CACR,WAAW;CACX,OAAO;CACP,QAAQ;CAEjB,IAAI,UAAO;EACP,OAAO,GAAG,KAAK,UAAS;CAC5B;CAEA,IAAI,SAAM;EACN,OAAO,GAAG,KAAK,UAAS;CAC5B;CAbS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAkB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAlB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAkB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,WAAA;GAAA,OAAA;GAAA,UAAA;GAAA,MAAA;GAAA,OAAA;EAAA;EAAA,MAAA,EAAA,gBAAA,aAAA;EAAA,UAAA;EAAA,UCX/B;EAeA,QAAA,CAAA,wZAAA;CAAA,CAAA;;ADJa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAT9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAgB,YACd;GAAI,MAGV,EACF,OAAO,aACV;GAAA,UAAA;GAAA,QAAA,CAAA,wZAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,UACxB,MAAA,M;E,aACA,MAAA,M;E,SACA,MAAA,M;E,UACA,MAAA,M;;;AEEL,IAAa,qBAAb,MAAa,mBAAkB;CACA,KAAK;CACvB,OAAuB;CACvB,cAAc;CACd,eAAe;CACf,cAAc;CACd,YAA2B;CAC3B,WAAW;CACX,UAAU;CAEnB,QAAQ;CACR,WAAW;CACH,iBAAyC,CAAE;CAC3C,kBAA6B,CAAE;CAEvC,WAAW,OAAoB;EAC3B,KAAK,QAAQ,SAAS;CAC1B;CAEA,iBAAiB,IAA2B;EACxC,KAAK,WAAW;CACpB;CAEA,kBAAkB,IAAc;EAC5B,KAAK,YAAY;CACrB;CAEA,iBAAiB,UAAiB;EAC9B,KAAK,WAAW;CACpB;CAEA,YAAY,OAAY;EACpB,KAAK,QAAS,MAAM,OAA4B;EAChD,KAAK,SAAS,KAAK,KAAK;CAC5B;CAEA,aAAU;EACN,KAAK,UAAS;CAClB;CAtCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAkB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAlB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAkB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;GAAA,MAAA;GAAA,aAAA;GAAA,cAAA;GAAA,aAAA;GAAA,WAAA;GAAA,UAAA;GAAA,SAAA;EAAA;EAAA,WARhB,CACP;GACI,SAAS;GACT,aAAa,iBAAiB,kBAAkB;GAChD,OAAO;EACV,CACJ;EAAA,UAAA;EAAA,UChBL;EAcA,QAAA,CAAA,6uBAAA;CAAA,CAAA;;ADIa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAb9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAgB,YACd;GAAI,WAGL,CACP;IACI,SAAS;IACT,aAAa,iBAAgB,kBAAmB;IAChD,OAAO;GACV,CACJ;GAAA,UAAA;GAAA,QAAA,CAAA,6uBAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,SACxB,MAAA,M;E,gBACA,MAAA,M;E,iBACA,MAAA,M;E,gBACA,MAAA,M;E,cACA,MAAA,M;E,aACA,MAAA,M;E,YACA,MAAA,M;;;AEJL,IAAa,sBAAb,MAAa,oBAAmB;CACD,KAAK;CACvB,UAAgC,CAAA;CAChC,cAAc;CACd,cAAc;CACd,WAAW;CACX,UAAU;CAEnB,QAAQ;CACR,WAAW;CACH,iBAAyC,CAAE;CAC3C,kBAA6B,CAAE;CAEvC,WAAW,OAAoB;EAC3B,KAAK,QAAQ,SAAS;CAC1B;CAEA,iBAAiB,IAA2B;EACxC,KAAK,WAAW;CACpB;CAEA,kBAAkB,IAAc;EAC5B,KAAK,YAAY;CACrB;CAEA,iBAAiB,UAAiB;EAC9B,KAAK,WAAW;CACpB;CAEA,aAAa,OAAY;EACrB,KAAK,QAAS,MAAM,OAA6B;EACjD,KAAK,SAAS,KAAK,KAAK;CAC5B;CAEA,aAAU;EACN,KAAK,UAAS;CAClB;CApCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAmB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;GAAA,SAAA;GAAA,aAAA;GAAA,aAAA;GAAA,UAAA;GAAA,SAAA;EAAA;EAAA,WARjB,CACP;GACI,SAAS;GACT,aAAa,iBAAiB,mBAAmB;GACjD,OAAO;EACV,CACJ;EAAA,UAAA;EAAA,UCpBL;EAmBA,QAAA,CAAA,mhBAAA;CAAA,CAAA;;ADGa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAb/B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,YACf;GAAI,WAGL,CACP;IACI,SAAS;IACT,aAAa,iBAAgB,mBAAoB;IACjD,OAAO;GACV,CACJ;GAAA,UAAA;GAAA,QAAA,CAAA,mhBAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,YACxB,MAAA,M;E,gBACA,MAAA,M;E,gBACA,MAAA,M;E,aACA,MAAA,M;E,YACA,MAAA,M;;;AEZL,IAAa,wBAAb,MAAa,sBAAqB;CACH,KAAK;CACvB,cAAc;CACd,cAAc;CACd,OAAO;CACP,YAA2B;CAC3B,WAAW;CACX,UAAU;CACV,cAAc;CAEvB,QAAQ;CACR,WAAW;CACH,iBAAyC,CAAE;CAC3C,kBAA6B,CAAE;CAEvC,WAAW,OAAoB;EAC3B,KAAK,QAAQ,SAAS;CAC1B;CAEA,iBAAiB,IAA2B;EACxC,KAAK,WAAW;CACpB;CAEA,kBAAkB,IAAc;EAC5B,KAAK,YAAY;CACrB;CAEA,iBAAiB,UAAiB;EAC9B,KAAK,WAAW;CACpB;CAEA,YAAY,OAAY;EACpB,KAAK,QAAS,MAAM,OAA+B;EACnD,KAAK,SAAS,KAAK,KAAK;CAC5B;CAEA,aAAU;EACN,KAAK,UAAS;CAClB;CAtCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAqB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAArB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAqB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;GAAA,aAAA;GAAA,aAAA;GAAA,MAAA;GAAA,WAAA;GAAA,UAAA;GAAA,SAAA;GAAA,aAAA;EAAA;EAAA,WARnB,CACP;GACI,SAAS;GACT,aAAa,iBAAiB,qBAAqB;GACnD,OAAO;EACV,CACJ;EAAA,UAAA;EAAA,UCdL;EAkBA,QAAA,CAAA,q5BAAA;CAAA,CAAA;;ADFa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAqB,YAAA,CAAA;EAbjC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAmB,YACjB;GAAI,WAGL,CACP;IACI,SAAS;IACT,aAAa,iBAAgB,qBAAsB;IACnD,OAAO;GACV,CACJ;GAAA,UAAA;GAAA,QAAA,CAAA,q5BAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,gBACxB,MAAA,M;E,gBACA,MAAA,M;E,SACA,MAAA,M;E,cACA,MAAA,M;E,aACA,MAAA,M;E,YACA,MAAA,M;E,gBACA,MAAA,M;;;AERL,IAAa,sBAAb,MAAa,oBAAmB;CACD,KAAK;CACvB,cAAc;CAEvB,UAAU;CACV,WAAW;CACH,iBAA0C,CAAE;CAC5C,kBAA6B,CAAE;CAEvC,WAAW,OAAqB;EAC5B,KAAK,UAAU,SAAS;CAC5B;CAEA,iBAAiB,IAA4B;EACzC,KAAK,WAAW;CACpB;CAEA,kBAAkB,IAAc;EAC5B,KAAK,YAAY;CACrB;CAEA,iBAAiB,UAAiB;EAC9B,KAAK,WAAW;CACpB;CAEA,aAAa,OAAY;EACrB,KAAK,UAAW,MAAM,OAA4B;EAClD,KAAK,SAAS,KAAK,OAAO;CAC9B;CAEA,aAAU;EACN,KAAK,UAAS;CAClB;CAhCS,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAmB,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,IAAA;GAAA,aAAA;EAAA;EAAA,WARjB,CACP;GACI,SAAS;GACT,aAAa,iBAAiB,mBAAmB;GACjD,OAAO;EACV,CACJ;EAAA,UAAA;EAAA,UCdL;EAcA,QAAA,CAAA,mnCAAA;CAAA,CAAA;;ADEa,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAb/B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,YACf;GAAI,WAGL,CACP;IACI,SAAS;IACT,aAAa,iBAAgB,mBAAoB;IACjD,OAAO;GACV,CACJ;GAAA,UAAA;GAAA,QAAA,CAAA,mnCAAA;EAAA,CAAA;;;;GAGA,MAAA;GAAM,MAAA,CAAA,EAAE,UAAU,KAAI,CAAE;;E,gBACxB,MAAA,M"}
1
+ {"version":3,"file":"lluc_llull-ui-lib-forms.mjs","names":[],"sources":["../../../projects/ui-lib/forms/form-field/form-field.component.ts","../../../projects/ui-lib/forms/form-field/form-field.component.html","../../../projects/ui-lib/forms/form-input/form-input.component.ts","../../../projects/ui-lib/forms/form-input/form-input.component.html","../../../projects/ui-lib/forms/form-select/form-select.component.ts","../../../projects/ui-lib/forms/form-select/form-select.component.html","../../../projects/ui-lib/forms/form-textarea/form-textarea.component.ts","../../../projects/ui-lib/forms/form-textarea/form-textarea.component.html","../../../projects/ui-lib/forms/form-toggle/form-toggle.component.ts","../../../projects/ui-lib/forms/form-toggle/form-toggle.component.html"],"sourcesContent":["import { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'lib-form-field',\n standalone: true,\n templateUrl: './form-field.component.html',\n styleUrl: './form-field.component.scss',\n host: {\n class: 'form-field',\n },\n})\nexport class FormFieldComponent {\n @Input({ required: true }) controlId = '';\n @Input() label = '';\n @Input() required = false;\n @Input() hint = '';\n @Input() error = '';\n\n get errorId(): string {\n return `${this.controlId}-error`;\n }\n\n get hintId(): string {\n return `${this.controlId}-hint`;\n }\n}\n","@if (label) {\n <label [for]=\"controlId\">\n {{ label }}\n @if (required) {\n <span class=\"form-field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n}\n<ng-content />\n@if (hint && !error) {\n <span class=\"form-field-hint\" [id]=\"hintId\">{{ hint }}</span>\n}\n@if (error) {\n <span class=\"form-field-error\" [id]=\"errorId\" role=\"alert\">{{ error }}</span>\n}\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport type UiLibInputType = 'text' | 'email' | 'tel' | 'url' | 'search' | 'password';\n\n@Component({\n selector: 'lib-form-input',\n standalone: true,\n templateUrl: './form-input.component.html',\n styleUrl: './form-input.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormInputComponent),\n multi: true,\n },\n ],\n})\nexport class FormInputComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() type: UiLibInputType = 'text';\n @Input() placeholder = '';\n @Input() autocomplete = '';\n @Input() describedBy = '';\n @Input() maxLength: number | null = null;\n @Input() required = false;\n @Input() invalid = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleInput(event: Event): void {\n this.value = (event.target as HTMLInputElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [attr.autocomplete]=\"autocomplete || null\"\n [attr.maxlength]=\"maxLength ?? null\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (input)=\"handleInput($event)\"\n (blur)=\"handleBlur()\"\n/>\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface UiLibSelectOptionI {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\n@Component({\n selector: 'lib-form-select',\n standalone: true,\n templateUrl: './form-select.component.html',\n styleUrl: './form-select.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormSelectComponent),\n multi: true,\n },\n ],\n})\nexport class FormSelectComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() options: UiLibSelectOptionI[] = [];\n @Input() placeholder = '';\n @Input() describedBy = '';\n @Input() required = false;\n @Input() invalid = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleChange(event: Event): void {\n this.value = (event.target as HTMLSelectElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<select\n [id]=\"id\"\n [value]=\"value\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (change)=\"handleChange($event)\"\n (blur)=\"handleBlur()\"\n>\n @if (placeholder) {\n <option value=\"\" disabled>{{ placeholder }}</option>\n }\n @for (option of options; track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled ?? false\">\n {{ option.label }}\n </option>\n }\n</select>\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n@Component({\n selector: 'lib-form-textarea',\n standalone: true,\n templateUrl: './form-textarea.component.html',\n styleUrl: './form-textarea.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormTextareaComponent),\n multi: true,\n },\n ],\n})\nexport class FormTextareaComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() placeholder = '';\n @Input() describedBy = '';\n @Input() rows = 6;\n @Input() maxLength: number | null = null;\n @Input() required = false;\n @Input() invalid = false;\n @Input() showCounter = false;\n\n value = '';\n disabled = false;\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: string | null): void {\n this.value = value ?? '';\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleInput(event: Event): void {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.onChange(this.value);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<textarea\n [id]=\"id\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [rows]=\"rows\"\n [attr.maxlength]=\"maxLength ?? null\"\n [attr.aria-describedby]=\"describedBy || null\"\n [attr.aria-invalid]=\"invalid ? 'true' : null\"\n [required]=\"required\"\n [disabled]=\"disabled\"\n (input)=\"handleInput($event)\"\n (blur)=\"handleBlur()\"\n></textarea>\n@if (showCounter && maxLength) {\n <span class=\"form-textarea-counter\" aria-live=\"polite\">\n {{ value.length }} / {{ maxLength }}\n </span>\n}\n","import { Component, forwardRef, Input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n@Component({\n selector: 'lib-form-toggle',\n standalone: true,\n templateUrl: './form-toggle.component.html',\n styleUrl: './form-toggle.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FormToggleComponent),\n multi: true,\n },\n ],\n})\nexport class FormToggleComponent implements ControlValueAccessor {\n @Input({ required: true }) id = '';\n @Input() describedBy = '';\n\n checked = false;\n disabled = false;\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n\n writeValue(value: boolean | null): void {\n this.checked = value ?? false;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(disabled: boolean): void {\n this.disabled = disabled;\n }\n\n handleChange(event: Event): void {\n this.checked = (event.target as HTMLInputElement).checked;\n this.onChange(this.checked);\n }\n\n handleBlur(): void {\n this.onTouched();\n }\n}\n","<label class=\"form-toggle\" [for]=\"id\">\n <input\n [id]=\"id\"\n type=\"checkbox\"\n role=\"switch\"\n [checked]=\"checked\"\n [attr.aria-describedby]=\"describedBy || null\"\n [disabled]=\"disabled\"\n (change)=\"handleChange($event)\"\n (blur)=\"handleBlur()\"\n />\n <span class=\"form-toggle-track\" aria-hidden=\"true\"><span></span></span>\n <span class=\"form-toggle-label\"><ng-content /></span>\n</label>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lluc_llull/ui-lib",
3
- "version": "0.36.0",
3
+ "version": "0.36.1",
4
4
  "description": "Angular UI component library",
5
5
  "author": "lluc_llull",
6
6
  "license": "MIT",
@@ -191,10 +191,6 @@ ul {
191
191
  }
192
192
 
193
193
  .debug-grid-overlay {
194
- display: none;
195
- }
196
-
197
- body.show-grid .debug-grid-overlay {
198
194
  position: fixed !important;
199
195
  inset-block: 0;
200
196
  left: 50%;
@@ -207,14 +203,119 @@ body.show-grid .debug-grid-overlay {
207
203
  grid-template-columns: repeat(12, 1fr);
208
204
  column-gap: 1.5rem;
209
205
  }
210
- body.show-grid .debug-grid-overlay div {
206
+ .debug-grid-overlay div {
211
207
  height: 100%;
212
208
  background-color: rgba(255, 0, 0, 0.13);
213
209
  }
210
+ .debug-grid-overlay {
211
+ visibility: hidden;
212
+ opacity: 0;
213
+ transition: opacity 160ms ease-out, visibility 0s linear 520ms;
214
+ }
215
+ .debug-grid-overlay div {
216
+ transform: scaleY(0);
217
+ transform-origin: top;
218
+ transition: transform 360ms cubic-bezier(0.25, 1, 0.5, 1);
219
+ }
220
+ .debug-grid-overlay div:nth-child(1) {
221
+ transition-delay: 154ms;
222
+ }
223
+ .debug-grid-overlay div:nth-child(2) {
224
+ transition-delay: 140ms;
225
+ }
226
+ .debug-grid-overlay div:nth-child(3) {
227
+ transition-delay: 126ms;
228
+ }
229
+ .debug-grid-overlay div:nth-child(4) {
230
+ transition-delay: 112ms;
231
+ }
232
+ .debug-grid-overlay div:nth-child(5) {
233
+ transition-delay: 98ms;
234
+ }
235
+ .debug-grid-overlay div:nth-child(6) {
236
+ transition-delay: 84ms;
237
+ }
238
+ .debug-grid-overlay div:nth-child(7) {
239
+ transition-delay: 70ms;
240
+ }
241
+ .debug-grid-overlay div:nth-child(8) {
242
+ transition-delay: 56ms;
243
+ }
244
+ .debug-grid-overlay div:nth-child(9) {
245
+ transition-delay: 42ms;
246
+ }
247
+ .debug-grid-overlay div:nth-child(10) {
248
+ transition-delay: 28ms;
249
+ }
250
+ .debug-grid-overlay div:nth-child(11) {
251
+ transition-delay: 14ms;
252
+ }
253
+ .debug-grid-overlay div:nth-child(12) {
254
+ transition-delay: 0ms;
255
+ }
256
+
214
257
  body.show-grid .debug-grid-overlay {
215
- display: grid !important;
258
+ visibility: visible;
259
+ opacity: 1;
260
+ transition: opacity 160ms ease-out, visibility 0s;
261
+ }
262
+ body.show-grid .debug-grid-overlay div:nth-child(1) {
263
+ transform: scaleY(1);
264
+ transition-delay: 0ms;
265
+ }
266
+ body.show-grid .debug-grid-overlay div:nth-child(2) {
267
+ transform: scaleY(1);
268
+ transition-delay: 14ms;
269
+ }
270
+ body.show-grid .debug-grid-overlay div:nth-child(3) {
271
+ transform: scaleY(1);
272
+ transition-delay: 28ms;
273
+ }
274
+ body.show-grid .debug-grid-overlay div:nth-child(4) {
275
+ transform: scaleY(1);
276
+ transition-delay: 42ms;
277
+ }
278
+ body.show-grid .debug-grid-overlay div:nth-child(5) {
279
+ transform: scaleY(1);
280
+ transition-delay: 56ms;
281
+ }
282
+ body.show-grid .debug-grid-overlay div:nth-child(6) {
283
+ transform: scaleY(1);
284
+ transition-delay: 70ms;
285
+ }
286
+ body.show-grid .debug-grid-overlay div:nth-child(7) {
287
+ transform: scaleY(1);
288
+ transition-delay: 84ms;
289
+ }
290
+ body.show-grid .debug-grid-overlay div:nth-child(8) {
291
+ transform: scaleY(1);
292
+ transition-delay: 98ms;
293
+ }
294
+ body.show-grid .debug-grid-overlay div:nth-child(9) {
295
+ transform: scaleY(1);
296
+ transition-delay: 112ms;
297
+ }
298
+ body.show-grid .debug-grid-overlay div:nth-child(10) {
299
+ transform: scaleY(1);
300
+ transition-delay: 126ms;
301
+ }
302
+ body.show-grid .debug-grid-overlay div:nth-child(11) {
303
+ transform: scaleY(1);
304
+ transition-delay: 140ms;
305
+ }
306
+ body.show-grid .debug-grid-overlay div:nth-child(12) {
307
+ transform: scaleY(1);
308
+ transition-delay: 154ms;
216
309
  }
217
310
 
311
+ @media (prefers-reduced-motion: reduce) {
312
+ .debug-grid-overlay,
313
+ .debug-grid-overlay div,
314
+ body.show-grid .debug-grid-overlay {
315
+ transition-duration: 1ms;
316
+ transition-delay: 0ms;
317
+ }
318
+ }
218
319
  .main-grid {
219
320
  display: grid;
220
321
  grid-template-columns: repeat(12, minmax(0, 1fr));
package/styles/main.css CHANGED
@@ -191,10 +191,6 @@ ul {
191
191
  }
192
192
 
193
193
  .debug-grid-overlay {
194
- display: none;
195
- }
196
-
197
- body.show-grid .debug-grid-overlay {
198
194
  position: fixed !important;
199
195
  inset-block: 0;
200
196
  left: 50%;
@@ -207,14 +203,119 @@ body.show-grid .debug-grid-overlay {
207
203
  grid-template-columns: repeat(12, 1fr);
208
204
  column-gap: 1.5rem;
209
205
  }
210
- body.show-grid .debug-grid-overlay div {
206
+ .debug-grid-overlay div {
211
207
  height: 100%;
212
208
  background-color: rgba(255, 0, 0, 0.13);
213
209
  }
210
+ .debug-grid-overlay {
211
+ visibility: hidden;
212
+ opacity: 0;
213
+ transition: opacity 160ms ease-out, visibility 0s linear 520ms;
214
+ }
215
+ .debug-grid-overlay div {
216
+ transform: scaleY(0);
217
+ transform-origin: top;
218
+ transition: transform 360ms cubic-bezier(0.25, 1, 0.5, 1);
219
+ }
220
+ .debug-grid-overlay div:nth-child(1) {
221
+ transition-delay: 154ms;
222
+ }
223
+ .debug-grid-overlay div:nth-child(2) {
224
+ transition-delay: 140ms;
225
+ }
226
+ .debug-grid-overlay div:nth-child(3) {
227
+ transition-delay: 126ms;
228
+ }
229
+ .debug-grid-overlay div:nth-child(4) {
230
+ transition-delay: 112ms;
231
+ }
232
+ .debug-grid-overlay div:nth-child(5) {
233
+ transition-delay: 98ms;
234
+ }
235
+ .debug-grid-overlay div:nth-child(6) {
236
+ transition-delay: 84ms;
237
+ }
238
+ .debug-grid-overlay div:nth-child(7) {
239
+ transition-delay: 70ms;
240
+ }
241
+ .debug-grid-overlay div:nth-child(8) {
242
+ transition-delay: 56ms;
243
+ }
244
+ .debug-grid-overlay div:nth-child(9) {
245
+ transition-delay: 42ms;
246
+ }
247
+ .debug-grid-overlay div:nth-child(10) {
248
+ transition-delay: 28ms;
249
+ }
250
+ .debug-grid-overlay div:nth-child(11) {
251
+ transition-delay: 14ms;
252
+ }
253
+ .debug-grid-overlay div:nth-child(12) {
254
+ transition-delay: 0ms;
255
+ }
256
+
214
257
  body.show-grid .debug-grid-overlay {
215
- display: grid !important;
258
+ visibility: visible;
259
+ opacity: 1;
260
+ transition: opacity 160ms ease-out, visibility 0s;
261
+ }
262
+ body.show-grid .debug-grid-overlay div:nth-child(1) {
263
+ transform: scaleY(1);
264
+ transition-delay: 0ms;
265
+ }
266
+ body.show-grid .debug-grid-overlay div:nth-child(2) {
267
+ transform: scaleY(1);
268
+ transition-delay: 14ms;
269
+ }
270
+ body.show-grid .debug-grid-overlay div:nth-child(3) {
271
+ transform: scaleY(1);
272
+ transition-delay: 28ms;
273
+ }
274
+ body.show-grid .debug-grid-overlay div:nth-child(4) {
275
+ transform: scaleY(1);
276
+ transition-delay: 42ms;
277
+ }
278
+ body.show-grid .debug-grid-overlay div:nth-child(5) {
279
+ transform: scaleY(1);
280
+ transition-delay: 56ms;
281
+ }
282
+ body.show-grid .debug-grid-overlay div:nth-child(6) {
283
+ transform: scaleY(1);
284
+ transition-delay: 70ms;
285
+ }
286
+ body.show-grid .debug-grid-overlay div:nth-child(7) {
287
+ transform: scaleY(1);
288
+ transition-delay: 84ms;
289
+ }
290
+ body.show-grid .debug-grid-overlay div:nth-child(8) {
291
+ transform: scaleY(1);
292
+ transition-delay: 98ms;
293
+ }
294
+ body.show-grid .debug-grid-overlay div:nth-child(9) {
295
+ transform: scaleY(1);
296
+ transition-delay: 112ms;
297
+ }
298
+ body.show-grid .debug-grid-overlay div:nth-child(10) {
299
+ transform: scaleY(1);
300
+ transition-delay: 126ms;
301
+ }
302
+ body.show-grid .debug-grid-overlay div:nth-child(11) {
303
+ transform: scaleY(1);
304
+ transition-delay: 140ms;
305
+ }
306
+ body.show-grid .debug-grid-overlay div:nth-child(12) {
307
+ transform: scaleY(1);
308
+ transition-delay: 154ms;
216
309
  }
217
310
 
311
+ @media (prefers-reduced-motion: reduce) {
312
+ .debug-grid-overlay,
313
+ .debug-grid-overlay div,
314
+ body.show-grid .debug-grid-overlay {
315
+ transition-duration: 1ms;
316
+ transition-delay: 0ms;
317
+ }
318
+ }
218
319
  .main-grid {
219
320
  display: grid;
220
321
  grid-template-columns: repeat(12, minmax(0, 1fr));