fix(dees-actionbar): always render actionbar wrapper and delay adding visible class to ensure grid/opacity animations run reliably
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# 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)
|
## 2026-01-01 - 3.27.0 - feat(services)
|
||||||
introduce DeesServiceLibLoader to lazy-load heavy client libraries from CDN and update components to use it
|
introduce DeesServiceLibLoader to lazy-load heavy client libraries from CDN and update components to use it
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-catalog',
|
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.'
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,22 +128,30 @@ export class DeesActionbar extends DeesElement {
|
|||||||
cssManager.defaultStyles,
|
cssManager.defaultStyles,
|
||||||
css`
|
css`
|
||||||
:host {
|
:host {
|
||||||
display: grid;
|
display: block;
|
||||||
grid-template-rows: 0fr;
|
|
||||||
transition: grid-template-rows 0.2s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host(.visible) {
|
|
||||||
grid-template-rows: 1fr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actionbar-item {
|
.actionbar-item {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-rows: 0fr;
|
||||||
min-height: 0;
|
transition: grid-template-rows 0.2s ease-out;
|
||||||
background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(0 0% 12%)')};
|
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%)')};
|
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;
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.visible) .actionbar-content {
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
@@ -305,47 +313,48 @@ export class DeesActionbar extends DeesElement {
|
|||||||
];
|
];
|
||||||
|
|
||||||
public render(): TemplateResult {
|
public render(): TemplateResult {
|
||||||
if (!this.currentBar) {
|
|
||||||
return html``;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bar = this.currentBar;
|
const bar = this.currentBar;
|
||||||
const type = bar.type || 'info';
|
const type = bar?.type || 'info';
|
||||||
const hasTimeout = bar.timeout && this.timeRemaining > 0;
|
const hasTimeout = bar?.timeout && this.timeRemaining > 0;
|
||||||
|
|
||||||
|
// ALWAYS render wrapper - required for grid animation to work
|
||||||
return html`
|
return html`
|
||||||
<div class="actionbar-item">
|
<div class="actionbar-item">
|
||||||
${hasTimeout ? html`
|
<div class="actionbar-content">
|
||||||
<div class="progress-bar">
|
${bar ? html`
|
||||||
<div
|
${hasTimeout ? html`
|
||||||
class="progress-bar-fill ${type}"
|
<div class="progress-bar">
|
||||||
style="width: ${this.progressPercent}%"
|
<div
|
||||||
></div>
|
class="progress-bar-fill ${type}"
|
||||||
</div>
|
style="width: ${this.progressPercent}%"
|
||||||
` : ''}
|
></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 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>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -433,7 +442,7 @@ export class DeesActionbar extends DeesElement {
|
|||||||
this.currentResolve = null;
|
this.currentResolve = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private processQueue(): void {
|
private async processQueue(): Promise<void> {
|
||||||
if (this.queue.length === 0) {
|
if (this.queue.length === 0) {
|
||||||
// Hide with animation - don't await, let it run async
|
// Hide with animation - don't await, let it run async
|
||||||
this.hideCurrentBar();
|
this.hideCurrentBar();
|
||||||
@@ -444,7 +453,12 @@ export class DeesActionbar extends DeesElement {
|
|||||||
this.currentBar = item.options;
|
this.currentBar = item.options;
|
||||||
this.currentResolve = item.resolve;
|
this.currentResolve = item.resolve;
|
||||||
this.isVisible = true;
|
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
|
// Setup timeout if configured
|
||||||
if (item.options.timeout) {
|
if (item.options.timeout) {
|
||||||
|
|||||||
Reference in New Issue
Block a user