@lesterarte/sefin-ui 0.0.3-dev.2 → 0.0.3-dev.21

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,6 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Output, Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { Input, ChangeDetectionStrategy, Component, EventEmitter, Output, forwardRef, ViewChild, HostListener } from '@angular/core';
3
+ import * as i1 from '@angular/common';
3
4
  import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/forms';
6
+ import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
4
7
 
5
8
  /**
6
9
  * Color design tokens as TypeScript constants
@@ -339,12 +342,36 @@ class ThemeLoader {
339
342
  /**
340
343
  * Load a theme and apply it to the document root
341
344
  * @param themeName - Predefined theme name ('light', 'dark', 'brand') or a CustomTheme object
345
+ * @param variant - Optional variant ('light' or 'dark') for CustomTheme with variants support
342
346
  */
343
- static loadTheme(themeName = 'light') {
344
- const theme = typeof themeName === 'string' ? this.getTheme(themeName) : themeName;
347
+ static loadTheme(themeName = 'light', variant) {
348
+ let theme;
349
+ let colors;
350
+ if (typeof themeName === 'string') {
351
+ theme = this.getTheme(themeName);
352
+ colors = theme.colors;
353
+ }
354
+ else {
355
+ theme = themeName;
356
+ // If variant is specified and theme has variants, use variant colors
357
+ if (variant && theme.variants) {
358
+ const variantColors = theme.variants[variant];
359
+ if (variantColors) {
360
+ colors = variantColors;
361
+ }
362
+ else {
363
+ // Fallback to base colors if variant doesn't exist
364
+ colors = theme.colors;
365
+ }
366
+ }
367
+ else {
368
+ // Use base colors if no variant specified or no variants defined
369
+ colors = theme.colors;
370
+ }
371
+ }
345
372
  const root = document.documentElement;
346
373
  // Apply color tokens
347
- Object.entries(theme.colors).forEach(([key, value]) => {
374
+ Object.entries(colors).forEach(([key, value]) => {
348
375
  if (value) {
349
376
  root.style.setProperty(`--sefin-color-${key}`, value);
350
377
  }
@@ -392,9 +419,30 @@ class ThemeLoader {
392
419
  root.style.setProperty(`--sefin-shadow-${key}`, value);
393
420
  });
394
421
  // Set theme attribute for CSS selectors
395
- const themeAttribute = typeof themeName === 'string' ? themeName : themeName.name;
422
+ let themeAttribute;
423
+ if (typeof themeName === 'string') {
424
+ themeAttribute = themeName;
425
+ }
426
+ else {
427
+ themeAttribute = variant
428
+ ? `${themeName.name}-${variant}`
429
+ : themeName.name;
430
+ }
396
431
  root.setAttribute('data-theme', themeAttribute);
397
432
  }
433
+ /**
434
+ * Load a custom theme variant (light or dark)
435
+ * @param customTheme - CustomTheme object with variants support
436
+ * @param variant - Variant to load ('light' or 'dark')
437
+ */
438
+ static loadThemeVariant(customTheme, variant) {
439
+ if (!customTheme.variants) {
440
+ console.warn(`Theme "${customTheme.name}" does not have variants. Loading base theme.`);
441
+ this.loadTheme(customTheme);
442
+ return;
443
+ }
444
+ this.loadTheme(customTheme, variant);
445
+ }
398
446
  /**
399
447
  * Get theme configuration by name
400
448
  */
@@ -412,12 +460,34 @@ class ThemeLoader {
412
460
  /**
413
461
  * Get all CSS variables as a string (useful for SSR or static generation)
414
462
  * @param themeName - Predefined theme name ('light', 'dark', 'brand') or a CustomTheme object
463
+ * @param variant - Optional variant ('light' or 'dark') for CustomTheme with variants support
415
464
  */
416
- static getThemeCSS(themeName = 'light') {
417
- const theme = typeof themeName === 'string' ? this.getTheme(themeName) : themeName;
465
+ static getThemeCSS(themeName = 'light', variant) {
466
+ let theme;
467
+ let colors;
468
+ if (typeof themeName === 'string') {
469
+ theme = this.getTheme(themeName);
470
+ colors = theme.colors;
471
+ }
472
+ else {
473
+ theme = themeName;
474
+ // If variant is specified and theme has variants, use variant colors
475
+ if (variant && theme.variants) {
476
+ const variantColors = theme.variants[variant];
477
+ if (variantColors) {
478
+ colors = variantColors;
479
+ }
480
+ else {
481
+ colors = theme.colors;
482
+ }
483
+ }
484
+ else {
485
+ colors = theme.colors;
486
+ }
487
+ }
418
488
  let css = ':root {\n';
419
489
  // Color tokens
420
- Object.entries(theme.colors).forEach(([key, value]) => {
490
+ Object.entries(colors).forEach(([key, value]) => {
421
491
  if (value) {
422
492
  css += ` --sefin-color-${key}: ${value};\n`;
423
493
  }
@@ -481,11 +551,128 @@ class ThemeLoader {
481
551
  * Shared index
482
552
  */
483
553
 
554
+ class AvatarComponent {
555
+ /** Avatar size. Options: 'xs' | 'sm' | 'md' | 'lg' | 'xl' */
556
+ size = 'md';
557
+ /** Image source URL */
558
+ src;
559
+ /** Alt text for the image */
560
+ alt = '';
561
+ /** Initials to display when no image is provided */
562
+ initials;
563
+ /** Whether to show a border/ring around the avatar */
564
+ bordered = false;
565
+ /** Additional CSS classes */
566
+ class = '';
567
+ get avatarClasses() {
568
+ return [
569
+ 'sefin-avatar',
570
+ `sefin-avatar--${this.size}`,
571
+ this.bordered ? 'sefin-avatar--bordered' : '',
572
+ this.class,
573
+ ]
574
+ .filter(Boolean)
575
+ .join(' ');
576
+ }
577
+ get displayInitials() {
578
+ if (this.initials) {
579
+ return this.initials.toUpperCase().slice(0, 2);
580
+ }
581
+ return '';
582
+ }
583
+ onImageError(event) {
584
+ const img = event.target;
585
+ img.style.display = 'none';
586
+ }
587
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
588
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: AvatarComponent, isStandalone: true, selector: "sefin-avatar", inputs: { size: "size", src: "src", alt: "alt", initials: "initials", bordered: "bordered", class: "class" }, ngImport: i0, template: "<div [class]=\"avatarClasses\">\n <img\n *ngIf=\"src\"\n [src]=\"src\"\n [alt]=\"alt || 'Avatar'\"\n (error)=\"onImageError($event)\"\n class=\"sefin-avatar__image\"\n />\n <span *ngIf=\"!src && displayInitials\" class=\"sefin-avatar__initials\">\n {{ displayInitials }}\n </span>\n <svg\n *ngIf=\"!src && !displayInitials\"\n class=\"sefin-avatar__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M20 21V19C20 17.9391 19.5786 16.9217 18.8284 16.1716C18.0783 15.4214 17.0609 15 16 15H8C6.93913 15 5.92172 15.4214 5.17157 16.1716C4.42143 16.9217 4 17.9391 4 19V21M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</div>\n\n", styles: [".sefin-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:50%;overflow:hidden;background-color:var(--sefin-color-surface);color:var(--sefin-color-text-secondary);font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);-webkit-user-select:none;user-select:none}.sefin-avatar--xs{width:24px;height:24px;font-size:var(--sefin-font-size-xs, 10px)}.sefin-avatar--sm{width:32px;height:32px;font-size:var(--sefin-font-size-xs, 11px)}.sefin-avatar--md{width:40px;height:40px;font-size:var(--sefin-font-size-sm, 13px)}.sefin-avatar--lg{width:56px;height:56px;font-size:var(--sefin-font-size-base, 16px)}.sefin-avatar--xl{width:80px;height:80px;font-size:var(--sefin-font-size-lg, 20px)}.sefin-avatar--bordered{border:2px solid var(--sefin-color-border);box-shadow:0 0 0 2px var(--sefin-color-surface)}.sefin-avatar__image{width:100%;height:100%;object-fit:cover;display:block}.sefin-avatar__initials{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--sefin-color-text);background-color:var(--sefin-color-primary);background:linear-gradient(135deg,var(--sefin-color-primary) 0%,var(--sefin-color-primary-dark, var(--sefin-color-primary)) 100%);color:#fff;font-weight:var(--sefin-font-weight-semibold);line-height:1}.sefin-avatar__icon{width:60%;height:60%;color:var(--sefin-color-text-secondary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
589
+ }
590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AvatarComponent, decorators: [{
591
+ type: Component,
592
+ args: [{ selector: 'sefin-avatar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"avatarClasses\">\n <img\n *ngIf=\"src\"\n [src]=\"src\"\n [alt]=\"alt || 'Avatar'\"\n (error)=\"onImageError($event)\"\n class=\"sefin-avatar__image\"\n />\n <span *ngIf=\"!src && displayInitials\" class=\"sefin-avatar__initials\">\n {{ displayInitials }}\n </span>\n <svg\n *ngIf=\"!src && !displayInitials\"\n class=\"sefin-avatar__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M20 21V19C20 17.9391 19.5786 16.9217 18.8284 16.1716C18.0783 15.4214 17.0609 15 16 15H8C6.93913 15 5.92172 15.4214 5.17157 16.1716C4.42143 16.9217 4 17.9391 4 19V21M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</div>\n\n", styles: [".sefin-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:50%;overflow:hidden;background-color:var(--sefin-color-surface);color:var(--sefin-color-text-secondary);font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);-webkit-user-select:none;user-select:none}.sefin-avatar--xs{width:24px;height:24px;font-size:var(--sefin-font-size-xs, 10px)}.sefin-avatar--sm{width:32px;height:32px;font-size:var(--sefin-font-size-xs, 11px)}.sefin-avatar--md{width:40px;height:40px;font-size:var(--sefin-font-size-sm, 13px)}.sefin-avatar--lg{width:56px;height:56px;font-size:var(--sefin-font-size-base, 16px)}.sefin-avatar--xl{width:80px;height:80px;font-size:var(--sefin-font-size-lg, 20px)}.sefin-avatar--bordered{border:2px solid var(--sefin-color-border);box-shadow:0 0 0 2px var(--sefin-color-surface)}.sefin-avatar__image{width:100%;height:100%;object-fit:cover;display:block}.sefin-avatar__initials{display:flex;align-items:center;justify-content:center;width:100%;height:100%;color:var(--sefin-color-text);background-color:var(--sefin-color-primary);background:linear-gradient(135deg,var(--sefin-color-primary) 0%,var(--sefin-color-primary-dark, var(--sefin-color-primary)) 100%);color:#fff;font-weight:var(--sefin-font-weight-semibold);line-height:1}.sefin-avatar__icon{width:60%;height:60%;color:var(--sefin-color-text-secondary)}\n"] }]
593
+ }], propDecorators: { size: [{
594
+ type: Input
595
+ }], src: [{
596
+ type: Input
597
+ }], alt: [{
598
+ type: Input
599
+ }], initials: [{
600
+ type: Input
601
+ }], bordered: [{
602
+ type: Input
603
+ }], class: [{
604
+ type: Input
605
+ }] } });
606
+
607
+ class BadgeComponent {
608
+ /** Badge variant style. Options: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' */
609
+ variant = 'default';
610
+ /** Badge size. Options: 'sm' | 'md' | 'lg' */
611
+ size = 'md';
612
+ /** Whether the badge should be displayed as a dot (no text) */
613
+ dot = false;
614
+ /** Maximum number to show before displaying as "+N" */
615
+ max;
616
+ /** Badge value (number or text) */
617
+ value;
618
+ /** Additional CSS classes */
619
+ class = '';
620
+ get badgeClasses() {
621
+ return [
622
+ 'sefin-badge',
623
+ `sefin-badge--${this.variant}`,
624
+ `sefin-badge--${this.size}`,
625
+ this.dot ? 'sefin-badge--dot' : '',
626
+ this.class,
627
+ ]
628
+ .filter(Boolean)
629
+ .join(' ');
630
+ }
631
+ get displayValue() {
632
+ if (this.dot) {
633
+ return '';
634
+ }
635
+ if (this.value === undefined || this.value === null) {
636
+ return '';
637
+ }
638
+ if (typeof this.value === 'number') {
639
+ if (this.max !== undefined && this.value > this.max) {
640
+ return `+${this.max}`;
641
+ }
642
+ return String(this.value);
643
+ }
644
+ return String(this.value);
645
+ }
646
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
647
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: BadgeComponent, isStandalone: true, selector: "sefin-badge", inputs: { variant: "variant", size: "size", dot: "dot", max: "max", value: "value", class: "class" }, ngImport: i0, template: "<span [class]=\"badgeClasses\" [attr.aria-label]=\"displayValue || 'Badge'\">\n <span *ngIf=\"!dot\" class=\"sefin-badge__content\">{{ displayValue }}</span>\n</span>", styles: [".sefin-badge{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:1;border-radius:var(--sefin-border-radius-full, 9999px);white-space:nowrap;vertical-align:middle;box-sizing:border-box}.sefin-badge--sm{min-width:16px;height:16px;padding:0 var(--sefin-spacing-xs, 4px);font-size:var(--sefin-font-size-xs, 10px)}.sefin-badge--sm:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-xs, 4px)}.sefin-badge--md{min-width:20px;height:20px;padding:0 var(--sefin-spacing-xs, 4px);font-size:var(--sefin-font-size-xs, 11px)}.sefin-badge--md:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-sm, 6px)}.sefin-badge--lg{min-width:24px;height:24px;padding:0 var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, 12px)}.sefin-badge--lg:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-md, 8px)}.sefin-badge--dot{width:8px;height:8px;min-width:8px;padding:0;border-radius:50%!important}.sefin-badge--dot.sefin-badge--sm{width:6px;height:6px;min-width:6px;border-radius:50%!important}.sefin-badge--dot.sefin-badge--md{width:8px;height:8px;min-width:8px;border-radius:50%!important}.sefin-badge--dot.sefin-badge--lg{width:10px;height:10px;min-width:10px;border-radius:50%!important}.sefin-badge--default{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-badge--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-badge--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-badge--success{background-color:var(--sefin-color-success);color:#fff}.sefin-badge--warning{background-color:var(--sefin-color-warning);color:#fff}.sefin-badge--error{background-color:var(--sefin-color-error);color:#fff}.sefin-badge__content{display:inline-block;line-height:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
648
+ }
649
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: BadgeComponent, decorators: [{
650
+ type: Component,
651
+ args: [{ selector: 'sefin-badge', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span [class]=\"badgeClasses\" [attr.aria-label]=\"displayValue || 'Badge'\">\n <span *ngIf=\"!dot\" class=\"sefin-badge__content\">{{ displayValue }}</span>\n</span>", styles: [".sefin-badge{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:1;border-radius:var(--sefin-border-radius-full, 9999px);white-space:nowrap;vertical-align:middle;box-sizing:border-box}.sefin-badge--sm{min-width:16px;height:16px;padding:0 var(--sefin-spacing-xs, 4px);font-size:var(--sefin-font-size-xs, 10px)}.sefin-badge--sm:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-xs, 4px)}.sefin-badge--md{min-width:20px;height:20px;padding:0 var(--sefin-spacing-xs, 4px);font-size:var(--sefin-font-size-xs, 11px)}.sefin-badge--md:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-sm, 6px)}.sefin-badge--lg{min-width:24px;height:24px;padding:0 var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, 12px)}.sefin-badge--lg:not(.sefin-badge--dot){padding:0 var(--sefin-spacing-md, 8px)}.sefin-badge--dot{width:8px;height:8px;min-width:8px;padding:0;border-radius:50%!important}.sefin-badge--dot.sefin-badge--sm{width:6px;height:6px;min-width:6px;border-radius:50%!important}.sefin-badge--dot.sefin-badge--md{width:8px;height:8px;min-width:8px;border-radius:50%!important}.sefin-badge--dot.sefin-badge--lg{width:10px;height:10px;min-width:10px;border-radius:50%!important}.sefin-badge--default{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-badge--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-badge--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-badge--success{background-color:var(--sefin-color-success);color:#fff}.sefin-badge--warning{background-color:var(--sefin-color-warning);color:#fff}.sefin-badge--error{background-color:var(--sefin-color-error);color:#fff}.sefin-badge__content{display:inline-block;line-height:1}\n"] }]
652
+ }], propDecorators: { variant: [{
653
+ type: Input
654
+ }], size: [{
655
+ type: Input
656
+ }], dot: [{
657
+ type: Input
658
+ }], max: [{
659
+ type: Input
660
+ }], value: [{
661
+ type: Input
662
+ }], class: [{
663
+ type: Input
664
+ }] } });
665
+
484
666
  class ButtonComponent {
667
+ /** Button variant style. Options: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' */
485
668
  variant = 'primary';
669
+ /** Button size. Options: 'sm' | 'md' | 'lg' */
486
670
  size = 'md';
671
+ /** Whether the button is disabled */
487
672
  disabled = false;
673
+ /** Button type. Options: 'button' | 'submit' | 'reset' */
488
674
  type = 'button';
675
+ /** Additional CSS classes */
489
676
  class = '';
490
677
  clicked = new EventEmitter();
491
678
  onClick(event) {
@@ -505,11 +692,11 @@ class ButtonComponent {
505
692
  .join(' ');
506
693
  }
507
694
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
508
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: ButtonComponent, isStandalone: true, selector: "sefin-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", class: "class" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button [type]=\"type\" [disabled]=\"disabled\" [class]=\"buttonClasses\" (click)=\"onClick($event)\">\n <ng-content></ng-content>\n</button>\n", styles: [".sefin-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium, 500);border-radius:var(--sefin-radius-md, 8px);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent}.sefin-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-button--sm{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-sm, .875rem);min-height:32px}.sefin-button--md{padding:var(--sefin-spacing-md, 16px) var(--sefin-spacing-lg, 24px);font-size:var(--sefin-font-size-base, 1rem);min-height:40px}.sefin-button--lg{padding:var(--sefin-spacing-lg, 24px) var(--sefin-spacing-xl, 32px);font-size:var(--sefin-font-size-lg, 1.125rem);min-height:48px}.sefin-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
695
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: ButtonComponent, isStandalone: true, selector: "sefin-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", class: "class" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button [type]=\"type\" [disabled]=\"disabled\" [class]=\"buttonClasses\" (click)=\"onClick($event)\">\n <ng-content></ng-content>\n</button>\n", styles: [".sefin-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent}.sefin-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-button--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-button--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-button--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
509
696
  }
510
697
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ButtonComponent, decorators: [{
511
698
  type: Component,
512
- args: [{ selector: 'sefin-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button [type]=\"type\" [disabled]=\"disabled\" [class]=\"buttonClasses\" (click)=\"onClick($event)\">\n <ng-content></ng-content>\n</button>\n", styles: [".sefin-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium, 500);border-radius:var(--sefin-radius-md, 8px);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent}.sefin-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-button--sm{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-sm, .875rem);min-height:32px}.sefin-button--md{padding:var(--sefin-spacing-md, 16px) var(--sefin-spacing-lg, 24px);font-size:var(--sefin-font-size-base, 1rem);min-height:40px}.sefin-button--lg{padding:var(--sefin-spacing-lg, 24px) var(--sefin-spacing-xl, 32px);font-size:var(--sefin-font-size-lg, 1.125rem);min-height:48px}.sefin-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}\n"] }]
699
+ args: [{ selector: 'sefin-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button [type]=\"type\" [disabled]=\"disabled\" [class]=\"buttonClasses\" (click)=\"onClick($event)\">\n <ng-content></ng-content>\n</button>\n", styles: [".sefin-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent}.sefin-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-button--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-button--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-button--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}\n"] }]
513
700
  }], propDecorators: { variant: [{
514
701
  type: Input
515
702
  }], size: [{
@@ -524,10 +711,1067 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
524
711
  type: Output
525
712
  }] } });
526
713
 
714
+ class IconButtonComponent {
715
+ /** Button variant style. Options: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' */
716
+ variant = 'primary';
717
+ /** Button size. Options: 'sm' | 'md' | 'lg' */
718
+ size = 'md';
719
+ /** Whether the button is disabled */
720
+ disabled = false;
721
+ /** Button type. Options: 'button' | 'submit' | 'reset' */
722
+ type = 'button';
723
+ /** Additional CSS classes */
724
+ class = '';
725
+ /** Accessibility label for the button */
726
+ ariaLabel = '';
727
+ /** Whether the button should be rounded (circular) */
728
+ rounded = false;
729
+ clicked = new EventEmitter();
730
+ onClick(event) {
731
+ if (!this.disabled) {
732
+ this.clicked.emit(event);
733
+ }
734
+ }
735
+ get buttonClasses() {
736
+ return [
737
+ 'sefin-icon-button',
738
+ `sefin-icon-button--${this.variant}`,
739
+ `sefin-icon-button--${this.size}`,
740
+ this.disabled ? 'sefin-icon-button--disabled' : '',
741
+ this.rounded ? 'sefin-icon-button--rounded' : '',
742
+ this.class,
743
+ ]
744
+ .filter(Boolean)
745
+ .join(' ');
746
+ }
747
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
748
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: IconButtonComponent, isStandalone: true, selector: "sefin-icon-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", class: "class", ariaLabel: "ariaLabel", rounded: "rounded" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button \n [type]=\"type\" \n [disabled]=\"disabled\" \n [class]=\"buttonClasses\" \n (click)=\"onClick($event)\"\n [attr.aria-label]=\"ariaLabel || null\"\n>\n <ng-content></ng-content>\n</button>\n\n", styles: [".sefin-icon-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;padding:0;aspect-ratio:1;flex-shrink:0}.sefin-icon-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-icon-button--sm{width:32px;height:32px;min-width:32px;min-height:32px}.sefin-icon-button--md{width:40px;height:40px;min-width:40px;min-height:40px}.sefin-icon-button--lg{width:48px;height:48px;min-width:48px;min-height:48px}.sefin-icon-button--rounded{border-radius:50%}.sefin-icon-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-icon-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-icon-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-icon-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-icon-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-icon-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-icon-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-icon-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-icon-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-icon-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-icon-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-icon-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-icon-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.sefin-icon-button svg{width:100%;height:100%;display:block}.sefin-icon-button--sm svg{width:16px;height:16px}.sefin-icon-button--md svg{width:20px;height:20px}.sefin-icon-button--lg svg{width:24px;height:24px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
749
+ }
750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: IconButtonComponent, decorators: [{
751
+ type: Component,
752
+ args: [{ selector: 'sefin-icon-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button \n [type]=\"type\" \n [disabled]=\"disabled\" \n [class]=\"buttonClasses\" \n (click)=\"onClick($event)\"\n [attr.aria-label]=\"ariaLabel || null\"\n>\n <ng-content></ng-content>\n</button>\n\n", styles: [".sefin-icon-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;padding:0;aspect-ratio:1;flex-shrink:0}.sefin-icon-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-icon-button--sm{width:32px;height:32px;min-width:32px;min-height:32px}.sefin-icon-button--md{width:40px;height:40px;min-width:40px;min-height:40px}.sefin-icon-button--lg{width:48px;height:48px;min-width:48px;min-height:48px}.sefin-icon-button--rounded{border-radius:50%}.sefin-icon-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-icon-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-icon-button--primary:active:not(:disabled){transform:translateY(1px)}.sefin-icon-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-icon-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-icon-button--secondary:active:not(:disabled){transform:translateY(1px)}.sefin-icon-button--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-icon-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-icon-button--ghost{background-color:transparent;color:var(--sefin-color-primary)}.sefin-icon-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-icon-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-icon-button--danger:hover:not(:disabled){background-color:var(--sefin-color-error);opacity:.9}.sefin-icon-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.sefin-icon-button svg{width:100%;height:100%;display:block}.sefin-icon-button--sm svg{width:16px;height:16px}.sefin-icon-button--md svg{width:20px;height:20px}.sefin-icon-button--lg svg{width:24px;height:24px}\n"] }]
753
+ }], propDecorators: { variant: [{
754
+ type: Input
755
+ }], size: [{
756
+ type: Input
757
+ }], disabled: [{
758
+ type: Input
759
+ }], type: [{
760
+ type: Input
761
+ }], class: [{
762
+ type: Input
763
+ }], ariaLabel: [{
764
+ type: Input
765
+ }], rounded: [{
766
+ type: Input
767
+ }], clicked: [{
768
+ type: Output
769
+ }] } });
770
+
771
+ class FabButtonComponent {
772
+ /** Button variant style. Options: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' */
773
+ variant = 'primary';
774
+ /** FAB size. Options: 'sm' | 'md' | 'lg' */
775
+ size = 'md';
776
+ /** Whether the button is disabled */
777
+ disabled = false;
778
+ /** Button type. Options: 'button' | 'submit' | 'reset' */
779
+ type = 'button';
780
+ /** Additional CSS classes */
781
+ class = '';
782
+ /** Accessibility label for the button */
783
+ ariaLabel = '';
784
+ clicked = new EventEmitter();
785
+ onClick(event) {
786
+ if (!this.disabled) {
787
+ this.clicked.emit(event);
788
+ }
789
+ }
790
+ get buttonClasses() {
791
+ return [
792
+ 'sefin-fab-button',
793
+ `sefin-fab-button--${this.variant}`,
794
+ `sefin-fab-button--${this.size}`,
795
+ this.disabled ? 'sefin-fab-button--disabled' : '',
796
+ this.class,
797
+ ]
798
+ .filter(Boolean)
799
+ .join(' ');
800
+ }
801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FabButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: FabButtonComponent, isStandalone: true, selector: "sefin-fab-button", inputs: { variant: "variant", size: "size", disabled: "disabled", type: "type", class: "class", ariaLabel: "ariaLabel" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button \n [type]=\"type\" \n [disabled]=\"disabled\" \n [class]=\"buttonClasses\" \n (click)=\"onClick($event)\"\n [attr.aria-label]=\"ariaLabel || null\"\n>\n <ng-content></ng-content>\n</button>\n\n", styles: [".sefin-fab-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);border-radius:50%;transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;padding:0;aspect-ratio:1;flex-shrink:0;box-shadow:var(--sefin-shadow-lg);position:relative}.sefin-fab-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-fab-button--sm{width:40px;height:40px;min-width:40px;min-height:40px;box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--md{width:56px;height:56px;min-width:56px;min-height:56px;box-shadow:var(--sefin-shadow-lg)}.sefin-fab-button--lg{width:64px;height:64px;min-width:64px;min-height:64px;box-shadow:var(--sefin-shadow-xl)}.sefin-fab-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-fab-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark);box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--primary:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-fab-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark);box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--secondary:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--outline{background-color:var(--sefin-color-surface);color:var(--sefin-color-primary);border-color:var(--sefin-color-primary);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff;box-shadow:var(--sefin-shadow-lg);transform:translateY(-2px)}.sefin-fab-button--outline:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--ghost{background-color:var(--sefin-color-surface);color:var(--sefin-color-primary);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover);box-shadow:var(--sefin-shadow-lg);transform:translateY(-2px)}.sefin-fab-button--ghost:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-sm)}.sefin-fab-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-fab-button--danger:hover:not(:disabled){opacity:.9;box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--danger:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none;box-shadow:var(--sefin-shadow-sm)}.sefin-fab-button svg{display:block;flex-shrink:0}.sefin-fab-button--sm svg{width:20px;height:20px}.sefin-fab-button--md svg{width:24px;height:24px}.sefin-fab-button--lg svg{width:28px;height:28px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
803
+ }
804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FabButtonComponent, decorators: [{
805
+ type: Component,
806
+ args: [{ selector: 'sefin-fab-button', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<button \n [type]=\"type\" \n [disabled]=\"disabled\" \n [class]=\"buttonClasses\" \n (click)=\"onClick($event)\"\n [attr.aria-label]=\"ariaLabel || null\"\n>\n <ng-content></ng-content>\n</button>\n\n", styles: [".sefin-fab-button{display:inline-flex;align-items:center;justify-content:center;font-family:var(--sefin-font-family-base);border-radius:50%;transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;padding:0;aspect-ratio:1;flex-shrink:0;box-shadow:var(--sefin-shadow-lg);position:relative}.sefin-fab-button:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-fab-button--sm{width:40px;height:40px;min-width:40px;min-height:40px;box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--md{width:56px;height:56px;min-width:56px;min-height:56px;box-shadow:var(--sefin-shadow-lg)}.sefin-fab-button--lg{width:64px;height:64px;min-width:64px;min-height:64px;box-shadow:var(--sefin-shadow-xl)}.sefin-fab-button--primary{background-color:var(--sefin-color-primary);color:#fff}.sefin-fab-button--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark);box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--primary:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--secondary{background-color:var(--sefin-color-secondary);color:#fff}.sefin-fab-button--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark);box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--secondary:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--outline{background-color:var(--sefin-color-surface);color:var(--sefin-color-primary);border-color:var(--sefin-color-primary);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff;box-shadow:var(--sefin-shadow-lg);transform:translateY(-2px)}.sefin-fab-button--outline:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--ghost{background-color:var(--sefin-color-surface);color:var(--sefin-color-primary);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover);box-shadow:var(--sefin-shadow-lg);transform:translateY(-2px)}.sefin-fab-button--ghost:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-sm)}.sefin-fab-button--danger{background-color:var(--sefin-color-error);color:#fff}.sefin-fab-button--danger:hover:not(:disabled){opacity:.9;box-shadow:var(--sefin-shadow-xl);transform:translateY(-2px)}.sefin-fab-button--danger:active:not(:disabled){transform:translateY(0);box-shadow:var(--sefin-shadow-md)}.sefin-fab-button--disabled{opacity:.6;cursor:not-allowed;pointer-events:none;box-shadow:var(--sefin-shadow-sm)}.sefin-fab-button svg{display:block;flex-shrink:0}.sefin-fab-button--sm svg{width:20px;height:20px}.sefin-fab-button--md svg{width:24px;height:24px}.sefin-fab-button--lg svg{width:28px;height:28px}\n"] }]
807
+ }], propDecorators: { variant: [{
808
+ type: Input
809
+ }], size: [{
810
+ type: Input
811
+ }], disabled: [{
812
+ type: Input
813
+ }], type: [{
814
+ type: Input
815
+ }], class: [{
816
+ type: Input
817
+ }], ariaLabel: [{
818
+ type: Input
819
+ }], clicked: [{
820
+ type: Output
821
+ }] } });
822
+
823
+ class ChipComponent {
824
+ /** Chip variant style. Options: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' */
825
+ variant = 'default';
826
+ /** Chip size. Options: 'sm' | 'md' | 'lg' */
827
+ size = 'md';
828
+ /** Whether the chip is disabled */
829
+ disabled = false;
830
+ /** Whether the chip can be removed (shows remove button) */
831
+ removable = false;
832
+ /** Whether the chip is selected (for selectable chips) */
833
+ selected = false;
834
+ /** Additional CSS classes */
835
+ class = '';
836
+ removed = new EventEmitter();
837
+ clicked = new EventEmitter();
838
+ onRemove(event) {
839
+ event.stopPropagation();
840
+ if (!this.disabled) {
841
+ this.removed.emit(event);
842
+ }
843
+ }
844
+ onClick(event) {
845
+ if (!this.disabled) {
846
+ this.clicked.emit(event);
847
+ }
848
+ }
849
+ get chipClasses() {
850
+ return [
851
+ 'sefin-chip',
852
+ `sefin-chip--${this.variant}`,
853
+ `sefin-chip--${this.size}`,
854
+ this.disabled ? 'sefin-chip--disabled' : '',
855
+ this.selected ? 'sefin-chip--selected' : '',
856
+ this.class,
857
+ ]
858
+ .filter(Boolean)
859
+ .join(' ');
860
+ }
861
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
862
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: ChipComponent, isStandalone: true, selector: "sefin-chip", inputs: { variant: "variant", size: "size", disabled: "disabled", removable: "removable", selected: "selected", class: "class" }, outputs: { removed: "removed", clicked: "clicked" }, ngImport: i0, template: "<div\n [class]=\"chipClasses\"\n (click)=\"onClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-selected]=\"selected\"\n role=\"button\"\n tabindex=\"0\"\n>\n <span class=\"sefin-chip__content\">\n <ng-content></ng-content>\n </span>\n <button\n *ngIf=\"removable && !disabled\"\n type=\"button\"\n class=\"sefin-chip__remove\"\n (click)=\"onRemove($event)\"\n aria-label=\"Remove\"\n tabindex=\"-1\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10.5 3.5L3.5 10.5M3.5 3.5L10.5 10.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n</div>\n\n", styles: [".sefin-chip{display:inline-flex;align-items:center;gap:var(--sefin-spacing-xs, 4px);font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);border-radius:var(--sefin-radius-full);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;white-space:nowrap;-webkit-user-select:none;user-select:none}.sefin-chip:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-chip--sm{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-xs, 12px);min-height:24px}.sefin-chip--md{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-sm, 14px);min-height:32px}.sefin-chip--lg{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-lg, 24px);font-size:var(--sefin-font-size-base, 16px);min-height:40px}.sefin-chip--default{background-color:var(--sefin-color-surface);color:var(--sefin-color-text);border-color:var(--sefin-color-border)}.sefin-chip--default:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-chip--default.sefin-chip--selected,.sefin-chip--primary{background-color:var(--sefin-color-primary);color:#fff;border-color:var(--sefin-color-primary)}.sefin-chip--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-chip--secondary{background-color:var(--sefin-color-secondary);color:#fff;border-color:var(--sefin-color-secondary)}.sefin-chip--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-chip--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-chip--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-chip--outline.sefin-chip--selected{background-color:var(--sefin-color-primary);color:#fff}.sefin-chip--ghost{background-color:transparent;color:var(--sefin-color-text)}.sefin-chip--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-chip--ghost.sefin-chip--selected{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-chip--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.sefin-chip__content{display:inline-flex;align-items:center;gap:var(--sefin-spacing-xs, 4px)}.sefin-chip__remove{display:inline-flex;align-items:center;justify-content:center;padding:0;margin-left:var(--sefin-spacing-xs, 4px);background:none;border:none;cursor:pointer;outline:none;color:currentColor;opacity:.7;transition:opacity .2s ease-in-out;border-radius:50%;width:16px;height:16px;flex-shrink:0}.sefin-chip__remove:hover{opacity:1;background-color:#0000001a}.sefin-chip__remove:focus-visible{outline:2px solid currentColor;outline-offset:2px}.sefin-chip__remove svg{display:block;width:12px;height:12px}.sefin-chip ::ng-deep svg,.sefin-chip ::ng-deep sefin-icon{flex-shrink:0}.sefin-chip--sm ::ng-deep svg{width:12px;height:12px}.sefin-chip--md ::ng-deep svg{width:14px;height:14px}.sefin-chip--lg ::ng-deep svg{width:16px;height:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
863
+ }
864
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ChipComponent, decorators: [{
865
+ type: Component,
866
+ args: [{ selector: 'sefin-chip', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [class]=\"chipClasses\"\n (click)=\"onClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-selected]=\"selected\"\n role=\"button\"\n tabindex=\"0\"\n>\n <span class=\"sefin-chip__content\">\n <ng-content></ng-content>\n </span>\n <button\n *ngIf=\"removable && !disabled\"\n type=\"button\"\n class=\"sefin-chip__remove\"\n (click)=\"onRemove($event)\"\n aria-label=\"Remove\"\n tabindex=\"-1\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10.5 3.5L3.5 10.5M3.5 3.5L10.5 10.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n</div>\n\n", styles: [".sefin-chip{display:inline-flex;align-items:center;gap:var(--sefin-spacing-xs, 4px);font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-medium);line-height:var(--sefin-line-height-normal);border-radius:var(--sefin-radius-full);transition:all .2s ease-in-out;cursor:pointer;outline:none;border:1px solid transparent;white-space:nowrap;-webkit-user-select:none;user-select:none}.sefin-chip:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-chip--sm{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-xs, 12px);min-height:24px}.sefin-chip--md{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-sm, 14px);min-height:32px}.sefin-chip--lg{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-lg, 24px);font-size:var(--sefin-font-size-base, 16px);min-height:40px}.sefin-chip--default{background-color:var(--sefin-color-surface);color:var(--sefin-color-text);border-color:var(--sefin-color-border)}.sefin-chip--default:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-chip--default.sefin-chip--selected,.sefin-chip--primary{background-color:var(--sefin-color-primary);color:#fff;border-color:var(--sefin-color-primary)}.sefin-chip--primary:hover:not(:disabled){background-color:var(--sefin-color-primary-dark)}.sefin-chip--secondary{background-color:var(--sefin-color-secondary);color:#fff;border-color:var(--sefin-color-secondary)}.sefin-chip--secondary:hover:not(:disabled){background-color:var(--sefin-color-secondary-dark)}.sefin-chip--outline{background-color:transparent;color:var(--sefin-color-primary);border-color:var(--sefin-color-primary)}.sefin-chip--outline:hover:not(:disabled){background-color:var(--sefin-color-primary);color:#fff}.sefin-chip--outline.sefin-chip--selected{background-color:var(--sefin-color-primary);color:#fff}.sefin-chip--ghost{background-color:transparent;color:var(--sefin-color-text)}.sefin-chip--ghost:hover:not(:disabled){background-color:var(--sefin-color-surface-hover)}.sefin-chip--ghost.sefin-chip--selected{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-primary)}.sefin-chip--disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.sefin-chip__content{display:inline-flex;align-items:center;gap:var(--sefin-spacing-xs, 4px)}.sefin-chip__remove{display:inline-flex;align-items:center;justify-content:center;padding:0;margin-left:var(--sefin-spacing-xs, 4px);background:none;border:none;cursor:pointer;outline:none;color:currentColor;opacity:.7;transition:opacity .2s ease-in-out;border-radius:50%;width:16px;height:16px;flex-shrink:0}.sefin-chip__remove:hover{opacity:1;background-color:#0000001a}.sefin-chip__remove:focus-visible{outline:2px solid currentColor;outline-offset:2px}.sefin-chip__remove svg{display:block;width:12px;height:12px}.sefin-chip ::ng-deep svg,.sefin-chip ::ng-deep sefin-icon{flex-shrink:0}.sefin-chip--sm ::ng-deep svg{width:12px;height:12px}.sefin-chip--md ::ng-deep svg{width:14px;height:14px}.sefin-chip--lg ::ng-deep svg{width:16px;height:16px}\n"] }]
867
+ }], propDecorators: { variant: [{
868
+ type: Input
869
+ }], size: [{
870
+ type: Input
871
+ }], disabled: [{
872
+ type: Input
873
+ }], removable: [{
874
+ type: Input
875
+ }], selected: [{
876
+ type: Input
877
+ }], class: [{
878
+ type: Input
879
+ }], removed: [{
880
+ type: Output
881
+ }], clicked: [{
882
+ type: Output
883
+ }] } });
884
+
885
+ class LinkComponent {
886
+ /** Link variant style. Options: 'default' | 'primary' | 'secondary' | 'underline' */
887
+ variant = 'default';
888
+ /** Link size. Options: 'sm' | 'md' | 'lg' */
889
+ size = 'md';
890
+ /** Whether the link is disabled */
891
+ disabled = false;
892
+ /** Link URL */
893
+ href;
894
+ /** Link target attribute (e.g., '_blank') */
895
+ target;
896
+ /** Link rel attribute */
897
+ rel;
898
+ /** Additional CSS classes */
899
+ class = '';
900
+ /** Whether to show underline */
901
+ underline = false;
902
+ get linkClasses() {
903
+ return [
904
+ 'sefin-link',
905
+ `sefin-link--${this.variant}`,
906
+ `sefin-link--${this.size}`,
907
+ this.disabled ? 'sefin-link--disabled' : '',
908
+ this.underline ? 'sefin-link--underline' : '',
909
+ this.class,
910
+ ]
911
+ .filter(Boolean)
912
+ .join(' ');
913
+ }
914
+ onClick(event) {
915
+ if (this.disabled) {
916
+ event.preventDefault();
917
+ event.stopPropagation();
918
+ }
919
+ }
920
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
921
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: LinkComponent, isStandalone: true, selector: "sefin-link", inputs: { variant: "variant", size: "size", disabled: "disabled", href: "href", target: "target", rel: "rel", class: "class", underline: "underline" }, ngImport: i0, template: "<a\n [class]=\"linkClasses\"\n [href]=\"disabled ? null : (href || '#')\"\n [attr.target]=\"target\"\n [attr.rel]=\"rel\"\n [attr.aria-disabled]=\"disabled ? true : null\"\n (click)=\"onClick($event)\"\n>\n <ng-content></ng-content>\n</a>\n\n", styles: [".sefin-link{display:inline-flex;align-items:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);text-decoration:none;transition:all .2s ease-in-out;cursor:pointer;outline:none}.sefin-link:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px;border-radius:2px}.sefin-link--sm{font-size:var(--sefin-font-size-sm)}.sefin-link--md{font-size:var(--sefin-font-size-base)}.sefin-link--lg{font-size:var(--sefin-font-size-lg)}.sefin-link--default{color:var(--sefin-color-text);text-decoration:none}.sefin-link--default:hover:not(.sefin-link--default--disabled){color:var(--sefin-color-primary)}.sefin-link--primary{color:var(--sefin-color-primary);text-decoration:none}.sefin-link--primary:hover:not(.sefin-link--primary--disabled){color:var(--sefin-color-primary-dark)}.sefin-link--primary:active:not(.sefin-link--primary--disabled){color:var(--sefin-color-primary-dark)}.sefin-link--secondary{color:var(--sefin-color-text-secondary);text-decoration:none}.sefin-link--secondary:hover:not(.sefin-link--secondary--disabled){color:var(--sefin-color-primary)}.sefin-link--underline{color:var(--sefin-color-primary);text-decoration:underline;text-underline-offset:2px}.sefin-link--underline:hover:not(.sefin-link--underline--disabled){color:var(--sefin-color-primary-dark);text-decoration-thickness:2px}.sefin-link--underline.sefin-link--default{color:var(--sefin-color-text);text-decoration:underline;text-underline-offset:2px}.sefin-link--underline.sefin-link--default:hover:not(.sefin-link--underline.sefin-link--default--disabled){color:var(--sefin-color-primary);text-decoration-thickness:2px}.sefin-link--disabled{opacity:.6;cursor:not-allowed;pointer-events:none;color:var(--sefin-color-text-disabled)}.sefin-link--disabled:hover{color:var(--sefin-color-text-disabled)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.Default });
922
+ }
923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LinkComponent, decorators: [{
924
+ type: Component,
925
+ args: [{ selector: 'sefin-link', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<a\n [class]=\"linkClasses\"\n [href]=\"disabled ? null : (href || '#')\"\n [attr.target]=\"target\"\n [attr.rel]=\"rel\"\n [attr.aria-disabled]=\"disabled ? true : null\"\n (click)=\"onClick($event)\"\n>\n <ng-content></ng-content>\n</a>\n\n", styles: [".sefin-link{display:inline-flex;align-items:center;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);text-decoration:none;transition:all .2s ease-in-out;cursor:pointer;outline:none}.sefin-link:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px;border-radius:2px}.sefin-link--sm{font-size:var(--sefin-font-size-sm)}.sefin-link--md{font-size:var(--sefin-font-size-base)}.sefin-link--lg{font-size:var(--sefin-font-size-lg)}.sefin-link--default{color:var(--sefin-color-text);text-decoration:none}.sefin-link--default:hover:not(.sefin-link--default--disabled){color:var(--sefin-color-primary)}.sefin-link--primary{color:var(--sefin-color-primary);text-decoration:none}.sefin-link--primary:hover:not(.sefin-link--primary--disabled){color:var(--sefin-color-primary-dark)}.sefin-link--primary:active:not(.sefin-link--primary--disabled){color:var(--sefin-color-primary-dark)}.sefin-link--secondary{color:var(--sefin-color-text-secondary);text-decoration:none}.sefin-link--secondary:hover:not(.sefin-link--secondary--disabled){color:var(--sefin-color-primary)}.sefin-link--underline{color:var(--sefin-color-primary);text-decoration:underline;text-underline-offset:2px}.sefin-link--underline:hover:not(.sefin-link--underline--disabled){color:var(--sefin-color-primary-dark);text-decoration-thickness:2px}.sefin-link--underline.sefin-link--default{color:var(--sefin-color-text);text-decoration:underline;text-underline-offset:2px}.sefin-link--underline.sefin-link--default:hover:not(.sefin-link--underline.sefin-link--default--disabled){color:var(--sefin-color-primary);text-decoration-thickness:2px}.sefin-link--disabled{opacity:.6;cursor:not-allowed;pointer-events:none;color:var(--sefin-color-text-disabled)}.sefin-link--disabled:hover{color:var(--sefin-color-text-disabled)}\n"] }]
926
+ }], propDecorators: { variant: [{
927
+ type: Input
928
+ }], size: [{
929
+ type: Input
930
+ }], disabled: [{
931
+ type: Input
932
+ }], href: [{
933
+ type: Input
934
+ }], target: [{
935
+ type: Input
936
+ }], rel: [{
937
+ type: Input
938
+ }], class: [{
939
+ type: Input
940
+ }], underline: [{
941
+ type: Input
942
+ }] } });
943
+
944
+ class StackComponent {
945
+ direction = 'column';
946
+ spacing = 'md';
947
+ align = 'stretch';
948
+ justify = 'start';
949
+ wrap = false;
950
+ class = '';
951
+ get stackClasses() {
952
+ return [
953
+ 'sefin-stack',
954
+ `sefin-stack--${this.direction}`,
955
+ `sefin-stack--spacing-${this.spacing}`,
956
+ `sefin-stack--align-${this.align}`,
957
+ `sefin-stack--justify-${this.justify}`,
958
+ this.wrap ? 'sefin-stack--wrap' : '',
959
+ this.class,
960
+ ]
961
+ .filter(Boolean)
962
+ .join(' ');
963
+ }
964
+ get spacingValue() {
965
+ const spacingMap = {
966
+ 'xs': '4px',
967
+ 'sm': '8px',
968
+ 'md': '16px',
969
+ 'lg': '24px',
970
+ 'xl': '32px',
971
+ '2xl': '48px',
972
+ };
973
+ return spacingMap[this.spacing] || spacingMap['md'];
974
+ }
975
+ get stackStyles() {
976
+ return {
977
+ gap: this.spacingValue,
978
+ };
979
+ }
980
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: StackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
981
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: StackComponent, isStandalone: true, selector: "sefin-stack", inputs: { direction: "direction", spacing: "spacing", align: "align", justify: "justify", wrap: "wrap", class: "class" }, ngImport: i0, template: "<div [class]=\"stackClasses\" [ngStyle]=\"stackStyles\">\n <ng-content></ng-content>\n</div>\n\n", styles: [".sefin-stack{display:flex!important;gap:var(--sefin-spacing-md, 16px)}.sefin-stack--column{flex-direction:column}.sefin-stack--row{flex-direction:row}.sefin-stack--wrap{flex-wrap:wrap}.sefin-stack--spacing-xs{gap:var(--sefin-spacing-xs, 4px)!important}.sefin-stack--spacing-sm{gap:var(--sefin-spacing-sm, 8px)!important}.sefin-stack--spacing-md{gap:var(--sefin-spacing-md, 16px)!important}.sefin-stack--spacing-lg{gap:var(--sefin-spacing-lg, 24px)!important}.sefin-stack--spacing-xl{gap:var(--sefin-spacing-xl, 32px)!important}.sefin-stack--spacing-2xl{gap:var(--sefin-spacing-2xl, 48px)!important}.sefin-stack--align-start{align-items:flex-start}.sefin-stack--align-center{align-items:center}.sefin-stack--align-end{align-items:flex-end}.sefin-stack--align-stretch{align-items:stretch}.sefin-stack--justify-start{justify-content:flex-start}.sefin-stack--justify-center{justify-content:center}.sefin-stack--justify-end{justify-content:flex-end}.sefin-stack--justify-space-between{justify-content:space-between}.sefin-stack--justify-space-around{justify-content:space-around}.sefin-stack--justify-space-evenly{justify-content:space-evenly}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
982
+ }
983
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: StackComponent, decorators: [{
984
+ type: Component,
985
+ args: [{ selector: 'sefin-stack', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<div [class]=\"stackClasses\" [ngStyle]=\"stackStyles\">\n <ng-content></ng-content>\n</div>\n\n", styles: [".sefin-stack{display:flex!important;gap:var(--sefin-spacing-md, 16px)}.sefin-stack--column{flex-direction:column}.sefin-stack--row{flex-direction:row}.sefin-stack--wrap{flex-wrap:wrap}.sefin-stack--spacing-xs{gap:var(--sefin-spacing-xs, 4px)!important}.sefin-stack--spacing-sm{gap:var(--sefin-spacing-sm, 8px)!important}.sefin-stack--spacing-md{gap:var(--sefin-spacing-md, 16px)!important}.sefin-stack--spacing-lg{gap:var(--sefin-spacing-lg, 24px)!important}.sefin-stack--spacing-xl{gap:var(--sefin-spacing-xl, 32px)!important}.sefin-stack--spacing-2xl{gap:var(--sefin-spacing-2xl, 48px)!important}.sefin-stack--align-start{align-items:flex-start}.sefin-stack--align-center{align-items:center}.sefin-stack--align-end{align-items:flex-end}.sefin-stack--align-stretch{align-items:stretch}.sefin-stack--justify-start{justify-content:flex-start}.sefin-stack--justify-center{justify-content:center}.sefin-stack--justify-end{justify-content:flex-end}.sefin-stack--justify-space-between{justify-content:space-between}.sefin-stack--justify-space-around{justify-content:space-around}.sefin-stack--justify-space-evenly{justify-content:space-evenly}\n"] }]
986
+ }], propDecorators: { direction: [{
987
+ type: Input
988
+ }], spacing: [{
989
+ type: Input
990
+ }], align: [{
991
+ type: Input
992
+ }], justify: [{
993
+ type: Input
994
+ }], wrap: [{
995
+ type: Input
996
+ }], class: [{
997
+ type: Input
998
+ }] } });
999
+
1000
+ class CheckboxComponent {
1001
+ checkboxInput;
1002
+ size = 'md';
1003
+ disabled = false;
1004
+ indeterminate = false;
1005
+ class = '';
1006
+ label = '';
1007
+ name = '';
1008
+ value = false;
1009
+ valueChange = new EventEmitter();
1010
+ checkedChange = new EventEmitter();
1011
+ onChange = (value) => { };
1012
+ onTouched = () => { };
1013
+ ngAfterViewInit() {
1014
+ if (this.checkboxInput?.nativeElement && this.indeterminate && !this.value) {
1015
+ this.checkboxInput.nativeElement.indeterminate = true;
1016
+ }
1017
+ }
1018
+ ngOnChanges(changes) {
1019
+ if (this.checkboxInput?.nativeElement && (changes['indeterminate'] || changes['value'])) {
1020
+ this.checkboxInput.nativeElement.indeterminate = this.indeterminate && !this.value;
1021
+ }
1022
+ }
1023
+ onCheckboxChange(event) {
1024
+ if (this.disabled) {
1025
+ return;
1026
+ }
1027
+ const target = event.target;
1028
+ this.value = target.checked;
1029
+ this.indeterminate = false;
1030
+ if (this.checkboxInput?.nativeElement) {
1031
+ this.checkboxInput.nativeElement.indeterminate = false;
1032
+ }
1033
+ this.onChange(this.value);
1034
+ this.onTouched();
1035
+ this.valueChange.emit(this.value);
1036
+ this.checkedChange.emit(this.value);
1037
+ }
1038
+ writeValue(value) {
1039
+ this.value = value;
1040
+ if (value) {
1041
+ this.indeterminate = false;
1042
+ if (this.checkboxInput?.nativeElement) {
1043
+ this.checkboxInput.nativeElement.indeterminate = false;
1044
+ }
1045
+ }
1046
+ }
1047
+ registerOnChange(fn) {
1048
+ this.onChange = fn;
1049
+ }
1050
+ registerOnTouched(fn) {
1051
+ this.onTouched = fn;
1052
+ }
1053
+ setDisabledState(isDisabled) {
1054
+ this.disabled = isDisabled;
1055
+ }
1056
+ get wrapperClasses() {
1057
+ return [
1058
+ 'sefin-checkbox__wrapper',
1059
+ this.disabled ? 'sefin-checkbox__wrapper--disabled' : '',
1060
+ this.class,
1061
+ ]
1062
+ .filter(Boolean)
1063
+ .join(' ');
1064
+ }
1065
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1066
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: CheckboxComponent, isStandalone: true, selector: "sefin-checkbox", inputs: { size: "size", disabled: "disabled", indeterminate: "indeterminate", class: "class", label: "label", name: "name", value: "value" }, outputs: { valueChange: "valueChange", checkedChange: "checkedChange" }, providers: [
1067
+ {
1068
+ provide: NG_VALUE_ACCESSOR,
1069
+ useExisting: forwardRef(() => CheckboxComponent),
1070
+ multi: true,
1071
+ },
1072
+ ], viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<label [class]=\"wrapperClasses\">\n <input\n type=\"checkbox\"\n class=\"sefin-checkbox\"\n [class.sefin-checkbox--sm]=\"size === 'sm'\"\n [class.sefin-checkbox--md]=\"size === 'md'\"\n [class.sefin-checkbox--lg]=\"size === 'lg'\"\n [class.sefin-checkbox--disabled]=\"disabled\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [name]=\"name\"\n (change)=\"onCheckboxChange($event)\"\n #checkboxInput\n />\n <span \n class=\"sefin-checkbox__checkmark\" \n [class.sefin-checkbox__checkmark--sm]=\"size === 'sm'\" \n [class.sefin-checkbox__checkmark--md]=\"size === 'md'\" \n [class.sefin-checkbox__checkmark--lg]=\"size === 'lg'\" \n [class.sefin-checkbox__checkmark--checked]=\"value\" \n [class.sefin-checkbox__checkmark--indeterminate]=\"indeterminate && !value\"\n >\n <svg\n *ngIf=\"value\"\n class=\"sefin-checkbox__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66667 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"indeterminate && !value\"\n class=\"sefin-checkbox__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </span>\n <span *ngIf=\"label\" class=\"sefin-checkbox__label\" [class.sefin-checkbox__label--sm]=\"size === 'sm'\" [class.sefin-checkbox__label--md]=\"size === 'md'\" [class.sefin-checkbox__label--lg]=\"size === 'lg'\">{{ label }}</span>\n</label>\n\n\n", styles: [".sefin-checkbox__wrapper{display:inline-flex;align-items:center;gap:var(--sefin-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.sefin-checkbox__wrapper--disabled{cursor:not-allowed;opacity:.6}.sefin-checkbox{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.sefin-checkbox__checkmark{display:flex;align-items:center;justify-content:center;border:2px solid var(--sefin-color-border);background-color:var(--sefin-color-surface);border-radius:var(--sefin-radius-sm);transition:background-color .2s ease-in-out,border-color .2s ease-in-out,color .2s ease-in-out;flex-shrink:0;color:transparent;box-sizing:border-box}.sefin-checkbox__checkmark--checked,.sefin-checkbox__checkmark--indeterminate{background-color:var(--sefin-color-primary);border-color:var(--sefin-color-primary);color:#fff}.sefin-checkbox__checkmark--sm{width:16px;height:16px;min-width:16px;min-height:16px}.sefin-checkbox__checkmark--md{width:20px;height:20px;min-width:20px;min-height:20px}.sefin-checkbox__checkmark--lg{width:24px;height:24px;min-width:24px;min-height:24px}.sefin-checkbox__wrapper:hover .sefin-checkbox__checkmark{border-color:var(--sefin-color-border-focus)}.sefin-checkbox__wrapper--disabled:hover .sefin-checkbox__checkmark{border-color:var(--sefin-color-border)}.sefin-checkbox__wrapper:focus-within .sefin-checkbox__checkmark{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-checkbox__wrapper:focus-within{outline:none}.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark{background-color:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border);cursor:not-allowed}.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark--checked,.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark--indeterminate{background-color:var(--sefin-color-border);border-color:var(--sefin-color-border);opacity:.6}.sefin-checkbox__icon{width:12px;height:12px;stroke-width:2;flex-shrink:0}.sefin-checkbox__checkmark--sm .sefin-checkbox__icon{width:10px;height:10px}.sefin-checkbox__checkmark--md .sefin-checkbox__icon{width:12px;height:12px}.sefin-checkbox__checkmark--lg .sefin-checkbox__icon{width:14px;height:14px}.sefin-checkbox__label{font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);-webkit-user-select:none;user-select:none}.sefin-checkbox__label--sm{font-size:var(--sefin-font-size-sm)}.sefin-checkbox__label--md{font-size:var(--sefin-font-size-base)}.sefin-checkbox__label--lg{font-size:var(--sefin-font-size-lg)}.sefin-checkbox__wrapper--disabled .sefin-checkbox__label{color:var(--sefin-color-text-disabled)}.sefin-checkbox--disabled{cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
1073
+ }
1074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CheckboxComponent, decorators: [{
1075
+ type: Component,
1076
+ args: [{ selector: 'sefin-checkbox', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, providers: [
1077
+ {
1078
+ provide: NG_VALUE_ACCESSOR,
1079
+ useExisting: forwardRef(() => CheckboxComponent),
1080
+ multi: true,
1081
+ },
1082
+ ], template: "<label [class]=\"wrapperClasses\">\n <input\n type=\"checkbox\"\n class=\"sefin-checkbox\"\n [class.sefin-checkbox--sm]=\"size === 'sm'\"\n [class.sefin-checkbox--md]=\"size === 'md'\"\n [class.sefin-checkbox--lg]=\"size === 'lg'\"\n [class.sefin-checkbox--disabled]=\"disabled\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [name]=\"name\"\n (change)=\"onCheckboxChange($event)\"\n #checkboxInput\n />\n <span \n class=\"sefin-checkbox__checkmark\" \n [class.sefin-checkbox__checkmark--sm]=\"size === 'sm'\" \n [class.sefin-checkbox__checkmark--md]=\"size === 'md'\" \n [class.sefin-checkbox__checkmark--lg]=\"size === 'lg'\" \n [class.sefin-checkbox__checkmark--checked]=\"value\" \n [class.sefin-checkbox__checkmark--indeterminate]=\"indeterminate && !value\"\n >\n <svg\n *ngIf=\"value\"\n class=\"sefin-checkbox__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66667 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"indeterminate && !value\"\n class=\"sefin-checkbox__icon\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </span>\n <span *ngIf=\"label\" class=\"sefin-checkbox__label\" [class.sefin-checkbox__label--sm]=\"size === 'sm'\" [class.sefin-checkbox__label--md]=\"size === 'md'\" [class.sefin-checkbox__label--lg]=\"size === 'lg'\">{{ label }}</span>\n</label>\n\n\n", styles: [".sefin-checkbox__wrapper{display:inline-flex;align-items:center;gap:var(--sefin-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.sefin-checkbox__wrapper--disabled{cursor:not-allowed;opacity:.6}.sefin-checkbox{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.sefin-checkbox__checkmark{display:flex;align-items:center;justify-content:center;border:2px solid var(--sefin-color-border);background-color:var(--sefin-color-surface);border-radius:var(--sefin-radius-sm);transition:background-color .2s ease-in-out,border-color .2s ease-in-out,color .2s ease-in-out;flex-shrink:0;color:transparent;box-sizing:border-box}.sefin-checkbox__checkmark--checked,.sefin-checkbox__checkmark--indeterminate{background-color:var(--sefin-color-primary);border-color:var(--sefin-color-primary);color:#fff}.sefin-checkbox__checkmark--sm{width:16px;height:16px;min-width:16px;min-height:16px}.sefin-checkbox__checkmark--md{width:20px;height:20px;min-width:20px;min-height:20px}.sefin-checkbox__checkmark--lg{width:24px;height:24px;min-width:24px;min-height:24px}.sefin-checkbox__wrapper:hover .sefin-checkbox__checkmark{border-color:var(--sefin-color-border-focus)}.sefin-checkbox__wrapper--disabled:hover .sefin-checkbox__checkmark{border-color:var(--sefin-color-border)}.sefin-checkbox__wrapper:focus-within .sefin-checkbox__checkmark{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-checkbox__wrapper:focus-within{outline:none}.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark{background-color:var(--sefin-color-surface-hover);border-color:var(--sefin-color-border);cursor:not-allowed}.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark--checked,.sefin-checkbox__wrapper--disabled .sefin-checkbox__checkmark--indeterminate{background-color:var(--sefin-color-border);border-color:var(--sefin-color-border);opacity:.6}.sefin-checkbox__icon{width:12px;height:12px;stroke-width:2;flex-shrink:0}.sefin-checkbox__checkmark--sm .sefin-checkbox__icon{width:10px;height:10px}.sefin-checkbox__checkmark--md .sefin-checkbox__icon{width:12px;height:12px}.sefin-checkbox__checkmark--lg .sefin-checkbox__icon{width:14px;height:14px}.sefin-checkbox__label{font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);-webkit-user-select:none;user-select:none}.sefin-checkbox__label--sm{font-size:var(--sefin-font-size-sm)}.sefin-checkbox__label--md{font-size:var(--sefin-font-size-base)}.sefin-checkbox__label--lg{font-size:var(--sefin-font-size-lg)}.sefin-checkbox__wrapper--disabled .sefin-checkbox__label{color:var(--sefin-color-text-disabled)}.sefin-checkbox--disabled{cursor:not-allowed}\n"] }]
1083
+ }], propDecorators: { checkboxInput: [{
1084
+ type: ViewChild,
1085
+ args: ['checkboxInput', { static: false }]
1086
+ }], size: [{
1087
+ type: Input
1088
+ }], disabled: [{
1089
+ type: Input
1090
+ }], indeterminate: [{
1091
+ type: Input
1092
+ }], class: [{
1093
+ type: Input
1094
+ }], label: [{
1095
+ type: Input
1096
+ }], name: [{
1097
+ type: Input
1098
+ }], value: [{
1099
+ type: Input
1100
+ }], valueChange: [{
1101
+ type: Output
1102
+ }], checkedChange: [{
1103
+ type: Output
1104
+ }] } });
1105
+
1106
+ class SelectComponent {
1107
+ containerRef;
1108
+ dropdownRef;
1109
+ buttonRef;
1110
+ options = [];
1111
+ placeholder = 'Seleccionar...';
1112
+ disabled = false;
1113
+ size = 'md';
1114
+ class = '';
1115
+ value = null;
1116
+ valueChange = new EventEmitter();
1117
+ optionSelected = new EventEmitter();
1118
+ isOpen = false;
1119
+ selectedIndex = -1;
1120
+ onChange = (value) => { };
1121
+ onTouched = () => { };
1122
+ ngOnInit() {
1123
+ this.updateSelectedIndex();
1124
+ }
1125
+ ngOnChanges(changes) {
1126
+ if (changes['value'] || changes['options']) {
1127
+ this.updateSelectedIndex();
1128
+ }
1129
+ }
1130
+ ngOnDestroy() { }
1131
+ onClickOutside(event) {
1132
+ if (this.containerRef?.nativeElement && this.isOpen) {
1133
+ const clickedInside = this.containerRef.nativeElement.contains(event.target);
1134
+ if (!clickedInside) {
1135
+ this.closeDropdown();
1136
+ }
1137
+ }
1138
+ }
1139
+ onEscapeKey(event) {
1140
+ const keyboardEvent = event;
1141
+ if (this.isOpen) {
1142
+ keyboardEvent.preventDefault();
1143
+ this.closeDropdown();
1144
+ this.buttonRef?.nativeElement?.focus();
1145
+ }
1146
+ }
1147
+ toggleDropdown() {
1148
+ if (this.disabled)
1149
+ return;
1150
+ if (this.isOpen) {
1151
+ this.closeDropdown();
1152
+ }
1153
+ else {
1154
+ this.openDropdown();
1155
+ }
1156
+ }
1157
+ openDropdown() {
1158
+ if (this.disabled || !this.options || this.options.length === 0)
1159
+ return;
1160
+ this.isOpen = true;
1161
+ this.updateSelectedIndex();
1162
+ // If no selection, focus first enabled option
1163
+ if (this.selectedIndex < 0) {
1164
+ const enabledOptions = this.options.filter((opt) => !opt.disabled);
1165
+ if (enabledOptions.length > 0) {
1166
+ this.selectedIndex = this.options.indexOf(enabledOptions[0]);
1167
+ }
1168
+ }
1169
+ // Scroll to selected option when opening
1170
+ setTimeout(() => {
1171
+ this.scrollToSelected();
1172
+ }, 0);
1173
+ }
1174
+ closeDropdown() {
1175
+ this.isOpen = false;
1176
+ this.selectedIndex = -1;
1177
+ }
1178
+ selectOption(option) {
1179
+ if (option.disabled)
1180
+ return;
1181
+ this.value = option.value;
1182
+ this.onChange(this.value);
1183
+ this.onTouched();
1184
+ this.valueChange.emit(this.value);
1185
+ this.optionSelected.emit(option);
1186
+ this.closeDropdown();
1187
+ this.buttonRef?.nativeElement?.focus();
1188
+ }
1189
+ onKeyDown(event) {
1190
+ if (this.disabled)
1191
+ return;
1192
+ if (!this.isOpen) {
1193
+ if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
1194
+ event.preventDefault();
1195
+ this.openDropdown();
1196
+ }
1197
+ return;
1198
+ }
1199
+ if (!this.options || this.options.length === 0)
1200
+ return;
1201
+ const enabledOptions = this.options.filter((opt) => !opt.disabled);
1202
+ switch (event.key) {
1203
+ case 'ArrowDown':
1204
+ event.preventDefault();
1205
+ if (enabledOptions.length === 0)
1206
+ return;
1207
+ let nextIndex = this.selectedIndex + 1;
1208
+ while (nextIndex < this.options.length && this.options[nextIndex].disabled) {
1209
+ nextIndex++;
1210
+ }
1211
+ if (nextIndex < this.options.length) {
1212
+ this.selectedIndex = nextIndex;
1213
+ }
1214
+ else {
1215
+ // Wrap to first enabled option
1216
+ this.selectedIndex = this.options.indexOf(enabledOptions[0]);
1217
+ }
1218
+ setTimeout(() => this.scrollToSelected(), 0);
1219
+ break;
1220
+ case 'ArrowUp':
1221
+ event.preventDefault();
1222
+ if (enabledOptions.length === 0)
1223
+ return;
1224
+ let prevIndex = this.selectedIndex - 1;
1225
+ while (prevIndex >= 0 && this.options[prevIndex].disabled) {
1226
+ prevIndex--;
1227
+ }
1228
+ if (prevIndex >= 0) {
1229
+ this.selectedIndex = prevIndex;
1230
+ }
1231
+ else {
1232
+ // Wrap to last enabled option
1233
+ const lastOption = enabledOptions[enabledOptions.length - 1];
1234
+ this.selectedIndex = this.options.indexOf(lastOption);
1235
+ }
1236
+ setTimeout(() => this.scrollToSelected(), 0);
1237
+ break;
1238
+ case 'Enter':
1239
+ event.preventDefault();
1240
+ if (this.selectedIndex >= 0 && this.selectedIndex < this.options.length) {
1241
+ const option = this.options[this.selectedIndex];
1242
+ if (!option.disabled) {
1243
+ this.selectOption(option);
1244
+ }
1245
+ }
1246
+ break;
1247
+ case 'Escape':
1248
+ event.preventDefault();
1249
+ this.closeDropdown();
1250
+ this.buttonRef?.nativeElement?.focus();
1251
+ break;
1252
+ case 'Home':
1253
+ event.preventDefault();
1254
+ if (enabledOptions.length > 0) {
1255
+ this.selectedIndex = this.options.indexOf(enabledOptions[0]);
1256
+ setTimeout(() => this.scrollToSelected(), 0);
1257
+ }
1258
+ break;
1259
+ case 'End':
1260
+ event.preventDefault();
1261
+ if (enabledOptions.length > 0) {
1262
+ const lastOption = enabledOptions[enabledOptions.length - 1];
1263
+ this.selectedIndex = this.options.indexOf(lastOption);
1264
+ setTimeout(() => this.scrollToSelected(), 0);
1265
+ }
1266
+ break;
1267
+ }
1268
+ }
1269
+ updateSelectedIndex() {
1270
+ if (this.value === null || !this.options) {
1271
+ this.selectedIndex = -1;
1272
+ return;
1273
+ }
1274
+ const index = this.options.findIndex((opt) => opt.value === this.value);
1275
+ this.selectedIndex = index >= 0 ? index : -1;
1276
+ }
1277
+ scrollToSelected() {
1278
+ try {
1279
+ if (this.dropdownRef?.nativeElement &&
1280
+ this.selectedIndex >= 0 &&
1281
+ this.selectedIndex < this.options.length) {
1282
+ const selectedElement = this.dropdownRef.nativeElement.querySelector(`[data-index="${this.selectedIndex}"]`);
1283
+ if (selectedElement && selectedElement instanceof HTMLElement) {
1284
+ selectedElement.scrollIntoView({
1285
+ block: 'nearest',
1286
+ behavior: 'smooth',
1287
+ });
1288
+ }
1289
+ }
1290
+ }
1291
+ catch (error) {
1292
+ console.warn('Could not scroll to selected option:', error);
1293
+ }
1294
+ }
1295
+ getSelectedLabel() {
1296
+ if (this.value === null || !this.options) {
1297
+ return '';
1298
+ }
1299
+ const selectedOption = this.options.find((opt) => opt.value === this.value);
1300
+ return selectedOption?.label || '';
1301
+ }
1302
+ writeValue(value) {
1303
+ this.value = value;
1304
+ this.updateSelectedIndex();
1305
+ }
1306
+ registerOnChange(fn) {
1307
+ this.onChange = fn;
1308
+ }
1309
+ registerOnTouched(fn) {
1310
+ this.onTouched = fn;
1311
+ }
1312
+ setDisabledState(isDisabled) {
1313
+ this.disabled = isDisabled;
1314
+ if (isDisabled && this.isOpen) {
1315
+ this.closeDropdown();
1316
+ }
1317
+ }
1318
+ get buttonClasses() {
1319
+ return [
1320
+ 'sefin-select__button',
1321
+ `sefin-select__button--${this.size}`,
1322
+ this.disabled ? 'sefin-select__button--disabled' : '',
1323
+ this.isOpen ? 'sefin-select__button--open' : '',
1324
+ this.class,
1325
+ ]
1326
+ .filter(Boolean)
1327
+ .join(' ');
1328
+ }
1329
+ get containerClasses() {
1330
+ return [
1331
+ 'sefin-select',
1332
+ this.isOpen ? 'sefin-select--open' : '',
1333
+ ]
1334
+ .filter(Boolean)
1335
+ .join(' ');
1336
+ }
1337
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1338
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: SelectComponent, isStandalone: true, selector: "sefin-select", inputs: { options: "options", placeholder: "placeholder", disabled: "disabled", size: "size", class: "class", value: "value" }, outputs: { valueChange: "valueChange", optionSelected: "optionSelected" }, host: { listeners: { "document:click": "onClickOutside($event)", "document:keydown.escape": "onEscapeKey($event)" } }, providers: [
1339
+ {
1340
+ provide: NG_VALUE_ACCESSOR,
1341
+ useExisting: forwardRef(() => SelectComponent),
1342
+ multi: true,
1343
+ },
1344
+ ], viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }, { propertyName: "dropdownRef", first: true, predicate: ["dropdownRef"], descendants: true }, { propertyName: "buttonRef", first: true, predicate: ["buttonRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"containerClasses\" #containerRef>\n <button\n #buttonRef\n type=\"button\"\n [class]=\"buttonClasses\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-haspopup]=\"true\"\n aria-label=\"Select option\"\n >\n <span class=\"sefin-select__value\" [class.sefin-select__value--placeholder]=\"!getSelectedLabel()\">\n {{ getSelectedLabel() || placeholder }}\n </span>\n <div class=\"sefin-select__arrow\" [class.sefin-select__arrow--open]=\"isOpen\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </button>\n <div\n *ngIf=\"isOpen && options && options.length > 0\"\n #dropdownRef\n class=\"sefin-select__dropdown\"\n role=\"listbox\"\n >\n <ul class=\"sefin-select__list\">\n <li\n *ngFor=\"let option of options; let i = index\"\n [attr.data-index]=\"i\"\n [class.sefin-select__option]=\"true\"\n [class.sefin-select__option--selected]=\"i === selectedIndex\"\n [class.sefin-select__option--disabled]=\"option.disabled\"\n [class.sefin-select__option--active]=\"option.value === value\"\n (click)=\"selectOption(option)\"\n [attr.aria-selected]=\"option.value === value\"\n role=\"option\"\n >\n {{ option.label }}\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"isOpen && (!options || options.length === 0)\"\n class=\"sefin-select__dropdown sefin-select__dropdown--empty\"\n >\n <div class=\"sefin-select__no-options\">\n No hay opciones disponibles\n </div>\n </div>\n</div>\n\n", styles: [".sefin-select{position:relative;width:100%}.sefin-select__button{width:100%;display:flex;align-items:center;justify-content:space-between;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;outline:none;cursor:pointer;text-align:left;gap:var(--sefin-spacing-sm)}.sefin-select__button:focus-visible{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-select__button:hover:not(.sefin-select__button--disabled){border-color:var(--sefin-color-border-focus)}.sefin-select__button--disabled{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text-disabled);cursor:not-allowed;opacity:.6}.sefin-select__button--open{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-select__button--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-select__button--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-select__button--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sefin-color-text)}.sefin-select__value--placeholder{color:var(--sefin-color-text-secondary)}.sefin-select__arrow{display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--sefin-color-text-secondary);pointer-events:none;transition:transform .2s ease-in-out}.sefin-select__arrow svg{width:16px;height:16px}.sefin-select__arrow--open{transform:rotate(180deg)}.sefin-select__dropdown{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;right:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);max-height:300px;overflow-y:auto;overflow-x:hidden}.sefin-select__dropdown--empty{padding:var(--sefin-spacing-md)}.sefin-select__list{list-style:none;margin:0;padding:var(--sefin-spacing-xs)}.sefin-select__option{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;border-radius:var(--sefin-radius-sm);transition:all .15s ease-in-out;-webkit-user-select:none;user-select:none}.sefin-select__option:hover:not(.sefin-select__option--disabled){background-color:var(--sefin-color-surface-hover)}.sefin-select__option--selected,.sefin-select__option--active{background-color:var(--sefin-color-primary-light, var(--sefin-color-surface-hover));color:var(--sefin-color-text);font-weight:var(--sefin-font-weight-medium)}.sefin-select__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.sefin-select__no-options{padding:var(--sefin-spacing-md);text-align:center;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary)}.sefin-select--open .sefin-select__button{border-color:var(--sefin-color-border-focus)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
1345
+ }
1346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SelectComponent, decorators: [{
1347
+ type: Component,
1348
+ args: [{ selector: 'sefin-select', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, providers: [
1349
+ {
1350
+ provide: NG_VALUE_ACCESSOR,
1351
+ useExisting: forwardRef(() => SelectComponent),
1352
+ multi: true,
1353
+ },
1354
+ ], template: "<div [class]=\"containerClasses\" #containerRef>\n <button\n #buttonRef\n type=\"button\"\n [class]=\"buttonClasses\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-haspopup]=\"true\"\n aria-label=\"Select option\"\n >\n <span class=\"sefin-select__value\" [class.sefin-select__value--placeholder]=\"!getSelectedLabel()\">\n {{ getSelectedLabel() || placeholder }}\n </span>\n <div class=\"sefin-select__arrow\" [class.sefin-select__arrow--open]=\"isOpen\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </button>\n <div\n *ngIf=\"isOpen && options && options.length > 0\"\n #dropdownRef\n class=\"sefin-select__dropdown\"\n role=\"listbox\"\n >\n <ul class=\"sefin-select__list\">\n <li\n *ngFor=\"let option of options; let i = index\"\n [attr.data-index]=\"i\"\n [class.sefin-select__option]=\"true\"\n [class.sefin-select__option--selected]=\"i === selectedIndex\"\n [class.sefin-select__option--disabled]=\"option.disabled\"\n [class.sefin-select__option--active]=\"option.value === value\"\n (click)=\"selectOption(option)\"\n [attr.aria-selected]=\"option.value === value\"\n role=\"option\"\n >\n {{ option.label }}\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"isOpen && (!options || options.length === 0)\"\n class=\"sefin-select__dropdown sefin-select__dropdown--empty\"\n >\n <div class=\"sefin-select__no-options\">\n No hay opciones disponibles\n </div>\n </div>\n</div>\n\n", styles: [".sefin-select{position:relative;width:100%}.sefin-select__button{width:100%;display:flex;align-items:center;justify-content:space-between;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;outline:none;cursor:pointer;text-align:left;gap:var(--sefin-spacing-sm)}.sefin-select__button:focus-visible{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-select__button:hover:not(.sefin-select__button--disabled){border-color:var(--sefin-color-border-focus)}.sefin-select__button--disabled{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text-disabled);cursor:not-allowed;opacity:.6}.sefin-select__button--open{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-select__button--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-select__button--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-select__button--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-select__value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sefin-color-text)}.sefin-select__value--placeholder{color:var(--sefin-color-text-secondary)}.sefin-select__arrow{display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--sefin-color-text-secondary);pointer-events:none;transition:transform .2s ease-in-out}.sefin-select__arrow svg{width:16px;height:16px}.sefin-select__arrow--open{transform:rotate(180deg)}.sefin-select__dropdown{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;right:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);max-height:300px;overflow-y:auto;overflow-x:hidden}.sefin-select__dropdown--empty{padding:var(--sefin-spacing-md)}.sefin-select__list{list-style:none;margin:0;padding:var(--sefin-spacing-xs)}.sefin-select__option{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;border-radius:var(--sefin-radius-sm);transition:all .15s ease-in-out;-webkit-user-select:none;user-select:none}.sefin-select__option:hover:not(.sefin-select__option--disabled){background-color:var(--sefin-color-surface-hover)}.sefin-select__option--selected,.sefin-select__option--active{background-color:var(--sefin-color-primary-light, var(--sefin-color-surface-hover));color:var(--sefin-color-text);font-weight:var(--sefin-font-weight-medium)}.sefin-select__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.sefin-select__no-options{padding:var(--sefin-spacing-md);text-align:center;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary)}.sefin-select--open .sefin-select__button{border-color:var(--sefin-color-border-focus)}\n"] }]
1355
+ }], propDecorators: { containerRef: [{
1356
+ type: ViewChild,
1357
+ args: ['containerRef', { static: false }]
1358
+ }], dropdownRef: [{
1359
+ type: ViewChild,
1360
+ args: ['dropdownRef', { static: false }]
1361
+ }], buttonRef: [{
1362
+ type: ViewChild,
1363
+ args: ['buttonRef', { static: false }]
1364
+ }], options: [{
1365
+ type: Input
1366
+ }], placeholder: [{
1367
+ type: Input
1368
+ }], disabled: [{
1369
+ type: Input
1370
+ }], size: [{
1371
+ type: Input
1372
+ }], class: [{
1373
+ type: Input
1374
+ }], value: [{
1375
+ type: Input
1376
+ }], valueChange: [{
1377
+ type: Output
1378
+ }], optionSelected: [{
1379
+ type: Output
1380
+ }], onClickOutside: [{
1381
+ type: HostListener,
1382
+ args: ['document:click', ['$event']]
1383
+ }], onEscapeKey: [{
1384
+ type: HostListener,
1385
+ args: ['document:keydown.escape', ['$event']]
1386
+ }] } });
1387
+
1388
+ class SwitchComponent {
1389
+ size = 'md';
1390
+ disabled = false;
1391
+ class = '';
1392
+ label = '';
1393
+ name = '';
1394
+ value = false;
1395
+ valueChange = new EventEmitter();
1396
+ checkedChange = new EventEmitter();
1397
+ onChange = (value) => { };
1398
+ onTouched = () => { };
1399
+ onSwitchChange(event) {
1400
+ if (this.disabled) {
1401
+ return;
1402
+ }
1403
+ const target = event.target;
1404
+ this.value = target.checked;
1405
+ this.onChange(this.value);
1406
+ this.onTouched();
1407
+ this.valueChange.emit(this.value);
1408
+ this.checkedChange.emit(this.value);
1409
+ }
1410
+ writeValue(value) {
1411
+ this.value = value;
1412
+ }
1413
+ registerOnChange(fn) {
1414
+ this.onChange = fn;
1415
+ }
1416
+ registerOnTouched(fn) {
1417
+ this.onTouched = fn;
1418
+ }
1419
+ setDisabledState(isDisabled) {
1420
+ this.disabled = isDisabled;
1421
+ }
1422
+ get wrapperClasses() {
1423
+ return [
1424
+ 'sefin-switch__wrapper',
1425
+ this.disabled ? 'sefin-switch__wrapper--disabled' : '',
1426
+ this.class,
1427
+ ]
1428
+ .filter(Boolean)
1429
+ .join(' ');
1430
+ }
1431
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1432
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: SwitchComponent, isStandalone: true, selector: "sefin-switch", inputs: { size: "size", disabled: "disabled", class: "class", label: "label", name: "name", value: "value" }, outputs: { valueChange: "valueChange", checkedChange: "checkedChange" }, providers: [
1433
+ {
1434
+ provide: NG_VALUE_ACCESSOR,
1435
+ useExisting: forwardRef(() => SwitchComponent),
1436
+ multi: true,
1437
+ },
1438
+ ], ngImport: i0, template: "<label [class]=\"wrapperClasses\">\n <input\n type=\"checkbox\"\n class=\"sefin-switch\"\n [class.sefin-switch--sm]=\"size === 'sm'\"\n [class.sefin-switch--md]=\"size === 'md'\"\n [class.sefin-switch--lg]=\"size === 'lg'\"\n [class.sefin-switch--disabled]=\"disabled\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [name]=\"name\"\n (change)=\"onSwitchChange($event)\"\n />\n <span \n class=\"sefin-switch__track\" \n [class.sefin-switch__track--sm]=\"size === 'sm'\" \n [class.sefin-switch__track--md]=\"size === 'md'\" \n [class.sefin-switch__track--lg]=\"size === 'lg'\" \n [class.sefin-switch__track--checked]=\"value\" \n >\n <span \n class=\"sefin-switch__thumb\"\n [class.sefin-switch__thumb--sm]=\"size === 'sm'\"\n [class.sefin-switch__thumb--md]=\"size === 'md'\"\n [class.sefin-switch__thumb--lg]=\"size === 'lg'\"\n ></span>\n </span>\n <span *ngIf=\"label\" class=\"sefin-switch__label\" [class.sefin-switch__label--sm]=\"size === 'sm'\" [class.sefin-switch__label--md]=\"size === 'md'\" [class.sefin-switch__label--lg]=\"size === 'lg'\">{{ label }}</span>\n</label>\n\n", styles: [".sefin-switch__wrapper{display:inline-flex;align-items:center;gap:var(--sefin-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.sefin-switch__wrapper--disabled{cursor:not-allowed;opacity:.6}.sefin-switch{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.sefin-switch__track{position:relative;display:inline-block;background-color:var(--sefin-color-border);border-radius:9999px;transition:background-color .2s ease-in-out;flex-shrink:0;box-sizing:border-box}.sefin-switch__track--checked{background-color:var(--sefin-color-primary)}.sefin-switch__track--sm{width:32px;height:18px}.sefin-switch__track--md{width:40px;height:22px}.sefin-switch__track--lg{width:48px;height:26px}.sefin-switch__thumb{position:absolute;top:50%;left:2px;transform:translateY(-50%);background-color:#fff;border-radius:50%;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out;box-shadow:0 2px 4px #0003;box-sizing:border-box}.sefin-switch__thumb--sm{width:14px;height:14px}.sefin-switch__thumb--md{width:18px;height:18px}.sefin-switch__thumb--lg{width:22px;height:22px}.sefin-switch__track--sm.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(14px)}.sefin-switch__track--md.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(18px)}.sefin-switch__track--lg.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(22px)}.sefin-switch__wrapper:hover .sefin-switch__track:not(.sefin-switch__track--checked){background-color:var(--sefin-color-border-focus)}.sefin-switch__wrapper--disabled:hover .sefin-switch__track{background-color:var(--sefin-color-border)}.sefin-switch__wrapper:focus-within .sefin-switch__track{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-switch__wrapper:focus-within{outline:none}.sefin-switch__wrapper--disabled .sefin-switch__track{background-color:var(--sefin-color-border);cursor:not-allowed}.sefin-switch__wrapper--disabled .sefin-switch__track--checked{background-color:var(--sefin-color-border);opacity:.6}.sefin-switch__wrapper--disabled .sefin-switch__thumb{box-shadow:0 1px 2px #0000001a}.sefin-switch__label{font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);-webkit-user-select:none;user-select:none}.sefin-switch__label--sm{font-size:var(--sefin-font-size-sm)}.sefin-switch__label--md{font-size:var(--sefin-font-size-base)}.sefin-switch__label--lg{font-size:var(--sefin-font-size-lg)}.sefin-switch__wrapper--disabled .sefin-switch__label{color:var(--sefin-color-text-disabled)}.sefin-switch--disabled{cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
1439
+ }
1440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SwitchComponent, decorators: [{
1441
+ type: Component,
1442
+ args: [{ selector: 'sefin-switch', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, providers: [
1443
+ {
1444
+ provide: NG_VALUE_ACCESSOR,
1445
+ useExisting: forwardRef(() => SwitchComponent),
1446
+ multi: true,
1447
+ },
1448
+ ], template: "<label [class]=\"wrapperClasses\">\n <input\n type=\"checkbox\"\n class=\"sefin-switch\"\n [class.sefin-switch--sm]=\"size === 'sm'\"\n [class.sefin-switch--md]=\"size === 'md'\"\n [class.sefin-switch--lg]=\"size === 'lg'\"\n [class.sefin-switch--disabled]=\"disabled\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n [name]=\"name\"\n (change)=\"onSwitchChange($event)\"\n />\n <span \n class=\"sefin-switch__track\" \n [class.sefin-switch__track--sm]=\"size === 'sm'\" \n [class.sefin-switch__track--md]=\"size === 'md'\" \n [class.sefin-switch__track--lg]=\"size === 'lg'\" \n [class.sefin-switch__track--checked]=\"value\" \n >\n <span \n class=\"sefin-switch__thumb\"\n [class.sefin-switch__thumb--sm]=\"size === 'sm'\"\n [class.sefin-switch__thumb--md]=\"size === 'md'\"\n [class.sefin-switch__thumb--lg]=\"size === 'lg'\"\n ></span>\n </span>\n <span *ngIf=\"label\" class=\"sefin-switch__label\" [class.sefin-switch__label--sm]=\"size === 'sm'\" [class.sefin-switch__label--md]=\"size === 'md'\" [class.sefin-switch__label--lg]=\"size === 'lg'\">{{ label }}</span>\n</label>\n\n", styles: [".sefin-switch__wrapper{display:inline-flex;align-items:center;gap:var(--sefin-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.sefin-switch__wrapper--disabled{cursor:not-allowed;opacity:.6}.sefin-switch{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.sefin-switch__track{position:relative;display:inline-block;background-color:var(--sefin-color-border);border-radius:9999px;transition:background-color .2s ease-in-out;flex-shrink:0;box-sizing:border-box}.sefin-switch__track--checked{background-color:var(--sefin-color-primary)}.sefin-switch__track--sm{width:32px;height:18px}.sefin-switch__track--md{width:40px;height:22px}.sefin-switch__track--lg{width:48px;height:26px}.sefin-switch__thumb{position:absolute;top:50%;left:2px;transform:translateY(-50%);background-color:#fff;border-radius:50%;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out;box-shadow:0 2px 4px #0003;box-sizing:border-box}.sefin-switch__thumb--sm{width:14px;height:14px}.sefin-switch__thumb--md{width:18px;height:18px}.sefin-switch__thumb--lg{width:22px;height:22px}.sefin-switch__track--sm.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(14px)}.sefin-switch__track--md.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(18px)}.sefin-switch__track--lg.sefin-switch__track--checked .sefin-switch__thumb{transform:translateY(-50%) translate(22px)}.sefin-switch__wrapper:hover .sefin-switch__track:not(.sefin-switch__track--checked){background-color:var(--sefin-color-border-focus)}.sefin-switch__wrapper--disabled:hover .sefin-switch__track{background-color:var(--sefin-color-border)}.sefin-switch__wrapper:focus-within .sefin-switch__track{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-switch__wrapper:focus-within{outline:none}.sefin-switch__wrapper--disabled .sefin-switch__track{background-color:var(--sefin-color-border);cursor:not-allowed}.sefin-switch__wrapper--disabled .sefin-switch__track--checked{background-color:var(--sefin-color-border);opacity:.6}.sefin-switch__wrapper--disabled .sefin-switch__thumb{box-shadow:0 1px 2px #0000001a}.sefin-switch__label{font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);-webkit-user-select:none;user-select:none}.sefin-switch__label--sm{font-size:var(--sefin-font-size-sm)}.sefin-switch__label--md{font-size:var(--sefin-font-size-base)}.sefin-switch__label--lg{font-size:var(--sefin-font-size-lg)}.sefin-switch__wrapper--disabled .sefin-switch__label{color:var(--sefin-color-text-disabled)}.sefin-switch--disabled{cursor:not-allowed}\n"] }]
1449
+ }], propDecorators: { size: [{
1450
+ type: Input
1451
+ }], disabled: [{
1452
+ type: Input
1453
+ }], class: [{
1454
+ type: Input
1455
+ }], label: [{
1456
+ type: Input
1457
+ }], name: [{
1458
+ type: Input
1459
+ }], value: [{
1460
+ type: Input
1461
+ }], valueChange: [{
1462
+ type: Output
1463
+ }], checkedChange: [{
1464
+ type: Output
1465
+ }] } });
1466
+
1467
+ class TypographyComponent {
1468
+ variant = 'p';
1469
+ size;
1470
+ weight;
1471
+ color = 'text';
1472
+ lineHeight;
1473
+ class = '';
1474
+ text;
1475
+ get typographyClasses() {
1476
+ return [
1477
+ 'sefin-typography',
1478
+ `sefin-typography--${this.variant}`,
1479
+ this.size ? `sefin-typography--${this.size}` : '',
1480
+ this.weight ? `sefin-typography--${this.weight}` : '',
1481
+ `sefin-typography--${this.color}`,
1482
+ this.lineHeight ? `sefin-typography--line-height-${this.lineHeight}` : '',
1483
+ this.class,
1484
+ ]
1485
+ .filter(Boolean)
1486
+ .join(' ');
1487
+ }
1488
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TypographyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1489
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: TypographyComponent, isStandalone: true, selector: "sefin-typography", inputs: { variant: "variant", size: "size", weight: "weight", color: "color", lineHeight: "lineHeight", class: "class", text: "text" }, ngImport: i0, template: "<ng-container [ngSwitch]=\"variant\">\n <h1 *ngSwitchCase=\"'h1'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h1>\n <h2 *ngSwitchCase=\"'h2'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h2>\n <h3 *ngSwitchCase=\"'h3'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h3>\n <h4 *ngSwitchCase=\"'h4'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h4>\n <h5 *ngSwitchCase=\"'h5'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h5>\n <h6 *ngSwitchCase=\"'h6'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h6>\n <p *ngSwitchCase=\"'p'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></p>\n <span *ngSwitchDefault [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></span>\n</ng-container>\n", styles: [".sefin-typography{font-family:var(--sefin-font-family-base);margin:0;padding:0}.sefin-typography--h1{font-size:var(--sefin-font-size-4xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h2{font-size:var(--sefin-font-size-3xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h3{font-size:var(--sefin-font-size-2xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h4{font-size:var(--sefin-font-size-xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h5{font-size:var(--sefin-font-size-lg);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h6{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--p,.sefin-typography--span{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal)}.sefin-typography--xs{font-size:var(--sefin-font-size-xs)}.sefin-typography--sm{font-size:var(--sefin-font-size-sm)}.sefin-typography--base{font-size:var(--sefin-font-size-base)}.sefin-typography--lg{font-size:var(--sefin-font-size-lg)}.sefin-typography--xl{font-size:var(--sefin-font-size-xl)}.sefin-typography--2xl{font-size:var(--sefin-font-size-2xl)}.sefin-typography--3xl{font-size:var(--sefin-font-size-3xl)}.sefin-typography--4xl{font-size:var(--sefin-font-size-4xl)}.sefin-typography--5xl{font-size:var(--sefin-font-size-5xl)}.sefin-typography--light{font-weight:var(--sefin-font-weight-light)}.sefin-typography--normal{font-weight:var(--sefin-font-weight-normal)}.sefin-typography--medium{font-weight:var(--sefin-font-weight-medium)}.sefin-typography--semibold{font-weight:var(--sefin-font-weight-semibold)}.sefin-typography--bold{font-weight:var(--sefin-font-weight-bold)}.sefin-typography--text{color:var(--sefin-color-text)}.sefin-typography--text-secondary{color:var(--sefin-color-text-secondary)}.sefin-typography--text-disabled{color:var(--sefin-color-text-disabled)}.sefin-typography--primary{color:var(--sefin-color-primary)}.sefin-typography--secondary{color:var(--sefin-color-secondary)}.sefin-typography--success{color:var(--sefin-color-success)}.sefin-typography--warning{color:var(--sefin-color-warning)}.sefin-typography--error{color:var(--sefin-color-error)}.sefin-typography--line-height-tight{line-height:var(--sefin-line-height-tight)}.sefin-typography--line-height-normal{line-height:var(--sefin-line-height-normal)}.sefin-typography--line-height-relaxed{line-height:var(--sefin-line-height-relaxed)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.Default });
1490
+ }
1491
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TypographyComponent, decorators: [{
1492
+ type: Component,
1493
+ args: [{ selector: 'sefin-typography', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<ng-container [ngSwitch]=\"variant\">\n <h1 *ngSwitchCase=\"'h1'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h1>\n <h2 *ngSwitchCase=\"'h2'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h2>\n <h3 *ngSwitchCase=\"'h3'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h3>\n <h4 *ngSwitchCase=\"'h4'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h4>\n <h5 *ngSwitchCase=\"'h5'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h5>\n <h6 *ngSwitchCase=\"'h6'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></h6>\n <p *ngSwitchCase=\"'p'\" [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></p>\n <span *ngSwitchDefault [class]=\"typographyClasses\">{{ text }}<ng-content></ng-content></span>\n</ng-container>\n", styles: [".sefin-typography{font-family:var(--sefin-font-family-base);margin:0;padding:0}.sefin-typography--h1{font-size:var(--sefin-font-size-4xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h2{font-size:var(--sefin-font-size-3xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h3{font-size:var(--sefin-font-size-2xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h4{font-size:var(--sefin-font-size-xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h5{font-size:var(--sefin-font-size-lg);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h6{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--p,.sefin-typography--span{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal)}.sefin-typography--xs{font-size:var(--sefin-font-size-xs)}.sefin-typography--sm{font-size:var(--sefin-font-size-sm)}.sefin-typography--base{font-size:var(--sefin-font-size-base)}.sefin-typography--lg{font-size:var(--sefin-font-size-lg)}.sefin-typography--xl{font-size:var(--sefin-font-size-xl)}.sefin-typography--2xl{font-size:var(--sefin-font-size-2xl)}.sefin-typography--3xl{font-size:var(--sefin-font-size-3xl)}.sefin-typography--4xl{font-size:var(--sefin-font-size-4xl)}.sefin-typography--5xl{font-size:var(--sefin-font-size-5xl)}.sefin-typography--light{font-weight:var(--sefin-font-weight-light)}.sefin-typography--normal{font-weight:var(--sefin-font-weight-normal)}.sefin-typography--medium{font-weight:var(--sefin-font-weight-medium)}.sefin-typography--semibold{font-weight:var(--sefin-font-weight-semibold)}.sefin-typography--bold{font-weight:var(--sefin-font-weight-bold)}.sefin-typography--text{color:var(--sefin-color-text)}.sefin-typography--text-secondary{color:var(--sefin-color-text-secondary)}.sefin-typography--text-disabled{color:var(--sefin-color-text-disabled)}.sefin-typography--primary{color:var(--sefin-color-primary)}.sefin-typography--secondary{color:var(--sefin-color-secondary)}.sefin-typography--success{color:var(--sefin-color-success)}.sefin-typography--warning{color:var(--sefin-color-warning)}.sefin-typography--error{color:var(--sefin-color-error)}.sefin-typography--line-height-tight{line-height:var(--sefin-line-height-tight)}.sefin-typography--line-height-normal{line-height:var(--sefin-line-height-normal)}.sefin-typography--line-height-relaxed{line-height:var(--sefin-line-height-relaxed)}\n"] }]
1494
+ }], propDecorators: { variant: [{
1495
+ type: Input
1496
+ }], size: [{
1497
+ type: Input
1498
+ }], weight: [{
1499
+ type: Input
1500
+ }], color: [{
1501
+ type: Input
1502
+ }], lineHeight: [{
1503
+ type: Input
1504
+ }], class: [{
1505
+ type: Input
1506
+ }], text: [{
1507
+ type: Input
1508
+ }] } });
1509
+
527
1510
  /**
528
1511
  * Atoms index
529
1512
  */
530
1513
 
1514
+ class AutocompleteComponent {
1515
+ inputRef;
1516
+ dropdownRef;
1517
+ containerRef;
1518
+ options = [];
1519
+ placeholder = '';
1520
+ disabled = false;
1521
+ size = 'md';
1522
+ class = '';
1523
+ value = null;
1524
+ minChars = 0;
1525
+ maxResults = 10;
1526
+ valueChange = new EventEmitter();
1527
+ optionSelected = new EventEmitter();
1528
+ inputChange = new EventEmitter();
1529
+ searchText = '';
1530
+ filteredOptions = [];
1531
+ isOpen = false;
1532
+ selectedIndex = -1;
1533
+ ngOnInit() {
1534
+ if (this.value !== null) {
1535
+ const selectedOption = this.options.find((opt) => opt.value === this.value);
1536
+ this.searchText = selectedOption?.label || String(this.value);
1537
+ }
1538
+ }
1539
+ ngOnChanges(changes) {
1540
+ if (changes['options']) {
1541
+ const options = changes['options'].currentValue || [];
1542
+ if (this.value !== null) {
1543
+ const selectedOption = options.find((opt) => opt.value === this.value);
1544
+ if (selectedOption) {
1545
+ this.searchText = selectedOption.label;
1546
+ }
1547
+ else {
1548
+ this.searchText = '';
1549
+ }
1550
+ }
1551
+ }
1552
+ if (changes['value']) {
1553
+ if (this.value !== null) {
1554
+ const selectedOption = this.options.find((opt) => opt.value === this.value);
1555
+ this.searchText = selectedOption?.label || String(this.value);
1556
+ }
1557
+ else {
1558
+ this.searchText = '';
1559
+ }
1560
+ this.filteredOptions = [];
1561
+ this.isOpen = false;
1562
+ }
1563
+ }
1564
+ ngOnDestroy() {
1565
+ }
1566
+ onClickOutside(event) {
1567
+ if (this.containerRef?.nativeElement && this.isOpen) {
1568
+ const clickedInside = this.containerRef.nativeElement.contains(event.target);
1569
+ if (!clickedInside) {
1570
+ this.isOpen = false;
1571
+ this.selectedIndex = -1;
1572
+ }
1573
+ }
1574
+ }
1575
+ onInputChange(value) {
1576
+ this.searchText = value;
1577
+ this.inputChange.emit(value);
1578
+ if (this.options && this.options.length > 0) {
1579
+ this.filterOptions();
1580
+ this.isOpen = value.length >= this.minChars;
1581
+ }
1582
+ else {
1583
+ this.isOpen = false;
1584
+ this.filteredOptions = [];
1585
+ }
1586
+ }
1587
+ filterOptions() {
1588
+ if (!this.options || this.options.length === 0) {
1589
+ this.filteredOptions = [];
1590
+ return;
1591
+ }
1592
+ if (this.minChars > 0 &&
1593
+ (!this.searchText || this.searchText.length < this.minChars)) {
1594
+ this.filteredOptions = [];
1595
+ return;
1596
+ }
1597
+ const searchText = this.searchText || '';
1598
+ if (searchText.length === 0) {
1599
+ this.filteredOptions = this.options
1600
+ .filter((option) => !option.disabled)
1601
+ .slice(0, this.maxResults);
1602
+ return;
1603
+ }
1604
+ const searchLower = searchText.toLowerCase();
1605
+ this.filteredOptions = this.options
1606
+ .filter((option) => {
1607
+ if (option.disabled)
1608
+ return false;
1609
+ return option.label.toLowerCase().includes(searchLower);
1610
+ })
1611
+ .slice(0, this.maxResults);
1612
+ }
1613
+ selectOption(option) {
1614
+ if (option.disabled)
1615
+ return;
1616
+ this.searchText = option.label;
1617
+ this.value = option.value;
1618
+ this.valueChange.emit(option.value);
1619
+ this.optionSelected.emit(option);
1620
+ this.isOpen = false;
1621
+ this.selectedIndex = -1;
1622
+ }
1623
+ onInputFocus() {
1624
+ if (this.disabled)
1625
+ return;
1626
+ if (this.options &&
1627
+ Array.isArray(this.options) &&
1628
+ this.options.length > 0) {
1629
+ this.filterOptions();
1630
+ this.isOpen = this.filteredOptions.length > 0;
1631
+ }
1632
+ else {
1633
+ this.isOpen = false;
1634
+ this.filteredOptions = [];
1635
+ }
1636
+ }
1637
+ onInputBlur() {
1638
+ if (this.disabled || !this.searchText) {
1639
+ return;
1640
+ }
1641
+ const exactMatch = this.options.find((option) => !option.disabled &&
1642
+ option.label.toLowerCase().trim() === this.searchText.toLowerCase().trim());
1643
+ if (!exactMatch) {
1644
+ this.searchText = '';
1645
+ this.value = null;
1646
+ this.valueChange.emit(null);
1647
+ this.isOpen = false;
1648
+ this.filteredOptions = [];
1649
+ this.selectedIndex = -1;
1650
+ }
1651
+ }
1652
+ onKeyDown(event) {
1653
+ if (!this.isOpen ||
1654
+ !this.filteredOptions ||
1655
+ this.filteredOptions.length === 0) {
1656
+ return;
1657
+ }
1658
+ switch (event.key) {
1659
+ case 'ArrowDown':
1660
+ event.preventDefault();
1661
+ this.selectedIndex = Math.min(this.selectedIndex + 1, this.filteredOptions.length - 1);
1662
+ setTimeout(() => this.scrollToSelected(), 0);
1663
+ break;
1664
+ case 'ArrowUp':
1665
+ event.preventDefault();
1666
+ this.selectedIndex = Math.max(this.selectedIndex - 1, -1);
1667
+ setTimeout(() => this.scrollToSelected(), 0);
1668
+ break;
1669
+ case 'Enter':
1670
+ event.preventDefault();
1671
+ if (this.selectedIndex >= 0 &&
1672
+ this.selectedIndex < this.filteredOptions.length) {
1673
+ this.selectOption(this.filteredOptions[this.selectedIndex]);
1674
+ }
1675
+ break;
1676
+ case 'Escape':
1677
+ event.preventDefault();
1678
+ this.isOpen = false;
1679
+ this.selectedIndex = -1;
1680
+ break;
1681
+ }
1682
+ }
1683
+ scrollToSelected() {
1684
+ try {
1685
+ if (this.dropdownRef?.nativeElement && this.selectedIndex >= 0) {
1686
+ const selectedElement = this.dropdownRef.nativeElement.querySelector(`[data-index="${this.selectedIndex}"]`);
1687
+ if (selectedElement && selectedElement instanceof HTMLElement) {
1688
+ selectedElement.scrollIntoView({
1689
+ block: 'nearest',
1690
+ behavior: 'smooth',
1691
+ });
1692
+ }
1693
+ }
1694
+ }
1695
+ catch (error) {
1696
+ console.warn('Could not scroll to selected option:', error);
1697
+ }
1698
+ }
1699
+ clearValue() {
1700
+ this.searchText = '';
1701
+ this.value = null;
1702
+ this.valueChange.emit(null);
1703
+ this.isOpen = false;
1704
+ this.filteredOptions = [];
1705
+ if (this.inputRef?.nativeElement) {
1706
+ this.inputRef.nativeElement.focus();
1707
+ }
1708
+ }
1709
+ get inputClasses() {
1710
+ return [
1711
+ 'sefin-autocomplete__input',
1712
+ `sefin-autocomplete__input--${this.size}`,
1713
+ this.disabled ? 'sefin-autocomplete__input--disabled' : '',
1714
+ this.class,
1715
+ ]
1716
+ .filter(Boolean)
1717
+ .join(' ');
1718
+ }
1719
+ get containerClasses() {
1720
+ return [
1721
+ 'sefin-autocomplete',
1722
+ this.isOpen && this.filteredOptions.length > 0
1723
+ ? 'sefin-autocomplete--open'
1724
+ : '',
1725
+ ]
1726
+ .filter(Boolean)
1727
+ .join(' ');
1728
+ }
1729
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1730
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: AutocompleteComponent, isStandalone: true, selector: "sefin-autocomplete", inputs: { options: "options", placeholder: "placeholder", disabled: "disabled", size: "size", class: "class", value: "value", minChars: "minChars", maxResults: "maxResults" }, outputs: { valueChange: "valueChange", optionSelected: "optionSelected", inputChange: "inputChange" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true }, { propertyName: "dropdownRef", first: true, predicate: ["dropdownRef"], descendants: true }, { propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-autocomplete__wrapper\">\n <input\n #inputRef\n type=\"text\"\n [class]=\"inputClasses\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [ngModel]=\"searchText\"\n (ngModelChange)=\"onInputChange($event)\"\n (focus)=\"onInputFocus()\"\n (click)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onKeyDown($event)\"\n autocomplete=\"off\"\n />\n <div class=\"sefin-autocomplete__actions\">\n <button\n *ngIf=\"searchText && !disabled\"\n type=\"button\"\n class=\"sefin-autocomplete__clear\"\n (click)=\"clearValue()\"\n aria-label=\"Clear\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"sefin-autocomplete__arrow\" [class.sefin-autocomplete__arrow--open]=\"isOpen\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"isOpen && filteredOptions && filteredOptions.length > 0\"\n #dropdownRef\n class=\"sefin-autocomplete__dropdown\"\n >\n <ul class=\"sefin-autocomplete__list\">\n <li\n *ngFor=\"let option of filteredOptions; let i = index\"\n [attr.data-index]=\"i\"\n [class.sefin-autocomplete__option]=\"true\"\n [class.sefin-autocomplete__option--selected]=\"i === selectedIndex\"\n [class.sefin-autocomplete__option--disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [attr.aria-selected]=\"i === selectedIndex\"\n role=\"option\"\n >\n {{ option.label }}\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"\n isOpen &&\n filteredOptions &&\n filteredOptions.length === 0 &&\n searchText &&\n searchText.length >= minChars\n \"\n class=\"sefin-autocomplete__dropdown sefin-autocomplete__dropdown--empty\"\n >\n <div class=\"sefin-autocomplete__no-results\">\n No se encontraron resultados\n </div>\n </div>\n</div>\n", styles: [".sefin-autocomplete{position:relative;width:100%}.sefin-autocomplete__wrapper{position:relative;display:flex;align-items:center;width:100%}.sefin-autocomplete__input{width:100%;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;outline:none}.sefin-autocomplete__input::placeholder{color:var(--sefin-color-text-secondary);font-family:var(--sefin-font-family-base)}.sefin-autocomplete__input:focus{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-autocomplete__input:disabled{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text-disabled);cursor:not-allowed;opacity:.6}.sefin-autocomplete__input--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);padding-right:calc(var(--sefin-spacing-md) * 2.5);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-autocomplete__input--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);padding-right:calc(var(--sefin-spacing-lg) * 2);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-autocomplete__input--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);padding-right:calc(var(--sefin-spacing-xl) * 1.75);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-autocomplete__input--disabled{cursor:not-allowed}.sefin-autocomplete__actions{position:absolute;right:var(--sefin-spacing-sm);display:flex;align-items:center;gap:var(--sefin-spacing-xs)}.sefin-autocomplete__clear{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text-secondary);cursor:pointer;transition:all .2s ease-in-out}.sefin-autocomplete__clear:hover{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-autocomplete__clear:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-autocomplete__clear svg{width:16px;height:16px}.sefin-autocomplete__arrow{display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:var(--sefin-color-text-secondary);pointer-events:none;transition:transform .2s ease-in-out}.sefin-autocomplete__arrow svg{width:16px;height:16px}.sefin-autocomplete__arrow--open{transform:rotate(180deg)}.sefin-autocomplete__dropdown{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;right:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);max-height:300px;overflow-y:auto}.sefin-autocomplete__dropdown--empty{padding:var(--sefin-spacing-md)}.sefin-autocomplete__list{list-style:none;margin:0;padding:var(--sefin-spacing-xs)}.sefin-autocomplete__option{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;border-radius:var(--sefin-radius-sm);transition:all .15s ease-in-out;-webkit-user-select:none;user-select:none}.sefin-autocomplete__option:hover:not(.sefin-autocomplete__option--disabled){background-color:var(--sefin-color-surface-hover)}.sefin-autocomplete__option--selected{background-color:var(--sefin-color-primary-light);color:var(--sefin-color-primary);font-weight:var(--sefin-font-weight-medium)}.sefin-autocomplete__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.sefin-autocomplete__no-results{padding:var(--sefin-spacing-md);text-align:center;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary)}.sefin-autocomplete--open .sefin-autocomplete__input{border-color:var(--sefin-color-border-focus)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
1731
+ }
1732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AutocompleteComponent, decorators: [{
1733
+ type: Component,
1734
+ args: [{ selector: 'sefin-autocomplete', standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.Default, template: "<div [class]=\"containerClasses\" #containerRef>\n <div class=\"sefin-autocomplete__wrapper\">\n <input\n #inputRef\n type=\"text\"\n [class]=\"inputClasses\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [ngModel]=\"searchText\"\n (ngModelChange)=\"onInputChange($event)\"\n (focus)=\"onInputFocus()\"\n (click)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown)=\"onKeyDown($event)\"\n autocomplete=\"off\"\n />\n <div class=\"sefin-autocomplete__actions\">\n <button\n *ngIf=\"searchText && !disabled\"\n type=\"button\"\n class=\"sefin-autocomplete__clear\"\n (click)=\"clearValue()\"\n aria-label=\"Clear\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <div class=\"sefin-autocomplete__arrow\" [class.sefin-autocomplete__arrow--open]=\"isOpen\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </div>\n </div>\n <div\n *ngIf=\"isOpen && filteredOptions && filteredOptions.length > 0\"\n #dropdownRef\n class=\"sefin-autocomplete__dropdown\"\n >\n <ul class=\"sefin-autocomplete__list\">\n <li\n *ngFor=\"let option of filteredOptions; let i = index\"\n [attr.data-index]=\"i\"\n [class.sefin-autocomplete__option]=\"true\"\n [class.sefin-autocomplete__option--selected]=\"i === selectedIndex\"\n [class.sefin-autocomplete__option--disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [attr.aria-selected]=\"i === selectedIndex\"\n role=\"option\"\n >\n {{ option.label }}\n </li>\n </ul>\n </div>\n <div\n *ngIf=\"\n isOpen &&\n filteredOptions &&\n filteredOptions.length === 0 &&\n searchText &&\n searchText.length >= minChars\n \"\n class=\"sefin-autocomplete__dropdown sefin-autocomplete__dropdown--empty\"\n >\n <div class=\"sefin-autocomplete__no-results\">\n No se encontraron resultados\n </div>\n </div>\n</div>\n", styles: [".sefin-autocomplete{position:relative;width:100%}.sefin-autocomplete__wrapper{position:relative;display:flex;align-items:center;width:100%}.sefin-autocomplete__input{width:100%;font-family:var(--sefin-font-family-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);transition:all .2s ease-in-out;outline:none}.sefin-autocomplete__input::placeholder{color:var(--sefin-color-text-secondary);font-family:var(--sefin-font-family-base)}.sefin-autocomplete__input:focus{border-color:var(--sefin-color-border-focus);box-shadow:0 0 0 3px var(--sefin-color-primary-light)}.sefin-autocomplete__input:disabled{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text-disabled);cursor:not-allowed;opacity:.6}.sefin-autocomplete__input--sm{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);padding-right:calc(var(--sefin-spacing-md) * 2.5);font-size:var(--sefin-font-size-sm);line-height:var(--sefin-line-height-normal);min-height:32px}.sefin-autocomplete__input--md{padding:var(--sefin-spacing-md) var(--sefin-spacing-lg);padding-right:calc(var(--sefin-spacing-lg) * 2);font-size:var(--sefin-font-size-base);line-height:var(--sefin-line-height-normal);min-height:40px}.sefin-autocomplete__input--lg{padding:var(--sefin-spacing-lg) var(--sefin-spacing-xl);padding-right:calc(var(--sefin-spacing-xl) * 1.75);font-size:var(--sefin-font-size-lg);line-height:var(--sefin-line-height-normal);min-height:48px}.sefin-autocomplete__input--disabled{cursor:not-allowed}.sefin-autocomplete__actions{position:absolute;right:var(--sefin-spacing-sm);display:flex;align-items:center;gap:var(--sefin-spacing-xs)}.sefin-autocomplete__clear{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;border-radius:var(--sefin-radius-sm);color:var(--sefin-color-text-secondary);cursor:pointer;transition:all .2s ease-in-out}.sefin-autocomplete__clear:hover{background-color:var(--sefin-color-surface-hover);color:var(--sefin-color-text)}.sefin-autocomplete__clear:focus-visible{outline:2px solid var(--sefin-color-border-focus);outline-offset:2px}.sefin-autocomplete__clear svg{width:16px;height:16px}.sefin-autocomplete__arrow{display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:var(--sefin-color-text-secondary);pointer-events:none;transition:transform .2s ease-in-out}.sefin-autocomplete__arrow svg{width:16px;height:16px}.sefin-autocomplete__arrow--open{transform:rotate(180deg)}.sefin-autocomplete__dropdown{position:absolute;top:calc(100% + var(--sefin-spacing-xs));left:0;right:0;z-index:9999;background-color:var(--sefin-color-surface);border:1px solid var(--sefin-color-border);border-radius:var(--sefin-radius-md);box-shadow:var(--sefin-shadow-lg);max-height:300px;overflow-y:auto}.sefin-autocomplete__dropdown--empty{padding:var(--sefin-spacing-md)}.sefin-autocomplete__list{list-style:none;margin:0;padding:var(--sefin-spacing-xs)}.sefin-autocomplete__option{padding:var(--sefin-spacing-sm) var(--sefin-spacing-md);font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text);cursor:pointer;border-radius:var(--sefin-radius-sm);transition:all .15s ease-in-out;-webkit-user-select:none;user-select:none}.sefin-autocomplete__option:hover:not(.sefin-autocomplete__option--disabled){background-color:var(--sefin-color-surface-hover)}.sefin-autocomplete__option--selected{background-color:var(--sefin-color-primary-light);color:var(--sefin-color-primary);font-weight:var(--sefin-font-weight-medium)}.sefin-autocomplete__option--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.sefin-autocomplete__no-results{padding:var(--sefin-spacing-md);text-align:center;font-family:var(--sefin-font-family-base);font-size:var(--sefin-font-size-sm);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal);color:var(--sefin-color-text-secondary)}.sefin-autocomplete--open .sefin-autocomplete__input{border-color:var(--sefin-color-border-focus)}\n"] }]
1735
+ }], propDecorators: { inputRef: [{
1736
+ type: ViewChild,
1737
+ args: ['inputRef', { static: false }]
1738
+ }], dropdownRef: [{
1739
+ type: ViewChild,
1740
+ args: ['dropdownRef', { static: false }]
1741
+ }], containerRef: [{
1742
+ type: ViewChild,
1743
+ args: ['containerRef', { static: false }]
1744
+ }], options: [{
1745
+ type: Input
1746
+ }], placeholder: [{
1747
+ type: Input
1748
+ }], disabled: [{
1749
+ type: Input
1750
+ }], size: [{
1751
+ type: Input
1752
+ }], class: [{
1753
+ type: Input
1754
+ }], value: [{
1755
+ type: Input
1756
+ }], minChars: [{
1757
+ type: Input
1758
+ }], maxResults: [{
1759
+ type: Input
1760
+ }], valueChange: [{
1761
+ type: Output
1762
+ }], optionSelected: [{
1763
+ type: Output
1764
+ }], inputChange: [{
1765
+ type: Output
1766
+ }], onClickOutside: [{
1767
+ type: HostListener,
1768
+ args: ['document:click', ['$event']]
1769
+ }] } });
1770
+
1771
+ /**
1772
+ * Molecules index
1773
+ */
1774
+
531
1775
  /*
532
1776
  * Public API Surface of @lesterarte/sefin-ui
533
1777
  */
@@ -539,5 +1783,5 @@ const STYLES_PATH = './styles/index.scss';
539
1783
  * Generated bundle index. Do not edit.
540
1784
  */
541
1785
 
542
- export { BORDER_RADIUS_TOKENS, BRAND_THEME, ButtonComponent, COLOR_TOKENS, DARK_THEME, DESIGN_TOKENS, LIGHT_THEME, SHADOW_TOKENS, SPACING_TOKENS, STYLES_PATH, TYPOGRAPHY_TOKENS, ThemeLoader };
1786
+ export { AutocompleteComponent, AvatarComponent, BORDER_RADIUS_TOKENS, BRAND_THEME, BadgeComponent, ButtonComponent, COLOR_TOKENS, CheckboxComponent, ChipComponent, DARK_THEME, DESIGN_TOKENS, FabButtonComponent, IconButtonComponent, LIGHT_THEME, LinkComponent, SHADOW_TOKENS, SPACING_TOKENS, STYLES_PATH, SelectComponent, StackComponent, SwitchComponent, TYPOGRAPHY_TOKENS, ThemeLoader, TypographyComponent };
543
1787
  //# sourceMappingURL=lesterarte-sefin-ui.mjs.map