ng-magary 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule, NgOptimizedImage, DatePipe, DOCUMENT, NgStyle, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { input, output, computed, ChangeDetectionStrategy, Component, NgModule, inject, ElementRef, signal, HostListener, model, linkedSignal, effect, forwardRef, ViewEncapsulation, contentChild, TemplateRef, EventEmitter, Output, Input, ContentChild, ViewChild, booleanAttribute, numberAttribute, Renderer2, ChangeDetectorRef, viewChild, contentChildren, PLATFORM_ID, Inject, viewChildren, DestroyRef, untracked, afterNextRender, Directive, Injectable } from '@angular/core';
4
+ import { input, output, computed, ChangeDetectionStrategy, Component, NgModule, inject, ElementRef, signal, HostListener, model, linkedSignal, effect, forwardRef, ViewEncapsulation, contentChild, TemplateRef, EventEmitter, Output, Input, ContentChild, ViewChild, booleanAttribute, viewChild, numberAttribute, Renderer2, ChangeDetectorRef, contentChildren, PLATFORM_ID, Inject, viewChildren, DestroyRef, untracked, afterNextRender, Directive, Injectable } from '@angular/core';
5
5
  import * as i2 from 'lucide-angular';
6
6
  import { LucideAngularModule, MonitorPlay, X, ChevronRight, ChevronLeft, RotateCcw, ZoomOut, ZoomIn, Share2, Download, Minimize, Maximize, Pause, Play, ChevronDown, ChevronUp } from 'lucide-angular';
7
7
  import * as i1$1 from '@angular/forms';
@@ -11,6 +11,8 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
11
11
  import { trigger, transition, style, animate, query, group, state } from '@angular/animations';
12
12
  import { DomSanitizer } from '@angular/platform-browser';
13
13
  import { HttpClient, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
14
+ import * as i1$2 from '@angular/cdk/overlay';
15
+ import { OverlayModule } from '@angular/cdk/overlay';
14
16
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
15
17
  import { merge, fromEvent, Subject } from 'rxjs';
16
18
  import { map, debounceTime, filter, throttleTime } from 'rxjs/operators';
@@ -2450,8 +2452,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
2450
2452
  }] });
2451
2453
 
2452
2454
  class MagarySelect {
2453
- elementRef;
2454
- // Signal Inputs based on Rules
2455
+ // Signal Inputs
2455
2456
  options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
2456
2457
  optionLabel = input(...(ngDevMode ? [undefined, { debugName: "optionLabel" }] : []));
2457
2458
  optionValue = input(...(ngDevMode ? [undefined, { debugName: "optionValue" }] : []));
@@ -2463,14 +2464,13 @@ class MagarySelect {
2463
2464
  // Internal State
2464
2465
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
2465
2466
  focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
2466
- value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : [])); // Actual value of the selection
2467
+ value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
2467
2468
  filterValue = signal('', ...(ngDevMode ? [{ debugName: "filterValue" }] : []));
2469
+ // Element Reference for Overlay Width
2470
+ trigger = viewChild.required('trigger');
2468
2471
  // CVA Callbacks
2469
2472
  onChange = () => { };
2470
2473
  onTouched = () => { };
2471
- constructor(elementRef) {
2472
- this.elementRef = elementRef;
2473
- }
2474
2474
  // Computed Helpers
2475
2475
  visibleOptions = computed(() => {
2476
2476
  const opts = this.options();
@@ -2484,7 +2484,6 @@ class MagarySelect {
2484
2484
  if (!val)
2485
2485
  return '';
2486
2486
  const opts = this.options();
2487
- // Find option that matches value
2488
2487
  const selectedOption = opts.find((opt) => this.getValue(opt) === val);
2489
2488
  return selectedOption ? this.getLabel(selectedOption) : '';
2490
2489
  }, ...(ngDevMode ? [{ debugName: "selectedLabel" }] : []));
@@ -2500,19 +2499,23 @@ class MagarySelect {
2500
2499
  }
2501
2500
  else {
2502
2501
  this.onTouched();
2502
+ this.focused.set(false);
2503
2503
  }
2504
2504
  }
2505
+ close() {
2506
+ this.isOpen.set(false);
2507
+ this.focused.set(false);
2508
+ this.onTouched();
2509
+ }
2505
2510
  selectOption(option) {
2506
2511
  const val = this.getValue(option);
2507
2512
  this.value.set(val);
2508
2513
  this.onChange(val);
2509
- this.isOpen.set(false);
2510
- this.focused.set(true); // Keep focus style
2514
+ this.close();
2511
2515
  }
2512
2516
  isSelected(option) {
2513
2517
  return this.getValue(option) === this.value();
2514
2518
  }
2515
- // Utilities to handle Object vs Primitive options
2516
2519
  getLabel(option) {
2517
2520
  const labelProp = this.optionLabel();
2518
2521
  return labelProp ? option[labelProp] : option;
@@ -2531,14 +2534,6 @@ class MagarySelect {
2531
2534
  this.onChange(null);
2532
2535
  this.onTouched();
2533
2536
  }
2534
- // Click Outside Listener
2535
- onDocumentClick(event) {
2536
- if (!this.elementRef.nativeElement.contains(event.target)) {
2537
- this.isOpen.set(false);
2538
- this.focused.set(false);
2539
- this.onTouched();
2540
- }
2541
- }
2542
2537
  // CVA Implementation
2543
2538
  writeValue(obj) {
2544
2539
  this.value.set(obj);
@@ -2550,36 +2545,27 @@ class MagarySelect {
2550
2545
  this.onTouched = fn;
2551
2546
  }
2552
2547
  setDisabledState(isDisabled) {
2553
- // We can't write to a signal input, but the CVA contract implies managing disabled state.
2554
- // In signal-input paradigm, the parent should bind [disabled].
2555
- // However, CVA setDisabledState is usually called by reactive forms.
2556
- // We might need a separate signal if we want to support both.
2557
- // effectively merging input disabled + form disabled.
2558
- // For now, we rely on the input, assuming correct usage.
2559
- // Ideally we would merge: effectiveDisabled = computed(() => this.disabled() || this.formDisabled())
2560
- }
2561
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MagarySelect, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2562
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MagarySelect, isStandalone: true, selector: "magary-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
2548
+ // Handled by signal input usually, but we could update a local signal if needed
2549
+ }
2550
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MagarySelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
2551
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: MagarySelect, isStandalone: true, selector: "magary-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
2563
2552
  {
2564
2553
  provide: NG_VALUE_ACCESSOR,
2565
2554
  useExisting: forwardRef(() => MagarySelect),
2566
2555
  multi: true,
2567
2556
  },
2568
- ], ngImport: i0, template: "<div\r\n class=\"magary-select-container\"\r\n [class.disabled]=\"disabled()\"\r\n [class.focused]=\"focused()\"\r\n [class.filled]=\"hasValue()\"\r\n (click)=\"toggleOverlay()\"\r\n>\r\n <div class=\"selected-value\">\r\n @if (hasValue()) {\r\n <span>{{ selectedLabel() }}</span>\r\n } @else {\r\n <span class=\"placeholder\">{{ placeholder() }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"icons-container\">\r\n @if (showClear() && hasValue() && !disabled()) {\r\n <lucide-icon\r\n name=\"x\"\r\n [size]=\"16\"\r\n class=\"clear-icon\"\r\n (click)=\"clear($event)\"\r\n >\r\n </lucide-icon>\r\n }\r\n @if (loading()) {\r\n <lucide-icon name=\"loader\" class=\"spin\" [size]=\"18\"></lucide-icon>\r\n } @else {\r\n <lucide-icon name=\"chevron-down\" [size]=\"18\"></lucide-icon>\r\n }\r\n </div>\r\n\r\n <!-- Overlay (Dropdown) -->\r\n @if (isOpen()) {\r\n <div\r\n class=\"select-overlay fade-in\"\r\n (click)=\"$event.stopPropagation()\"\r\n tabindex=\"-1\"\r\n >\r\n @if (filter()) {\r\n <div class=\"filter-container\">\r\n <input\r\n type=\"text\"\r\n class=\"filter-input\"\r\n [value]=\"filterValue()\"\r\n (input)=\"onFilterInput($event)\"\r\n placeholder=\"Search...\"\r\n autofocus\r\n />\r\n <lucide-icon\r\n name=\"search\"\r\n [size]=\"14\"\r\n class=\"filter-icon\"\r\n ></lucide-icon>\r\n </div>\r\n }\r\n\r\n <ul class=\"select-list\" role=\"listbox\">\r\n @for (option of visibleOptions(); track option) {\r\n <li\r\n class=\"select-item\"\r\n [class.selected]=\"isSelected(option)\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n (click)=\"selectOption(option); $event.stopPropagation()\"\r\n >\r\n {{ getLabel(option) }}\r\n @if (isSelected(option)) {\r\n <lucide-icon\r\n name=\"check\"\r\n [size]=\"16\"\r\n class=\"check-icon\"\r\n ></lucide-icon>\r\n }\r\n </li>\r\n }\r\n @if (visibleOptions().length === 0) {\r\n <li class=\"empty-message\">No results found</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.magary-select-container{position:relative;display:flex;align-items:center;justify-content:space-between;background-color:var(--surface-0);border:1px solid var(--surface-300);border-radius:var(--border-radius, .5rem);padding:.5rem .75rem;cursor:pointer;transition:all .2s ease;min-height:42px;-webkit-user-select:none;user-select:none}.magary-select-container:hover:not(.disabled){border-color:var(--primary-400)}.magary-select-container.focused{border-color:var(--primary-500);box-shadow:0 0 0 2px var(--primary-100)}.magary-select-container.disabled{background-color:var(--surface-100);color:var(--text-secondary);cursor:not-allowed;opacity:.7}.selected-value{flex:1;color:var(--text-primary);font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.selected-value .placeholder{color:var(--text-secondary)}.icons-container{display:flex;align-items:center;color:var(--text-secondary);margin-left:.5rem}.select-overlay{position:absolute;top:calc(100% + 4px);left:0;width:100%;background:var(--surface-0);border:1px solid var(--surface-200);border-radius:var(--border-radius, .5rem);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:1000;max-height:200px;overflow-y:auto;padding:.25rem}.select-list{list-style:none;padding:0;margin:0}.select-item{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;font-size:.875rem;color:var(--text-primary);border-radius:.25rem;cursor:pointer;transition:background-color .15s ease}.select-item:hover{background-color:var(--surface-100)}.select-item.selected{background-color:var(--primary-50);color:var(--primary-700);font-weight:500}.select-item .check-icon{color:var(--primary-500)}.clear-icon{cursor:pointer;margin-right:.5rem;transition:color .2s}.clear-icon:hover{color:var(--text-primary)}.filter-container{padding:.5rem;position:sticky;top:0;background:var(--surface-0);z-index:10;border-bottom:1px solid var(--surface-200);display:flex;align-items:center;gap:.5rem}.filter-container .filter-input{width:100%;padding:.375rem 2rem .375rem .5rem;border:1px solid var(--surface-300);border-radius:var(--border-radius);outline:none;font-size:.875rem;background:var(--surface-50);color:var(--text-primary)}.filter-container .filter-input:focus{border-color:var(--primary-500)}.filter-container .filter-icon{position:absolute;right:1rem;color:var(--text-secondary);pointer-events:none}.empty-message{padding:.75rem;color:var(--text-secondary);font-size:.875rem;text-align:center}.spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.fade-in{animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i2.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
2557
+ ], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\r\n #trigger\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n class=\"magary-select-container\"\r\n [class.disabled]=\"disabled()\"\r\n [class.focused]=\"focused()\"\r\n [class.filled]=\"hasValue()\"\r\n (click)=\"toggleOverlay()\"\r\n>\r\n <div class=\"selected-value\">\r\n @if (hasValue()) {\r\n <span>{{ selectedLabel() }}</span>\r\n } @else {\r\n <span class=\"placeholder\">{{ placeholder() }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"icons-container\">\r\n @if (showClear() && hasValue() && !disabled()) {\r\n <lucide-icon\r\n name=\"x\"\r\n [size]=\"16\"\r\n class=\"clear-icon\"\r\n (click)=\"clear($event)\"\r\n >\r\n </lucide-icon>\r\n }\r\n @if (loading()) {\r\n <lucide-icon name=\"loader\" class=\"spin\" [size]=\"18\"></lucide-icon>\r\n } @else {\r\n <lucide-icon name=\"chevron-down\" [size]=\"18\"></lucide-icon>\r\n }\r\n </div>\r\n\r\n <!-- CDK Overlay Template -->\r\n <ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"isOpen()\"\r\n [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\r\n [cdkConnectedOverlayMinWidth]=\"trigger.offsetWidth\"\r\n [cdkConnectedOverlayOffsetY]=\"4\"\r\n (backdropClick)=\"close()\"\r\n >\r\n <div\r\n class=\"select-overlay fade-in\"\r\n (click)=\"$event.stopPropagation()\"\r\n tabindex=\"-1\"\r\n >\r\n @if (filter()) {\r\n <div class=\"filter-container\">\r\n <input\r\n type=\"text\"\r\n class=\"filter-input\"\r\n [value]=\"filterValue()\"\r\n (input)=\"onFilterInput($event)\"\r\n placeholder=\"Search...\"\r\n autofocus\r\n />\r\n <lucide-icon\r\n name=\"search\"\r\n [size]=\"14\"\r\n class=\"filter-icon\"\r\n ></lucide-icon>\r\n </div>\r\n }\r\n\r\n <ul class=\"select-list\" role=\"listbox\">\r\n @for (option of visibleOptions(); track option) {\r\n <li\r\n class=\"select-item\"\r\n [class.selected]=\"isSelected(option)\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n (click)=\"selectOption(option)\"\r\n >\r\n {{ getLabel(option) }}\r\n @if (isSelected(option)) {\r\n <lucide-icon\r\n name=\"check\"\r\n [size]=\"16\"\r\n class=\"check-icon\"\r\n ></lucide-icon>\r\n }\r\n </li>\r\n }\r\n @if (visibleOptions().length === 0) {\r\n <li class=\"empty-message\">No results found</li>\r\n }\r\n </ul>\r\n </div>\r\n </ng-template>\r\n</div>\r\n", styles: [":host{display:block;width:100%}.magary-select-container{position:relative;display:flex;align-items:center;justify-content:space-between;background-color:var(--surface-0);border:1px solid var(--surface-300);border-radius:var(--border-radius, .5rem);padding:.5rem .75rem;cursor:pointer;transition:all .2s ease;min-height:42px;-webkit-user-select:none;user-select:none}.magary-select-container:hover:not(.disabled){border-color:var(--primary-400)}.magary-select-container.focused{border-color:var(--primary-500);box-shadow:0 0 0 2px var(--primary-100)}.magary-select-container.disabled{background-color:var(--surface-100);color:var(--text-secondary);cursor:not-allowed;opacity:.7}.selected-value{flex:1;color:var(--text-primary);font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.selected-value .placeholder{color:var(--text-secondary)}.icons-container{display:flex;align-items:center;color:var(--text-secondary);margin-left:.5rem}.select-overlay{width:100%;background:var(--surface-0);border:1px solid var(--surface-200);border-radius:var(--border-radius, .5rem);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;max-height:200px;overflow-y:auto;padding:.25rem;margin-top:4px}.select-list{list-style:none;padding:0;margin:0}.select-item{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;font-size:.875rem;color:var(--text-primary);border-radius:.25rem;cursor:pointer;transition:background-color .15s ease}.select-item:hover{background-color:var(--surface-100)}.select-item.selected{background-color:var(--primary-50);color:var(--primary-700);font-weight:500}.select-item .check-icon{color:var(--primary-500)}.clear-icon{cursor:pointer;margin-right:.5rem;transition:color .2s}.clear-icon:hover{color:var(--text-primary)}.filter-container{padding:.5rem;position:sticky;top:0;background:var(--surface-0);z-index:10;border-bottom:1px solid var(--surface-200);display:flex;align-items:center;gap:.5rem}.filter-container .filter-input{width:100%;padding:.375rem 2rem .375rem .5rem;border:1px solid var(--surface-300);border-radius:var(--border-radius);outline:none;font-size:.875rem;background:var(--surface-50);color:var(--text-primary)}.filter-container .filter-input:focus{border-color:var(--primary-500)}.filter-container .filter-icon{position:absolute;right:1rem;color:var(--text-secondary);pointer-events:none}.empty-message{padding:.75rem;color:var(--text-secondary);font-size:.875rem;text-align:center}.spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.fade-in{animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i2.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
2569
2558
  }
2570
2559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MagarySelect, decorators: [{
2571
2560
  type: Component,
2572
- args: [{ selector: 'magary-select', standalone: true, imports: [CommonModule, LucideAngularModule], providers: [
2561
+ args: [{ selector: 'magary-select', standalone: true, imports: [CommonModule, OverlayModule, LucideAngularModule], providers: [
2573
2562
  {
2574
2563
  provide: NG_VALUE_ACCESSOR,
2575
2564
  useExisting: forwardRef(() => MagarySelect),
2576
2565
  multi: true,
2577
2566
  },
2578
- ], template: "<div\r\n class=\"magary-select-container\"\r\n [class.disabled]=\"disabled()\"\r\n [class.focused]=\"focused()\"\r\n [class.filled]=\"hasValue()\"\r\n (click)=\"toggleOverlay()\"\r\n>\r\n <div class=\"selected-value\">\r\n @if (hasValue()) {\r\n <span>{{ selectedLabel() }}</span>\r\n } @else {\r\n <span class=\"placeholder\">{{ placeholder() }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"icons-container\">\r\n @if (showClear() && hasValue() && !disabled()) {\r\n <lucide-icon\r\n name=\"x\"\r\n [size]=\"16\"\r\n class=\"clear-icon\"\r\n (click)=\"clear($event)\"\r\n >\r\n </lucide-icon>\r\n }\r\n @if (loading()) {\r\n <lucide-icon name=\"loader\" class=\"spin\" [size]=\"18\"></lucide-icon>\r\n } @else {\r\n <lucide-icon name=\"chevron-down\" [size]=\"18\"></lucide-icon>\r\n }\r\n </div>\r\n\r\n <!-- Overlay (Dropdown) -->\r\n @if (isOpen()) {\r\n <div\r\n class=\"select-overlay fade-in\"\r\n (click)=\"$event.stopPropagation()\"\r\n tabindex=\"-1\"\r\n >\r\n @if (filter()) {\r\n <div class=\"filter-container\">\r\n <input\r\n type=\"text\"\r\n class=\"filter-input\"\r\n [value]=\"filterValue()\"\r\n (input)=\"onFilterInput($event)\"\r\n placeholder=\"Search...\"\r\n autofocus\r\n />\r\n <lucide-icon\r\n name=\"search\"\r\n [size]=\"14\"\r\n class=\"filter-icon\"\r\n ></lucide-icon>\r\n </div>\r\n }\r\n\r\n <ul class=\"select-list\" role=\"listbox\">\r\n @for (option of visibleOptions(); track option) {\r\n <li\r\n class=\"select-item\"\r\n [class.selected]=\"isSelected(option)\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n (click)=\"selectOption(option); $event.stopPropagation()\"\r\n >\r\n {{ getLabel(option) }}\r\n @if (isSelected(option)) {\r\n <lucide-icon\r\n name=\"check\"\r\n [size]=\"16\"\r\n class=\"check-icon\"\r\n ></lucide-icon>\r\n }\r\n </li>\r\n }\r\n @if (visibleOptions().length === 0) {\r\n <li class=\"empty-message\">No results found</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n</div>\r\n", styles: [":host{display:block;width:100%}.magary-select-container{position:relative;display:flex;align-items:center;justify-content:space-between;background-color:var(--surface-0);border:1px solid var(--surface-300);border-radius:var(--border-radius, .5rem);padding:.5rem .75rem;cursor:pointer;transition:all .2s ease;min-height:42px;-webkit-user-select:none;user-select:none}.magary-select-container:hover:not(.disabled){border-color:var(--primary-400)}.magary-select-container.focused{border-color:var(--primary-500);box-shadow:0 0 0 2px var(--primary-100)}.magary-select-container.disabled{background-color:var(--surface-100);color:var(--text-secondary);cursor:not-allowed;opacity:.7}.selected-value{flex:1;color:var(--text-primary);font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.selected-value .placeholder{color:var(--text-secondary)}.icons-container{display:flex;align-items:center;color:var(--text-secondary);margin-left:.5rem}.select-overlay{position:absolute;top:calc(100% + 4px);left:0;width:100%;background:var(--surface-0);border:1px solid var(--surface-200);border-radius:var(--border-radius, .5rem);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;z-index:1000;max-height:200px;overflow-y:auto;padding:.25rem}.select-list{list-style:none;padding:0;margin:0}.select-item{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;font-size:.875rem;color:var(--text-primary);border-radius:.25rem;cursor:pointer;transition:background-color .15s ease}.select-item:hover{background-color:var(--surface-100)}.select-item.selected{background-color:var(--primary-50);color:var(--primary-700);font-weight:500}.select-item .check-icon{color:var(--primary-500)}.clear-icon{cursor:pointer;margin-right:.5rem;transition:color .2s}.clear-icon:hover{color:var(--text-primary)}.filter-container{padding:.5rem;position:sticky;top:0;background:var(--surface-0);z-index:10;border-bottom:1px solid var(--surface-200);display:flex;align-items:center;gap:.5rem}.filter-container .filter-input{width:100%;padding:.375rem 2rem .375rem .5rem;border:1px solid var(--surface-300);border-radius:var(--border-radius);outline:none;font-size:.875rem;background:var(--surface-50);color:var(--text-primary)}.filter-container .filter-input:focus{border-color:var(--primary-500)}.filter-container .filter-icon{position:absolute;right:1rem;color:var(--text-secondary);pointer-events:none}.empty-message{padding:.75rem;color:var(--text-secondary);font-size:.875rem;text-align:center}.spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.fade-in{animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"] }]
2579
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], onDocumentClick: [{
2580
- type: HostListener,
2581
- args: ['document:click', ['$event']]
2582
- }] } });
2567
+ ], template: "<div\r\n #trigger\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n class=\"magary-select-container\"\r\n [class.disabled]=\"disabled()\"\r\n [class.focused]=\"focused()\"\r\n [class.filled]=\"hasValue()\"\r\n (click)=\"toggleOverlay()\"\r\n>\r\n <div class=\"selected-value\">\r\n @if (hasValue()) {\r\n <span>{{ selectedLabel() }}</span>\r\n } @else {\r\n <span class=\"placeholder\">{{ placeholder() }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"icons-container\">\r\n @if (showClear() && hasValue() && !disabled()) {\r\n <lucide-icon\r\n name=\"x\"\r\n [size]=\"16\"\r\n class=\"clear-icon\"\r\n (click)=\"clear($event)\"\r\n >\r\n </lucide-icon>\r\n }\r\n @if (loading()) {\r\n <lucide-icon name=\"loader\" class=\"spin\" [size]=\"18\"></lucide-icon>\r\n } @else {\r\n <lucide-icon name=\"chevron-down\" [size]=\"18\"></lucide-icon>\r\n }\r\n </div>\r\n\r\n <!-- CDK Overlay Template -->\r\n <ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"isOpen()\"\r\n [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\r\n [cdkConnectedOverlayMinWidth]=\"trigger.offsetWidth\"\r\n [cdkConnectedOverlayOffsetY]=\"4\"\r\n (backdropClick)=\"close()\"\r\n >\r\n <div\r\n class=\"select-overlay fade-in\"\r\n (click)=\"$event.stopPropagation()\"\r\n tabindex=\"-1\"\r\n >\r\n @if (filter()) {\r\n <div class=\"filter-container\">\r\n <input\r\n type=\"text\"\r\n class=\"filter-input\"\r\n [value]=\"filterValue()\"\r\n (input)=\"onFilterInput($event)\"\r\n placeholder=\"Search...\"\r\n autofocus\r\n />\r\n <lucide-icon\r\n name=\"search\"\r\n [size]=\"14\"\r\n class=\"filter-icon\"\r\n ></lucide-icon>\r\n </div>\r\n }\r\n\r\n <ul class=\"select-list\" role=\"listbox\">\r\n @for (option of visibleOptions(); track option) {\r\n <li\r\n class=\"select-item\"\r\n [class.selected]=\"isSelected(option)\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n (click)=\"selectOption(option)\"\r\n >\r\n {{ getLabel(option) }}\r\n @if (isSelected(option)) {\r\n <lucide-icon\r\n name=\"check\"\r\n [size]=\"16\"\r\n class=\"check-icon\"\r\n ></lucide-icon>\r\n }\r\n </li>\r\n }\r\n @if (visibleOptions().length === 0) {\r\n <li class=\"empty-message\">No results found</li>\r\n }\r\n </ul>\r\n </div>\r\n </ng-template>\r\n</div>\r\n", styles: [":host{display:block;width:100%}.magary-select-container{position:relative;display:flex;align-items:center;justify-content:space-between;background-color:var(--surface-0);border:1px solid var(--surface-300);border-radius:var(--border-radius, .5rem);padding:.5rem .75rem;cursor:pointer;transition:all .2s ease;min-height:42px;-webkit-user-select:none;user-select:none}.magary-select-container:hover:not(.disabled){border-color:var(--primary-400)}.magary-select-container.focused{border-color:var(--primary-500);box-shadow:0 0 0 2px var(--primary-100)}.magary-select-container.disabled{background-color:var(--surface-100);color:var(--text-secondary);cursor:not-allowed;opacity:.7}.selected-value{flex:1;color:var(--text-primary);font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.selected-value .placeholder{color:var(--text-secondary)}.icons-container{display:flex;align-items:center;color:var(--text-secondary);margin-left:.5rem}.select-overlay{width:100%;background:var(--surface-0);border:1px solid var(--surface-200);border-radius:var(--border-radius, .5rem);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;max-height:200px;overflow-y:auto;padding:.25rem;margin-top:4px}.select-list{list-style:none;padding:0;margin:0}.select-item{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;font-size:.875rem;color:var(--text-primary);border-radius:.25rem;cursor:pointer;transition:background-color .15s ease}.select-item:hover{background-color:var(--surface-100)}.select-item.selected{background-color:var(--primary-50);color:var(--primary-700);font-weight:500}.select-item .check-icon{color:var(--primary-500)}.clear-icon{cursor:pointer;margin-right:.5rem;transition:color .2s}.clear-icon:hover{color:var(--text-primary)}.filter-container{padding:.5rem;position:sticky;top:0;background:var(--surface-0);z-index:10;border-bottom:1px solid var(--surface-200);display:flex;align-items:center;gap:.5rem}.filter-container .filter-input{width:100%;padding:.375rem 2rem .375rem .5rem;border:1px solid var(--surface-300);border-radius:var(--border-radius);outline:none;font-size:.875rem;background:var(--surface-50);color:var(--text-primary)}.filter-container .filter-input:focus{border-color:var(--primary-500)}.filter-container .filter-icon{position:absolute;right:1rem;color:var(--text-secondary);pointer-events:none}.empty-message{padding:.75rem;color:var(--text-secondary);font-size:.875rem;text-align:center}.spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.fade-in{animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"] }]
2568
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], showClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClear", required: false }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
2583
2569
 
2584
2570
  class MagarySelectModule {
2585
2571
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: MagarySelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -8694,7 +8680,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
8694
8680
 
8695
8681
  // 🔘 Button //
8696
8682
 
8697
- const MAGARY_VERSION = '0.0.7';
8683
+ const MAGARY_VERSION = '0.0.8';
8698
8684
 
8699
8685
  /*
8700
8686
  * Public API Surface of ng-magary