fix(dees-actionbar): always render actionbar wrapper and delay adding visible class to ensure grid/opacity animations run reliably

This commit is contained in:
2026-01-01 21:33:30 +00:00
parent 8d6bd20321
commit 87fb3d91c3
3 changed files with 70 additions and 48 deletions

View File

@@ -1,5 +1,13 @@
# Changelog
## 2026-01-01 - 3.27.1 - fix(dees-actionbar)
always render actionbar wrapper and delay adding visible class to ensure grid/opacity animations run reliably
- Always render the actionbar wrapper (.actionbar-item and .actionbar-content) instead of returning early so grid-template-rows and opacity transitions can animate.
- Use optional chaining for current bar access (bar?.type, bar?.timeout) to avoid runtime errors when no bar is present.
- Adjust styles and structure: set :host display:block; move background/border to .actionbar-item; add .actionbar-content with min-height/opacity and transitions.
- Make processQueue asynchronous and await updateComplete, then add the 'visible' class inside requestAnimationFrame so the CSS transition is triggered after render.
## 2026-01-01 - 3.27.0 - feat(services)
introduce DeesServiceLibLoader to lazy-load heavy client libraries from CDN and update components to use it

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@design.estate/dees-catalog',
version: '3.27.0',
version: '3.27.1',
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
}

View File

@@ -128,22 +128,30 @@ export class DeesActionbar extends DeesElement {
cssManager.defaultStyles,
css`
:host {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.2s ease-out;
}
:host(.visible) {
grid-template-rows: 1fr;
display: block;
}
.actionbar-item {
display: flex;
flex-direction: column;
min-height: 0;
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.2s ease-out;
background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(0 0% 12%)')};
border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 88%)', 'hsl(0 0% 20%)')};
}
:host(.visible) .actionbar-item {
grid-template-rows: 1fr;
}
.actionbar-content {
overflow: hidden;
min-height: 0;
opacity: 0;
transition: opacity 0.2s ease-out;
}
:host(.visible) .actionbar-content {
opacity: 1;
}
.progress-bar {
@@ -305,47 +313,48 @@ export class DeesActionbar extends DeesElement {
];
public render(): TemplateResult {
if (!this.currentBar) {
return html``;
}
const bar = this.currentBar;
const type = bar.type || 'info';
const hasTimeout = bar.timeout && this.timeRemaining > 0;
const type = bar?.type || 'info';
const hasTimeout = bar?.timeout && this.timeRemaining > 0;
// ALWAYS render wrapper - required for grid animation to work
return html`
<div class="actionbar-item">
${hasTimeout ? html`
<div class="progress-bar">
<div
class="progress-bar-fill ${type}"
style="width: ${this.progressPercent}%"
></div>
</div>
` : ''}
<div class="content">
<div class="message-section">
${bar.icon ? html`
<dees-icon
class="message-icon ${type}"
.icon=${bar.icon}
iconSize="16"
></dees-icon>
` : ''}
<span class="message-text">${bar.message}</span>
</div>
<div class="actions-section">
${bar.actions.map(action => this.renderActionButton(action, bar, hasTimeout))}
${bar.dismissible ? html`
<div
class="dismiss-button"
@click=${() => this.handleDismiss()}
title="Dismiss"
>
<dees-icon .icon=${'lucide:x'} iconSize="14"></dees-icon>
<div class="actionbar-content">
${bar ? html`
${hasTimeout ? html`
<div class="progress-bar">
<div
class="progress-bar-fill ${type}"
style="width: ${this.progressPercent}%"
></div>
</div>
` : ''}
</div>
<div class="content">
<div class="message-section">
${bar.icon ? html`
<dees-icon
class="message-icon ${type}"
.icon=${bar.icon}
iconSize="16"
></dees-icon>
` : ''}
<span class="message-text">${bar.message}</span>
</div>
<div class="actions-section">
${bar.actions.map(action => this.renderActionButton(action, bar, hasTimeout))}
${bar.dismissible ? html`
<div
class="dismiss-button"
@click=${() => this.handleDismiss()}
title="Dismiss"
>
<dees-icon .icon=${'lucide:x'} iconSize="14"></dees-icon>
</div>
` : ''}
</div>
</div>
` : ''}
</div>
</div>
`;
@@ -433,7 +442,7 @@ export class DeesActionbar extends DeesElement {
this.currentResolve = null;
}
private processQueue(): void {
private async processQueue(): Promise<void> {
if (this.queue.length === 0) {
// Hide with animation - don't await, let it run async
this.hideCurrentBar();
@@ -444,7 +453,12 @@ export class DeesActionbar extends DeesElement {
this.currentBar = item.options;
this.currentResolve = item.resolve;
this.isVisible = true;
this.classList.add('visible');
// Wait for Lit render, then add class on next frame to trigger animation
await this.updateComplete;
requestAnimationFrame(() => {
this.classList.add('visible');
});
// Setup timeout if configured
if (item.options.timeout) {