codexly-ui 0.0.32 → 0.0.34

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.
@@ -145,9 +145,15 @@ const CLX_COLOR_HEX = {
145
145
  };
146
146
 
147
147
  const BADGE_SIZE_MAP = {
148
+ xs: 'text-[10px] px-1.5 py-0.5',
148
149
  sm: 'text-xs px-2 py-1',
149
150
  md: 'text-xs px-2.5 py-1 font-medium',
150
151
  };
152
+ const BADGE_CIRCLE_SIZE_MAP = {
153
+ xs: 'text-[10px] w-4 h-4',
154
+ sm: 'text-xs w-5 h-5',
155
+ md: 'text-xs w-6 h-6 font-medium',
156
+ };
151
157
  const BADGE_SHAPE_MAP = {
152
158
  rounded: 'rounded',
153
159
  pill: 'rounded-md',
@@ -163,7 +169,8 @@ class ClxBadgeComponent {
163
169
  _hostClass = computed(() => {
164
170
  const t = resolveColor(this.color());
165
171
  const variant = this.variant();
166
- const sizeClass = BADGE_SIZE_MAP[this.size()];
172
+ const isCircle = this.shape() === 'circle';
173
+ const sizeClass = isCircle ? BADGE_CIRCLE_SIZE_MAP[this.size()] : BADGE_SIZE_MAP[this.size()];
167
174
  const shapeClass = BADGE_SHAPE_MAP[this.shape()];
168
175
  const posClass = this.positioned()
169
176
  ? 'absolute top-0 right-0 translate-x-1/2 -translate-y-1/2'
@@ -1731,7 +1738,7 @@ class ClxCarouselComponent {
1731
1738
  _slides = contentChildren(ClxCarouselDirective, ...(ngDevMode ? [{ debugName: "_slides" }] : []));
1732
1739
  _autoPlayTimer = null;
1733
1740
  _touchStartX = 0;
1734
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
1741
+ _zone;
1735
1742
  _aspectClass = computed(() => CAROUSEL_ASPECT_RATIO_MAP[this.aspectRatio()] ?? '', ...(ngDevMode ? [{ debugName: "_aspectClass" }] : []));
1736
1743
  _viewportClass = computed(() => {
1737
1744
  const base = this._aspectClass();
@@ -1748,6 +1755,8 @@ class ClxCarouselComponent {
1748
1755
  }));
1749
1756
  }, ...(ngDevMode ? [{ debugName: "_dotItems" }] : []));
1750
1757
  constructor() {
1758
+ const zone = inject(NgZone, { optional: true });
1759
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
1751
1760
  effect(() => {
1752
1761
  const active = this.autoPlay();
1753
1762
  const ms = this.interval();
@@ -4936,7 +4945,11 @@ class ClxAlertComponent {
4936
4945
  _resolve = inject(CLX_ALERT_RESOLVE);
4937
4946
  _animate = inject(ClxAnimateService);
4938
4947
  _el = inject((ElementRef));
4939
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
4948
+ _zone;
4949
+ constructor() {
4950
+ const zone = inject(NgZone, { optional: true });
4951
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
4952
+ }
4940
4953
  // ─── Resolved options ─────────────────────────────────────────────────────
4941
4954
  get _type() { return this._opts.type ?? 'info'; }
4942
4955
  _icon = signal(ALERT_ICON_MAP[this._type], ...(ngDevMode ? [{ debugName: "_icon" }] : []));
@@ -5157,7 +5170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
5157
5170
  }
5158
5171
  </div>
5159
5172
  `, styles: ["clx-alert{display:flex;align-items:center;justify-content:center;width:100%}.clx-alert-card{will-change:transform,opacity}\n"] }]
5160
- }] });
5173
+ }], ctorParameters: () => [] });
5161
5174
 
5162
5175
  const MODAL_SIZE_MAP = {
5163
5176
  sm: 'w-full max-w-[400px]',
@@ -5984,7 +5997,11 @@ class ClxToastComponent {
5984
5997
  dismiss = output();
5985
5998
  _animate = inject(ClxAnimateService);
5986
5999
  _el = inject((ElementRef));
5987
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
6000
+ _zone;
6001
+ constructor() {
6002
+ const zone = inject(NgZone, { optional: true });
6003
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
6004
+ }
5988
6005
  // ─── Timer state ──────────────────────────────────────────────────────────
5989
6006
  _progressPct = signal(100, ...(ngDevMode ? [{ debugName: "_progressPct" }] : []));
5990
6007
  _timerHandle = null;
@@ -6204,7 +6221,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
6204
6221
  }
6205
6222
  </div>
6206
6223
  `, styles: ["clx-toast{display:block;width:100%}.clx-toast-card{will-change:transform,opacity}\n"] }]
6207
- }], propDecorators: { entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
6224
+ }], ctorParameters: () => [], propDecorators: { entry: [{ type: i0.Input, args: [{ isSignal: true, alias: "entry", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
6208
6225
 
6209
6226
  class ClxToastContainerComponent {
6210
6227
  entries = model([], ...(ngDevMode ? [{ debugName: "entries" }] : []));
@@ -9066,7 +9083,7 @@ class ClxEditorComponent {
9066
9083
  _sourceEl;
9067
9084
  // ── Services ─────────────────────────────────────────────────────────────
9068
9085
  _cdr = inject(ChangeDetectorRef);
9069
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
9086
+ _zone;
9070
9087
  _destroyRef = inject(DestroyRef);
9071
9088
  _modal = inject(ClxModalService);
9072
9089
  // ── Select options ────────────────────────────────────────────────────────
@@ -9090,6 +9107,10 @@ class ClxEditorComponent {
9090
9107
  _copiedTimer = null;
9091
9108
  _onChange = () => { };
9092
9109
  _onTouched = () => { };
9110
+ constructor() {
9111
+ const zone = inject(NgZone, { optional: true });
9112
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
9113
+ }
9093
9114
  // ── Lifecycle ─────────────────────────────────────────────────────────────
9094
9115
  ngAfterViewInit() {
9095
9116
  document.execCommand('defaultParagraphSeparator', false, 'p');
@@ -9727,7 +9748,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
9727
9748
  <p [class]="_sizeCfg().hint + ' text-gray-400'">{{ hint() }}</p>
9728
9749
  }
9729
9750
  `, 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"] }]
9730
- }], 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: [{
9751
+ }], 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: [{
9731
9752
  type: ViewChild,
9732
9753
  args: ['bodyEl', { static: false }]
9733
9754
  }], _sourceEl: [{
@@ -10882,7 +10903,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
10882
10903
  }] } });
10883
10904
 
10884
10905
  class ClxAppLayoutComponent {
10885
- _zone = inject(NgZone, { optional: true }) ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
10906
+ _zone;
10886
10907
  _document = inject(DOCUMENT);
10887
10908
  activeColor = input('indigo', ...(ngDevMode ? [{ debugName: "activeColor" }] : []));
10888
10909
  _sidebarOpen = signal(false, ...(ngDevMode ? [{ debugName: "_sidebarOpen" }] : []));
@@ -10891,6 +10912,10 @@ class ClxAppLayoutComponent {
10891
10912
  _isMobile = signal(true, ...(ngDevMode ? [{ debugName: "_isMobile" }] : []));
10892
10913
  collapsedChange = output();
10893
10914
  expandedChange = output();
10915
+ constructor() {
10916
+ const zone = inject(NgZone, { optional: true });
10917
+ this._zone = zone ?? { run: (fn) => fn(), runOutsideAngular: (fn) => fn() };
10918
+ }
10894
10919
  _showBackdrop = computed(() => this._sidebarOpen() && this._isMobile(), ...(ngDevMode ? [{ debugName: "_showBackdrop" }] : []));
10895
10920
  _isExpanded = computed(() => !this.collapsed() || this._hovered(), ...(ngDevMode ? [{ debugName: "_isExpanded" }] : []));
10896
10921
  _sidebarCls = computed(() => {
@@ -11087,7 +11112,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
11087
11112
  changeDetection: ChangeDetectionStrategy.OnPush,
11088
11113
  host: { class: 'flex h-screen overflow-hidden' },
11089
11114
  }]
11090
- }], propDecorators: { activeColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeColor", required: false }] }], collapsedChange: [{ type: i0.Output, args: ["collapsedChange"] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }] } });
11115
+ }], 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"] }] } });
11091
11116
 
11092
11117
  class ClxBrandComponent {
11093
11118
  logo = input.required(...(ngDevMode ? [{ debugName: "logo" }] : []));
@@ -11471,6 +11496,251 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
11471
11496
  }]
11472
11497
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }] } });
11473
11498
 
11499
+ class ClxProfileComponent {
11500
+ // ── Inputs ──────────────────────────────────────────────────────────────────
11501
+ firstName = input('', ...(ngDevMode ? [{ debugName: "firstName" }] : []));
11502
+ lastName = input('', ...(ngDevMode ? [{ debugName: "lastName" }] : []));
11503
+ username = input('', ...(ngDevMode ? [{ debugName: "username" }] : []));
11504
+ role = input('', ...(ngDevMode ? [{ debugName: "role" }] : []));
11505
+ avatarSrc = input(null, ...(ngDevMode ? [{ debugName: "avatarSrc" }] : []));
11506
+ color = input('indigo', ...(ngDevMode ? [{ debugName: "color" }] : []));
11507
+ menuItems = input([], ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
11508
+ signOutLabel = input('Cerrar sesión', ...(ngDevMode ? [{ debugName: "signOutLabel" }] : []));
11509
+ // ── Outputs ─────────────────────────────────────────────────────────────────
11510
+ menuAction = output();
11511
+ signOut = output();
11512
+ // ── CDK Overlay ─────────────────────────────────────────────────────────────
11513
+ _sso = inject(ScrollStrategyOptions);
11514
+ _scrollStrategy = this._sso.reposition();
11515
+ _positions = [
11516
+ { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 8 },
11517
+ { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -8 },
11518
+ ];
11519
+ // ── State ────────────────────────────────────────────────────────────────────
11520
+ _isOpen = signal(false, ...(ngDevMode ? [{ debugName: "_isOpen" }] : []));
11521
+ // ── Computed ─────────────────────────────────────────────────────────────────
11522
+ fullName = computed(() => `${this.firstName()} ${this.lastName()}`.trim() || this.username(), ...(ngDevMode ? [{ debugName: "fullName" }] : []));
11523
+ _initials = computed(() => {
11524
+ const f = this.firstName().charAt(0).toUpperCase();
11525
+ const l = this.lastName().charAt(0).toUpperCase();
11526
+ return f && l ? `${f}${l}` : (f || this.username().charAt(0).toUpperCase());
11527
+ }, ...(ngDevMode ? [{ debugName: "_initials" }] : []));
11528
+ _ringClass = computed(() => {
11529
+ const t = resolveColor(this.color());
11530
+ return `focus-visible:${t.ringBase}`;
11531
+ }, ...(ngDevMode ? [{ debugName: "_ringClass" }] : []));
11532
+ _headerBgClass = computed(() => {
11533
+ const t = resolveColor(this.color());
11534
+ return `${t.bgSubtle}`;
11535
+ }, ...(ngDevMode ? [{ debugName: "_headerBgClass" }] : []));
11536
+ _badgeClass = computed(() => {
11537
+ const t = resolveColor(this.color());
11538
+ return `${t.bgSubtle} ${t.textSubtle}`;
11539
+ }, ...(ngDevMode ? [{ debugName: "_badgeClass" }] : []));
11540
+ _itemHoverClass = computed(() => {
11541
+ const t = resolveColor(this.color());
11542
+ return t.hoverBgSubtle;
11543
+ }, ...(ngDevMode ? [{ debugName: "_itemHoverClass" }] : []));
11544
+ _signOutClass = computed(() => 'text-red-600 hover:text-red-700 hover:bg-red-50', ...(ngDevMode ? [{ debugName: "_signOutClass" }] : []));
11545
+ // ── Methods ──────────────────────────────────────────────────────────────────
11546
+ _toggle() { this._isOpen.update(v => !v); }
11547
+ _close() { this._isOpen.set(false); }
11548
+ _onKeydown(event) {
11549
+ if (event.key === 'Escape')
11550
+ this._close();
11551
+ }
11552
+ _onAction(action) {
11553
+ this.menuAction.emit(action);
11554
+ this._close();
11555
+ }
11556
+ _onSignOut() {
11557
+ this.signOut.emit();
11558
+ this._close();
11559
+ }
11560
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.23", ngImport: i0, type: ClxProfileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11561
+ 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: `
11562
+ <!-- ── Trigger ─────────────────────────────────────────────────────────── -->
11563
+ <button
11564
+ #origin="cdkOverlayOrigin"
11565
+ cdkOverlayOrigin
11566
+ type="button"
11567
+ class="flex items-center gap-2 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 cursor-pointer"
11568
+ [class]="_ringClass()"
11569
+ (click)="_toggle()">
11570
+ <clx-avatar
11571
+ [initials]="_initials()"
11572
+ [src]="avatarSrc()"
11573
+ [color]="color()"
11574
+ size="sm" />
11575
+ </button>
11576
+
11577
+ <!-- ── Overlay panel ─────────────────────────────────────────────────── -->
11578
+ <ng-template
11579
+ cdkConnectedOverlay
11580
+ [cdkConnectedOverlayOrigin]="origin"
11581
+ [cdkConnectedOverlayOpen]="_isOpen()"
11582
+ [cdkConnectedOverlayPositions]="_positions"
11583
+ [cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
11584
+ [cdkConnectedOverlayPush]="true"
11585
+ (overlayOutsideClick)="_close()"
11586
+ (overlayKeydown)="_onKeydown($event)">
11587
+
11588
+ <div class="w-64 bg-white rounded-2xl shadow-xl border border-slate-200 overflow-hidden mt-2">
11589
+
11590
+ <!-- Header: avatar + name + role -->
11591
+ <div class="px-4 py-4 flex items-center gap-3" [class]="_headerBgClass()">
11592
+ <clx-avatar
11593
+ [initials]="_initials()"
11594
+ [src]="avatarSrc()"
11595
+ [color]="color()"
11596
+ size="md" />
11597
+ <div class="flex-1 min-w-0">
11598
+ <p class="text-sm font-semibold text-slate-800 truncate">{{ fullName() }}</p>
11599
+ <p class="text-xs text-slate-500 truncate">{{ username() }}</p>
11600
+ @if (role()) {
11601
+ <span class="inline-flex items-center mt-1 px-2 py-0.5 rounded-full text-xs font-medium"
11602
+ [class]="_badgeClass()">
11603
+ {{ role() }}
11604
+ </span>
11605
+ }
11606
+ </div>
11607
+ </div>
11608
+
11609
+ <!-- Divider -->
11610
+ <div class="border-t border-slate-100"></div>
11611
+
11612
+ <!-- Menu items -->
11613
+ @if (menuItems().length) {
11614
+ <div class="p-1.5">
11615
+ @for (item of menuItems(); track item.action) {
11616
+ <button
11617
+ type="button"
11618
+ 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"
11619
+ [class]="_itemHoverClass()"
11620
+ (click)="_onAction(item.action)">
11621
+ <span clx-icon [name]="item.icon" size="sm"
11622
+ class="text-slate-400 group-hover:text-slate-600 transition-colors"></span>
11623
+ {{ item.label }}
11624
+ </button>
11625
+ }
11626
+ </div>
11627
+ <!-- Divider before signout -->
11628
+ <div class="border-t border-slate-100 mx-3"></div>
11629
+ }
11630
+
11631
+ <!-- Sign out -->
11632
+ <div class="p-1.5">
11633
+ <button
11634
+ type="button"
11635
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors text-left"
11636
+ [class]="_signOutClass()"
11637
+ (click)="_onSignOut()">
11638
+ <span clx-icon name="logout" size="sm"></span>
11639
+ {{ signOutLabel() }}
11640
+ </button>
11641
+ </div>
11642
+
11643
+ </div>
11644
+ </ng-template>
11645
+ `, 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 });
11646
+ }
11647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImport: i0, type: ClxProfileComponent, decorators: [{
11648
+ type: Component,
11649
+ args: [{
11650
+ selector: 'clx-profile',
11651
+ standalone: true,
11652
+ imports: [OverlayModule, ClxAvatarComponent, ClxIconComponent, ClxButtonComponent],
11653
+ template: `
11654
+ <!-- ── Trigger ─────────────────────────────────────────────────────────── -->
11655
+ <button
11656
+ #origin="cdkOverlayOrigin"
11657
+ cdkOverlayOrigin
11658
+ type="button"
11659
+ class="flex items-center gap-2 rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 cursor-pointer"
11660
+ [class]="_ringClass()"
11661
+ (click)="_toggle()">
11662
+ <clx-avatar
11663
+ [initials]="_initials()"
11664
+ [src]="avatarSrc()"
11665
+ [color]="color()"
11666
+ size="sm" />
11667
+ </button>
11668
+
11669
+ <!-- ── Overlay panel ─────────────────────────────────────────────────── -->
11670
+ <ng-template
11671
+ cdkConnectedOverlay
11672
+ [cdkConnectedOverlayOrigin]="origin"
11673
+ [cdkConnectedOverlayOpen]="_isOpen()"
11674
+ [cdkConnectedOverlayPositions]="_positions"
11675
+ [cdkConnectedOverlayScrollStrategy]="_scrollStrategy"
11676
+ [cdkConnectedOverlayPush]="true"
11677
+ (overlayOutsideClick)="_close()"
11678
+ (overlayKeydown)="_onKeydown($event)">
11679
+
11680
+ <div class="w-64 bg-white rounded-2xl shadow-xl border border-slate-200 overflow-hidden mt-2">
11681
+
11682
+ <!-- Header: avatar + name + role -->
11683
+ <div class="px-4 py-4 flex items-center gap-3" [class]="_headerBgClass()">
11684
+ <clx-avatar
11685
+ [initials]="_initials()"
11686
+ [src]="avatarSrc()"
11687
+ [color]="color()"
11688
+ size="md" />
11689
+ <div class="flex-1 min-w-0">
11690
+ <p class="text-sm font-semibold text-slate-800 truncate">{{ fullName() }}</p>
11691
+ <p class="text-xs text-slate-500 truncate">{{ username() }}</p>
11692
+ @if (role()) {
11693
+ <span class="inline-flex items-center mt-1 px-2 py-0.5 rounded-full text-xs font-medium"
11694
+ [class]="_badgeClass()">
11695
+ {{ role() }}
11696
+ </span>
11697
+ }
11698
+ </div>
11699
+ </div>
11700
+
11701
+ <!-- Divider -->
11702
+ <div class="border-t border-slate-100"></div>
11703
+
11704
+ <!-- Menu items -->
11705
+ @if (menuItems().length) {
11706
+ <div class="p-1.5">
11707
+ @for (item of menuItems(); track item.action) {
11708
+ <button
11709
+ type="button"
11710
+ 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"
11711
+ [class]="_itemHoverClass()"
11712
+ (click)="_onAction(item.action)">
11713
+ <span clx-icon [name]="item.icon" size="sm"
11714
+ class="text-slate-400 group-hover:text-slate-600 transition-colors"></span>
11715
+ {{ item.label }}
11716
+ </button>
11717
+ }
11718
+ </div>
11719
+ <!-- Divider before signout -->
11720
+ <div class="border-t border-slate-100 mx-3"></div>
11721
+ }
11722
+
11723
+ <!-- Sign out -->
11724
+ <div class="p-1.5">
11725
+ <button
11726
+ type="button"
11727
+ class="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors text-left"
11728
+ [class]="_signOutClass()"
11729
+ (click)="_onSignOut()">
11730
+ <span clx-icon name="logout" size="sm"></span>
11731
+ {{ signOutLabel() }}
11732
+ </button>
11733
+ </div>
11734
+
11735
+ </div>
11736
+ </ng-template>
11737
+ `,
11738
+ encapsulation: ViewEncapsulation.None,
11739
+ changeDetection: ChangeDetectionStrategy.OnPush,
11740
+ host: { class: 'relative inline-flex items-center' },
11741
+ }]
11742
+ }], 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"] }] } });
11743
+
11474
11744
  // ── Base classes ─────────────────────────────────────────────────────────────
11475
11745
  const TABLE_BASE_CLASS = 'w-full text-left border-collapse text-sm';
11476
11746
  const TABLE_HEADER_CELL_CLASS = 'px-4 py-3 font-semibold whitespace-nowrap';
@@ -14089,5 +14359,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.23", ngImpo
14089
14359
  * Generated bundle index. Do not edit.
14090
14360
  */
14091
14361
 
14092
- 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 };
14362
+ 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 };
14093
14363
  //# sourceMappingURL=codexly-ui.mjs.map