diff --git a/dev/upload.html b/dev/upload.html
index 071edbcf7f..1ca316999f 100644
--- a/dev/upload.html
+++ b/dev/upload.html
@@ -55,9 +55,9 @@
-
-
-
+
+
+
diff --git a/packages/component-base/src/style-props.js b/packages/component-base/src/style-props.js
index 735a44cc3f..54748b9271 100644
--- a/packages/component-base/src/style-props.js
+++ b/packages/component-base/src/style-props.js
@@ -66,9 +66,12 @@ addGlobalThemeStyles(
--_vaadin-icon-fullscreen: url('data:image/svg+xml;utf8,');
--_vaadin-icon-menu: url('data:image/svg+xml;utf8,');
--_vaadin-icon-minus: url('data:image/svg+xml;utf8,');
+ --_vaadin-icon-play: url('data:image/svg+xml;utf8,');
--_vaadin-icon-paper-airplane: url('data:image/svg+xml;utf8,');
--_vaadin-icon-plus: url('data:image/svg+xml;utf8,');
+ --_vaadin-icon-refresh: url('data:image/svg+xml;utf8,');
--_vaadin-icon-sort: url('data:image/svg+xml;utf8,');
+ --_vaadin-icon-upload: url('data:image/svg+xml;utf8,');
--_vaadin-icon-user: url('data:image/svg+xml;utf8,');
--_vaadin-icon-warn: url('data:image/svg+xml;utf8,');
diff --git a/packages/upload/src/styles/vaadin-upload-base-styles.d.ts b/packages/upload/src/styles/vaadin-upload-base-styles.d.ts
new file mode 100644
index 0000000000..c2218c8c53
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-base-styles.d.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import type { CSSResult } from 'lit';
+
+export const uploadStyles: CSSResult;
diff --git a/packages/upload/src/styles/vaadin-upload-base-styles.js b/packages/upload/src/styles/vaadin-upload-base-styles.js
new file mode 100644
index 0000000000..480e24ebf4
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-base-styles.js
@@ -0,0 +1,60 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import { css } from 'lit';
+
+export const uploadStyles = css`
+ :host {
+ background: var(--vaadin-upload-background, transparent);
+ border: var(
+ --vaadin-upload-border,
+ var(--vaadin-upload-border-width, 1px) solid var(--vaadin-upload-border-color, var(--vaadin-border-color))
+ );
+ border-radius: var(--vaadin-upload-border-radius, var(--vaadin-radius-m));
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ gap: var(--vaadin-upload-gap, var(--vaadin-gap-container-block));
+ padding: var(--vaadin-upload-padding, var(--vaadin-padding));
+ position: relative;
+ }
+
+ :host([dragover-valid]) {
+ --vaadin-upload-background: var(--vaadin-background-container);
+ --vaadin-upload-border: 1px dashed var(--vaadin-color);
+ );
+ }
+
+ :host([hidden]) {
+ display: none !important;
+ }
+
+ [hidden] {
+ display: none !important;
+ }
+
+ [part='primary-buttons'] {
+ align-items: center;
+ display: flex;
+ gap: var(--vaadin-gap-container-inline);
+ }
+
+ [part='drop-label'] {
+ align-items: center;
+ color: var(--vaadin-upload-drop-label-color, var(--vaadin-color));
+ display: flex;
+ font-size: var(--vaadin-upload-drop-label-font-size, inherit);
+ font-weight: var(--vaadin-upload-drop-label-font-weight, inherit);
+ gap: var(--vaadin-upload-drop-label-gap, var(--vaadin-gap-container-inline));
+ line-height: var(--vaadin-upload-drop-label-line-height, inherit);
+ }
+
+ :host([nodrop]) {
+ --vaadin-upload-border: none;
+ --vaadin-upload-border-radius: 0;
+ --vaadin-upload-padding: 0;
+ }
+
+`;
diff --git a/packages/upload/src/styles/vaadin-upload-file-base-styles.d.ts b/packages/upload/src/styles/vaadin-upload-file-base-styles.d.ts
new file mode 100644
index 0000000000..c0e4063f17
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-file-base-styles.d.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright (c) 2016 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import type { CSSResult } from 'lit';
+
+export const uploadFileStyles: CSSResult;
diff --git a/packages/upload/src/styles/vaadin-upload-file-base-styles.js b/packages/upload/src/styles/vaadin-upload-file-base-styles.js
new file mode 100644
index 0000000000..48e6950ff7
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-file-base-styles.js
@@ -0,0 +1,143 @@
+/**
+ * @license
+ * Copyright (c) 2016 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import { css } from 'lit';
+
+export const uploadFileStyles = css`
+ :host {
+ display: flex;
+ flex-direction: column;
+ gap: var(--vaadin-upload-file-gap, var(--vaadin-gap-container-block));
+ padding: var(--vaadin-upload-file-padding, var(--vaadin-padding));
+ }
+
+ [hidden] {
+ display: none;
+ }
+
+ [part='row'] {
+ align-items: center;
+ display: flex;
+ justify-content: space-between;
+ }
+
+ [part='info'] {
+ display: flex;
+ gap: var(--vaadin-gap-container-inline);
+ overflow: hidden;
+ }
+
+ [part='done-icon']:not([hidden]),
+ [part='warning-icon']:not([hidden]) {
+ display: flex;
+ }
+
+ [part='done-icon']::before,
+ [part='warning-icon']::before {
+ content: '';
+ display: inline-block;
+ flex: none;
+ height: var(--vaadin-icon-size, 1lh);
+ width: var(--vaadin-icon-size, 1lh);
+ }
+
+ [part='done-icon']::before {
+ background: var(--vaadin-upload-file-done-color, currentColor);
+ mask-image: var(--_vaadin-icon-checkmark);
+ }
+
+ [part='warning-icon']::before {
+ background: var(--vaadin-upload-file-warning-color, currentColor);
+ mask-image: var(--_vaadin-icon-warn);
+ }
+
+ [part='done-icon'][hidden] + [part='warning-icon'][hidden] ~ [part='meta'] {
+ padding-inline-start: calc(var(--vaadin-icon-size, 1lh) + var(--vaadin-gap-container-inline));
+ }
+
+ [part='meta'] {
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ }
+
+ [part='name'] {
+ color: var(--vaadin-upload-file-name-color, var(--vaadin-color));
+ font-size: var(--vaadin-upload-file-name-font-size, inherit);
+ font-weight: var(--vaadin-upload-file-name-font-weight, inherit);
+ line-height: var(--vaadin-upload-file-name-line-height, inherit);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ [part='status'] {
+ color: var(--vaadin-upload-file-status-color, var(--vaadin-color-subtle));
+ font-size: var(--vaadin-upload-file-status-font-size, inherit);
+ font-weight: var(--vaadin-upload-file-status-font-weight, inherit);
+ line-height: var(--vaadin-upload-file-status-line-height, inherit);
+ }
+
+ [part='error'] {
+ color: var(--vaadin-upload-file-error-color, var(--vaadin-color));
+ font-size: var(--vaadin-upload-file-error-font-size, inherit);
+ font-weight: var(--vaadin-upload-file-error-font-weight, inherit);
+ line-height: var(--vaadin-upload-file-error-line-height, inherit);
+ }
+
+ [part='commands'] {
+ display: flex;
+ }
+
+ button {
+ background: var(--vaadin-upload-file-button-background, transparent);
+ border: var(
+ --vaadin-upload-file-button-border,
+ var(--vaadin-upload-file-button-border-width, 1px) solid
+ var(--vaadin-upload-file-button-border-color, transparent)
+ );
+ border-radius: var(--vaadin-upload-file-button-border-radius, var(--vaadin-radius-m));
+ color: var(--vaadin-upload-file-button-text-color, var(--vaadin-color));
+ cursor: var(--vaadin-clickable-cursor);
+ flex-shrink: 0;
+ font-family: var(--vaadin-upload-file-button-font-family, inherit);
+ font-size: var(--vaadin-upload-file-button-font-size, inherit);
+ font-weight: var(--vaadin-upload-file-button-font-weight, 500);
+ height: var(--vaadin-upload-file-button-height, auto);
+ line-height: var(--vaadin-upload-file-button-line-height, inherit);
+ padding: var(--vaadin-upload-file-button-padding, var(--vaadin-padding-container));
+ }
+
+ [part='start-button']::before,
+ [part='retry-button']::before,
+ [part='remove-button']::before {
+ background: currentColor;
+ content: '';
+ display: block;
+ height: var(--vaadin-icon-size, 1lh);
+ width: var(--vaadin-icon-size, 1lh);
+ }
+
+ [part='start-button']::before {
+ mask-image: var(--_vaadin-icon-play);
+ }
+
+ [part='retry-button']::before {
+ mask-image: var(--_vaadin-icon-refresh);
+ }
+
+ [part='remove-button']::before {
+ mask-image: var(--_vaadin-icon-cross);
+ }
+
+ ::slotted([slot='progress']) {
+ margin-inline-start: calc(var(--vaadin-icon-size, 1lh) + var(--vaadin-gap-container-inline));
+ width: auto;
+ }
+
+ :host([complete]) ::slotted([slot='progress']),
+ :host([error]) ::slotted([slot='progress']) {
+ display: none;
+ }
+`;
diff --git a/packages/upload/src/styles/vaadin-upload-file-list-base-styles.d.ts b/packages/upload/src/styles/vaadin-upload-file-list-base-styles.d.ts
new file mode 100644
index 0000000000..e3967c5b56
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-file-list-base-styles.d.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import type { CSSResult } from 'lit';
+
+export const uploadFileListStyles: CSSResult;
diff --git a/packages/upload/src/styles/vaadin-upload-file-list-base-styles.js b/packages/upload/src/styles/vaadin-upload-file-list-base-styles.js
new file mode 100644
index 0000000000..1564ec6296
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-file-list-base-styles.js
@@ -0,0 +1,30 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import { css } from 'lit';
+
+export const uploadFileListStyles = css`
+ :host {
+ display: block;
+ }
+
+ :host([hidden]) {
+ display: none !important;
+ }
+
+ [part='list'] {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ }
+
+ ::slotted(li:not(:last-of-type)) {
+ border-bottom: var(
+ --vaadin-upload-file-list-border,
+ var(--vaadin-upload-file-list-border-width, 1px) solid
+ var(--vaadin-upload-file-list-border-color, var(--vaadin-border-color))
+ );
+ }
+`;
diff --git a/packages/upload/src/styles/vaadin-upload-icon-base-styles.d.ts b/packages/upload/src/styles/vaadin-upload-icon-base-styles.d.ts
new file mode 100644
index 0000000000..541895a268
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-icon-base-styles.d.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import type { CSSResult } from 'lit';
+
+export const uploadIconStyles: CSSResult;
diff --git a/packages/upload/src/styles/vaadin-upload-icon-base-styles.js b/packages/upload/src/styles/vaadin-upload-icon-base-styles.js
new file mode 100644
index 0000000000..ee83a0edbc
--- /dev/null
+++ b/packages/upload/src/styles/vaadin-upload-icon-base-styles.js
@@ -0,0 +1,26 @@
+/**
+ * @license
+ * Copyright (c) 2000 - 2025 Vaadin Ltd.
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
+ */
+import { css } from 'lit';
+
+export const uploadIconStyles = css`
+ :host {
+ display: inline-flex;
+ }
+
+ :host::before {
+ background: var(--vaadin-upload-icon-color, currentColor);
+ content: '';
+ display: inline-block;
+ flex: none;
+ height: var(--vaadin-icon-size, 1lh);
+ mask-image: var(--_vaadin-icon-upload);
+ width: var(--vaadin-icon-size, 1lh);
+ }
+
+ :host([hidden]) {
+ display: none !important;
+ }
+`;
diff --git a/packages/upload/src/vaadin-upload-icon.js b/packages/upload/src/vaadin-upload-icon.js
index 472d52ed4b..7013fbb2ff 100644
--- a/packages/upload/src/vaadin-upload-icon.js
+++ b/packages/upload/src/vaadin-upload-icon.js
@@ -3,10 +3,11 @@
* Copyright (c) 2016 - 2025 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
-import { css, html, LitElement } from 'lit';
+import { html, LitElement } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
+import { uploadIconStyles } from './styles/vaadin-upload-icon-base-styles.js';
/**
* An element used internally by ``. Not intended to be used separately.
@@ -21,15 +22,7 @@ class UploadIcon extends ThemableMixin(LumoInjectionMixin(LitElement)) {
}
static get styles() {
- return css`
- :host {
- display: inline-block;
- }
-
- :host([hidden]) {
- display: none !important;
- }
- `;
+ return uploadIconStyles;
}
static get lumoInjector() {