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:
@ -168,7 +168,7 @@ export class DeesChips extends DeesElement {
|
|||||||
event.stopPropagation(); // prevent the selectChip event from being triggered
|
event.stopPropagation(); // prevent the selectChip event from being triggered
|
||||||
this.removeChip(chip);
|
this.removeChip(chip);
|
||||||
}}
|
}}
|
||||||
.iconFA=${'xmark'}
|
.icon=${'fa:xmark'}
|
||||||
></dees-icon>
|
></dees-icon>
|
||||||
`
|
`
|
||||||
: html``}
|
: html``}
|
||||||
|
@ -175,21 +175,21 @@ export class DeesDataviewStatusobject extends DeesElement {
|
|||||||
DeesContextmenu.openContextMenuWithOptions(event, [
|
DeesContextmenu.openContextMenuWithOptions(event, [
|
||||||
{
|
{
|
||||||
name: 'Copy Value',
|
name: 'Copy Value',
|
||||||
iconName: 'lucideCopy',
|
iconName: 'lucide:copy',
|
||||||
action: async () => {
|
action: async () => {
|
||||||
await this.copyToClipboard(detailArg.value, 'Value');
|
await this.copyToClipboard(detailArg.value, 'Value');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Copy Key',
|
name: 'Copy Key',
|
||||||
iconName: 'lucideKey',
|
iconName: 'lucide:key',
|
||||||
action: async () => {
|
action: async () => {
|
||||||
await this.copyToClipboard(detailArg.name, 'Key');
|
await this.copyToClipboard(detailArg.name, 'Key');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Copy Key:Value',
|
name: 'Copy Key:Value',
|
||||||
iconName: 'lucideCopyPlus',
|
iconName: 'lucide:copy-plus',
|
||||||
action: async () => {
|
action: async () => {
|
||||||
await this.copyToClipboard(`${detailArg.name}: ${detailArg.value}`, 'Key:Value');
|
await this.copyToClipboard(`${detailArg.name}: ${detailArg.value}`, 'Key:Value');
|
||||||
},
|
},
|
||||||
|
@ -37,6 +37,9 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
@property()
|
@property()
|
||||||
public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';
|
public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
private isLoading: boolean = false;
|
||||||
|
|
||||||
@property({
|
@property({
|
||||||
type: String,
|
type: String,
|
||||||
})
|
})
|
||||||
@ -317,6 +320,53 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
line-height: 1.5;
|
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`
|
${isImage && this.canShowPreview(fileArg) ? html`
|
||||||
<img class="image-preview" src="${URL.createObjectURL(fileArg)}" alt="${fileArg.name}">
|
<img class="image-preview" src="${URL.createObjectURL(fileArg)}" alt="${fileArg.name}">
|
||||||
` : html`
|
` : html`
|
||||||
<dees-icon .iconName=${this.getFileIcon(fileArg)}></dees-icon>
|
<dees-icon .icon=${this.getFileIcon(fileArg)}></dees-icon>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
@ -366,7 +416,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
@click=${() => this.removeFile(fileArg)}
|
@click=${() => this.removeFile(fileArg)}
|
||||||
title="Remove file"
|
title="Remove file"
|
||||||
>
|
>
|
||||||
<dees-icon .iconName=${'lucide:x'}></dees-icon>
|
<dees-icon .icon=${'lucide:x'}></dees-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -375,13 +425,20 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
</div>
|
</div>
|
||||||
` : html`
|
` : html`
|
||||||
<div class="drop-hint">
|
<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>Drag files here or click to browse</div>
|
||||||
</div>
|
</div>
|
||||||
`}
|
`}
|
||||||
<div class="uploadButton" @click=${this.openFileSelector}>
|
<div class="uploadButton ${this.isLoading ? 'loading' : ''}" @click=${this.openFileSelector}>
|
||||||
<dees-icon .iconName=${'lucide:upload'}></dees-icon>
|
<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}
|
${this.buttonText}
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.description ? html`
|
${this.description ? html`
|
||||||
@ -482,8 +539,25 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async openFileSelector() {
|
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"]');
|
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();
|
inputFile.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,6 +590,10 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
|||||||
inputFile.addEventListener('change', async (event: Event) => {
|
inputFile.addEventListener('change', async (event: Event) => {
|
||||||
const target = event.target as HTMLInputElement;
|
const target = event.target as HTMLInputElement;
|
||||||
const newFiles = Array.from(target.files);
|
const newFiles = Array.from(target.files);
|
||||||
|
|
||||||
|
// Always reset loading state when file dialog interaction completes
|
||||||
|
this.isLoading = false;
|
||||||
|
|
||||||
await this.addFiles(newFiles);
|
await this.addFiles(newFiles);
|
||||||
// Reset the input value to allow selecting the same file again if needed
|
// Reset the input value to allow selecting the same file again if needed
|
||||||
target.value = '';
|
target.value = '';
|
||||||
|
@ -231,7 +231,7 @@ export class DeesInputText extends DeesInputBase {
|
|||||||
${this.isPasswordBool
|
${this.isPasswordBool
|
||||||
? html`
|
? html`
|
||||||
<div class="showPassword" @click=${this.togglePasswordView}>
|
<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>
|
</div>
|
||||||
`
|
`
|
||||||
: html``}
|
: html``}
|
||||||
|
@ -82,7 +82,7 @@ export class DeesLabel extends DeesElement {
|
|||||||
${this.required ? html`<span class="required">*</span>` : ''}
|
${this.required ? html`<span class="required">*</span>` : ''}
|
||||||
${this.description
|
${this.description
|
||||||
? html`
|
? html`
|
||||||
<dees-icon .iconName=${'lucideInfo'}></dees-icon>
|
<dees-icon .icon=${'lucide:info'}></dees-icon>
|
||||||
<dees-speechbubble .text=${this.description}></dees-speechbubble>
|
<dees-speechbubble .text=${this.description}></dees-speechbubble>
|
||||||
`
|
`
|
||||||
: html``}
|
: html``}
|
||||||
|
@ -252,7 +252,7 @@ export class DeesShoppingProductcard extends DeesElement {
|
|||||||
${imageUrl ? html`
|
${imageUrl ? html`
|
||||||
<img src="${imageUrl}" alt="${name}">
|
<img src="${imageUrl}" alt="${name}">
|
||||||
` : html`
|
` : html`
|
||||||
<dees-icon .iconName=${iconName}></dees-icon>
|
<dees-icon .icon=${iconName}></dees-icon>
|
||||||
`}
|
`}
|
||||||
${this.selectable ? html`
|
${this.selectable ? html`
|
||||||
<div
|
<div
|
||||||
@ -262,7 +262,7 @@ export class DeesShoppingProductcard extends DeesElement {
|
|||||||
this.handleSelectionToggle();
|
this.handleSelectionToggle();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<dees-icon .iconName=${'lucide:check'}></dees-icon>
|
<dees-icon .icon=${'lucide:check'}></dees-icon>
|
||||||
</div>
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
</div>
|
</div>
|
||||||
@ -275,7 +275,7 @@ export class DeesShoppingProductcard extends DeesElement {
|
|||||||
<div class="product-description">${description}</div>
|
<div class="product-description">${description}</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
<div class="stock-status ${inStock ? 'in-stock' : 'out-of-stock'}">
|
<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}
|
${stockText}
|
||||||
</div>
|
</div>
|
||||||
<div class="product-footer">
|
<div class="product-footer">
|
||||||
|
@ -120,9 +120,9 @@ export class DeesSpinner extends DeesElement {
|
|||||||
<div class="${this.status}" id="loading">
|
<div class="${this.status}" id="loading">
|
||||||
${(() => {
|
${(() => {
|
||||||
if (this.status === 'success') {
|
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') {
|
} 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>
|
</div>
|
||||||
|
@ -391,7 +391,7 @@ export class DeesStatsGrid extends DeesElement {
|
|||||||
type="outline"
|
type="outline"
|
||||||
size="sm"
|
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}
|
${action.name}
|
||||||
</dees-button>
|
</dees-button>
|
||||||
`)}
|
`)}
|
||||||
@ -427,7 +427,7 @@ export class DeesStatsGrid extends DeesElement {
|
|||||||
<div class="tile-header">
|
<div class="tile-header">
|
||||||
<h3 class="tile-title">${tile.title}</h3>
|
<h3 class="tile-title">${tile.title}</h3>
|
||||||
${tile.icon ? html`
|
${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>
|
</div>
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ export class DeesTable<T> extends DeesElement {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
${action.iconName
|
${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}`
|
||||||
: action.name}
|
: action.name}
|
||||||
</div>`
|
</div>`
|
||||||
@ -743,7 +743,7 @@ export class DeesTable<T> extends DeesElement {
|
|||||||
${actionArg.iconName
|
${actionArg.iconName
|
||||||
? html`
|
? html`
|
||||||
<dees-icon
|
<dees-icon
|
||||||
.iconFA=${actionArg.iconName}
|
.icon=${actionArg.iconName}
|
||||||
></dees-icon>
|
></dees-icon>
|
||||||
`
|
`
|
||||||
: actionArg.name}
|
: actionArg.name}
|
||||||
@ -785,7 +785,7 @@ export class DeesTable<T> extends DeesElement {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
${action.iconName
|
${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}`
|
||||||
: action.name}
|
: action.name}
|
||||||
</div>`
|
</div>`
|
||||||
|
Reference in New Issue
Block a user