fix(icons): update icon usage across components

- Replace .iconName property with .icon for dees-icon component
- Fix incorrect lucide icon names to use proper prefix and kebab-case
- Replace deprecated .iconFA property with .icon
- Add loading animation to dees-input-fileupload button
- Maintain compatibility with external interfaces expecting iconName
This commit is contained in:
Juergen Kunz
2025-06-30 12:57:13 +00:00
parent 1db74177b3
commit 956edf0d63
9 changed files with 101 additions and 23 deletions

View File

@ -168,7 +168,7 @@ export class DeesChips extends DeesElement {
event.stopPropagation(); // prevent the selectChip event from being triggered
this.removeChip(chip);
}}
.iconFA=${'xmark'}
.icon=${'fa:xmark'}
></dees-icon>
`
: html``}

View File

@ -175,21 +175,21 @@ export class DeesDataviewStatusobject extends DeesElement {
DeesContextmenu.openContextMenuWithOptions(event, [
{
name: 'Copy Value',
iconName: 'lucideCopy',
iconName: 'lucide:copy',
action: async () => {
await this.copyToClipboard(detailArg.value, 'Value');
},
},
{
name: 'Copy Key',
iconName: 'lucideKey',
iconName: 'lucide:key',
action: async () => {
await this.copyToClipboard(detailArg.name, 'Key');
},
},
{
name: 'Copy Key:Value',
iconName: 'lucideCopyPlus',
iconName: 'lucide:copy-plus',
action: async () => {
await this.copyToClipboard(`${detailArg.name}: ${detailArg.value}`, 'Key:Value');
},

View File

@ -37,6 +37,9 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
@property()
public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';
@property({ type: Boolean })
private isLoading: boolean = false;
@property({
type: String,
})
@ -317,6 +320,53 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
margin-top: 6px;
line-height: 1.5;
}
/* Loading state styles */
.uploadButton.loading {
pointer-events: none;
opacity: 0.8;
}
.uploadButton .button-content {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.loading-spinner {
width: 16px;
height: 16px;
border: 2px solid ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
border-top-color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
border-radius: 50%;
animation: spin 0.6s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.02);
opacity: 0.9;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.uploadButton.loading {
animation: pulse 1s ease-in-out infinite;
}
`,
];
@ -353,7 +403,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
${isImage && this.canShowPreview(fileArg) ? html`
<img class="image-preview" src="${URL.createObjectURL(fileArg)}" alt="${fileArg.name}">
` : html`
<dees-icon .iconName=${this.getFileIcon(fileArg)}></dees-icon>
<dees-icon .icon=${this.getFileIcon(fileArg)}></dees-icon>
`}
</div>
<div class="info">
@ -366,7 +416,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
@click=${() => this.removeFile(fileArg)}
title="Remove file"
>
<dees-icon .iconName=${'lucide:x'}></dees-icon>
<dees-icon .icon=${'lucide:x'}></dees-icon>
</button>
</div>
</div>
@ -375,13 +425,20 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
</div>
` : html`
<div class="drop-hint">
<dees-icon .iconName=${'lucide:cloud-upload'}></dees-icon>
<dees-icon .icon=${'lucide:cloud-upload'}></dees-icon>
<div>Drag files here or click to browse</div>
</div>
`}
<div class="uploadButton" @click=${this.openFileSelector}>
<dees-icon .iconName=${'lucide:upload'}></dees-icon>
<div class="uploadButton ${this.isLoading ? 'loading' : ''}" @click=${this.openFileSelector}>
<div class="button-content">
${this.isLoading ? html`
<div class="loading-spinner"></div>
<span>Opening...</span>
` : html`
<dees-icon .icon=${'lucide:upload'}></dees-icon>
${this.buttonText}
`}
</div>
</div>
</div>
${this.description ? html`
@ -482,8 +539,25 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
}
public async openFileSelector() {
if (this.disabled) return;
if (this.disabled || this.isLoading) return;
// Set loading state
this.isLoading = true;
const inputFile: HTMLInputElement = this.shadowRoot.querySelector('input[type="file"]');
// Set up a focus handler to detect when the dialog is closed without selection
const handleFocus = () => {
setTimeout(() => {
// Check if no file was selected
if (!inputFile.files || inputFile.files.length === 0) {
this.isLoading = false;
}
window.removeEventListener('focus', handleFocus);
}, 300);
};
window.addEventListener('focus', handleFocus);
inputFile.click();
}
@ -516,6 +590,10 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
inputFile.addEventListener('change', async (event: Event) => {
const target = event.target as HTMLInputElement;
const newFiles = Array.from(target.files);
// Always reset loading state when file dialog interaction completes
this.isLoading = false;
await this.addFiles(newFiles);
// Reset the input value to allow selecting the same file again if needed
target.value = '';

View File

@ -231,7 +231,7 @@ export class DeesInputText extends DeesInputBase {
${this.isPasswordBool
? html`
<div class="showPassword" @click=${this.togglePasswordView}>
<dees-icon .iconName=${this.showPasswordBool ? 'lucideEye' : 'lucideEyeOff'}></dees-icon>
<dees-icon .icon=${this.showPasswordBool ? 'lucide:eye' : 'lucide:eye-off'}></dees-icon>
</div>
`
: html``}

View File

@ -82,7 +82,7 @@ export class DeesLabel extends DeesElement {
${this.required ? html`<span class="required">*</span>` : ''}
${this.description
? html`
<dees-icon .iconName=${'lucideInfo'}></dees-icon>
<dees-icon .icon=${'lucide:info'}></dees-icon>
<dees-speechbubble .text=${this.description}></dees-speechbubble>
`
: html``}

View File

@ -252,7 +252,7 @@ export class DeesShoppingProductcard extends DeesElement {
${imageUrl ? html`
<img src="${imageUrl}" alt="${name}">
` : html`
<dees-icon .iconName=${iconName}></dees-icon>
<dees-icon .icon=${iconName}></dees-icon>
`}
${this.selectable ? html`
<div
@ -262,7 +262,7 @@ export class DeesShoppingProductcard extends DeesElement {
this.handleSelectionToggle();
}}
>
<dees-icon .iconName=${'lucide:check'}></dees-icon>
<dees-icon .icon=${'lucide:check'}></dees-icon>
</div>
` : ''}
</div>
@ -275,7 +275,7 @@ export class DeesShoppingProductcard extends DeesElement {
<div class="product-description">${description}</div>
` : ''}
<div class="stock-status ${inStock ? 'in-stock' : 'out-of-stock'}">
<dees-icon .iconName=${inStock ? 'lucide:check-circle' : 'lucide:x-circle'}></dees-icon>
<dees-icon .icon=${inStock ? 'lucide:check-circle' : 'lucide:x-circle'}></dees-icon>
${stockText}
</div>
<div class="product-footer">

View File

@ -120,9 +120,9 @@ export class DeesSpinner extends DeesElement {
<div class="${this.status}" id="loading">
${(() => {
if (this.status === 'success') {
return html`<dees-icon style="transform: translateX(1%) translateY(3%);" .iconFA=${'circleCheck' as any}></dees-icon>`;
return html`<dees-icon style="transform: translateX(1%) translateY(3%);" .icon=${'fa:circle-check'}></dees-icon>`;
} else if (this.status === 'error') {
return html`<dees-icon .iconFA=${'circleXmark' as any}></dees-icon>`;
return html`<dees-icon .icon=${'fa:circle-xmark'}></dees-icon>`;
}
})()}
</div>

View File

@ -391,7 +391,7 @@ export class DeesStatsGrid extends DeesElement {
type="outline"
size="sm"
>
${action.iconName ? html`<dees-icon .iconFA=${action.iconName} size="small"></dees-icon>` : ''}
${action.iconName ? html`<dees-icon .icon=${action.iconName} size="small"></dees-icon>` : ''}
${action.name}
</dees-button>
`)}
@ -427,7 +427,7 @@ export class DeesStatsGrid extends DeesElement {
<div class="tile-header">
<h3 class="tile-title">${tile.title}</h3>
${tile.icon ? html`
<dees-icon class="tile-icon" .iconFA=${tile.icon} size="small"></dees-icon>
<dees-icon class="tile-icon" .icon=${tile.icon} size="small"></dees-icon>
` : ''}
</div>

View File

@ -568,7 +568,7 @@ export class DeesTable<T> extends DeesElement {
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
? html`<dees-icon .iconSize=${14} .icon=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`
@ -743,7 +743,7 @@ export class DeesTable<T> extends DeesElement {
${actionArg.iconName
? html`
<dees-icon
.iconFA=${actionArg.iconName}
.icon=${actionArg.iconName}
></dees-icon>
`
: actionArg.name}
@ -785,7 +785,7 @@ export class DeesTable<T> extends DeesElement {
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
? html`<dees-icon .iconSize=${14} .icon=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`