codexly-ui 0.0.31 → 0.0.33

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.
@@ -11,6 +11,7 @@ import { Chart, LineController, BarController, PieController, DoughnutController
11
11
  import * as i1$2 from '@angular/cdk/portal';
12
12
  import { PortalModule, ComponentPortal } from '@angular/cdk/portal';
13
13
  import { FocusTrapFactory } from '@angular/cdk/a11y';
14
+ import { CdkScrollable } from '@angular/cdk/scrolling';
14
15
  import { RouterLink, RouterLinkActive } from '@angular/router';
15
16
 
16
17
  // ── Parse 'red' | 'red-500' → { color, shade } ───────────────────────────────
@@ -1730,7 +1731,7 @@ class ClxCarouselComponent {
1730
1731
  _slides = contentChildren(ClxCarouselDirective, ...(ngDevMode ? [{ debugName: "_slides" }] : []));
1731
1732
  _autoPlayTimer = null;
1732
1733
  _touchStartX = 0;
1733
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
1734
+ _zone;
1734
1735
  _aspectClass = computed(() => CAROUSEL_ASPECT_RATIO_MAP[this.aspectRatio()] ?? '', ...(ngDevMode ? [{ debugName: "_aspectClass" }] : []));
1735
1736
  _viewportClass = computed(() => {
1736
1737
  const base = this._aspectClass();
@@ -1747,6 +1748,8 @@ class ClxCarouselComponent {
1747
1748
  }));
1748
1749
  }, ...(ngDevMode ? [{ debugName: "_dotItems" }] : []));
1749
1750
  constructor() {
1751
+ const zone = inject(NgZone, { optional: true });
1752
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
1750
1753
  effect(() => {
1751
1754
  const active = this.autoPlay();
1752
1755
  const ms = this.interval();
@@ -4935,7 +4938,11 @@ class ClxAlertComponent {
4935
4938
  _resolve = inject(CLX_ALERT_RESOLVE);
4936
4939
  _animate = inject(ClxAnimateService);
4937
4940
  _el = inject((ElementRef));
4938
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
4941
+ _zone;
4942
+ constructor() {
4943
+ const zone = inject(NgZone, { optional: true });
4944
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
4945
+ }
4939
4946
  // ─── Resolved options ─────────────────────────────────────────────────────
4940
4947
  get _type() { return this._opts.type ?? 'info'; }
4941
4948
  _icon = signal(ALERT_ICON_MAP[this._type], ...(ngDevMode ? [{ debugName: "_icon" }] : []));
@@ -5156,7 +5163,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
5156
5163
  }
5157
5164
  </div>
5158
5165
  `, styles: ["clx-alert{display:flex;align-items:center;justify-content:center;width:100%}.clx-alert-card{will-change:transform,opacity}\n"] }]
5159
- }] });
5166
+ }], ctorParameters: () => [] });
5160
5167
 
5161
5168
  const MODAL_SIZE_MAP = {
5162
5169
  sm: 'w-full max-w-[400px]',
@@ -5983,7 +5990,11 @@ class ClxToastComponent {
5983
5990
  dismiss = output();
5984
5991
  _animate = inject(ClxAnimateService);
5985
5992
  _el = inject((ElementRef));
5986
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
5993
+ _zone;
5994
+ constructor() {
5995
+ const zone = inject(NgZone, { optional: true });
5996
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
5997
+ }
5987
5998
  // ─── Timer state ──────────────────────────────────────────────────────────
5988
5999
  _progressPct = signal(100, ...(ngDevMode ? [{ debugName: "_progressPct" }] : []));
5989
6000
  _timerHandle = null;
@@ -6203,7 +6214,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
6203
6214
  }
6204
6215
  </div>
6205
6216
  `, styles: ["clx-toast{display:block;width:100%}.clx-toast-card{will-change:transform,opacity}\n"] }]
6206
- }], propDecorators: { entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
6217
+ }], ctorParameters: () => [], propDecorators: { entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
6207
6218
 
6208
6219
  class ClxToastContainerComponent {
6209
6220
  entries = model([], ...(ngDevMode ? [{ debugName: "entries" }] : []));
@@ -9065,7 +9076,7 @@ class ClxEditorComponent {
9065
9076
  _sourceEl;
9066
9077
  // ── Services ─────────────────────────────────────────────────────────────
9067
9078
  _cdr = inject(ChangeDetectorRef);
9068
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
9079
+ _zone;
9069
9080
  _destroyRef = inject(DestroyRef);
9070
9081
  _modal = inject(ClxModalService);
9071
9082
  // ── Select options ────────────────────────────────────────────────────────
@@ -9089,6 +9100,10 @@ class ClxEditorComponent {
9089
9100
  _copiedTimer = null;
9090
9101
  _onChange = () => { };
9091
9102
  _onTouched = () => { };
9103
+ constructor() {
9104
+ const zone = inject(NgZone, { optional: true });
9105
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
9106
+ }
9092
9107
  // ── Lifecycle ─────────────────────────────────────────────────────────────
9093
9108
  ngAfterViewInit() {
9094
9109
  document.execCommand('defaultParagraphSeparator', false, 'p');
@@ -9726,7 +9741,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
9726
9741
  <p [class]="_sizeCfg().hint + ' text-gray-400'">{{ hint() }}</p>
9727
9742
  }
9728
9743
  `, host: { class: 'flex flex-col gap-1.5' }, styles: [".clx-editor-body:empty:before{content:attr(data-placeholder);color:#9ca3af;pointer-events:none}.clx-editor-body:focus{outline:none}.clx-editor-body p{margin:0 0 .4em}.clx-editor-body p:last-child{margin-bottom:0}.clx-editor-body h1{font-size:1.5em;font-weight:700;margin:.5em 0}.clx-editor-body h2{font-size:1.25em;font-weight:600;margin:.5em 0}.clx-editor-body h3{font-size:1.1em;font-weight:600;margin:.5em 0}.clx-editor-body ul,.clx-editor-body ol{padding-left:1.5em;margin:.35em 0}.clx-editor-body li{margin:.1em 0}.clx-editor-body blockquote{border-left:3px solid #e2e8f0;padding-left:.75em;color:#64748b;margin:.4em 0}.clx-editor-body code{background:#f1f5f9;border-radius:3px;padding:.1em .3em;font-size:.875em;font-family:ui-monospace,monospace}.clx-editor-body a{color:#6366f1;text-decoration:underline}.clx-editor-body hr{border:none;border-top:1px solid #e2e8f0;margin:.6em 0}.clx-editor-color-btn{position:relative;overflow:hidden}.clx-editor-color-btn input[type=color]{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer;border:none;padding:0}.clx-editor-toolbar-select clx-select .flex.flex-col{gap:0!important}.clx-editor-source{width:100%;resize:none;border:none;outline:none;background:#0f172a;color:#e2e8f0;font-family:ui-monospace,Cascadia Code,Fira Code,monospace;font-size:.8125rem;line-height:1.6;padding:1rem;tab-size:2}\n"] }]
9729
- }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], statusMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusMessage", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], _bodyEl: [{
9744
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], statusMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusMessage", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], _bodyEl: [{
9730
9745
  type: ViewChild,
9731
9746
  args: ['bodyEl', { static: false }]
9732
9747
  }], _sourceEl: [{
@@ -10881,7 +10896,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
10881
10896
  }] } });
10882
10897
 
10883
10898
  class ClxAppLayoutComponent {
10884
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
10899
+ _zone;
10885
10900
  _document = inject(DOCUMENT);
10886
10901
  activeColor = input('indigo', ...(ngDevMode ? [{ debugName: "activeColor" }] : []));
10887
10902
  _sidebarOpen = signal(false, ...(ngDevMode ? [{ debugName: "_sidebarOpen" }] : []));
@@ -10890,6 +10905,10 @@ class ClxAppLayoutComponent {
10890
10905
  _isMobile = signal(true, ...(ngDevMode ? [{ debugName: "_isMobile" }] : []));
10891
10906
  collapsedChange = output();
10892
10907
  expandedChange = output();
10908
+ constructor() {
10909
+ const zone = inject(NgZone, { optional: true });
10910
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
10911
+ }
10893
10912
  _showBackdrop = computed(() => this._sidebarOpen() && this._isMobile(), ...(ngDevMode ? [{ debugName: "_showBackdrop" }] : []));
10894
10913
  _isExpanded = computed(() => !this.collapsed() || this._hovered(), ...(ngDevMode ? [{ debugName: "_isExpanded" }] : []));
10895
10914
  _sidebarCls = computed(() => {
@@ -11014,19 +11033,19 @@ class ClxAppLayoutComponent {
11014
11033
  <ng-content select="[clx-header]"></ng-content>
11015
11034
  </header>
11016
11035
 
11017
- <main class="flex-1 overflow-y-auto bg-white">
11036
+ <main cdkScrollable class="flex-1 overflow-y-auto bg-white">
11018
11037
  <ng-content></ng-content>
11019
11038
  </main>
11020
11039
 
11021
11040
  </div>
11022
- `, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11041
+ `, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "directive", type: CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11023
11042
  }
11024
11043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImport: i0, type: ClxAppLayoutComponent, decorators: [{
11025
11044
  type: Component,
11026
11045
  args: [{
11027
11046
  selector: 'clx-app-layout',
11028
11047
  standalone: true,
11029
- imports: [ClxIconComponent],
11048
+ imports: [ClxIconComponent, CdkScrollable],
11030
11049
  template: `
11031
11050
  <!-- Mobile backdrop -->
11032
11051
  @if (_showBackdrop()) {
@@ -11076,7 +11095,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
11076
11095
  <ng-content select="[clx-header]"></ng-content>
11077
11096
  </header>
11078
11097
 
11079
- <main class="flex-1 overflow-y-auto bg-white">
11098
+ <main cdkScrollable class="flex-1 overflow-y-auto bg-white">
11080
11099
  <ng-content></ng-content>
11081
11100
  </main>
11082
11101
 
@@ -11086,7 +11105,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
11086
11105
  changeDetection: ChangeDetectionStrategy.OnPush,
11087
11106
  host: { class: 'flex h-screen overflow-hidden' },
11088
11107
  }]
11089
- }], propDecorators: { activeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeColor", required: false }] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }] } });
11108
+ }], ctorParameters: () => [], propDecorators: { activeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeColor", required: false }] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }] } });
11090
11109
 
11091
11110
  class ClxBrandComponent {
11092
11111
  logo = input.required(...(ngDevMode ? [{ debugName: "logo" }] : []));
@@ -11470,6 +11489,251 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
11470
11489
  }]
11471
11490
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }] } });
11472
11491
 
11492
+ class ClxProfileComponent {
11493
+ // ── Inputs ──────────────────────────────────────────────────────────────────
11494
+ firstName = input('', ...(ngDevMode ? [{ debugName: "firstName" }] : []));
11495
+ lastName = input('', ...(ngDevMode ? [{ debugName: "lastName" }] : []));
11496
+ username = input('', ...(ngDevMode ? [{ debugName: "username" }] : []));
11497
+ role = input('', ...(ngDevMode ? [{ debugName: "role" }] : []));
11498
+ avatarSrc = input(null, ...(ngDevMode ? [{ debugName: "avatarSrc" }] : []));
11499
+ color = input('indigo', ...(ngDevMode ? [{ debugName: "color" }] : []));
11500
+ menuItems = input([], ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
11501
+ signOutLabel = input('Cerrar sesión', ...(ngDevMode ? [{ debugName: "signOutLabel" }] : []));
11502
+ // ── Outputs ─────────────────────────────────────────────────────────────────
11503
+ menuAction = output();
11504
+ signOut = output();
11505
+ // ── CDK Overlay ─────────────────────────────────────────────────────────────
11506
+ _sso = inject(ScrollStrategyOptions);
11507
+ _scrollStrategy = this._sso.reposition();
11508
+ _positions = [
11509
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 8 },
11510
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -8 },
11511
+ ];
11512
+ // ── State ────────────────────────────────────────────────────────────────────
11513
+ _isOpen = signal(false, ...(ngDevMode ? [{ debugName: "_isOpen" }] : []));
11514
+ // ── Computed ─────────────────────────────────────────────────────────────────
11515
+ fullName = computed(() => `${this.firstName()} ${this.lastName()}`.trim() || this.username(), ...(ngDevMode ? [{ debugName: "fullName" }] : []));
11516
+ _initials = computed(() => {
11517
+ const f = this.firstName().charAt(0).toUpperCase();
11518
+ const l = this.lastName().charAt(0).toUpperCase();
11519
+ return f && l ? `${f}${l}` : (f || this.username().charAt(0).toUpperCase());
11520
+ }, ...(ngDevMode ? [{ debugName: "_initials" }] : []));
11521
+ _ringClass = computed(() => {
11522
+ const t = resolveColor(this.color());
11523
+ return `focus-visible:${t.ringBase}`;
11524
+ }, ...(ngDevMode ? [{ debugName: "_ringClass" }] : []));
11525
+ _headerBgClass = computed(() => {
11526
+ const t = resolveColor(this.color());
11527
+ return `${t.bgSubtle}`;
11528
+ }, ...(ngDevMode ? [{ debugName: "_headerBgClass" }] : []));
11529
+ _badgeClass = computed(() => {
11530
+ const t = resolveColor(this.color());
11531
+ return `${t.bgSubtle} ${t.textSubtle}`;
11532
+ }, ...(ngDevMode ? [{ debugName: "_badgeClass" }] : []));
11533
+ _itemHoverClass = computed(() => {
11534
+ const t = resolveColor(this.color());
11535
+ return t.hoverBgSubtle;
11536
+ }, ...(ngDevMode ? [{ debugName: "_itemHoverClass" }] : []));
11537
+ _signOutClass = computed(() => 'text-red-600 hover:text-red-700 hover:bg-red-50', ...(ngDevMode ? [{ debugName: "_signOutClass" }] : []));
11538
+ // ── Methods ──────────────────────────────────────────────────────────────────
11539
+ _toggle() { this._isOpen.update(v => !v); }
11540
+ _close() { this._isOpen.set(false); }
11541
+ _onKeydown(event) {
11542
+ if (event.key === 'Escape')
11543
+ this._close();
11544
+ }
11545
+ _onAction(action) {
11546
+ this.menuAction.emit(action);
11547
+ this._close();
11548
+ }
11549
+ _onSignOut() {
11550
+ this.signOut.emit();
11551
+ this._close();
11552
+ }
11553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.23", ngImport: i0, type: ClxProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11554
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.23", type: ClxProfileComponent, isStandalone: true, selector: "clx-profile", inputs: { firstName: { classPropertyName: "firstName", publicName: "firstName", isSignal: true, isRequired: false, transformFunction: null }, lastName: { classPropertyName: "lastName", publicName: "lastName", isSignal: true, isRequired: false, transformFunction: null }, username: { classPropertyName: "username", publicName: "username", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, signOutLabel: { classPropertyName: "signOutLabel", publicName: "signOutLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuAction: "menuAction", signOut: "signOut" }, host: { classAttribute: "relative inline-flex items-center" }, ngImport: i0, template: `
11555
+ <!-- ── Trigger ─────────────────────────────────────────────────────────── -->
11556
+ <button
11557
+ #origin="cdkOverlayOrigin"
11558
+ cdkOverlayOrigin
11559
+ type="button"
11560
+ class="flex items-center gap-2 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 cursor-pointer"
11561
+ [class]="_ringClass()"
11562
+ (click)="_toggle()">
11563
+ <clx-avatar
11564
+ [initials]="_initials()"
11565
+ [src]="avatarSrc()"
11566
+ [color]="color()"
11567
+ size="sm" />
11568
+ </button>
11569
+
11570
+ <!-- ── Overlay panel ─────────────────────────────────────────────────── -->
11571
+ <ng-template
11572
+ cdkConnectedOverlay
11573
+ [cdkConnectedOverlayOrigin]="origin"
11574
+ [cdkConnectedOverlayOpen]="_isOpen()"
11575
+ [cdkConnectedOverlayPositions]="_positions"
11576
+ [cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
11577
+ [cdkConnectedOverlayPush]="true"
11578
+ (overlayOutsideClick)="_close()"
11579
+ (overlayKeydown)="_onKeydown($event)">
11580
+
11581
+ <div class="w-64 bg-white rounded-2xl shadow-xl border border-slate-200 overflow-hidden mt-2">
11582
+
11583
+ <!-- Header: avatar + name + role -->
11584
+ <div class="px-4 py-4 flex items-center gap-3" [class]="_headerBgClass()">
11585
+ <clx-avatar
11586
+ [initials]="_initials()"
11587
+ [src]="avatarSrc()"
11588
+ [color]="color()"
11589
+ size="md" />
11590
+ <div class="flex-1 min-w-0">
11591
+ <p class="text-sm font-semibold text-slate-800 truncate">{{ fullName() }}</p>
11592
+ <p class="text-xs text-slate-500 truncate">{{ username() }}</p>
11593
+ @if (role()) {
11594
+ <span class="inline-flex items-center mt-1 px-2 py-0.5 rounded-full text-xs font-medium"
11595
+ [class]="_badgeClass()">
11596
+ {{ role() }}
11597
+ </span>
11598
+ }
11599
+ </div>
11600
+ </div>
11601
+
11602
+ <!-- Divider -->
11603
+ <div class="border-t border-slate-100"></div>
11604
+
11605
+ <!-- Menu items -->
11606
+ @if (menuItems().length) {
11607
+ <div class="p-1.5">
11608
+ @for (item of menuItems(); track item.action) {
11609
+ <button
11610
+ type="button"
11611
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-slate-700 hover:text-slate-900 transition-colors text-left group"
11612
+ [class]="_itemHoverClass()"
11613
+ (click)="_onAction(item.action)">
11614
+ <span clx-icon [name]="item.icon" size="sm"
11615
+ class="text-slate-400 group-hover:text-slate-600 transition-colors"></span>
11616
+ {{ item.label }}
11617
+ </button>
11618
+ }
11619
+ </div>
11620
+ <!-- Divider before signout -->
11621
+ <div class="border-t border-slate-100 mx-3"></div>
11622
+ }
11623
+
11624
+ <!-- Sign out -->
11625
+ <div class="p-1.5">
11626
+ <button
11627
+ type="button"
11628
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors text-left"
11629
+ [class]="_signOutClass()"
11630
+ (click)="_onSignOut()">
11631
+ <span clx-icon name="logout" size="sm"></span>
11632
+ {{ signOutLabel() }}
11633
+ </button>
11634
+ </div>
11635
+
11636
+ </div>
11637
+ </ng-template>
11638
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ClxAvatarComponent, selector: "clx-avatar", inputs: ["src", "initials", "iconName", "color", "size", "shape", "alt"] }, { kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11639
+ }
11640
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImport: i0, type: ClxProfileComponent, decorators: [{
11641
+ type: Component,
11642
+ args: [{
11643
+ selector: 'clx-profile',
11644
+ standalone: true,
11645
+ imports: [OverlayModule, ClxAvatarComponent, ClxIconComponent, ClxButtonComponent],
11646
+ template: `
11647
+ <!-- ── Trigger ─────────────────────────────────────────────────────────── -->
11648
+ <button
11649
+ #origin="cdkOverlayOrigin"
11650
+ cdkOverlayOrigin
11651
+ type="button"
11652
+ class="flex items-center gap-2 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 cursor-pointer"
11653
+ [class]="_ringClass()"
11654
+ (click)="_toggle()">
11655
+ <clx-avatar
11656
+ [initials]="_initials()"
11657
+ [src]="avatarSrc()"
11658
+ [color]="color()"
11659
+ size="sm" />
11660
+ </button>
11661
+
11662
+ <!-- ── Overlay panel ─────────────────────────────────────────────────── -->
11663
+ <ng-template
11664
+ cdkConnectedOverlay
11665
+ [cdkConnectedOverlayOrigin]="origin"
11666
+ [cdkConnectedOverlayOpen]="_isOpen()"
11667
+ [cdkConnectedOverlayPositions]="_positions"
11668
+ [cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
11669
+ [cdkConnectedOverlayPush]="true"
11670
+ (overlayOutsideClick)="_close()"
11671
+ (overlayKeydown)="_onKeydown($event)">
11672
+
11673
+ <div class="w-64 bg-white rounded-2xl shadow-xl border border-slate-200 overflow-hidden mt-2">
11674
+
11675
+ <!-- Header: avatar + name + role -->
11676
+ <div class="px-4 py-4 flex items-center gap-3" [class]="_headerBgClass()">
11677
+ <clx-avatar
11678
+ [initials]="_initials()"
11679
+ [src]="avatarSrc()"
11680
+ [color]="color()"
11681
+ size="md" />
11682
+ <div class="flex-1 min-w-0">
11683
+ <p class="text-sm font-semibold text-slate-800 truncate">{{ fullName() }}</p>
11684
+ <p class="text-xs text-slate-500 truncate">{{ username() }}</p>
11685
+ @if (role()) {
11686
+ <span class="inline-flex items-center mt-1 px-2 py-0.5 rounded-full text-xs font-medium"
11687
+ [class]="_badgeClass()">
11688
+ {{ role() }}
11689
+ </span>
11690
+ }
11691
+ </div>
11692
+ </div>
11693
+
11694
+ <!-- Divider -->
11695
+ <div class="border-t border-slate-100"></div>
11696
+
11697
+ <!-- Menu items -->
11698
+ @if (menuItems().length) {
11699
+ <div class="p-1.5">
11700
+ @for (item of menuItems(); track item.action) {
11701
+ <button
11702
+ type="button"
11703
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-slate-700 hover:text-slate-900 transition-colors text-left group"
11704
+ [class]="_itemHoverClass()"
11705
+ (click)="_onAction(item.action)">
11706
+ <span clx-icon [name]="item.icon" size="sm"
11707
+ class="text-slate-400 group-hover:text-slate-600 transition-colors"></span>
11708
+ {{ item.label }}
11709
+ </button>
11710
+ }
11711
+ </div>
11712
+ <!-- Divider before signout -->
11713
+ <div class="border-t border-slate-100 mx-3"></div>
11714
+ }
11715
+
11716
+ <!-- Sign out -->
11717
+ <div class="p-1.5">
11718
+ <button
11719
+ type="button"
11720
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors text-left"
11721
+ [class]="_signOutClass()"
11722
+ (click)="_onSignOut()">
11723
+ <span clx-icon name="logout" size="sm"></span>
11724
+ {{ signOutLabel() }}
11725
+ </button>
11726
+ </div>
11727
+
11728
+ </div>
11729
+ </ng-template>
11730
+ `,
11731
+ encapsulation: ViewEncapsulation.None,
11732
+ changeDetection: ChangeDetectionStrategy.OnPush,
11733
+ host: { class: 'relative inline-flex items-center' },
11734
+ }]
11735
+ }], propDecorators: { firstName: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstName", required: false }] }], lastName: [{ type: i0.Input, args: [{ isSignal: true, alias: "lastName", required: false }] }], username: [{ type: i0.Input, args: [{ isSignal: true, alias: "username", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: false }] }], signOutLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "signOutLabel", required: false }] }], menuAction: [{ type: i0.Output, args: ["menuAction"] }], signOut: [{ type: i0.Output, args: ["signOut"] }] } });
11736
+
11473
11737
  // ── Base classes ─────────────────────────────────────────────────────────────
11474
11738
  const TABLE_BASE_CLASS = 'w-full text-left border-collapse text-sm';
11475
11739
  const TABLE_HEADER_CELL_CLASS = 'px-4 py-3 font-semibold whitespace-nowrap';
@@ -14088,5 +14352,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
14088
14352
  * Generated bundle index. Do not edit.
14089
14353
  */
14090
14354
 
14091
- export { CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_COLOR_HEX, CLX_COLOR_MAP, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_RADIO_GROUP, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardFooterDirective, ClxCardHeaderDirective, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxChartComponent, ClxCheckboxComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorLinkModalComponent, ClxFilterPanelComponent, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxModalComponent, ClxModalService, ClxNavGroupComponent, ClxNumberComponent, ClxPageEmptyComponent, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableComponent, ClxTabsComponent, ClxTagComponent, ClxTextareaComponent, ClxTimelineComponent, ClxTimelineItemComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWishlistComponent, ClxWizardComponent, parseColorInput, resolveColor };
14355
+ export { CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_COLOR_HEX, CLX_COLOR_MAP, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_RADIO_GROUP, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardFooterDirective, ClxCardHeaderDirective, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxChartComponent, ClxCheckboxComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorLinkModalComponent, ClxFilterPanelComponent, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxModalComponent, ClxModalService, ClxNavGroupComponent, ClxNumberComponent, ClxPageEmptyComponent, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProfileComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableComponent, ClxTabsComponent, ClxTagComponent, ClxTextareaComponent, ClxTimelineComponent, ClxTimelineItemComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWishlistComponent, ClxWizardComponent, parseColorInput, resolveColor };
14092
14356
  //# sourceMappingURL=codexly-ui.mjs.map