@balinasoftware/balinaui-components 3.3.7 → 3.3.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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, EventEmitter, HostListener, Output, Input, ViewChild } from '@angular/core';
2
+ import { Component, EventEmitter, HostListener, Output, Input } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i2 from '@angular/router';
@@ -103,115 +103,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
103
103
  }] } });
104
104
 
105
105
  class Button {
106
- // CONTENT
107
- text = 'Button';
108
- // BUTTON TYPE
106
+ // =========================================
107
+ // INPUTS
108
+ // =========================================
109
+ label = 'Button';
109
110
  type = 'button';
110
- // VARIANT
111
- variant = 'solid';
112
- // STANDARD COLOR
113
- color = 'primary';
114
- // CUSTOM COLORS
115
- customColor;
116
- hoverColor;
117
- activeColor;
118
- textColor;
119
- borderColor;
120
- hoverTextColor;
121
- activeTextColor;
122
- disabledColor;
123
- disabledTextColor;
124
- disabledBorderColor;
125
- // SIZE
126
- size = 'md';
127
- // DISABLED
128
111
  disabled = false;
129
- // CLICK EVENT
130
- buttonClick = new EventEmitter();
131
- // CLICK HANDLER
132
- handleClick(event) {
133
- if (this.disabled) {
112
+ loading = false;
113
+ customClass = '';
114
+ // =========================================
115
+ // OUTPUTS
116
+ // =========================================
117
+ clicked = new EventEmitter();
118
+ // =========================================
119
+ // CLICK
120
+ // =========================================
121
+ onClick(event) {
122
+ if (this.disabled ||
123
+ this.loading) {
134
124
  event.preventDefault();
135
125
  return;
136
126
  }
137
- this.buttonClick.emit(event);
138
- }
139
- // CSS VARIABLES
140
- get buttonStyles() {
141
- const styles = {};
142
- if (this.customColor) {
143
- styles['--button-custom-color'] = this.customColor;
144
- }
145
- if (this.hoverColor) {
146
- styles['--button-hover-color'] = this.hoverColor;
147
- }
148
- if (this.activeColor) {
149
- styles['--button-active-color'] = this.activeColor;
150
- }
151
- if (this.textColor) {
152
- styles['--button-text-color'] = this.textColor;
153
- }
154
- if (this.borderColor) {
155
- styles['--button-border-color'] = this.borderColor;
156
- }
157
- if (this.hoverTextColor) {
158
- styles['--button-hover-text-color'] = this.hoverTextColor;
159
- }
160
- if (this.activeTextColor) {
161
- styles['--button-active-text-color'] = this.activeTextColor;
162
- }
163
- if (this.disabledColor) {
164
- styles['--button-disabled-color'] = this.disabledColor;
165
- }
166
- if (this.disabledTextColor) {
167
- styles['--button-disabled-text-color'] =
168
- this.disabledTextColor;
169
- }
170
- if (this.disabledBorderColor) {
171
- styles['--button-disabled-border-color'] =
172
- this.disabledBorderColor;
173
- }
174
- return styles;
127
+ // Developer event
128
+ this.clicked.emit(event);
175
129
  }
176
130
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
177
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: Button, isStandalone: true, selector: "lib-button", inputs: { text: "text", type: "type", variant: "variant", color: "color", customColor: "customColor", hoverColor: "hoverColor", activeColor: "activeColor", textColor: "textColor", borderColor: "borderColor", hoverTextColor: "hoverTextColor", activeTextColor: "activeTextColor", disabledColor: "disabledColor", disabledTextColor: "disabledTextColor", disabledBorderColor: "disabledBorderColor", size: "size", disabled: "disabled" }, outputs: { buttonClick: "buttonClick" }, ngImport: i0, template: "<button\n [type]=\"type\"\n [disabled]=\"disabled\"\n\n [ngClass]=\"[\n 'lib-button',\n 'lib-button-' + variant,\n 'lib-button-' + color,\n 'lib-button-' + size\n ]\"\n\n [ngStyle]=\"buttonStyles\"\n\n (click)=\"handleClick($event)\"\n>\n {{ text }}\n</button>", styles: [".lib-button{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af;--button-custom-color: var(--button-default-color);--button-hover-color: var(--button-default-hover-color);--button-active-color: var(--button-default-active-color);--button-text-color: #ffffff;--button-border-color: var(--button-custom-color);--button-hover-text-color: var(--button-text-color);--button-active-text-color: var(--button-text-color);--button-disabled-color: #e5e7eb;--button-disabled-text-color: #9ca3af;--button-disabled-border-color: #d1d5db;display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid var(--button-border-color);font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:600;line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s ease,border-color .2s ease,color .2s ease,box-shadow .2s ease,transform .1s ease;outline:none}.lib-button-xs{min-height:28px;padding:5px 10px;font-size:12px;border-radius:6px}.lib-button-sm{min-height:34px;padding:7px 14px;font-size:13px;border-radius:7px}.lib-button-md{min-height:40px;padding:9px 18px;font-size:14px;border-radius:8px}.lib-button-lg{min-height:46px;padding:11px 22px;font-size:16px;border-radius:9px}.lib-button-xl{min-height:54px;padding:13px 28px;font-size:18px;border-radius:10px}.lib-button-solid{background:var(--button-custom-color);border-color:var(--button-border-color);color:var(--button-text-color)}.lib-button-solid:hover:not(:disabled){background:var(--button-hover-color);border-color:var(--button-hover-color);color:var(--button-hover-text-color)}.lib-button-solid:active:not(:disabled){background:var(--button-active-color);border-color:var(--button-active-color);color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-outline{background:transparent;border-color:var(--button-border-color);color:var(--button-custom-color)}.lib-button-outline:hover:not(:disabled){background:var(--button-hover-color);border-color:var(--button-hover-color);color:var(--button-hover-text-color)}.lib-button-outline:active:not(:disabled){background:var(--button-active-color);border-color:var(--button-active-color);color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-ghost{background:transparent;border-color:transparent;color:var(--button-custom-color)}.lib-button-ghost:hover:not(:disabled){background:var(--button-hover-color);border-color:transparent;color:var(--button-hover-text-color)}.lib-button-ghost:active:not(:disabled){background:var(--button-active-color);border-color:transparent;color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-primary{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af}.lib-button-secondary{--button-default-color: #64748b;--button-default-hover-color: #475569;--button-default-active-color: #334155}.lib-button-success{--button-default-color: #16a34a;--button-default-hover-color: #15803d;--button-default-active-color: #166534}.lib-button-danger{--button-default-color: #dc2626;--button-default-hover-color: #b91c1c;--button-default-active-color: #991b1b}.lib-button-warning{--button-default-color: #f59e0b;--button-default-hover-color: #d97706;--button-default-active-color: #b45309}.lib-button-info{--button-default-color: #0891b2;--button-default-hover-color: #0e7490;--button-default-active-color: #155e75}.lib-button-neutral{--button-default-color: #374151;--button-default-hover-color: #1f2937;--button-default-active-color: #111827}.lib-button-light{--button-default-color: #f8fafc;--button-default-hover-color: #e2e8f0;--button-default-active-color: #cbd5e1;--button-text-color: #1e293b}.lib-button-dark{--button-default-color: #1e293b;--button-default-hover-color: #0f172a;--button-default-active-color: #020617;--button-text-color: #ffffff}.lib-button-link{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af;background:transparent;border-color:transparent;color:var(--button-custom-color);padding-left:4px;padding-right:4px}.lib-button-link:hover:not(:disabled){background:transparent;border-color:transparent;color:var(--button-hover-color);text-decoration:underline}.lib-button-link:active:not(:disabled){background:transparent;border-color:transparent;color:var(--button-active-color);transform:none}.lib-button:focus-visible{outline:3px solid rgba(37,99,235,.25);outline-offset:2px}.lib-button:disabled{background:var(--button-disabled-color)!important;border-color:var(--button-disabled-border-color)!important;color:var(--button-disabled-text-color)!important;cursor:not-allowed;opacity:.8;transform:none!important;box-shadow:none!important}.lib-button-link:disabled{background:transparent!important;border-color:transparent!important;color:var(--button-disabled-text-color)!important;text-decoration:none}@media(max-width:480px){.lib-button-xl{min-height:50px;padding:11px 22px;font-size:16px}.lib-button-lg{min-height:44px;padding:10px 18px;font-size:15px}.lib-button-md{min-height:38px;padding:8px 16px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
131
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Button, isStandalone: true, selector: "lib-button", inputs: { label: "label", type: "type", disabled: "disabled", loading: "loading", customClass: "customClass" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n class=\"balina-button\"\n [class]=\"customClass\"\n [type]=\"type\"\n [disabled]=\"disabled || loading\"\n [attr.aria-busy]=\"loading\"\n (click)=\"onClick($event)\"\n>\n\n @if (loading) {\n\n <span\n class=\"button-spinner\"\n aria-hidden=\"true\"\n ></span>\n\n <span>\n Loading...\n </span>\n\n } @else {\n\n <span class=\"button-label\">\n {{ label }}\n </span>\n\n }\n\n</button>", styles: [".balina-button{--button-width: auto;--button-height: 44px;--button-padding: 0 22px;--button-background: #68479b;--button-background-hover: #593b84;--button-background-active: #4b326f;--button-text-color: #ffffff;--button-border: 1px solid #68479b;--button-radius: 6px;--button-font-family: Arial, Helvetica, sans-serif;--button-font-size: 14px;--button-font-weight: 600;--button-gap: 8px;--button-shadow: 0 2px 5px rgba(0, 0, 0, .08);--button-disabled-background: #dddddd;--button-disabled-text: #999999;--button-disabled-border: #dddddd;width:var(--button-width);min-height:var(--button-height);padding:var(--button-padding);display:inline-flex;align-items:center;justify-content:center;gap:var(--button-gap);box-sizing:border-box;border:var(--button-border);border-radius:var(--button-radius);background:var(--button-background);color:var(--button-text-color);font-family:var(--button-font-family);font-size:var(--button-font-size);font-weight:var(--button-font-weight);box-shadow:var(--button-shadow);outline:none;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease,transform .1s ease}.balina-button:hover:not(:disabled){background:var(--button-background-hover)}.balina-button:active:not(:disabled){background:var(--button-background-active);transform:translateY(1px)}.balina-button:focus-visible{box-shadow:0 0 0 3px #68479b33}.balina-button:disabled{background:var(--button-disabled-background);color:var(--button-disabled-text);border-color:var(--button-disabled-border);cursor:not-allowed;box-shadow:none;transform:none}.balina-button[aria-busy=true]{cursor:wait}.button-spinner{width:16px;height:16px;box-sizing:border-box;border:2px solid rgba(255,255,255,.4);border-top-color:var(--button-text-color);border-radius:50%;animation:button-spin .7s linear infinite}@keyframes button-spin{to{transform:rotate(360deg)}}.button-label{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap}@media(max-width:768px){.balina-button{min-height:var(--button-height);font-size:var(--button-font-size)}}\n"] });
178
132
  }
179
133
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Button, decorators: [{
180
134
  type: Component,
181
- args: [{ selector: 'lib-button', standalone: true, imports: [CommonModule], template: "<button\n [type]=\"type\"\n [disabled]=\"disabled\"\n\n [ngClass]=\"[\n 'lib-button',\n 'lib-button-' + variant,\n 'lib-button-' + color,\n 'lib-button-' + size\n ]\"\n\n [ngStyle]=\"buttonStyles\"\n\n (click)=\"handleClick($event)\"\n>\n {{ text }}\n</button>", styles: [".lib-button{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af;--button-custom-color: var(--button-default-color);--button-hover-color: var(--button-default-hover-color);--button-active-color: var(--button-default-active-color);--button-text-color: #ffffff;--button-border-color: var(--button-custom-color);--button-hover-text-color: var(--button-text-color);--button-active-text-color: var(--button-text-color);--button-disabled-color: #e5e7eb;--button-disabled-text-color: #9ca3af;--button-disabled-border-color: #d1d5db;display:inline-flex;align-items:center;justify-content:center;gap:8px;border:1px solid var(--button-border-color);font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:600;line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s ease,border-color .2s ease,color .2s ease,box-shadow .2s ease,transform .1s ease;outline:none}.lib-button-xs{min-height:28px;padding:5px 10px;font-size:12px;border-radius:6px}.lib-button-sm{min-height:34px;padding:7px 14px;font-size:13px;border-radius:7px}.lib-button-md{min-height:40px;padding:9px 18px;font-size:14px;border-radius:8px}.lib-button-lg{min-height:46px;padding:11px 22px;font-size:16px;border-radius:9px}.lib-button-xl{min-height:54px;padding:13px 28px;font-size:18px;border-radius:10px}.lib-button-solid{background:var(--button-custom-color);border-color:var(--button-border-color);color:var(--button-text-color)}.lib-button-solid:hover:not(:disabled){background:var(--button-hover-color);border-color:var(--button-hover-color);color:var(--button-hover-text-color)}.lib-button-solid:active:not(:disabled){background:var(--button-active-color);border-color:var(--button-active-color);color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-outline{background:transparent;border-color:var(--button-border-color);color:var(--button-custom-color)}.lib-button-outline:hover:not(:disabled){background:var(--button-hover-color);border-color:var(--button-hover-color);color:var(--button-hover-text-color)}.lib-button-outline:active:not(:disabled){background:var(--button-active-color);border-color:var(--button-active-color);color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-ghost{background:transparent;border-color:transparent;color:var(--button-custom-color)}.lib-button-ghost:hover:not(:disabled){background:var(--button-hover-color);border-color:transparent;color:var(--button-hover-text-color)}.lib-button-ghost:active:not(:disabled){background:var(--button-active-color);border-color:transparent;color:var(--button-active-text-color);transform:translateY(1px)}.lib-button-primary{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af}.lib-button-secondary{--button-default-color: #64748b;--button-default-hover-color: #475569;--button-default-active-color: #334155}.lib-button-success{--button-default-color: #16a34a;--button-default-hover-color: #15803d;--button-default-active-color: #166534}.lib-button-danger{--button-default-color: #dc2626;--button-default-hover-color: #b91c1c;--button-default-active-color: #991b1b}.lib-button-warning{--button-default-color: #f59e0b;--button-default-hover-color: #d97706;--button-default-active-color: #b45309}.lib-button-info{--button-default-color: #0891b2;--button-default-hover-color: #0e7490;--button-default-active-color: #155e75}.lib-button-neutral{--button-default-color: #374151;--button-default-hover-color: #1f2937;--button-default-active-color: #111827}.lib-button-light{--button-default-color: #f8fafc;--button-default-hover-color: #e2e8f0;--button-default-active-color: #cbd5e1;--button-text-color: #1e293b}.lib-button-dark{--button-default-color: #1e293b;--button-default-hover-color: #0f172a;--button-default-active-color: #020617;--button-text-color: #ffffff}.lib-button-link{--button-default-color: #2563eb;--button-default-hover-color: #1d4ed8;--button-default-active-color: #1e40af;background:transparent;border-color:transparent;color:var(--button-custom-color);padding-left:4px;padding-right:4px}.lib-button-link:hover:not(:disabled){background:transparent;border-color:transparent;color:var(--button-hover-color);text-decoration:underline}.lib-button-link:active:not(:disabled){background:transparent;border-color:transparent;color:var(--button-active-color);transform:none}.lib-button:focus-visible{outline:3px solid rgba(37,99,235,.25);outline-offset:2px}.lib-button:disabled{background:var(--button-disabled-color)!important;border-color:var(--button-disabled-border-color)!important;color:var(--button-disabled-text-color)!important;cursor:not-allowed;opacity:.8;transform:none!important;box-shadow:none!important}.lib-button-link:disabled{background:transparent!important;border-color:transparent!important;color:var(--button-disabled-text-color)!important;text-decoration:none}@media(max-width:480px){.lib-button-xl{min-height:50px;padding:11px 22px;font-size:16px}.lib-button-lg{min-height:44px;padding:10px 18px;font-size:15px}.lib-button-md{min-height:38px;padding:8px 16px}}\n"] }]
182
- }], propDecorators: { text: [{
135
+ args: [{ selector: 'lib-button', standalone: true, imports: [], template: "<button\n class=\"balina-button\"\n [class]=\"customClass\"\n [type]=\"type\"\n [disabled]=\"disabled || loading\"\n [attr.aria-busy]=\"loading\"\n (click)=\"onClick($event)\"\n>\n\n @if (loading) {\n\n <span\n class=\"button-spinner\"\n aria-hidden=\"true\"\n ></span>\n\n <span>\n Loading...\n </span>\n\n } @else {\n\n <span class=\"button-label\">\n {{ label }}\n </span>\n\n }\n\n</button>", styles: [".balina-button{--button-width: auto;--button-height: 44px;--button-padding: 0 22px;--button-background: #68479b;--button-background-hover: #593b84;--button-background-active: #4b326f;--button-text-color: #ffffff;--button-border: 1px solid #68479b;--button-radius: 6px;--button-font-family: Arial, Helvetica, sans-serif;--button-font-size: 14px;--button-font-weight: 600;--button-gap: 8px;--button-shadow: 0 2px 5px rgba(0, 0, 0, .08);--button-disabled-background: #dddddd;--button-disabled-text: #999999;--button-disabled-border: #dddddd;width:var(--button-width);min-height:var(--button-height);padding:var(--button-padding);display:inline-flex;align-items:center;justify-content:center;gap:var(--button-gap);box-sizing:border-box;border:var(--button-border);border-radius:var(--button-radius);background:var(--button-background);color:var(--button-text-color);font-family:var(--button-font-family);font-size:var(--button-font-size);font-weight:var(--button-font-weight);box-shadow:var(--button-shadow);outline:none;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease,transform .1s ease}.balina-button:hover:not(:disabled){background:var(--button-background-hover)}.balina-button:active:not(:disabled){background:var(--button-background-active);transform:translateY(1px)}.balina-button:focus-visible{box-shadow:0 0 0 3px #68479b33}.balina-button:disabled{background:var(--button-disabled-background);color:var(--button-disabled-text);border-color:var(--button-disabled-border);cursor:not-allowed;box-shadow:none;transform:none}.balina-button[aria-busy=true]{cursor:wait}.button-spinner{width:16px;height:16px;box-sizing:border-box;border:2px solid rgba(255,255,255,.4);border-top-color:var(--button-text-color);border-radius:50%;animation:button-spin .7s linear infinite}@keyframes button-spin{to{transform:rotate(360deg)}}.button-label{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap}@media(max-width:768px){.balina-button{min-height:var(--button-height);font-size:var(--button-font-size)}}\n"] }]
136
+ }], propDecorators: { label: [{
183
137
  type: Input
184
138
  }], type: [{
185
139
  type: Input
186
- }], variant: [{
187
- type: Input
188
- }], color: [{
189
- type: Input
190
- }], customColor: [{
191
- type: Input
192
- }], hoverColor: [{
193
- type: Input
194
- }], activeColor: [{
195
- type: Input
196
- }], textColor: [{
197
- type: Input
198
- }], borderColor: [{
199
- type: Input
200
- }], hoverTextColor: [{
201
- type: Input
202
- }], activeTextColor: [{
203
- type: Input
204
- }], disabledColor: [{
205
- type: Input
206
- }], disabledTextColor: [{
207
- type: Input
208
- }], disabledBorderColor: [{
140
+ }], disabled: [{
209
141
  type: Input
210
- }], size: [{
142
+ }], loading: [{
211
143
  type: Input
212
- }], disabled: [{
144
+ }], customClass: [{
213
145
  type: Input
214
- }], buttonClick: [{
146
+ }], clicked: [{
215
147
  type: Output
216
148
  }] } });
217
149
 
@@ -221,15 +153,23 @@ class Card {
221
153
  day = 9;
222
154
  description = '156 flights were monitored with 96.8% on-time performance. Minor delays occurred due to weather and air traffic.';
223
155
  cardClick = new EventEmitter();
224
- onCardClick() {
225
- this.cardClick.emit();
156
+ customClass = '';
157
+ clickable = false;
158
+ disabled = false;
159
+ clicked = new EventEmitter();
160
+ onClick(event) {
161
+ if (!this.clickable ||
162
+ this.disabled) {
163
+ return;
164
+ }
165
+ this.clicked.emit(event);
226
166
  }
227
167
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Card, deps: [], target: i0.ɵɵFactoryTarget.Component });
228
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: Card, isStandalone: true, selector: "lib-card", inputs: { title: "title", month: "month", day: "day", description: "description" }, outputs: { cardClick: "cardClick" }, ngImport: i0, template: "<div class=\"card mat-elevation-z1\" (click)=\"onCardClick()\" role=\"button\" tabindex=\"0\">\n\n <!-- Title -->\n <h2 class=\"mat-headline-4 card-title\">\n {{ title }}\n </h2>\n\n <!-- Content -->\n <div class=\"card-content\">\n\n <!-- Date -->\n <div class=\"date-box\">\n\n <div class=\"month mat-title-medium\">\n {{ month }}\n </div>\n\n <div class=\"day mat-headline-5\">\n {{ day }}\n </div>\n\n </div>\n\n <!-- Description -->\n <div class=\"description mat-body-large\">\n {{ description }}\n </div>\n\n </div>\n\n</div>", styles: ["@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";.card{width:100%;min-height:180px;box-sizing:border-box;border:3px solid #dedede;border-radius:12px;padding:30px 26px;background:#fff;display:flex;flex-direction:column;cursor:pointer;transition:box-shadow .2s ease,transform .2s ease,border-color .2s ease}.card:hover{border-color:#c8c8c8;box-shadow:0 4px 12px #00000014;transform:translateY(-2px)}.card-title{margin:0 0 34px;font-size:38px;font-weight:700;line-height:1.1}.card-content{display:flex;align-items:center;gap:25px;flex:1;justify-content:center;margin:0 0 0 37px}.date-box{width:92px;min-width:92px;height:96px;border-radius:12px;background:#f3f1ee;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;border:1px solid #d6d1cc}.month{color:#6b1f2b;font-weight:700;font-size:24px;line-height:1}.day{color:#000;font-size:26px;font-weight:700;line-height:1;padding-top:6px}.description{max-width:560px;color:#222;font-size:20px;font-weight:500;line-height:1.3}@media(max-width:768px){.card{padding:25px 20px}.card-title{font-size:32px;margin-bottom:25px}.description{font-size:18px}}@media(max-width:500px){.card{min-height:auto;padding:22px 16px}.card-title{font-size:28px;margin-bottom:22px}.card-content{align-items:flex-start;gap:16px}.date-box{width:75px;min-width:75px;height:85px}.month{font-size:20px}.date-line{width:48px}.day{font-size:23px}.description{font-size:16px}}\n"] });
168
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: Card, isStandalone: true, selector: "lib-card", inputs: { title: "title", month: "month", day: "day", description: "description", customClass: "customClass", clickable: "clickable", disabled: "disabled" }, outputs: { cardClick: "cardClick", clicked: "clicked" }, ngImport: i0, template: "<div\n class=\"balina-card\"\n [class]=\"customClass\"\n [class.card-clickable]=\"clickable\"\n [class.card-disabled]=\"disabled\"\n (click)=\"onClick($event)\"\n>\n\n <!-- Title -->\n <h2 class=\"card-title\">\n {{ title }}\n </h2>\n\n <!-- Card Content -->\n <div class=\"card-content\">\n\n <!-- Date -->\n <div class=\"card-date\">\n\n <div class=\"card-month\">\n {{ month }}\n </div>\n\n <div class=\"card-line\"></div>\n\n <div class=\"card-day\">\n {{ day }}\n </div>\n\n </div>\n\n <!-- Description -->\n <div class=\"card-description\">\n {{ description }}\n </div>\n\n </div>\n\n</div>", styles: [".balina-card{--card-width: 100%;--card-height: 280px;--card-padding: 28px;--card-background: #ffffff;--card-border: 3px solid #dddddd;--card-radius: 12px;--card-title-color: #000000;--card-description-color: #222222;--card-date-background: #eef5ff;--card-month-color: #2962ff;--card-line-color: #b7b7b7;--card-title-size: 38px;--card-description-size: 20px;--card-month-size: 24px;--card-day-size: 24px;--card-font-family: Arial, Helvetica, sans-serif;width:var(--card-width);min-height:var(--card-height);box-sizing:border-box;padding:var(--card-padding);background:var(--card-background);border:var(--card-border);border-radius:var(--card-radius);font-family:var(--card-font-family);cursor:pointer;transition:box-shadow .2s ease,transform .2s ease}.balina-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-1px)}.card-title{margin:0;color:var(--card-title-color);font-size:var(--card-title-size);font-weight:700;line-height:1.2}.card-content{display:flex;align-items:center;gap:28px;margin-top:36px}.card-date{width:92px;height:96px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;padding:8px;background:var(--card-date-background);border-radius:10px}.card-month{color:var(--card-month-color);font-size:var(--card-month-size);font-weight:700;line-height:1}.card-line{width:80%;height:2px;margin:7px 0;background:var(--card-line-color)}.card-day{color:#000;font-size:var(--card-day-size);font-weight:600;line-height:1}.card-description{flex:1;color:var(--card-description-color);font-size:var(--card-description-size);font-weight:600;line-height:1.4}@media(max-width:768px){.balina-card{--card-title-size: 30px;--card-description-size: 17px;--card-height: auto;padding:22px}.card-content{gap:18px;margin-top:28px}.card-date{width:80px;height:88px}}@media(max-width:480px){.balina-card{--card-title-size: 26px;--card-description-size: 15px;padding:18px}.card-content{align-items:flex-start;gap:14px}.card-date{width:70px;height:80px}.card-month,.card-day{font-size:20px}}\n"] });
229
169
  }
230
170
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Card, decorators: [{
231
171
  type: Component,
232
- args: [{ selector: 'lib-card', standalone: true, imports: [], template: "<div class=\"card mat-elevation-z1\" (click)=\"onCardClick()\" role=\"button\" tabindex=\"0\">\n\n <!-- Title -->\n <h2 class=\"mat-headline-4 card-title\">\n {{ title }}\n </h2>\n\n <!-- Content -->\n <div class=\"card-content\">\n\n <!-- Date -->\n <div class=\"date-box\">\n\n <div class=\"month mat-title-medium\">\n {{ month }}\n </div>\n\n <div class=\"day mat-headline-5\">\n {{ day }}\n </div>\n\n </div>\n\n <!-- Description -->\n <div class=\"description mat-body-large\">\n {{ description }}\n </div>\n\n </div>\n\n</div>", styles: ["@import\"https://fonts.googleapis.com/icon?family=Material+Icons\";.card{width:100%;min-height:180px;box-sizing:border-box;border:3px solid #dedede;border-radius:12px;padding:30px 26px;background:#fff;display:flex;flex-direction:column;cursor:pointer;transition:box-shadow .2s ease,transform .2s ease,border-color .2s ease}.card:hover{border-color:#c8c8c8;box-shadow:0 4px 12px #00000014;transform:translateY(-2px)}.card-title{margin:0 0 34px;font-size:38px;font-weight:700;line-height:1.1}.card-content{display:flex;align-items:center;gap:25px;flex:1;justify-content:center;margin:0 0 0 37px}.date-box{width:92px;min-width:92px;height:96px;border-radius:12px;background:#f3f1ee;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;border:1px solid #d6d1cc}.month{color:#6b1f2b;font-weight:700;font-size:24px;line-height:1}.day{color:#000;font-size:26px;font-weight:700;line-height:1;padding-top:6px}.description{max-width:560px;color:#222;font-size:20px;font-weight:500;line-height:1.3}@media(max-width:768px){.card{padding:25px 20px}.card-title{font-size:32px;margin-bottom:25px}.description{font-size:18px}}@media(max-width:500px){.card{min-height:auto;padding:22px 16px}.card-title{font-size:28px;margin-bottom:22px}.card-content{align-items:flex-start;gap:16px}.date-box{width:75px;min-width:75px;height:85px}.month{font-size:20px}.date-line{width:48px}.day{font-size:23px}.description{font-size:16px}}\n"] }]
172
+ args: [{ selector: 'lib-card', standalone: true, imports: [], template: "<div\n class=\"balina-card\"\n [class]=\"customClass\"\n [class.card-clickable]=\"clickable\"\n [class.card-disabled]=\"disabled\"\n (click)=\"onClick($event)\"\n>\n\n <!-- Title -->\n <h2 class=\"card-title\">\n {{ title }}\n </h2>\n\n <!-- Card Content -->\n <div class=\"card-content\">\n\n <!-- Date -->\n <div class=\"card-date\">\n\n <div class=\"card-month\">\n {{ month }}\n </div>\n\n <div class=\"card-line\"></div>\n\n <div class=\"card-day\">\n {{ day }}\n </div>\n\n </div>\n\n <!-- Description -->\n <div class=\"card-description\">\n {{ description }}\n </div>\n\n </div>\n\n</div>", styles: [".balina-card{--card-width: 100%;--card-height: 280px;--card-padding: 28px;--card-background: #ffffff;--card-border: 3px solid #dddddd;--card-radius: 12px;--card-title-color: #000000;--card-description-color: #222222;--card-date-background: #eef5ff;--card-month-color: #2962ff;--card-line-color: #b7b7b7;--card-title-size: 38px;--card-description-size: 20px;--card-month-size: 24px;--card-day-size: 24px;--card-font-family: Arial, Helvetica, sans-serif;width:var(--card-width);min-height:var(--card-height);box-sizing:border-box;padding:var(--card-padding);background:var(--card-background);border:var(--card-border);border-radius:var(--card-radius);font-family:var(--card-font-family);cursor:pointer;transition:box-shadow .2s ease,transform .2s ease}.balina-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-1px)}.card-title{margin:0;color:var(--card-title-color);font-size:var(--card-title-size);font-weight:700;line-height:1.2}.card-content{display:flex;align-items:center;gap:28px;margin-top:36px}.card-date{width:92px;height:96px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box;padding:8px;background:var(--card-date-background);border-radius:10px}.card-month{color:var(--card-month-color);font-size:var(--card-month-size);font-weight:700;line-height:1}.card-line{width:80%;height:2px;margin:7px 0;background:var(--card-line-color)}.card-day{color:#000;font-size:var(--card-day-size);font-weight:600;line-height:1}.card-description{flex:1;color:var(--card-description-color);font-size:var(--card-description-size);font-weight:600;line-height:1.4}@media(max-width:768px){.balina-card{--card-title-size: 30px;--card-description-size: 17px;--card-height: auto;padding:22px}.card-content{gap:18px;margin-top:28px}.card-date{width:80px;height:88px}}@media(max-width:480px){.balina-card{--card-title-size: 26px;--card-description-size: 15px;padding:18px}.card-content{align-items:flex-start;gap:14px}.card-date{width:70px;height:80px}.card-month,.card-day{font-size:20px}}\n"] }]
233
173
  }], propDecorators: { title: [{
234
174
  type: Input
235
175
  }], month: [{
@@ -240,6 +180,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
240
180
  type: Input
241
181
  }], cardClick: [{
242
182
  type: Output
183
+ }], customClass: [{
184
+ type: Input
185
+ }], clickable: [{
186
+ type: Input
187
+ }], disabled: [{
188
+ type: Input
189
+ }], clicked: [{
190
+ type: Output
243
191
  }] } });
244
192
 
245
193
  class TimeFilter {
@@ -282,42 +230,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
282
230
  }] } });
283
231
 
284
232
  class TextBox {
233
+ // =========================================
234
+ // INPUTS
235
+ // =========================================
285
236
  placeholder = '';
286
237
  value = '';
287
- width = '300px';
288
- height = '44px';
289
238
  type = 'text';
290
239
  disabled = false;
240
+ readonly = false;
241
+ /**
242
+ * Developer can provide their own CSS class.
243
+ */
244
+ customClass = '';
245
+ // =========================================
246
+ // OUTPUT EVENTS
247
+ // =========================================
248
+ /**
249
+ * Emits the current value.
250
+ */
291
251
  valueChange = new EventEmitter();
252
+ /**
253
+ * Emits whenever the user types.
254
+ */
292
255
  inputChange = new EventEmitter();
256
+ /**
257
+ * Extra developer click event.
258
+ */
293
259
  clicked = new EventEmitter();
260
+ // =========================================
261
+ // INPUT HANDLER
262
+ // =========================================
294
263
  onInput(event) {
295
264
  const input = event.target;
296
265
  this.value = input.value;
266
+ // Two-way value event
297
267
  this.valueChange.emit(this.value);
268
+ // Developer input event
298
269
  this.inputChange.emit(this.value);
299
270
  }
271
+ // =========================================
272
+ // CLICK HANDLER
273
+ // =========================================
300
274
  onClick(event) {
275
+ // Allow developer to handle the click
301
276
  this.clicked.emit(event);
302
277
  }
303
278
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TextBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
304
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: TextBox, isStandalone: true, selector: "lib-text-box", inputs: { placeholder: "placeholder", value: "value", width: "width", height: "height", type: "type", disabled: "disabled" }, outputs: { valueChange: "valueChange", inputChange: "inputChange", clicked: "clicked" }, ngImport: i0, template: "<div\n class=\"text-box-container\"\n [style.width]=\"width\"\n>\n\n <input\n class=\"text-box-input\"\n\n [style.height]=\"height\"\n\n [type]=\"type\"\n\n [placeholder]=\"placeholder\"\n\n [value]=\"value\"\n\n [disabled]=\"disabled\"\n\n (input)=\"onInput($event)\"\n\n (click)=\"onClick($event)\"\n />\n\n</div>", styles: [".text-box-container{width:100%;display:flex;align-items:center;box-sizing:border-box}.text-box-input{width:100%;box-sizing:border-box;display:flex;align-items:center;padding:0 18px;border:1px solid #a9a9a9;border-radius:6px;outline:none;background:#fff;color:#222;font-family:Arial,Helvetica,sans-serif;font-size:14px;font-weight:600;transition:border-color .2s ease,box-shadow .2s ease}.text-box-input::placeholder{color:#777;opacity:1;font-size:14px;font-weight:600}.text-box-input:hover{border-color:#777}.text-box-input:focus{border-color:#555;box-shadow:0 0 0 1px #0000000d}.text-box-input:disabled{background:#f5f5f5;color:#999;cursor:not-allowed;border-color:#d0d0d0}@media(max-width:768px){.text-box-input{padding:0 14px;font-size:14px}.text-box-input::placeholder{font-size:14px}}\n"] });
279
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: TextBox, isStandalone: true, selector: "lib-text-box", inputs: { placeholder: "placeholder", value: "value", type: "type", disabled: "disabled", readonly: "readonly", customClass: "customClass" }, outputs: { valueChange: "valueChange", inputChange: "inputChange", clicked: "clicked" }, ngImport: i0, template: "<div\n class=\"text-box-container\"\n [class]=\"customClass\"\n>\n\n <input\n class=\"text-box-input\"\n\n [type]=\"type\"\n\n [placeholder]=\"placeholder\"\n\n [value]=\"value\"\n\n [disabled]=\"disabled\"\n\n [readonly]=\"readonly\"\n\n (input)=\"onInput($event)\"\n\n (click)=\"onClick($event)\"\n />\n\n</div>", styles: [".text-box-container{--textbox-width: 300px;--textbox-height: 44px;--textbox-background: #ffffff;--textbox-border: 1px solid #a9a9a9;--textbox-border-hover: #777777;--textbox-border-focus: #68479b;--textbox-radius: 6px;--textbox-text-color: #222222;--textbox-placeholder-color: #777777;--textbox-font-family: Arial, Helvetica, sans-serif;--textbox-font-size: 14px;--textbox-font-weight: 600;--textbox-padding: 0 18px;--textbox-focus-shadow: 0 0 0 1px rgba(104, 71, 155, .15);width:var(--textbox-width);height:var(--textbox-height);display:flex;align-items:center;box-sizing:border-box}.text-box-input{width:100%;height:100%;box-sizing:border-box;padding:var(--textbox-padding);border:var(--textbox-border);border-radius:var(--textbox-radius);outline:none;background:var(--textbox-background);color:var(--textbox-text-color);font-family:var(--textbox-font-family);font-size:var(--textbox-font-size);font-weight:var(--textbox-font-weight);transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease;cursor:text}.text-box-input::placeholder{color:var(--textbox-placeholder-color);opacity:1;font-family:var(--textbox-font-family);font-size:var(--textbox-font-size);font-weight:var(--textbox-font-weight)}.text-box-input:hover:not(:disabled){border-color:var(--textbox-border-hover)}.text-box-input:focus{border-color:var(--textbox-border-focus);box-shadow:var(--textbox-focus-shadow)}.text-box-input:disabled{background:#f5f5f5;color:#999;border-color:#d0d0d0;cursor:not-allowed}.text-box-input:read-only{cursor:default}@media(max-width:768px){.text-box-container{width:100%}.text-box-input{font-size:var(--textbox-font-size)}}\n"] });
305
280
  }
306
281
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: TextBox, decorators: [{
307
282
  type: Component,
308
- args: [{ selector: 'lib-text-box', standalone: true, imports: [], template: "<div\n class=\"text-box-container\"\n [style.width]=\"width\"\n>\n\n <input\n class=\"text-box-input\"\n\n [style.height]=\"height\"\n\n [type]=\"type\"\n\n [placeholder]=\"placeholder\"\n\n [value]=\"value\"\n\n [disabled]=\"disabled\"\n\n (input)=\"onInput($event)\"\n\n (click)=\"onClick($event)\"\n />\n\n</div>", styles: [".text-box-container{width:100%;display:flex;align-items:center;box-sizing:border-box}.text-box-input{width:100%;box-sizing:border-box;display:flex;align-items:center;padding:0 18px;border:1px solid #a9a9a9;border-radius:6px;outline:none;background:#fff;color:#222;font-family:Arial,Helvetica,sans-serif;font-size:14px;font-weight:600;transition:border-color .2s ease,box-shadow .2s ease}.text-box-input::placeholder{color:#777;opacity:1;font-size:14px;font-weight:600}.text-box-input:hover{border-color:#777}.text-box-input:focus{border-color:#555;box-shadow:0 0 0 1px #0000000d}.text-box-input:disabled{background:#f5f5f5;color:#999;cursor:not-allowed;border-color:#d0d0d0}@media(max-width:768px){.text-box-input{padding:0 14px;font-size:14px}.text-box-input::placeholder{font-size:14px}}\n"] }]
283
+ args: [{ selector: 'lib-text-box', standalone: true, imports: [], template: "<div\n class=\"text-box-container\"\n [class]=\"customClass\"\n>\n\n <input\n class=\"text-box-input\"\n\n [type]=\"type\"\n\n [placeholder]=\"placeholder\"\n\n [value]=\"value\"\n\n [disabled]=\"disabled\"\n\n [readonly]=\"readonly\"\n\n (input)=\"onInput($event)\"\n\n (click)=\"onClick($event)\"\n />\n\n</div>", styles: [".text-box-container{--textbox-width: 300px;--textbox-height: 44px;--textbox-background: #ffffff;--textbox-border: 1px solid #a9a9a9;--textbox-border-hover: #777777;--textbox-border-focus: #68479b;--textbox-radius: 6px;--textbox-text-color: #222222;--textbox-placeholder-color: #777777;--textbox-font-family: Arial, Helvetica, sans-serif;--textbox-font-size: 14px;--textbox-font-weight: 600;--textbox-padding: 0 18px;--textbox-focus-shadow: 0 0 0 1px rgba(104, 71, 155, .15);width:var(--textbox-width);height:var(--textbox-height);display:flex;align-items:center;box-sizing:border-box}.text-box-input{width:100%;height:100%;box-sizing:border-box;padding:var(--textbox-padding);border:var(--textbox-border);border-radius:var(--textbox-radius);outline:none;background:var(--textbox-background);color:var(--textbox-text-color);font-family:var(--textbox-font-family);font-size:var(--textbox-font-size);font-weight:var(--textbox-font-weight);transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease;cursor:text}.text-box-input::placeholder{color:var(--textbox-placeholder-color);opacity:1;font-family:var(--textbox-font-family);font-size:var(--textbox-font-size);font-weight:var(--textbox-font-weight)}.text-box-input:hover:not(:disabled){border-color:var(--textbox-border-hover)}.text-box-input:focus{border-color:var(--textbox-border-focus);box-shadow:var(--textbox-focus-shadow)}.text-box-input:disabled{background:#f5f5f5;color:#999;border-color:#d0d0d0;cursor:not-allowed}.text-box-input:read-only{cursor:default}@media(max-width:768px){.text-box-container{width:100%}.text-box-input{font-size:var(--textbox-font-size)}}\n"] }]
309
284
  }], propDecorators: { placeholder: [{
310
285
  type: Input
311
286
  }], value: [{
312
287
  type: Input
313
- }], width: [{
314
- type: Input
315
- }], height: [{
316
- type: Input
317
288
  }], type: [{
318
289
  type: Input
319
290
  }], disabled: [{
320
291
  type: Input
292
+ }], readonly: [{
293
+ type: Input
294
+ }], customClass: [{
295
+ type: Input
321
296
  }], valueChange: [{
322
297
  type: Output
323
298
  }], inputChange: [{
@@ -327,195 +302,294 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
327
302
  }] } });
328
303
 
329
304
  class DateInput {
330
- label = 'Date To';
305
+ // =========================================
306
+ // INPUTS
307
+ // =========================================
308
+ label = '';
309
+ placeholder = 'Select date';
331
310
  value = '';
332
- width = '420px';
333
- height = '72px';
334
- min = '';
335
- max = '';
311
+ disabled = false;
312
+ readonly = false;
313
+ customClass = '';
314
+ // =========================================
315
+ // OUTPUTS
316
+ // =========================================
336
317
  valueChange = new EventEmitter();
337
318
  dateChange = new EventEmitter();
319
+ openedChange = new EventEmitter();
338
320
  clicked = new EventEmitter();
339
- dateInput;
340
- /**
341
- * Open the browser's native date picker
342
- */
343
- openDatePicker(event) {
344
- if (event) {
345
- this.clicked.emit(event);
321
+ // =========================================
322
+ // INTERNAL STATE
323
+ // =========================================
324
+ isOpen = false;
325
+ currentDate = new Date();
326
+ // =========================================
327
+ // CALENDAR DAYS
328
+ // =========================================
329
+ get calendarDays() {
330
+ const year = this.currentDate.getFullYear();
331
+ const month = this.currentDate.getMonth();
332
+ const firstDay = new Date(year, month, 1);
333
+ const lastDay = new Date(year, month + 1, 0);
334
+ const days = [];
335
+ const startDay = firstDay.getDay();
336
+ for (let i = 0; i < startDay; i++) {
337
+ const previousDate = new Date(year, month, i - startDay + 1);
338
+ days.push(previousDate);
346
339
  }
347
- const input = this.dateInput?.nativeElement;
348
- if (!input) {
349
- return;
340
+ for (let day = 1; day <= lastDay.getDate(); day++) {
341
+ days.push(new Date(year, month, day));
350
342
  }
351
- // Modern browsers
352
- if ('showPicker' in HTMLInputElement.prototype) {
353
- input.showPicker();
343
+ const remaining = 42 - days.length;
344
+ for (let i = 1; i <= remaining; i++) {
345
+ days.push(new Date(year, month + 1, i));
354
346
  }
355
- else {
356
- // Fallback
357
- input.focus();
347
+ return days;
348
+ }
349
+ // =========================================
350
+ // MONTH NAME
351
+ // =========================================
352
+ get monthName() {
353
+ return this.currentDate.toLocaleString('default', {
354
+ month: 'long'
355
+ });
356
+ }
357
+ get year() {
358
+ return this.currentDate.getFullYear();
359
+ }
360
+ // =========================================
361
+ // OPEN / CLOSE
362
+ // =========================================
363
+ toggleCalendar(event) {
364
+ if (this.disabled ||
365
+ this.readonly) {
366
+ return;
358
367
  }
368
+ if (event) {
369
+ this.clicked.emit(event);
370
+ }
371
+ this.isOpen = !this.isOpen;
372
+ this.openedChange.emit(this.isOpen);
359
373
  }
360
- /**
361
- * Date changed
362
- */
363
- onDateChange(event) {
364
- const input = event.target;
365
- this.value = input.value;
374
+ // =========================================
375
+ // PREVIOUS MONTH
376
+ // =========================================
377
+ previousMonth() {
378
+ this.currentDate =
379
+ new Date(this.year, this.currentDate.getMonth() - 1, 1);
380
+ }
381
+ // =========================================
382
+ // NEXT MONTH
383
+ // =========================================
384
+ nextMonth() {
385
+ this.currentDate =
386
+ new Date(this.year, this.currentDate.getMonth() + 1, 1);
387
+ }
388
+ // =========================================
389
+ // SELECT DATE
390
+ // =========================================
391
+ selectDate(date, event) {
392
+ if (this.disabled) {
393
+ return;
394
+ }
395
+ this.value =
396
+ this.formatDate(date);
366
397
  this.valueChange.emit(this.value);
367
- this.dateChange.emit(this.value);
398
+ this.dateChange.emit(date);
399
+ this.clicked.emit(event);
400
+ this.isOpen = false;
401
+ this.openedChange.emit(false);
402
+ }
403
+ // =========================================
404
+ // FORMAT DATE
405
+ // =========================================
406
+ formatDate(date) {
407
+ const day = String(date.getDate())
408
+ .padStart(2, '0');
409
+ const month = String(date.getMonth() + 1)
410
+ .padStart(2, '0');
411
+ const year = date.getFullYear();
412
+ return `${year}-${month}-${day}`;
413
+ }
414
+ // =========================================
415
+ // CHECK CURRENT MONTH
416
+ // =========================================
417
+ isCurrentMonth(date) {
418
+ return (date.getMonth() ===
419
+ this.currentDate.getMonth() &&
420
+ date.getFullYear() ===
421
+ this.currentDate.getFullYear());
422
+ }
423
+ // =========================================
424
+ // CHECK TODAY
425
+ // =========================================
426
+ isToday(date) {
427
+ const today = new Date();
428
+ return (date.getDate() === today.getDate() &&
429
+ date.getMonth() === today.getMonth() &&
430
+ date.getFullYear() === today.getFullYear());
431
+ }
432
+ // =========================================
433
+ // CHECK SELECTED DATE
434
+ // =========================================
435
+ isSelected(date) {
436
+ return (this.value ===
437
+ this.formatDate(date));
438
+ }
439
+ // =========================================
440
+ // OUTSIDE CLICK
441
+ // =========================================
442
+ onDocumentClick(event) {
443
+ const target = event.target;
444
+ const dateInput = target.closest('lib-date-input');
445
+ if (!dateInput &&
446
+ this.isOpen) {
447
+ this.isOpen = false;
448
+ this.openedChange.emit(false);
449
+ }
368
450
  }
369
451
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DateInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
370
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.2", type: DateInput, isStandalone: true, selector: "lib-date-input", inputs: { label: "label", value: "value", width: "width", height: "height", min: "min", max: "max" }, outputs: { valueChange: "valueChange", dateChange: "dateChange", clicked: "clicked" }, viewQueries: [{ propertyName: "dateInput", first: true, predicate: ["dateInput"], descendants: true }], ngImport: i0, template: "<div\n class=\"date-container\"\n [style.width]=\"width\"\n>\n\n <div\n class=\"date-wrapper\"\n [style.height]=\"height\"\n (click)=\"openDatePicker($event)\"\n >\n\n <!-- Floating label -->\n\n <label class=\"date-label\">\n {{ label }}\n </label>\n\n\n <!-- Date input -->\n\n <input\n #dateInput\n class=\"date-input\"\n type=\"date\"\n\n [value]=\"value\"\n\n [min]=\"min\"\n [max]=\"max\"\n\n (change)=\"onDateChange($event)\"\n\n (click)=\"$event.stopPropagation()\"\n\n autocomplete=\"off\"\n />\n\n\n <!-- Calendar button -->\n\n <button\n type=\"button\"\n class=\"calendar-button\"\n\n (click)=\"openDatePicker($event)\"\n >\n\n <span class=\"calendar-icon\">\n\n <span class=\"calendar-top\"></span>\n\n <span class=\"calendar-body\"></span>\n\n </span>\n\n </button>\n\n </div>\n\n</div>", styles: [".date-container{position:relative;display:flex;flex-direction:column;box-sizing:border-box}.date-wrapper{position:relative;width:100%;display:flex;align-items:center;background:#fff;border:2px solid #68479b;border-radius:6px;box-sizing:border-box;cursor:pointer;overflow:visible;transition:border-color .2s ease}.date-wrapper:hover{border-color:#68479b}.date-wrapper:focus-within{border-color:#68479b}.date-label{position:absolute;top:0;left:18px;transform:translateY(-50%);padding:0 6px;background:#fff;color:#68479b;font-size:17px;font-weight:400;line-height:1;white-space:nowrap;z-index:5;pointer-events:none}.date-input{flex:1;min-width:0;width:100%;height:100%;padding:0 16px 0 24px;border:none;outline:none;background:transparent;color:#222;font-family:Arial,Helvetica,sans-serif;font-size:27px;font-weight:400;line-height:1;box-sizing:border-box;cursor:pointer;pointer-events:none}.calendar-button{flex:0 0 58px;width:58px;height:100%;display:flex;align-items:center;justify-content:center;padding:0;margin:0;border:none;background:#f1f1f1;cursor:pointer;box-sizing:border-box;border-radius:0 4px 4px 0;transition:background-color .2s ease}.calendar-button:hover{background:#e9e9e9}.calendar-icon{position:relative;width:28px;height:27px;display:block;border:3px solid #555555;border-radius:4px;box-sizing:border-box}.calendar-top{position:absolute;left:-3px;top:5px;width:28px;height:3px;background:#555}.calendar-body{position:absolute;left:6px;top:13px;width:10px;height:7px;border:2px solid #555555;box-sizing:border-box}.calendar-icon:before,.calendar-icon:after{content:\"\";position:absolute;top:-7px;width:3px;height:9px;background:#555;border-radius:2px}.calendar-icon:before{left:5px}.calendar-icon:after{right:5px}.date-input::-webkit-calendar-picker-indicator{display:none;opacity:0}@media(max-width:768px){.date-label{left:14px;font-size:15px}.date-input{padding-left:16px;font-size:21px}.calendar-button{flex-basis:52px;width:52px}.calendar-icon{transform:scale(.9)}}\n"] });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: DateInput, isStandalone: true, selector: "lib-date-input", inputs: { label: "label", placeholder: "placeholder", value: "value", disabled: "disabled", readonly: "readonly", customClass: "customClass" }, outputs: { valueChange: "valueChange", dateChange: "dateChange", openedChange: "openedChange", clicked: "clicked" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n class=\"date-input-container\"\n [class]=\"customClass\"\n [class.date-input-disabled]=\"disabled\"\n [class.date-input-open]=\"isOpen\"\n>\n\n <!-- INPUT -->\n\n <div\n class=\"date-input-field\"\n (click)=\"toggleCalendar($event)\"\n >\n\n @if (label) {\n <label class=\"date-input-label\">\n {{ label }}\n </label>\n }\n\n <span\n class=\"date-input-value\"\n [class.date-input-placeholder]=\"!value\"\n >\n {{ value || placeholder }}\n </span>\n\n <!-- Calendar Icon -->\n\n <span class=\"calendar-icon\">\n\n <span class=\"calendar-top\"></span>\n\n <span class=\"calendar-body\"></span>\n\n </span>\n\n </div>\n\n\n <!-- DATE PICKER -->\n\n @if (isOpen) {\n\n <div\n class=\"date-picker\"\n (click)=\"$event.stopPropagation()\"\n >\n\n <!-- HEADER -->\n\n <div class=\"date-picker-header\">\n\n <button\n type=\"button\"\n class=\"month-button\"\n (click)=\"previousMonth()\"\n >\n \u2039\n </button>\n\n <span class=\"month-title\">\n {{ monthName }} {{ year }}\n </span>\n\n <button\n type=\"button\"\n class=\"month-button\"\n (click)=\"nextMonth()\"\n >\n \u203A\n </button>\n\n </div>\n\n\n <!-- WEEK DAYS -->\n\n <div class=\"week-days\">\n\n <span>Sun</span>\n <span>Mon</span>\n <span>Tue</span>\n <span>Wed</span>\n <span>Thu</span>\n <span>Fri</span>\n <span>Sat</span>\n\n </div>\n\n\n <!-- DAYS -->\n\n <div class=\"calendar-days\">\n\n @for (\n date of calendarDays;\n track date.getTime()\n ) {\n\n <button\n type=\"button\"\n\n class=\"calendar-day\"\n\n [class.other-month]=\"\n !isCurrentMonth(date)\n \"\n\n [class.today]=\"\n isToday(date)\n \"\n\n [class.selected]=\"\n isSelected(date)\n \"\n\n (click)=\"\n selectDate(date, $event)\n \"\n >\n\n {{ date.getDate() }}\n\n </button>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [".date-input-container{--date-width: 300px;--date-height: 44px;--date-background: #ffffff;--date-border: 1px solid #a9a9a9;--date-border-hover: #777777;--date-border-focus: #68479b;--date-radius: 6px;--date-text: #222222;--date-placeholder: #777777;--date-primary: #68479b;--date-hover: #f3f0f7;--date-selected: #68479b;--date-selected-text: #ffffff;--date-font-family: Arial, Helvetica, sans-serif;--date-font-size: 14px;--date-shadow: 0 4px 12px rgba(0, 0, 0, .12);position:relative;width:var(--date-width);font-family:var(--date-font-family);box-sizing:border-box}.date-input-field{position:relative;width:100%;height:var(--date-height);display:flex;align-items:center;box-sizing:border-box;padding:0 50px 0 18px;border:var(--date-border);border-radius:var(--date-radius);background:var(--date-background);color:var(--date-text);font-size:var(--date-font-size);font-weight:600;cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease}.date-input-field:hover{border-color:var(--date-border-hover)}.date-input-open .date-input-field{border-color:var(--date-border-focus);box-shadow:0 0 0 1px #68479b1f}.date-input-label{position:absolute;top:0;left:14px;transform:translateY(-50%);padding:0 6px;background:var(--date-background);color:var(--date-border-focus);font-size:13px;font-weight:500;line-height:1;pointer-events:none}.date-input-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.date-input-placeholder{color:var(--date-placeholder)}.calendar-icon{position:absolute;right:17px;width:18px;height:18px;box-sizing:border-box;border:1.8px solid #555;border-radius:3px}.calendar-top{position:absolute;left:0;top:4px;width:100%;border-top:1.8px solid #555}.calendar-icon:before,.calendar-icon:after{content:\"\";position:absolute;top:-4px;width:2px;height:6px;background:#555;border-radius:2px}.calendar-icon:before{left:4px}.calendar-icon:after{right:4px}.date-picker{position:absolute;top:calc(100% + 6px);left:0;width:100%;min-width:300px;z-index:1000;padding:14px;box-sizing:border-box;background:#fff;border:1px solid #d5d5d5;border-radius:var(--date-radius);box-shadow:var(--date-shadow)}.date-picker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.month-title{font-size:15px;font-weight:700;color:var(--date-text)}.month-button{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#555;font-size:24px;line-height:1;cursor:pointer}.month-button:hover{background:var(--date-hover);color:var(--date-primary)}.week-days{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:6px;text-align:center;color:#777;font-size:12px;font-weight:600}.calendar-days{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.calendar-day{width:100%;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:var(--date-text);font-size:13px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.calendar-day:hover{background:var(--date-hover)}.calendar-day.other-month{color:silver}.calendar-day.today{border:1px solid var(--date-primary);color:var(--date-primary)}.calendar-day.selected{background:var(--date-selected);color:var(--date-selected-text);border:none}.date-input-disabled .date-input-field{background:#f5f5f5;border-color:#d0d0d0;color:#999;cursor:not-allowed}@media(max-width:768px){.date-input-container{width:100%}.date-picker{min-width:100%}}\n"] });
371
453
  }
372
454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: DateInput, decorators: [{
373
455
  type: Component,
374
- args: [{ selector: 'lib-date-input', standalone: true, imports: [], template: "<div\n class=\"date-container\"\n [style.width]=\"width\"\n>\n\n <div\n class=\"date-wrapper\"\n [style.height]=\"height\"\n (click)=\"openDatePicker($event)\"\n >\n\n <!-- Floating label -->\n\n <label class=\"date-label\">\n {{ label }}\n </label>\n\n\n <!-- Date input -->\n\n <input\n #dateInput\n class=\"date-input\"\n type=\"date\"\n\n [value]=\"value\"\n\n [min]=\"min\"\n [max]=\"max\"\n\n (change)=\"onDateChange($event)\"\n\n (click)=\"$event.stopPropagation()\"\n\n autocomplete=\"off\"\n />\n\n\n <!-- Calendar button -->\n\n <button\n type=\"button\"\n class=\"calendar-button\"\n\n (click)=\"openDatePicker($event)\"\n >\n\n <span class=\"calendar-icon\">\n\n <span class=\"calendar-top\"></span>\n\n <span class=\"calendar-body\"></span>\n\n </span>\n\n </button>\n\n </div>\n\n</div>", styles: [".date-container{position:relative;display:flex;flex-direction:column;box-sizing:border-box}.date-wrapper{position:relative;width:100%;display:flex;align-items:center;background:#fff;border:2px solid #68479b;border-radius:6px;box-sizing:border-box;cursor:pointer;overflow:visible;transition:border-color .2s ease}.date-wrapper:hover{border-color:#68479b}.date-wrapper:focus-within{border-color:#68479b}.date-label{position:absolute;top:0;left:18px;transform:translateY(-50%);padding:0 6px;background:#fff;color:#68479b;font-size:17px;font-weight:400;line-height:1;white-space:nowrap;z-index:5;pointer-events:none}.date-input{flex:1;min-width:0;width:100%;height:100%;padding:0 16px 0 24px;border:none;outline:none;background:transparent;color:#222;font-family:Arial,Helvetica,sans-serif;font-size:27px;font-weight:400;line-height:1;box-sizing:border-box;cursor:pointer;pointer-events:none}.calendar-button{flex:0 0 58px;width:58px;height:100%;display:flex;align-items:center;justify-content:center;padding:0;margin:0;border:none;background:#f1f1f1;cursor:pointer;box-sizing:border-box;border-radius:0 4px 4px 0;transition:background-color .2s ease}.calendar-button:hover{background:#e9e9e9}.calendar-icon{position:relative;width:28px;height:27px;display:block;border:3px solid #555555;border-radius:4px;box-sizing:border-box}.calendar-top{position:absolute;left:-3px;top:5px;width:28px;height:3px;background:#555}.calendar-body{position:absolute;left:6px;top:13px;width:10px;height:7px;border:2px solid #555555;box-sizing:border-box}.calendar-icon:before,.calendar-icon:after{content:\"\";position:absolute;top:-7px;width:3px;height:9px;background:#555;border-radius:2px}.calendar-icon:before{left:5px}.calendar-icon:after{right:5px}.date-input::-webkit-calendar-picker-indicator{display:none;opacity:0}@media(max-width:768px){.date-label{left:14px;font-size:15px}.date-input{padding-left:16px;font-size:21px}.calendar-button{flex-basis:52px;width:52px}.calendar-icon{transform:scale(.9)}}\n"] }]
456
+ args: [{ selector: 'lib-date-input', standalone: true, imports: [], template: "<div\n class=\"date-input-container\"\n [class]=\"customClass\"\n [class.date-input-disabled]=\"disabled\"\n [class.date-input-open]=\"isOpen\"\n>\n\n <!-- INPUT -->\n\n <div\n class=\"date-input-field\"\n (click)=\"toggleCalendar($event)\"\n >\n\n @if (label) {\n <label class=\"date-input-label\">\n {{ label }}\n </label>\n }\n\n <span\n class=\"date-input-value\"\n [class.date-input-placeholder]=\"!value\"\n >\n {{ value || placeholder }}\n </span>\n\n <!-- Calendar Icon -->\n\n <span class=\"calendar-icon\">\n\n <span class=\"calendar-top\"></span>\n\n <span class=\"calendar-body\"></span>\n\n </span>\n\n </div>\n\n\n <!-- DATE PICKER -->\n\n @if (isOpen) {\n\n <div\n class=\"date-picker\"\n (click)=\"$event.stopPropagation()\"\n >\n\n <!-- HEADER -->\n\n <div class=\"date-picker-header\">\n\n <button\n type=\"button\"\n class=\"month-button\"\n (click)=\"previousMonth()\"\n >\n \u2039\n </button>\n\n <span class=\"month-title\">\n {{ monthName }} {{ year }}\n </span>\n\n <button\n type=\"button\"\n class=\"month-button\"\n (click)=\"nextMonth()\"\n >\n \u203A\n </button>\n\n </div>\n\n\n <!-- WEEK DAYS -->\n\n <div class=\"week-days\">\n\n <span>Sun</span>\n <span>Mon</span>\n <span>Tue</span>\n <span>Wed</span>\n <span>Thu</span>\n <span>Fri</span>\n <span>Sat</span>\n\n </div>\n\n\n <!-- DAYS -->\n\n <div class=\"calendar-days\">\n\n @for (\n date of calendarDays;\n track date.getTime()\n ) {\n\n <button\n type=\"button\"\n\n class=\"calendar-day\"\n\n [class.other-month]=\"\n !isCurrentMonth(date)\n \"\n\n [class.today]=\"\n isToday(date)\n \"\n\n [class.selected]=\"\n isSelected(date)\n \"\n\n (click)=\"\n selectDate(date, $event)\n \"\n >\n\n {{ date.getDate() }}\n\n </button>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [".date-input-container{--date-width: 300px;--date-height: 44px;--date-background: #ffffff;--date-border: 1px solid #a9a9a9;--date-border-hover: #777777;--date-border-focus: #68479b;--date-radius: 6px;--date-text: #222222;--date-placeholder: #777777;--date-primary: #68479b;--date-hover: #f3f0f7;--date-selected: #68479b;--date-selected-text: #ffffff;--date-font-family: Arial, Helvetica, sans-serif;--date-font-size: 14px;--date-shadow: 0 4px 12px rgba(0, 0, 0, .12);position:relative;width:var(--date-width);font-family:var(--date-font-family);box-sizing:border-box}.date-input-field{position:relative;width:100%;height:var(--date-height);display:flex;align-items:center;box-sizing:border-box;padding:0 50px 0 18px;border:var(--date-border);border-radius:var(--date-radius);background:var(--date-background);color:var(--date-text);font-size:var(--date-font-size);font-weight:600;cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease}.date-input-field:hover{border-color:var(--date-border-hover)}.date-input-open .date-input-field{border-color:var(--date-border-focus);box-shadow:0 0 0 1px #68479b1f}.date-input-label{position:absolute;top:0;left:14px;transform:translateY(-50%);padding:0 6px;background:var(--date-background);color:var(--date-border-focus);font-size:13px;font-weight:500;line-height:1;pointer-events:none}.date-input-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.date-input-placeholder{color:var(--date-placeholder)}.calendar-icon{position:absolute;right:17px;width:18px;height:18px;box-sizing:border-box;border:1.8px solid #555;border-radius:3px}.calendar-top{position:absolute;left:0;top:4px;width:100%;border-top:1.8px solid #555}.calendar-icon:before,.calendar-icon:after{content:\"\";position:absolute;top:-4px;width:2px;height:6px;background:#555;border-radius:2px}.calendar-icon:before{left:4px}.calendar-icon:after{right:4px}.date-picker{position:absolute;top:calc(100% + 6px);left:0;width:100%;min-width:300px;z-index:1000;padding:14px;box-sizing:border-box;background:#fff;border:1px solid #d5d5d5;border-radius:var(--date-radius);box-shadow:var(--date-shadow)}.date-picker-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.month-title{font-size:15px;font-weight:700;color:var(--date-text)}.month-button{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#555;font-size:24px;line-height:1;cursor:pointer}.month-button:hover{background:var(--date-hover);color:var(--date-primary)}.week-days{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:6px;text-align:center;color:#777;font-size:12px;font-weight:600}.calendar-days{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.calendar-day{width:100%;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:var(--date-text);font-size:13px;cursor:pointer;transition:background-color .15s ease,color .15s ease}.calendar-day:hover{background:var(--date-hover)}.calendar-day.other-month{color:silver}.calendar-day.today{border:1px solid var(--date-primary);color:var(--date-primary)}.calendar-day.selected{background:var(--date-selected);color:var(--date-selected-text);border:none}.date-input-disabled .date-input-field{background:#f5f5f5;border-color:#d0d0d0;color:#999;cursor:not-allowed}@media(max-width:768px){.date-input-container{width:100%}.date-picker{min-width:100%}}\n"] }]
375
457
  }], propDecorators: { label: [{
376
458
  type: Input
377
- }], value: [{
459
+ }], placeholder: [{
378
460
  type: Input
379
- }], width: [{
461
+ }], value: [{
380
462
  type: Input
381
- }], height: [{
463
+ }], disabled: [{
382
464
  type: Input
383
- }], min: [{
465
+ }], readonly: [{
384
466
  type: Input
385
- }], max: [{
467
+ }], customClass: [{
386
468
  type: Input
387
469
  }], valueChange: [{
388
470
  type: Output
389
471
  }], dateChange: [{
390
472
  type: Output
473
+ }], openedChange: [{
474
+ type: Output
391
475
  }], clicked: [{
392
476
  type: Output
393
- }], dateInput: [{
394
- type: ViewChild,
395
- args: ['dateInput']
477
+ }], onDocumentClick: [{
478
+ type: HostListener,
479
+ args: ['document:click',
480
+ ['$event']]
396
481
  }] } });
397
482
 
398
483
  class Dropdown {
399
- elementRef;
400
- // =========================
401
- // Inputs
402
- // =========================
484
+ // =========================================
485
+ // INPUTS
486
+ // =========================================
403
487
  label = '';
404
- placeholder = '';
488
+ placeholder = 'Select';
405
489
  options = [];
406
490
  value = '';
407
- width = '250px';
408
- height = '50px';
409
- // =========================
410
- // Outputs
411
- // =========================
412
- // Selected value
491
+ disabled = false;
492
+ searchable = true;
493
+ customClass = '';
494
+ // =========================================
495
+ // OUTPUTS
496
+ // =========================================
497
+ /**
498
+ * Emits the selected value.
499
+ */
413
500
  valueChange = new EventEmitter();
414
- // Developer custom event
415
- optionClick = new EventEmitter();
416
- // Search event
417
- searchChange = new EventEmitter();
418
- // Open / close event
501
+ /**
502
+ * Emits the complete selected option.
503
+ */
504
+ selectionChange = new EventEmitter();
505
+ /**
506
+ * Emits when the dropdown opens/closes.
507
+ */
419
508
  openedChange = new EventEmitter();
420
- // =========================
421
- // Component state
422
- // =========================
509
+ /**
510
+ * Developer click event.
511
+ */
512
+ clicked = new EventEmitter();
513
+ // =========================================
514
+ // INTERNAL STATE
515
+ // =========================================
423
516
  isOpen = false;
424
517
  searchText = '';
425
- constructor(elementRef) {
426
- this.elementRef = elementRef;
427
- }
428
- // =========================
429
- // Filter options
430
- // =========================
518
+ // =========================================
519
+ // FILTERED OPTIONS
520
+ // =========================================
431
521
  get filteredOptions() {
432
522
  const search = this.searchText
433
- .toLowerCase()
434
- .trim();
523
+ .trim()
524
+ .toLowerCase();
435
525
  if (!search) {
436
526
  return this.options;
437
527
  }
438
- return this.options.filter(option => option
528
+ return this.options.filter(option => option.label
439
529
  .toLowerCase()
440
530
  .includes(search));
441
531
  }
442
- // =========================
443
- // Open dropdown
444
- // =========================
445
- openDropdown() {
446
- if (!this.isOpen) {
447
- this.isOpen = true;
448
- this.searchText = this.value;
449
- this.openedChange.emit(true);
450
- }
532
+ // =========================================
533
+ // SELECTED OPTION
534
+ // =========================================
535
+ get selectedOption() {
536
+ return this.options.find(option => option.value === this.value);
451
537
  }
452
- // =========================
453
- // Toggle dropdown
454
- // =========================
455
- toggleDropdown() {
456
- this.isOpen = !this.isOpen;
457
- if (this.isOpen) {
458
- this.searchText = this.value;
538
+ // =========================================
539
+ // OPEN / CLOSE
540
+ // =========================================
541
+ toggleDropdown(event) {
542
+ if (this.disabled) {
543
+ return;
544
+ }
545
+ if (event) {
546
+ this.clicked.emit(event);
459
547
  }
548
+ this.isOpen = !this.isOpen;
460
549
  this.openedChange.emit(this.isOpen);
461
- }
462
- // =========================
463
- // Input / Search
464
- // =========================
465
- onInput(event) {
466
- const input = event.target;
467
- this.searchText = input.value;
468
- // Automatically open while typing
469
550
  if (!this.isOpen) {
470
- this.isOpen = true;
471
- this.openedChange.emit(true);
551
+ this.searchText = '';
472
552
  }
473
- // Tell developer about search
474
- this.searchChange.emit(this.searchText);
475
553
  }
476
- // =========================
477
- // Select option
478
- // =========================
479
- selectOption(option) {
480
- // Put option name into input
481
- this.value = option;
482
- this.searchText = option;
483
- // Close dropdown
484
- this.isOpen = false;
485
- // Tell parent selected value
486
- this.valueChange.emit(option);
487
- // Developer custom event
488
- this.optionClick.emit(option);
489
- // Tell parent dropdown closed
490
- this.openedChange.emit(false);
491
- }
492
- // =========================
493
- // Clear
494
- // =========================
495
- clear() {
496
- this.value = '';
497
- this.searchText = '';
498
- this.valueChange.emit('');
499
- }
500
- // =========================
501
- // Click outside
502
- // =========================
503
554
  onDocumentClick(event) {
504
- const clickedInside = this.elementRef.nativeElement
505
- .contains(event.target);
506
- if (!clickedInside &&
507
- this.isOpen) {
555
+ const target = event.target;
556
+ const dropdown = target.closest('lib-dropdown');
557
+ if (!dropdown && this.isOpen) {
508
558
  this.isOpen = false;
559
+ this.searchText = '';
509
560
  this.openedChange.emit(false);
510
561
  }
511
562
  }
512
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Dropdown, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
513
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Dropdown, isStandalone: true, selector: "lib-dropdown", inputs: { label: "label", placeholder: "placeholder", options: "options", value: "value", width: "width", height: "height" }, outputs: { valueChange: "valueChange", optionClick: "optionClick", searchChange: "searchChange", openedChange: "openedChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n class=\"dropdown-container\"\n [style.width]=\"width\"\n>\n\n <!-- =========================\n INPUT\n ========================= -->\n\n <div\n class=\"dropdown-input-wrapper\"\n [style.height]=\"height\"\n [class.open]=\"isOpen\"\n >\n\n <!-- Floating label -->\n\n @if (label) {\n\n <label\n class=\"dropdown-label\"\n [class.active]=\"isOpen || value || searchText\"\n >\n {{ label }}\n </label>\n\n }\n\n\n <!-- Search input -->\n\n <input\n class=\"dropdown-input\"\n type=\"text\"\n [placeholder]=\"\n !isOpen && !value\n ? placeholder\n : ''\n \"\n [value]=\"searchText\"\n (input)=\"onInput($event)\"\n (click)=\"openDropdown()\"\n autocomplete=\"off\"\n />\n\n\n <!-- Arrow -->\n\n <button\n type=\"button\"\n class=\"dropdown-arrow\"\n (click)=\"toggleDropdown(); $event.stopPropagation()\"\n aria-label=\"Open dropdown\"\n >\n\n <span\n class=\"arrow\"\n [class.rotate]=\"isOpen\"\n >\n \u2304\n </span>\n\n </button>\n\n </div>\n\n\n <!-- =========================\n DROPDOWN OPTIONS\n ========================= -->\n\n @if (isOpen) {\n\n <div class=\"dropdown-menu\">\n\n @if (filteredOptions.length > 0) {\n\n @for (\n option of filteredOptions;\n track option\n ) {\n\n <button\n type=\"button\"\n class=\"dropdown-option\"\n [class.selected]=\"option === value\"\n (click)=\"selectOption(option)\"\n >\n\n {{ option }}\n\n </button>\n\n }\n\n } @else {\n\n <div class=\"no-results\">\n\n No results found\n\n </div>\n\n }\n\n </div>\n\n }\n\n</div>", styles: [".dropdown-container{position:relative;display:flex;flex-direction:column;box-sizing:border-box;font-family:Arial,Helvetica,sans-serif}.dropdown-input-wrapper{position:relative;width:100%;display:flex;align-items:center;box-sizing:border-box;background:#fff;border:1px solid #999999;border-radius:5px;transition:border-color .2s ease,box-shadow .2s ease}.dropdown-input-wrapper:hover{border-color:#777}.dropdown-input-wrapper.open{border-color:#555;box-shadow:0 0 0 1px #0000000a}.dropdown-input{flex:1;min-width:0;width:100%;height:100%;border:none;outline:none;background:transparent;padding:4px 14px 0;box-sizing:border-box;color:#222;font-size:14px;font-weight:400}.dropdown-input::placeholder{color:#555;opacity:1}.dropdown-label{position:absolute;top:50%;left:13px;transform:translateY(-50%);padding:0 4px;color:#555;background:#fff;font-size:14px;font-weight:400;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease}.dropdown-label.active{top:0;transform:translateY(-50%);font-size:11px;color:#555}.dropdown-arrow{flex:0 0 40px;width:40px;height:100%;display:flex;align-items:center;justify-content:center;padding:0;margin:0;border:none;background:transparent;cursor:pointer;color:#222}.arrow{display:flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:25px;line-height:15px;font-weight:400;transition:transform .2s ease}.arrow.rotate{transform:rotate(180deg)}.dropdown-arrow:hover .arrow{color:#000}.dropdown-menu{position:absolute;top:calc(100% + 2px);left:0;width:100%;max-height:210px;display:flex;flex-direction:column;overflow-y:auto;padding:5px 0;box-sizing:border-box;background:#fff;border-radius:0 0 14px 14px;box-shadow:0 4px 12px #00000014;z-index:1000}.dropdown-option{width:100%;min-height:38px;display:flex;align-items:center;justify-content:flex-start;padding:0 16px;border:none;outline:none;background:transparent;color:#333;font-family:inherit;font-size:14px;font-weight:400;text-align:left;cursor:pointer;box-sizing:border-box;transition:background-color .15s ease}.dropdown-option:hover{background-color:#f2f2f2}.dropdown-option.selected{background-color:#eee;color:#222}.no-results{min-height:38px;display:flex;align-items:center;padding:0 16px;color:#888;font-size:14px}.dropdown-menu::-webkit-scrollbar{width:5px}.dropdown-menu::-webkit-scrollbar-track{background:transparent}.dropdown-menu::-webkit-scrollbar-thumb{background:#222;border-radius:10px}@media(max-width:768px){.dropdown-input{font-size:14px}.dropdown-option{min-height:40px;padding:0 14px;font-size:14px}.dropdown-menu{max-height:200px}}\n"] });
563
+ // =========================================
564
+ // SELECT OPTION
565
+ // =========================================
566
+ selectOption(option, event) {
567
+ if (option.disabled) {
568
+ return;
569
+ }
570
+ this.value = option.value;
571
+ this.valueChange.emit(option.value);
572
+ this.selectionChange.emit(option);
573
+ this.clicked.emit(event);
574
+ this.isOpen = false;
575
+ this.openedChange.emit(false);
576
+ this.searchText = '';
577
+ }
578
+ // =========================================
579
+ // SEARCH
580
+ // =========================================
581
+ onSearch(event) {
582
+ const input = event.target;
583
+ this.searchText =
584
+ input.value;
585
+ }
586
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Dropdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
587
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: Dropdown, isStandalone: true, selector: "lib-dropdown", inputs: { label: "label", placeholder: "placeholder", options: "options", value: "value", disabled: "disabled", searchable: "searchable", customClass: "customClass" }, outputs: { valueChange: "valueChange", selectionChange: "selectionChange", openedChange: "openedChange", clicked: "clicked" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n class=\"dropdown-container\"\n [class]=\"customClass\"\n [class.dropdown-disabled]=\"disabled\"\n [class.dropdown-open]=\"isOpen\"\n>\n\n <!-- =====================================\n DROPDOWN FIELD\n ===================================== -->\n\n <div\n class=\"dropdown-field\"\n (click)=\"toggleDropdown($event)\"\n >\n\n <!-- Label -->\n\n @if (label) {\n <label class=\"dropdown-label\">\n {{ label }}\n </label>\n }\n\n\n <!-- Selected value -->\n\n <span\n class=\"dropdown-value\"\n [class.dropdown-placeholder]=\"!selectedOption\"\n >\n {{\n selectedOption?.label ||\n placeholder\n }}\n </span>\n\n\n <!-- Arrow -->\n\n <span\n class=\"dropdown-arrow\"\n [class.arrow-up]=\"isOpen\"\n >\n </span>\n\n </div>\n\n\n <!-- =====================================\n DROPDOWN MENU\n ===================================== -->\n\n @if (isOpen) {\n\n <div\n class=\"dropdown-menu\"\n (click)=\"$event.stopPropagation()\"\n >\n\n <!-- Search -->\n\n @if (searchable) {\n\n <div class=\"dropdown-search\">\n\n <input\n type=\"text\"\n class=\"dropdown-search-input\"\n\n placeholder=\"Search...\"\n\n [value]=\"searchText\"\n\n (input)=\"onSearch($event)\"\n />\n\n </div>\n\n }\n\n\n <!-- Options -->\n\n <div class=\"dropdown-options\">\n\n @for (\n option of filteredOptions;\n track option.value\n ) {\n\n <div\n class=\"dropdown-option\"\n\n [class.option-disabled]=\"\n option.disabled\n \"\n\n [class.option-selected]=\"\n option.value === value\n \"\n\n (click)=\"\n selectOption(option, $event)\n \"\n >\n\n {{ option.label }}\n\n </div>\n\n }\n\n\n <!-- No result -->\n\n @if (filteredOptions.length === 0) {\n\n <div class=\"dropdown-no-result\">\n No results found\n </div>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [".dropdown-container{--dropdown-width: 300px;--dropdown-height: 44px;--dropdown-background: #ffffff;--dropdown-border: 1px solid #a9a9a9;--dropdown-border-hover: #777777;--dropdown-border-focus: #68479b;--dropdown-radius: 6px;--dropdown-text-color: #222222;--dropdown-placeholder-color: #777777;--dropdown-menu-background: #ffffff;--dropdown-option-hover: #f3f0f7;--dropdown-option-selected: #eee8f5;--dropdown-disabled: #f5f5f5;--dropdown-font-family: Arial, Helvetica, sans-serif;--dropdown-font-size: 14px;--dropdown-font-weight: 600;--dropdown-shadow: 0 4px 12px rgba(0, 0, 0, .12);position:relative;width:var(--dropdown-width);font-family:var(--dropdown-font-family);box-sizing:border-box}.dropdown-field{position:relative;width:100%;height:var(--dropdown-height);display:flex;align-items:center;box-sizing:border-box;padding:0 48px 0 18px;border:var(--dropdown-border);border-radius:var(--dropdown-radius);background:var(--dropdown-background);color:var(--dropdown-text-color);font-size:var(--dropdown-font-size);font-weight:var(--dropdown-font-weight);cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease}.dropdown-field:hover{border-color:var(--dropdown-border-hover)}.dropdown-open .dropdown-field{border-color:var(--dropdown-border-focus);box-shadow:0 0 0 1px #68479b1f}.dropdown-label{position:absolute;top:0;left:14px;transform:translateY(-50%);padding:0 6px;background:var(--dropdown-background);color:var(--dropdown-border-focus);font-size:13px;font-weight:500;line-height:1;pointer-events:none}.dropdown-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--dropdown-text-color)}.dropdown-placeholder{color:var(--dropdown-placeholder-color)}.dropdown-arrow{position:absolute;right:18px;top:50%;width:9px;height:9px;border-right:2px solid #555;border-bottom:2px solid #555;transform:translateY(-65%) rotate(45deg);transition:transform .2s ease}.dropdown-arrow.arrow-up{transform:translateY(-25%) rotate(225deg)}.dropdown-menu{position:absolute;top:calc(100% + 6px);left:0;width:100%;z-index:1000;overflow:hidden;background:var(--dropdown-menu-background);border:1px solid #d0d0d0;border-radius:var(--dropdown-radius);box-shadow:var(--dropdown-shadow)}.dropdown-search{padding:8px;border-bottom:1px solid #eeeeee}.dropdown-search-input{width:100%;height:38px;box-sizing:border-box;padding:0 12px;border:1px solid #cfcfcf;border-radius:5px;outline:none;background:#fff;font-family:var(--dropdown-font-family);font-size:14px}.dropdown-search-input:focus{border-color:var(--dropdown-border-focus)}.dropdown-options{max-height:240px;overflow-y:auto}.dropdown-option{min-height:42px;display:flex;align-items:center;padding:0 14px;box-sizing:border-box;color:var(--dropdown-text-color);font-size:var(--dropdown-font-size);cursor:pointer;transition:background-color .15s ease}.dropdown-option:hover{background:var(--dropdown-option-hover)}.dropdown-option.option-selected{background:var(--dropdown-option-selected);color:var(--dropdown-border-focus);font-weight:600}.dropdown-option.option-disabled{color:#aaa;cursor:not-allowed;background:transparent}.dropdown-no-result{min-height:50px;display:flex;align-items:center;justify-content:center;padding:0 15px;color:#888;font-size:13px}.dropdown-disabled .dropdown-field{background:var(--dropdown-disabled);color:#999;border-color:#d0d0d0;cursor:not-allowed}.dropdown-options::-webkit-scrollbar{width:6px}.dropdown-options::-webkit-scrollbar-thumb{background:#c5c5c5;border-radius:10px}@media(max-width:768px){.dropdown-container{width:100%}.dropdown-field{height:var(--dropdown-height)}}\n"] });
514
588
  }
515
589
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: Dropdown, decorators: [{
516
590
  type: Component,
517
- args: [{ selector: 'lib-dropdown', standalone: true, imports: [], template: "<div\n class=\"dropdown-container\"\n [style.width]=\"width\"\n>\n\n <!-- =========================\n INPUT\n ========================= -->\n\n <div\n class=\"dropdown-input-wrapper\"\n [style.height]=\"height\"\n [class.open]=\"isOpen\"\n >\n\n <!-- Floating label -->\n\n @if (label) {\n\n <label\n class=\"dropdown-label\"\n [class.active]=\"isOpen || value || searchText\"\n >\n {{ label }}\n </label>\n\n }\n\n\n <!-- Search input -->\n\n <input\n class=\"dropdown-input\"\n type=\"text\"\n [placeholder]=\"\n !isOpen && !value\n ? placeholder\n : ''\n \"\n [value]=\"searchText\"\n (input)=\"onInput($event)\"\n (click)=\"openDropdown()\"\n autocomplete=\"off\"\n />\n\n\n <!-- Arrow -->\n\n <button\n type=\"button\"\n class=\"dropdown-arrow\"\n (click)=\"toggleDropdown(); $event.stopPropagation()\"\n aria-label=\"Open dropdown\"\n >\n\n <span\n class=\"arrow\"\n [class.rotate]=\"isOpen\"\n >\n \u2304\n </span>\n\n </button>\n\n </div>\n\n\n <!-- =========================\n DROPDOWN OPTIONS\n ========================= -->\n\n @if (isOpen) {\n\n <div class=\"dropdown-menu\">\n\n @if (filteredOptions.length > 0) {\n\n @for (\n option of filteredOptions;\n track option\n ) {\n\n <button\n type=\"button\"\n class=\"dropdown-option\"\n [class.selected]=\"option === value\"\n (click)=\"selectOption(option)\"\n >\n\n {{ option }}\n\n </button>\n\n }\n\n } @else {\n\n <div class=\"no-results\">\n\n No results found\n\n </div>\n\n }\n\n </div>\n\n }\n\n</div>", styles: [".dropdown-container{position:relative;display:flex;flex-direction:column;box-sizing:border-box;font-family:Arial,Helvetica,sans-serif}.dropdown-input-wrapper{position:relative;width:100%;display:flex;align-items:center;box-sizing:border-box;background:#fff;border:1px solid #999999;border-radius:5px;transition:border-color .2s ease,box-shadow .2s ease}.dropdown-input-wrapper:hover{border-color:#777}.dropdown-input-wrapper.open{border-color:#555;box-shadow:0 0 0 1px #0000000a}.dropdown-input{flex:1;min-width:0;width:100%;height:100%;border:none;outline:none;background:transparent;padding:4px 14px 0;box-sizing:border-box;color:#222;font-size:14px;font-weight:400}.dropdown-input::placeholder{color:#555;opacity:1}.dropdown-label{position:absolute;top:50%;left:13px;transform:translateY(-50%);padding:0 4px;color:#555;background:#fff;font-size:14px;font-weight:400;pointer-events:none;transition:top .15s ease,font-size .15s ease,color .15s ease}.dropdown-label.active{top:0;transform:translateY(-50%);font-size:11px;color:#555}.dropdown-arrow{flex:0 0 40px;width:40px;height:100%;display:flex;align-items:center;justify-content:center;padding:0;margin:0;border:none;background:transparent;cursor:pointer;color:#222}.arrow{display:flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:25px;line-height:15px;font-weight:400;transition:transform .2s ease}.arrow.rotate{transform:rotate(180deg)}.dropdown-arrow:hover .arrow{color:#000}.dropdown-menu{position:absolute;top:calc(100% + 2px);left:0;width:100%;max-height:210px;display:flex;flex-direction:column;overflow-y:auto;padding:5px 0;box-sizing:border-box;background:#fff;border-radius:0 0 14px 14px;box-shadow:0 4px 12px #00000014;z-index:1000}.dropdown-option{width:100%;min-height:38px;display:flex;align-items:center;justify-content:flex-start;padding:0 16px;border:none;outline:none;background:transparent;color:#333;font-family:inherit;font-size:14px;font-weight:400;text-align:left;cursor:pointer;box-sizing:border-box;transition:background-color .15s ease}.dropdown-option:hover{background-color:#f2f2f2}.dropdown-option.selected{background-color:#eee;color:#222}.no-results{min-height:38px;display:flex;align-items:center;padding:0 16px;color:#888;font-size:14px}.dropdown-menu::-webkit-scrollbar{width:5px}.dropdown-menu::-webkit-scrollbar-track{background:transparent}.dropdown-menu::-webkit-scrollbar-thumb{background:#222;border-radius:10px}@media(max-width:768px){.dropdown-input{font-size:14px}.dropdown-option{min-height:40px;padding:0 14px;font-size:14px}.dropdown-menu{max-height:200px}}\n"] }]
518
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{
591
+ args: [{ selector: 'lib-dropdown', standalone: true, imports: [], template: "<div\n class=\"dropdown-container\"\n [class]=\"customClass\"\n [class.dropdown-disabled]=\"disabled\"\n [class.dropdown-open]=\"isOpen\"\n>\n\n <!-- =====================================\n DROPDOWN FIELD\n ===================================== -->\n\n <div\n class=\"dropdown-field\"\n (click)=\"toggleDropdown($event)\"\n >\n\n <!-- Label -->\n\n @if (label) {\n <label class=\"dropdown-label\">\n {{ label }}\n </label>\n }\n\n\n <!-- Selected value -->\n\n <span\n class=\"dropdown-value\"\n [class.dropdown-placeholder]=\"!selectedOption\"\n >\n {{\n selectedOption?.label ||\n placeholder\n }}\n </span>\n\n\n <!-- Arrow -->\n\n <span\n class=\"dropdown-arrow\"\n [class.arrow-up]=\"isOpen\"\n >\n </span>\n\n </div>\n\n\n <!-- =====================================\n DROPDOWN MENU\n ===================================== -->\n\n @if (isOpen) {\n\n <div\n class=\"dropdown-menu\"\n (click)=\"$event.stopPropagation()\"\n >\n\n <!-- Search -->\n\n @if (searchable) {\n\n <div class=\"dropdown-search\">\n\n <input\n type=\"text\"\n class=\"dropdown-search-input\"\n\n placeholder=\"Search...\"\n\n [value]=\"searchText\"\n\n (input)=\"onSearch($event)\"\n />\n\n </div>\n\n }\n\n\n <!-- Options -->\n\n <div class=\"dropdown-options\">\n\n @for (\n option of filteredOptions;\n track option.value\n ) {\n\n <div\n class=\"dropdown-option\"\n\n [class.option-disabled]=\"\n option.disabled\n \"\n\n [class.option-selected]=\"\n option.value === value\n \"\n\n (click)=\"\n selectOption(option, $event)\n \"\n >\n\n {{ option.label }}\n\n </div>\n\n }\n\n\n <!-- No result -->\n\n @if (filteredOptions.length === 0) {\n\n <div class=\"dropdown-no-result\">\n No results found\n </div>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [".dropdown-container{--dropdown-width: 300px;--dropdown-height: 44px;--dropdown-background: #ffffff;--dropdown-border: 1px solid #a9a9a9;--dropdown-border-hover: #777777;--dropdown-border-focus: #68479b;--dropdown-radius: 6px;--dropdown-text-color: #222222;--dropdown-placeholder-color: #777777;--dropdown-menu-background: #ffffff;--dropdown-option-hover: #f3f0f7;--dropdown-option-selected: #eee8f5;--dropdown-disabled: #f5f5f5;--dropdown-font-family: Arial, Helvetica, sans-serif;--dropdown-font-size: 14px;--dropdown-font-weight: 600;--dropdown-shadow: 0 4px 12px rgba(0, 0, 0, .12);position:relative;width:var(--dropdown-width);font-family:var(--dropdown-font-family);box-sizing:border-box}.dropdown-field{position:relative;width:100%;height:var(--dropdown-height);display:flex;align-items:center;box-sizing:border-box;padding:0 48px 0 18px;border:var(--dropdown-border);border-radius:var(--dropdown-radius);background:var(--dropdown-background);color:var(--dropdown-text-color);font-size:var(--dropdown-font-size);font-weight:var(--dropdown-font-weight);cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease}.dropdown-field:hover{border-color:var(--dropdown-border-hover)}.dropdown-open .dropdown-field{border-color:var(--dropdown-border-focus);box-shadow:0 0 0 1px #68479b1f}.dropdown-label{position:absolute;top:0;left:14px;transform:translateY(-50%);padding:0 6px;background:var(--dropdown-background);color:var(--dropdown-border-focus);font-size:13px;font-weight:500;line-height:1;pointer-events:none}.dropdown-value{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--dropdown-text-color)}.dropdown-placeholder{color:var(--dropdown-placeholder-color)}.dropdown-arrow{position:absolute;right:18px;top:50%;width:9px;height:9px;border-right:2px solid #555;border-bottom:2px solid #555;transform:translateY(-65%) rotate(45deg);transition:transform .2s ease}.dropdown-arrow.arrow-up{transform:translateY(-25%) rotate(225deg)}.dropdown-menu{position:absolute;top:calc(100% + 6px);left:0;width:100%;z-index:1000;overflow:hidden;background:var(--dropdown-menu-background);border:1px solid #d0d0d0;border-radius:var(--dropdown-radius);box-shadow:var(--dropdown-shadow)}.dropdown-search{padding:8px;border-bottom:1px solid #eeeeee}.dropdown-search-input{width:100%;height:38px;box-sizing:border-box;padding:0 12px;border:1px solid #cfcfcf;border-radius:5px;outline:none;background:#fff;font-family:var(--dropdown-font-family);font-size:14px}.dropdown-search-input:focus{border-color:var(--dropdown-border-focus)}.dropdown-options{max-height:240px;overflow-y:auto}.dropdown-option{min-height:42px;display:flex;align-items:center;padding:0 14px;box-sizing:border-box;color:var(--dropdown-text-color);font-size:var(--dropdown-font-size);cursor:pointer;transition:background-color .15s ease}.dropdown-option:hover{background:var(--dropdown-option-hover)}.dropdown-option.option-selected{background:var(--dropdown-option-selected);color:var(--dropdown-border-focus);font-weight:600}.dropdown-option.option-disabled{color:#aaa;cursor:not-allowed;background:transparent}.dropdown-no-result{min-height:50px;display:flex;align-items:center;justify-content:center;padding:0 15px;color:#888;font-size:13px}.dropdown-disabled .dropdown-field{background:var(--dropdown-disabled);color:#999;border-color:#d0d0d0;cursor:not-allowed}.dropdown-options::-webkit-scrollbar{width:6px}.dropdown-options::-webkit-scrollbar-thumb{background:#c5c5c5;border-radius:10px}@media(max-width:768px){.dropdown-container{width:100%}.dropdown-field{height:var(--dropdown-height)}}\n"] }]
592
+ }], propDecorators: { label: [{
519
593
  type: Input
520
594
  }], placeholder: [{
521
595
  type: Input
@@ -523,22 +597,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
523
597
  type: Input
524
598
  }], value: [{
525
599
  type: Input
526
- }], width: [{
600
+ }], disabled: [{
527
601
  type: Input
528
- }], height: [{
602
+ }], searchable: [{
603
+ type: Input
604
+ }], customClass: [{
529
605
  type: Input
530
606
  }], valueChange: [{
531
607
  type: Output
532
- }], optionClick: [{
533
- type: Output
534
- }], searchChange: [{
608
+ }], selectionChange: [{
535
609
  type: Output
536
610
  }], openedChange: [{
537
611
  type: Output
612
+ }], clicked: [{
613
+ type: Output
538
614
  }], onDocumentClick: [{
539
615
  type: HostListener,
540
- args: ['document:click',
541
- ['$event']]
616
+ args: ['document:click', ['$event']]
542
617
  }] } });
543
618
 
544
619
  /*