Skip to content

feat: port upload Lumo styles to CSS files #9483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: port-lumo-styles-to-css-files_progress-bar
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev/upload.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<script type="module">
import '@vaadin/radio-group';
import '@vaadin/upload';
import '@vaadin/vaadin-lumo-styles/lumo.css';
import { createFiles, xhrCreator } from '@vaadin/upload/test/helpers.js';

const nextUpload = document.querySelector('#next-upload');
Expand Down
3 changes: 2 additions & 1 deletion packages/upload/src/vaadin-upload-file-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './vaadin-upload-file.js';
import { html, LitElement } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { CSSInjectionMixin } from '@vaadin/vaadin-themable-mixin/css-injection-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { uploadFileListStyles } from './styles/vaadin-upload-file-list-core-styles.js';
import { UploadFileListMixin } from './vaadin-upload-file-list-mixin.js';
Expand All @@ -20,7 +21,7 @@ import { UploadFileListMixin } from './vaadin-upload-file-list-mixin.js';
* @mixes UploadFileListMixin
* @private
*/
class UploadFileList extends UploadFileListMixin(ThemableMixin(PolylitMixin(LitElement))) {
class UploadFileList extends UploadFileListMixin(ThemableMixin(CSSInjectionMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-upload-file-list';
}
Expand Down
3 changes: 2 additions & 1 deletion packages/upload/src/vaadin-upload-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import './vaadin-upload-icons.js';
import { html, LitElement, nothing } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { CSSInjectionMixin } from '@vaadin/vaadin-themable-mixin/css-injection-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { uploadFileStyles } from './styles/vaadin-upload-file-core-styles.js';
import { UploadFileMixin } from './vaadin-upload-file-mixin.js';
Expand Down Expand Up @@ -53,7 +54,7 @@ import { UploadFileMixin } from './vaadin-upload-file-mixin.js';
* @mixes UploadFileMixin
* @mixes ThemableMixin
*/
class UploadFile extends UploadFileMixin(ThemableMixin(PolylitMixin(LitElement))) {
class UploadFile extends UploadFileMixin(ThemableMixin(CSSInjectionMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-upload-file';
}
Expand Down
3 changes: 2 additions & 1 deletion packages/upload/src/vaadin-upload-icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import { css, html, LitElement } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { CSSInjectionMixin } from '@vaadin/vaadin-themable-mixin/css-injection-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

/**
Expand All @@ -14,7 +15,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
* @extends HTMLElement
* @private
*/
class UploadIcon extends ThemableMixin(LitElement) {
class UploadIcon extends ThemableMixin(CSSInjectionMixin(LitElement)) {
static get is() {
return 'vaadin-upload-icon';
}
Expand Down
3 changes: 2 additions & 1 deletion packages/upload/src/vaadin-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { CSSInjectionMixin } from '@vaadin/vaadin-themable-mixin/css-injection-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { uploadStyles } from './styles/vaadin-upload-core-styles.js';
import { UploadMixin } from './vaadin-upload-mixin.js';
Expand Down Expand Up @@ -65,7 +66,7 @@ import { UploadMixin } from './vaadin-upload-mixin.js';
* @mixes ElementMixin
* @mixes UploadMixin
*/
class Upload extends UploadMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
class Upload extends UploadMixin(ElementMixin(ThemableMixin(CSSInjectionMixin(PolylitMixin(LitElement))))) {
static get is() {
return 'vaadin-upload';
}
Expand Down
6 changes: 4 additions & 2 deletions packages/upload/test/visual/lumo/upload.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { sendKeys } from '@vaadin/test-runner-commands';
import { fixtureSync } from '@vaadin/testing-helpers/dist/fixture.js';
import { fixtureSync } from '@vaadin/testing-helpers';
import { visualDiff } from '@web/test-runner-visual-regression';
import '../../../theme/lumo/vaadin-upload.js';
import '@vaadin/vaadin-lumo-styles/props.css';
import '@vaadin/vaadin-lumo-styles/components/upload.css';
import '../../../vaadin-upload.js';

describe('upload', () => {
let div, element;
Expand Down
1 change: 1 addition & 0 deletions packages/vaadin-lumo-styles/components.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@
@import './components/text-field.css';
@import './components/time-picker.css';
@import './components/tooltip.css';
@import './components/upload.css';
@import './components/vertical-layout.css';
27 changes: 27 additions & 0 deletions packages/vaadin-lumo-styles/components/upload.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @license
* Copyright (c) 2000 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
@import './button.css';
@import './progress-bar.css';

@import '../src/mixins/base-layer-reset.css' vaadin-upload;
@import '../src/components/upload.css' vaadin-upload;

@import '../src/mixins/base-layer-reset.css' vaadin-upload-icon;
@import '../src/components/upload-icon.css' vaadin-upload-icon;

@import '../src/mixins/base-layer-reset.css' vaadin-upload-file;
@import '../src/mixins/field-button.css' vaadin-upload-file;
@import '../src/components/upload-file.css' vaadin-upload-file;

@import '../src/mixins/base-layer-reset.css' vaadin-upload-file-list;
@import '../src/components/upload-file-list.css' vaadin-upload-file-list;

html {
--vaadin-upload-css-inject: 1;
--vaadin-upload-icon-css-inject: 1;
--vaadin-upload-file-css-inject: 1;
--vaadin-upload-file-list-css-inject: 1;
}
22 changes: 22 additions & 0 deletions packages/vaadin-lumo-styles/src/components/upload-file-list.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license
* Copyright (c) 2000 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
:host {
display: block;
}

:host([hidden]) {
display: none !important;
}

[part='list'] {
padding: 0;
margin: 0;
list-style-type: none;
}

::slotted(li:not(:first-of-type)) {
border-top: 1px solid var(--lumo-contrast-10pct);
}
131 changes: 131 additions & 0 deletions packages/vaadin-lumo-styles/src/components/upload-file.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @license
* Copyright (c) 2000 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
:host {
display: block;
padding: var(--lumo-space-s) 0;
outline: none;
--_focus-ring-color: var(--vaadin-focus-ring-color, var(--lumo-primary-color-50pct));
--_focus-ring-width: var(--vaadin-focus-ring-width, 2px);
}

[hidden] {
display: none;
Copy link
Preview

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding !important to the [hidden] rule (e.g. display: none !important;) to match the pattern used in other components and ensure it always overrides.

Suggested change
display: none;
display: none !important;

Copilot uses AI. Check for mistakes.

}

[part='row'] {
list-style-type: none;
display: flex;
align-items: baseline;
justify-content: space-between;
}

button {
background: transparent;
padding: 0;
border: none;
box-shadow: none;
}

:host([complete]) ::slotted([slot='progress']),
:host([error]) ::slotted([slot='progress']) {
display: none !important;
}

:host([focus-ring]) [part='row'] {
border-radius: var(--lumo-border-radius-s);
box-shadow: 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
}

[part='status'],
[part='error'] {
Copy link
Preview

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two separate [part='error'] blocks (this one at line 43 and another at line 123) with different colors. Consider merging them into one rule or reorganizing to avoid duplication.

Copilot uses AI. Check for mistakes.

color: var(--lumo-secondary-text-color);
font-size: var(--lumo-font-size-s);
}

[part='info'] {
display: flex;
align-items: baseline;
flex: auto;
}

[part='meta'] {
width: 0.001px;
flex: 1 1 auto;
}

[part='name'] {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

[part='commands'] {
display: flex;
align-items: baseline;
flex: none;
}

[part$='icon'] {
margin-right: var(--lumo-space-xs);
font-size: var(--lumo-icon-size-m);
font-family: 'lumo-icons';
Copy link
Preview

Copilot AI Jun 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The font-family value is quoted here but unquoted in upload-icon.css. For consistency, unify quoting across your CSS modules.

Copilot uses AI. Check for mistakes.

line-height: 1;
}

/* When both icons are hidden, let us keep space for one */
[part='done-icon'][hidden] + [part='warning-icon'][hidden] {
display: block !important;
visibility: hidden;
}

[part$='button'] {
flex: none;
margin-left: var(--lumo-space-xs);
cursor: var(--lumo-clickable-cursor);
}

[part$='button']:focus {
outline: none;
border-radius: var(--lumo-border-radius-s);
box-shadow: 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
}

[part$='icon']::before,
[part$='button']::before {
vertical-align: -0.25em;
}

[part='done-icon']::before {
content: var(--lumo-icons-checkmark);
color: var(--lumo-primary-text-color);
}

[part='warning-icon']::before {
content: var(--lumo-icons-error);
color: var(--lumo-error-text-color);
}

[part='start-button']::before {
content: var(--lumo-icons-play);
}

[part='retry-button']::before {
content: var(--lumo-icons-reload);
}

[part='remove-button']::before {
content: var(--lumo-icons-cross);
}

[part='error'] {
color: var(--lumo-error-text-color);
}

::slotted([slot='progress']) {
width: auto;
margin-left: calc(var(--lumo-icon-size-m) + var(--lumo-space-xs));
margin-right: calc(var(--lumo-icon-size-m) + var(--lumo-space-xs));
}
12 changes: 12 additions & 0 deletions packages/vaadin-lumo-styles/src/components/upload-icon.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @license
* Copyright (c) 2000 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
:host::before {
content: var(--lumo-icons-upload);
font-family: lumo-icons;
font-size: var(--lumo-icon-size-m);
line-height: 1;
vertical-align: -0.25em;
}
54 changes: 54 additions & 0 deletions packages/vaadin-lumo-styles/src/components/upload.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @license
* Copyright (c) 2000 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
:host {
display: block;
position: relative;
box-sizing: border-box;
line-height: var(--lumo-line-height-m);
}

:host([hidden]) {
display: none !important;
}

[hidden] {
display: none !important;
}

:host(:not([nodrop])) {
overflow: hidden;
border: 1px dashed var(--lumo-contrast-20pct);
border-radius: var(--lumo-border-radius-l);
padding: var(--lumo-space-m);
transition:
background-color 0.6s,
border-color 0.6s;
}

[part='drop-label'] {
display: inline-block;
white-space: normal;
padding: 0 var(--lumo-space-s);
color: var(--lumo-secondary-text-color);
font-family: var(--lumo-font-family);
}

:host([dragover-valid]) {
border-color: var(--lumo-primary-color-50pct);
background: var(--lumo-primary-color-10pct);
transition:
background-color 0.1s,
border-color 0.1s;
}

:host([dragover-valid]) [part='drop-label'] {
color: var(--lumo-primary-text-color);
}

:host([disabled]) [part='drop-label'],
:host([max-files-reached]) [part='drop-label'] {
color: var(--lumo-disabled-text-color);
}
Loading