codexly-ui 0.8.1 → 0.8.3
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.
- package/fesm2022/codexly-ui.mjs +52 -19
- package/fesm2022/codexly-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/codexly-ui.d.ts +19 -9
package/fesm2022/codexly-ui.mjs
CHANGED
|
@@ -9399,6 +9399,9 @@ class ClxAppLayoutComponent {
|
|
|
9399
9399
|
collapsed = signal(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
|
|
9400
9400
|
_hovered = signal(false, ...(ngDevMode ? [{ debugName: "_hovered" }] : /* istanbul ignore next */ []));
|
|
9401
9401
|
_isMobile = signal(true, ...(ngDevMode ? [{ debugName: "_isMobile" }] : /* istanbul ignore next */ []));
|
|
9402
|
+
/** True only for the duration of an explicit toggle/hover transition — see _sidebarCls(). */
|
|
9403
|
+
_animating = signal(false, ...(ngDevMode ? [{ debugName: "_animating" }] : /* istanbul ignore next */ []));
|
|
9404
|
+
_animatingTimer;
|
|
9402
9405
|
collapsedChange = output();
|
|
9403
9406
|
expandedChange = output();
|
|
9404
9407
|
constructor() {
|
|
@@ -9422,12 +9425,22 @@ class ClxAppLayoutComponent {
|
|
|
9422
9425
|
width = 'w-72';
|
|
9423
9426
|
}
|
|
9424
9427
|
const isOverlay = isDesktopCollapsed && hovered;
|
|
9428
|
+
// `width` only transitions while `_animating` is true (set for the duration of an explicit
|
|
9429
|
+
// collapse/expand/hover toggle — see _withTransition()). Left permanently on, this transition
|
|
9430
|
+
// would also animate every layout pass a native window resize causes (the sidebar's computed
|
|
9431
|
+
// width changes as a flex/fixed side-effect of the viewport reflow even when its Tailwind
|
|
9432
|
+
// width class hasn't), turning a single instant reflow into a 300ms interpolated one and
|
|
9433
|
+
// dragging the rest of the flex-sibling content along with it — the classic "resize lags,
|
|
9434
|
+
// catches up after you stop" symptom.
|
|
9435
|
+
const transition = this._animating()
|
|
9436
|
+
? 'transition-[width,transform] duration-300 ease-in-out lg:transition-[width]'
|
|
9437
|
+
: 'transition-none';
|
|
9425
9438
|
return [
|
|
9426
9439
|
`fixed inset-y-0 left-0 z-30 ${width} flex flex-col`,
|
|
9427
9440
|
'bg-clx-surface border-r border-clx-border overflow-hidden shrink-0',
|
|
9428
|
-
|
|
9441
|
+
transition,
|
|
9429
9442
|
isOverlay ? 'shadow-2xl' : '',
|
|
9430
|
-
'lg:
|
|
9443
|
+
'lg:relative lg:inset-auto lg:z-30 lg:translate-x-0',
|
|
9431
9444
|
(!this._isMobile() || this._sidebarOpen()) ? 'translate-x-0' : '-translate-x-full',
|
|
9432
9445
|
].join(' ');
|
|
9433
9446
|
}, ...(ngDevMode ? [{ debugName: "_sidebarCls" }] : /* istanbul ignore next */ []));
|
|
@@ -9458,23 +9471,38 @@ class ClxAppLayoutComponent {
|
|
|
9458
9471
|
}
|
|
9459
9472
|
ngOnDestroy() {
|
|
9460
9473
|
this._mql?.removeEventListener('change', this._mqlListener);
|
|
9474
|
+
clearTimeout(this._animatingTimer);
|
|
9475
|
+
}
|
|
9476
|
+
/** Arms the width/transform transition for one toggle's duration, then switches it back off
|
|
9477
|
+
* so a later window resize reflow doesn't get caught by a live CSS transition on `width`. */
|
|
9478
|
+
_withTransition(fn) {
|
|
9479
|
+
this._animating.set(true);
|
|
9480
|
+
fn();
|
|
9481
|
+
clearTimeout(this._animatingTimer);
|
|
9482
|
+
this._animatingTimer = setTimeout(() => this._animating.set(false), 320);
|
|
9461
9483
|
}
|
|
9462
9484
|
_toggleCollapsed() {
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9485
|
+
this._withTransition(() => {
|
|
9486
|
+
const next = !this.collapsed();
|
|
9487
|
+
this.collapsed.set(next);
|
|
9488
|
+
this._hovered.set(false);
|
|
9489
|
+
this.collapsedChange.emit(next);
|
|
9490
|
+
});
|
|
9467
9491
|
}
|
|
9468
9492
|
_onSidebarEnter() {
|
|
9469
9493
|
if (this.collapsed() && !this._isMobile()) {
|
|
9470
|
-
this.
|
|
9471
|
-
|
|
9494
|
+
this._withTransition(() => {
|
|
9495
|
+
this._hovered.set(true);
|
|
9496
|
+
this.expandedChange.emit(true);
|
|
9497
|
+
});
|
|
9472
9498
|
}
|
|
9473
9499
|
}
|
|
9474
9500
|
_onSidebarLeave() {
|
|
9475
9501
|
if (this._hovered()) {
|
|
9476
|
-
this.
|
|
9477
|
-
|
|
9502
|
+
this._withTransition(() => {
|
|
9503
|
+
this._hovered.set(false);
|
|
9504
|
+
this.expandedChange.emit(false);
|
|
9505
|
+
});
|
|
9478
9506
|
}
|
|
9479
9507
|
}
|
|
9480
9508
|
toggleSidebar() { this._sidebarOpen.update(v => !v); }
|
|
@@ -10055,18 +10083,22 @@ class ClxPageHeaderComponent {
|
|
|
10055
10083
|
_titleSlot = contentChild(ClxPageHeaderTitleDirective, ...(ngDevMode ? [{ debugName: "_titleSlot" }] : /* istanbul ignore next */ []));
|
|
10056
10084
|
_hasCustomTitle = computed(() => !!this._titleSlot(), ...(ngDevMode ? [{ debugName: "_hasCustomTitle" }] : /* istanbul ignore next */ []));
|
|
10057
10085
|
_color = computed(() => this._themeSvc.config().primaryColor, ...(ngDevMode ? [{ debugName: "_color" }] : /* istanbul ignore next */ []));
|
|
10058
|
-
|
|
10086
|
+
/** Title classes resolved from the theme — also usable by consumers projecting a custom
|
|
10087
|
+
* [clxPageHeaderTitle] block, via a template reference: `<clx-page-header #ph="clxPageHeader">`
|
|
10088
|
+
* then `[class]="ph.titleClass()"` on their own <h1>. */
|
|
10089
|
+
titleClass = computed(() => {
|
|
10059
10090
|
const s = this._themeSvc.pageHeaderTitleStyle();
|
|
10060
10091
|
const colorCls = s.color ? resolveColor(s.color).textSubtle : 'text-clx-text-label';
|
|
10061
10092
|
return `${TEXT_SIZE_CLASS[s.size]} font-[${s.weight}] ${colorCls} truncate`;
|
|
10062
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
10063
|
-
|
|
10093
|
+
}, ...(ngDevMode ? [{ debugName: "titleClass" }] : /* istanbul ignore next */ []));
|
|
10094
|
+
/** Subtitle classes resolved from the theme — same usage as titleClass. */
|
|
10095
|
+
subtitleClass = computed(() => {
|
|
10064
10096
|
const s = this._themeSvc.pageHeaderSubtitleStyle();
|
|
10065
10097
|
const colorCls = s.color ? resolveColor(s.color).textSubtle : 'text-clx-text-muted';
|
|
10066
10098
|
return `${TEXT_SIZE_CLASS[s.size]} font-[${s.weight}] ${colorCls} mt-0.5`;
|
|
10067
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
10099
|
+
}, ...(ngDevMode ? [{ debugName: "subtitleClass" }] : /* istanbul ignore next */ []));
|
|
10068
10100
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10069
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxPageHeaderComponent, isStandalone: true, selector: "clx-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, showBack: { classPropertyName: "showBack", publicName: "showBack", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { back: "back" }, host: { classAttribute: "flex items-center gap-3 flex-wrap" }, queries: [{ propertyName: "_titleSlot", first: true, predicate: ClxPageHeaderTitleDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
10101
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxPageHeaderComponent, isStandalone: true, selector: "clx-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, showBack: { classPropertyName: "showBack", publicName: "showBack", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { back: "back" }, host: { classAttribute: "flex items-center gap-3 flex-wrap" }, queries: [{ propertyName: "_titleSlot", first: true, predicate: ClxPageHeaderTitleDirective, descendants: true, isSignal: true }], exportAs: ["clxPageHeader"], ngImport: i0, template: `
|
|
10070
10102
|
@if (showBack()) {
|
|
10071
10103
|
<button clx-button variant="ghost" [color]="_color()" icon="arrow_back" [iconOnly]="true"
|
|
10072
10104
|
(click)="back.emit()"></button>
|
|
@@ -10079,9 +10111,9 @@ class ClxPageHeaderComponent {
|
|
|
10079
10111
|
</div>
|
|
10080
10112
|
} @else {
|
|
10081
10113
|
<div class="min-w-0">
|
|
10082
|
-
<h1 [class]="
|
|
10114
|
+
<h1 [class]="titleClass()">{{ title() }}</h1>
|
|
10083
10115
|
@if (subtitle()) {
|
|
10084
|
-
<p [class]="
|
|
10116
|
+
<p [class]="subtitleClass()">{{ subtitle() }}</p>
|
|
10085
10117
|
}
|
|
10086
10118
|
</div>
|
|
10087
10119
|
}
|
|
@@ -10094,6 +10126,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
10094
10126
|
args: [{
|
|
10095
10127
|
selector: 'clx-page-header',
|
|
10096
10128
|
standalone: true,
|
|
10129
|
+
exportAs: 'clxPageHeader',
|
|
10097
10130
|
imports: [ClxButtonComponent],
|
|
10098
10131
|
encapsulation: ViewEncapsulation.None,
|
|
10099
10132
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -10111,9 +10144,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
10111
10144
|
</div>
|
|
10112
10145
|
} @else {
|
|
10113
10146
|
<div class="min-w-0">
|
|
10114
|
-
<h1 [class]="
|
|
10147
|
+
<h1 [class]="titleClass()">{{ title() }}</h1>
|
|
10115
10148
|
@if (subtitle()) {
|
|
10116
|
-
<p [class]="
|
|
10149
|
+
<p [class]="subtitleClass()">{{ subtitle() }}</p>
|
|
10117
10150
|
}
|
|
10118
10151
|
</div>
|
|
10119
10152
|
}
|