diff --git a/cspell.json b/cspell.json
index e5b28277e..6c381b4df 100644
--- a/cspell.json
+++ b/cspell.json
@@ -105,6 +105,7 @@
"keydown",
"keyframes",
"keymaker",
+ "Kickstarter",
"Konnor",
"Kool",
"labelledby",
@@ -117,6 +118,7 @@
"lowercasing",
"Lucide",
"maxlength",
+ "mdash",
"Menlo",
"menuitemcheckbox",
"menuitemradio",
@@ -130,6 +132,7 @@
"mouseout",
"mouseup",
"multiselectable",
+ "nbsp",
"nextjs",
"nocheck",
"noindex",
@@ -179,6 +182,7 @@
"shadowrootmode",
"Shortcode",
"Shortcodes",
+ "signup",
"sitedir",
"slotchange",
"smartquotes",
diff --git a/package-lock.json b/package-lock.json
index f82819c0d..dd58b9bd2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14029,7 +14029,8 @@
"devDependencies": {
"@wc-toolkit/jsx-types": "^1.3.0",
"eleventy-plugin-git-commit-date": "^0.1.3",
- "esbuild": "^0.25.11"
+ "esbuild": "^0.25.11",
+ "npm-check-updates": "^19.1.2"
},
"engines": {
"node": ">=14.17.0"
@@ -14037,7 +14038,7 @@
},
"packages/webawesome-pro": {
"name": "@shoelace-style/webawesome-pro",
- "version": "3.0.0-beta.6",
+ "version": "3.0.0",
"dependencies": {
"@ctrl/tinycolor": "4.1.0",
"@floating-ui/dom": "^1.6.13",
@@ -14052,7 +14053,8 @@
"devDependencies": {
"@wc-toolkit/jsx-types": "^1.3.0",
"eleventy-plugin-git-commit-date": "^0.1.3",
- "esbuild": "^0.25.11"
+ "esbuild": "^0.25.11",
+ "npm-check-updates": "^19.1.2"
},
"engines": {
"node": ">=14.17.0"
@@ -14525,6 +14527,21 @@
"node": "^18 || >=20"
}
},
+ "packages/webawesome-pro/node_modules/npm-check-updates": {
+ "version": "19.1.2",
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-19.1.2.tgz",
+ "integrity": "sha512-FNeFCVgPOj0fz89hOpGtxP2rnnRHR7hD2E8qNU8SMWfkyDZXA/xpgjsL3UMLSo3F/K13QvJDnbxPngulNDDo/g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "ncu": "build/cli.js",
+ "npm-check-updates": "build/cli.js"
+ },
+ "engines": {
+ "node": ">=20.0.0",
+ "npm": ">=8.12.1"
+ }
+ },
"packages/webawesome/node_modules/@esbuild/aix-ppc64": {
"version": "0.25.11",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz",
@@ -14966,6 +14983,20 @@
"engines": {
"node": "^18 || >=20"
}
+ },
+ "packages/webawesome/node_modules/npm-check-updates": {
+ "version": "19.1.2",
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-19.1.2.tgz",
+ "integrity": "sha512-FNeFCVgPOj0fz89hOpGtxP2rnnRHR7hD2E8qNU8SMWfkyDZXA/xpgjsL3UMLSo3F/K13QvJDnbxPngulNDDo/g==",
+ "dev": true,
+ "bin": {
+ "ncu": "build/cli.js",
+ "npm-check-updates": "build/cli.js"
+ },
+ "engines": {
+ "node": ">=20.0.0",
+ "npm": ">=8.12.1"
+ }
}
}
}
diff --git a/package.json b/package.json
index 3393e2f48..2f2b446cc 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "@webawesome/monorepo",
"private": true,
"description": "A forward-thinking library of web components.",
- "version": "3.0.0-alpha.13",
+ "version": "3.0.0",
"homepage": "https://webawesome.com/",
"author": "Web Awesome",
"license": "MIT",
@@ -85,4 +85,4 @@
"prettier --write"
]
}
-}
+}
\ No newline at end of file
diff --git a/packages/webawesome/docs/_includes/_dialog-wa-launch.njk b/packages/webawesome/docs/_includes/_dialog-wa-launch.njk
index e1ddbeb19..e1326ccbc 100644
--- a/packages/webawesome/docs/_includes/_dialog-wa-launch.njk
+++ b/packages/webawesome/docs/_includes/_dialog-wa-launch.njk
@@ -14,8 +14,8 @@
Celebrate our official launch with a 20% discount on a Web Awesome Pro plan…for life ! But hurry, this lifetime discount is only available for a limited time.
-
Maybe Later
-
+ Maybe Later
+
Get Pro + Save 20%
@@ -43,13 +43,6 @@
return;
}
- // Helper function to safely track Plausible events
- const trackEvent = (eventName) => {
- if (typeof plausible !== 'undefined') {
- plausible(eventName);
- }
- };
-
// Initialize dialog functionality
let initCalled = false;
const initDialog = () => {
@@ -59,19 +52,8 @@
}
initCalled = true;
- // Track when dialog is shown
- dialog.addEventListener('wa-show', () => {
- trackEvent('launch_dialog:view');
- }, { once: true });
-
- // Track when dialog is dismissed
+ // Save dismissal state when dialog is hidden
dialog.addEventListener('wa-hide', (event) => {
- // Track overlay click or Escape key dismissal
- // Button clicks are tracked via CSS classes, so we only track non-button dismissals
- if (event.detail?.source === dialog) {
- trackEvent('launch_dialog:overlay_click');
- }
-
// Save dismissal state to localStorage
try {
localStorage.setItem(SITE_DIALOG_DISMISSED_KEY, 'true');
diff --git a/packages/webawesome/docs/_includes/base.njk b/packages/webawesome/docs/_includes/base.njk
index 26b50c2b1..eb7d837ec 100644
--- a/packages/webawesome/docs/_includes/base.njk
+++ b/packages/webawesome/docs/_includes/base.njk
@@ -17,7 +17,6 @@
{% if hasSidebar %}{% endif %}
-
{% block head %}
@@ -142,6 +141,9 @@
{% include "_dialog-wa-launch.njk" ignore missing %}
{% endif %}
+ {#- Cookie Consent Dialog -#}
+ {% include "cookie-consent.njk" ignore missing %}
+
{# Footer #}
{% block pageFooter %}{% endblock %}
diff --git a/packages/webawesome/docs/_includes/sidebar.njk b/packages/webawesome/docs/_includes/sidebar.njk
index ee902cd5d..1f85fb8c9 100644
--- a/packages/webawesome/docs/_includes/sidebar.njk
+++ b/packages/webawesome/docs/_includes/sidebar.njk
@@ -78,10 +78,18 @@
- Charts {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+ Charts {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}
Checkbox
Color Picker
- Combobox {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+
+
+
+ Combobox
+
+
+ {{ proBadge() }}
+
+
Comparison
@@ -89,8 +97,8 @@
- Data Grid {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
- Datepicker {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+ Data Grid {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}
+ Date Picker {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}
Details
Dialog
Divider
@@ -101,7 +109,7 @@
Dropdown Item
- File Input {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+ File Input {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}
Format Bytes
Format Date
Format Number
@@ -146,7 +154,7 @@
Tag
Textarea
- Toast {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+ Toast {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge( { description: "This will require access to Web Awesome Pro" }) }}
Tooltip
Tree
@@ -154,7 +162,7 @@
Tree Item
- Video {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}
+ Video {{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }} {{ proBadge( { description: "This will require access to Web Awesome Pro" }) }}
Zoomable Frame
{# PLOP_NEW_COMPONENT_PLACEHOLDER #}
diff --git a/packages/webawesome/docs/_layouts/component.njk b/packages/webawesome/docs/_layouts/component.njk
index 4c260f17c..b6dd8d18d 100644
--- a/packages/webawesome/docs/_layouts/component.njk
+++ b/packages/webawesome/docs/_layouts/component.njk
@@ -8,10 +8,13 @@
Since {{ component.since }}
{{ component.status }}
+ {% if isProComponent %}
+ Pro
+ {% endif %}
{{ component.summary | inlineMarkdown | safe }}
@@ -20,6 +23,37 @@
{# Component API #}
{% block afterContent %}
+ {# Importing #}
+
Importing
+
+ Autoloading components via projects is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
+
+
+ {% set componentName = component.tagName | stripPrefix %}
+ {% set componentPath = ["components/", componentName, "/", componentName, ".js"] | join("") %}
+
+ CDN
+ npm
+ React
+
+
+ Let your project code do the work! Sign up for free to use a project with your very own CDN — it's the fastest and easiest way to use Web Awesome.
+
+
+
+
+ To manually import this component from NPM, use the following code.
+
+ import '@awesome.me/webawesome/dist/{{ componentPath }}';
+
+
+
+ To manually import this component from React, use the following code.
+
+ import {{ component.name }} from '@awesome.me/webawesome/dist/react/{{ componentName }}';
+
+
+
{# Slots #}
{% if component.slots.length %}
Slots
@@ -270,38 +304,6 @@
{% endif %}
- {# Importing #}
- Importing
-
- Autoloading components via projects is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
-
-
-
- {% set componentName = component.tagName | stripPrefix %}
- {% set componentPath = ["components/", componentName, "/", componentName, ".js"] | join("") %}
-
- CDN
- npm
- React
-
-
- Let your project code do the work! Sign up for free to use a project with your very own CDN — it's the fastest and easiest way to use Web Awesome.
-
-
-
-
- To manually import this component from NPM, use the following code.
-
- import '@awesome.me/webawesome/dist/{{ componentPath }}';
-
-
-
- To manually import this component from React, use the following code.
-
- import {{ component.name }} from '@awesome.me/webawesome/dist/react/{{ componentName }}';
-
-
-
diff --git a/packages/webawesome/docs/_utils/simulate-webawesome-app.js b/packages/webawesome/docs/_utils/simulate-webawesome-app.js
index 0c07a25c7..f24682521 100644
--- a/packages/webawesome/docs/_utils/simulate-webawesome-app.js
+++ b/packages/webawesome/docs/_utils/simulate-webawesome-app.js
@@ -1,10 +1,20 @@
+import * as path from 'node:path';
import nunjucks from 'nunjucks';
+const baseDir = process.env.BASE_DIR || 'docs';
+
+const views = [path.join(baseDir), path.join(baseDir, '_layouts'), path.join(baseDir, '_includes')];
+
+const nunjucksEnv = new nunjucks.Environment(new nunjucks.FileSystemLoader(views), {
+ autoescape: true,
+ noCache: process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test',
+});
+
/**
* This function simulates what a server would do running "on top" of eleventy.
*/
export function SimulateWebAwesomeApp(str) {
- return nunjucks.renderString(str, {
+ return nunjucksEnv.renderString(str, {
// Stub the server EJS shortcodes.
currentUser: {
hasPro: false,
diff --git a/packages/webawesome/docs/docs/components/button-group.md b/packages/webawesome/docs/docs/components/button-group.md
index ce4c5ebf4..5a95cd281 100644
--- a/packages/webawesome/docs/docs/components/button-group.md
+++ b/packages/webawesome/docs/docs/components/button-group.md
@@ -40,60 +40,6 @@ Set the `orientation` attribute to `vertical` to make a vertical button group.
```
-### Theme Buttons
-
-Theme buttons are supported through the button group's `variant` attribute.
-
-```html {.example}
-
- Left
- Center
- Right
-
-
-
-
-
- Left
- Center
- Right
-
-
-
-
-
- Left
- Center
- Right
-
-
-
-
-
- Left
- Center
- Right
-
-
-
-
-
- Left
- Center
- Right
-
-```
-
-You can still use the buttons’ own `variant` attribute to override the inherited variant.
-
-```html {.example}
-
- Left
- Center
- Right
-
-```
-
### Pill Buttons
Pill buttons are supported through the button's `pill` attribute.
diff --git a/packages/webawesome/docs/docs/components/intersection-observer.md b/packages/webawesome/docs/docs/components/intersection-observer.md
index 1252b2bcd..c2fd70e25 100644
--- a/packages/webawesome/docs/docs/components/intersection-observer.md
+++ b/packages/webawesome/docs/docs/components/intersection-observer.md
@@ -2,6 +2,7 @@
title: Intersection Observer
description: Tracks immediate child elements and fires events as they move in and out of view.
layout: component
+category: Utilities
---
This component leverages the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) to track when its direct children enter or leave a designated root element. The `wa-intersect` event fires whenever elements cross the visibility threshold.
diff --git a/packages/webawesome/docs/docs/components/select.md b/packages/webawesome/docs/docs/components/select.md
index ff7135e8a..2878fc00b 100644
--- a/packages/webawesome/docs/docs/components/select.md
+++ b/packages/webawesome/docs/docs/components/select.md
@@ -285,9 +285,10 @@ Remember that custom tags are rendered in a shadow root. To style them, you can
const name = option.querySelector('wa-icon[slot="start"]').name;
// You can return a string, a Lit Template, or an HTMLElement here
+ // Important: include data-value so the tag can be removed properly!
return `
-
-
+
+
${option.label}
`;
@@ -299,6 +300,10 @@ Remember that custom tags are rendered in a shadow root. To style them, you can
Be sure you trust the content you are outputting! Passing unsanitized user input to `getTag()` can result in XSS vulnerabilities.
:::
+:::info
+When using custom tags with `with-remove`, you must include the `data-value` attribute set to the option's value. This allows the select to identify which option to deselect when the tag's remove button is clicked.
+:::
+
### Lazy loading options
Lazy loading options works similarly to native `` elements. The select component handles various scenarios intelligently:
diff --git a/packages/webawesome/docs/docs/resources/changelog.md b/packages/webawesome/docs/docs/resources/changelog.md
index bbe8c61a6..0e2eb6ef7 100644
--- a/packages/webawesome/docs/docs/resources/changelog.md
+++ b/packages/webawesome/docs/docs/resources/changelog.md
@@ -13,6 +13,9 @@ Components with the Experimental badge sh
## Next
+- Added `` as an experimental pro component [issue:1074]
+- Added version 2.0.0 of the [official Web Awesome Figma Design Kit](/docs/resources/figma)
+- Added npm support for Web Awesome Pro
- Added `layers.css` to define cascade layer order and updated palettes, themes, native styles, and utilities to import the new rule for more fail-safe modularity [pr:1793]
- Fixed a bug in `` that caused some touch devices to end up with the incorrect value [issue:1703]
- Fixed a bug in `` that prevented some slots from being detected correctly [discuss:1450]
@@ -20,9 +23,13 @@ Components with the Experimental badge sh
- Fixed a bug in `` that caused some icon libraries to render with the incorrect SVG fill [issue:1733]
- Fixed a bug in `` that caused the spinner to not show when lazy loading [issue:1678]
- Fixed a bug in `` that caused the browser to hang when cancelling the `wa-hide` event [issue:1483]
+- Fixed a bug in `` that prevented the icon dependency from being imported [issue:1825]
+- Fixed a bug in `` that prevented clicks on the tag's remove button from removing options in multiple mode
+- Fixed a bug in `` that caused tags to appear in alphabetical order instead of selection order when using `multiple`
- Improved performance of `` so initial rendering occurs faster, especially with multiple icons on the page [issue:1729]
- Fixed a bug in Web Awesome form controls that caused `` to set the form property to equal `"foo"` instead of returning an `HTMLFormElement` breaking platform expectations. [pr:1815]
- Fixed a bug in `` causing it to not copy over attributes for form submissions. [pr:1815]
+- Improved performance of all components by fixing how CSS is imported and reused [issue:1812]
- Modified the default `transition` styles of `` to use design tokens [pr:1693]
## 3.0.0
diff --git a/packages/webawesome/package.json b/packages/webawesome/package.json
index 176b36f6d..11c9a106e 100644
--- a/packages/webawesome/package.json
+++ b/packages/webawesome/package.json
@@ -64,10 +64,10 @@
"spellcheck": "cspell \"**/*.{js,ts,json,html,css,md}\" --no-progress --config=\"../../cspell.json\"",
"verify": "npm run prettier && npm run build && npm run test",
"prepublishOnly": "npm run verify",
- "check-updates": "npx npm-check-updates --interactive --format group",
+ "check-updates": "npm-check-updates --cooldown 7 --interactive --format group",
"print-version": "echo $npm_package_version",
"tag-version": "git tag -a \"v$(npm run print-version | tail -n1)\" -m \"tag v$(npm run print-version | tail -n1)\"",
- "postversion": "npm run tag-version"
+ "postversion": "npm run tag-version && node ./scripts/update-root-version.js"
},
"engines": {
"node": ">=14.17.0"
@@ -91,6 +91,7 @@
"devDependencies": {
"@wc-toolkit/jsx-types": "^1.3.0",
"eleventy-plugin-git-commit-date": "^0.1.3",
- "esbuild": "^0.25.11"
+ "esbuild": "^0.25.11",
+ "npm-check-updates": "^19.1.2"
}
}
diff --git a/packages/webawesome/scripts/build.js b/packages/webawesome/scripts/build.js
index f9c6112ef..4bfe15c27 100644
--- a/packages/webawesome/scripts/build.js
+++ b/packages/webawesome/scripts/build.js
@@ -230,9 +230,6 @@ export async function build(options = {}) {
js: `/*! Copyright ${currentYear} Fonticons, Inc. - https://webawesome.com/license */`,
},
plugins: [replace({ __WEBAWESOME_VERSION__: await getVersion() })],
- loader: {
- '.css': 'text',
- },
};
const unbundledConfig = {
diff --git a/packages/webawesome/scripts/update-root-version.js b/packages/webawesome/scripts/update-root-version.js
new file mode 100755
index 000000000..20490af94
--- /dev/null
+++ b/packages/webawesome/scripts/update-root-version.js
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+
+import * as fs from 'node:fs';
+import * as path from 'node:path';
+import * as url from 'url';
+
+const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
+
+const monorepoRoot = path.resolve(__dirname, '..', '..', '..');
+const rootPackageJSONFile = path.join(monorepoRoot, 'package.json');
+const webawesomePackageJSONFile = path.join(path.resolve(__dirname, '..'), 'package.json');
+
+const rootPackageJSON = JSON.parse(fs.readFileSync(rootPackageJSONFile));
+const webawesomePackageJSON = JSON.parse(fs.readFileSync(webawesomePackageJSONFile));
+
+const currentVersion = webawesomePackageJSON.version;
+rootPackageJSON.version = currentVersion;
+
+fs.writeFileSync(rootPackageJSONFile, JSON.stringify(rootPackageJSON, null, 2));
+
+const versionsFile = path.join(monorepoRoot, 'VERSIONS.txt');
+const versions = fs.readFileSync(versions).split(/\r?\n/);
+
+// TODO: Make this smart and understand semver and "insert" in the correct spot instead of appending.
+if (!versions.includes(currentVersion)) {
+ fs.appendFileSync(webawesomePackageJSON.version);
+}
diff --git a/packages/webawesome/src/components/animated-image/animated-image.css b/packages/webawesome/src/components/animated-image/animated-image.css
deleted file mode 100644
index 59f659044..000000000
--- a/packages/webawesome/src/components/animated-image/animated-image.css
+++ /dev/null
@@ -1,65 +0,0 @@
-:host {
- --control-box-size: 3rem;
- --icon-size: calc(var(--control-box-size) * 0.625);
-
- display: inline-flex;
- position: relative;
- cursor: pointer;
-}
-
-img {
- display: block;
- width: 100%;
- height: 100%;
-}
-
-img[aria-hidden='true'] {
- display: none;
-}
-
-.control-box {
- display: flex;
- position: absolute;
- align-items: center;
- justify-content: center;
- top: calc(50% - var(--control-box-size) / 2);
- right: calc(50% - var(--control-box-size) / 2);
- width: var(--control-box-size);
- height: var(--control-box-size);
- font-size: calc(var(--icon-size) * 0.75);
- background: none;
- border: solid var(--wa-border-width-s) currentColor;
- background-color: rgb(0 0 0 / 50%);
- border-radius: var(--wa-border-radius-circle);
- color: white;
- pointer-events: none;
- transition: opacity var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-@media (hover: hover) {
- :host([play]:hover) .control-box {
- opacity: 1;
- }
-}
-
-:where(:host([play]:not(:hover))) .control-box {
- opacity: 0;
-}
-
-:host([play]) slot[name='play-icon'],
-:host(:not([play])) slot[name='pause-icon'] {
- display: none;
-}
-
-/* Show control box on keyboard focus */
-.animated-image {
- &:focus {
- outline: none;
- }
-
- &:focus-visible .control-box {
- opacity: 1;
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-}
diff --git a/packages/webawesome/src/components/animated-image/animated-image.styles.ts b/packages/webawesome/src/components/animated-image/animated-image.styles.ts
new file mode 100644
index 000000000..94675b814
--- /dev/null
+++ b/packages/webawesome/src/components/animated-image/animated-image.styles.ts
@@ -0,0 +1,69 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --control-box-size: 3rem;
+ --icon-size: calc(var(--control-box-size) * 0.625);
+
+ display: inline-flex;
+ position: relative;
+ cursor: pointer;
+ }
+
+ img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ }
+
+ img[aria-hidden='true'] {
+ display: none;
+ }
+
+ .control-box {
+ display: flex;
+ position: absolute;
+ align-items: center;
+ justify-content: center;
+ top: calc(50% - var(--control-box-size) / 2);
+ right: calc(50% - var(--control-box-size) / 2);
+ width: var(--control-box-size);
+ height: var(--control-box-size);
+ font-size: calc(var(--icon-size) * 0.75);
+ background: none;
+ border: solid var(--wa-border-width-s) currentColor;
+ background-color: rgb(0 0 0 / 50%);
+ border-radius: var(--wa-border-radius-circle);
+ color: white;
+ pointer-events: none;
+ transition: opacity var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ @media (hover: hover) {
+ :host([play]:hover) .control-box {
+ opacity: 1;
+ }
+ }
+
+ :where(:host([play]:not(:hover))) .control-box {
+ opacity: 0;
+ }
+
+ :host([play]) slot[name='play-icon'],
+ :host(:not([play])) slot[name='pause-icon'] {
+ display: none;
+ }
+
+ /* Show control box on keyboard focus */
+ .animated-image {
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible .control-box {
+ opacity: 1;
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/animated-image/animated-image.ts b/packages/webawesome/src/components/animated-image/animated-image.ts
index f12ad4f06..c041841fa 100644
--- a/packages/webawesome/src/components/animated-image/animated-image.ts
+++ b/packages/webawesome/src/components/animated-image/animated-image.ts
@@ -6,7 +6,7 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './animated-image.css';
+import styles from './animated-image.styles.js';
/**
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
diff --git a/packages/webawesome/src/components/animation/animation.css b/packages/webawesome/src/components/animation/animation.css
deleted file mode 100644
index 92d692cdd..000000000
--- a/packages/webawesome/src/components/animation/animation.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:host {
- display: contents;
-}
diff --git a/packages/webawesome/src/components/animation/animation.styles.ts b/packages/webawesome/src/components/animation/animation.styles.ts
new file mode 100644
index 000000000..1ef4bf6f3
--- /dev/null
+++ b/packages/webawesome/src/components/animation/animation.styles.ts
@@ -0,0 +1,7 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: contents;
+ }
+`;
diff --git a/packages/webawesome/src/components/animation/animation.ts b/packages/webawesome/src/components/animation/animation.ts
index e77ee92aa..7a0e9b06d 100644
--- a/packages/webawesome/src/components/animation/animation.ts
+++ b/packages/webawesome/src/components/animation/animation.ts
@@ -5,7 +5,7 @@ import { WaFinishEvent } from '../../events/finish.js';
import { WaStartEvent } from '../../events/start.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './animation.css';
+import styles from './animation.styles.js';
import { animations } from './animations.js';
/**
diff --git a/packages/webawesome/src/components/avatar/avatar.css b/packages/webawesome/src/components/avatar/avatar.css
deleted file mode 100644
index 2c071cb5c..000000000
--- a/packages/webawesome/src/components/avatar/avatar.css
+++ /dev/null
@@ -1,53 +0,0 @@
-:host {
- --size: 3rem;
-
- display: inline-flex;
- align-items: center;
- justify-content: center;
- position: relative;
- width: var(--size);
- height: var(--size);
- color: var(--wa-color-neutral-on-normal);
- font: inherit;
- font-size: calc(var(--size) * 0.4);
- vertical-align: middle;
- background-color: var(--wa-color-neutral-fill-normal);
- border-radius: var(--wa-border-radius-circle);
- user-select: none;
- -webkit-user-select: none;
-}
-
-:host([shape='square']) {
- border-radius: 0;
-}
-
-:host([shape='rounded']) {
- border-radius: var(--wa-border-radius-m);
-}
-
-.icon {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
-}
-
-.initials {
- line-height: 1;
- text-transform: uppercase;
-}
-
-.image {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- object-fit: cover;
- overflow: hidden;
- border-radius: inherit;
-}
diff --git a/packages/webawesome/src/components/avatar/avatar.styles.ts b/packages/webawesome/src/components/avatar/avatar.styles.ts
new file mode 100644
index 000000000..98d8c5ae4
--- /dev/null
+++ b/packages/webawesome/src/components/avatar/avatar.styles.ts
@@ -0,0 +1,57 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --size: 3rem;
+
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ width: var(--size);
+ height: var(--size);
+ color: var(--wa-color-neutral-on-normal);
+ font: inherit;
+ font-size: calc(var(--size) * 0.4);
+ vertical-align: middle;
+ background-color: var(--wa-color-neutral-fill-normal);
+ border-radius: var(--wa-border-radius-circle);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ :host([shape='square']) {
+ border-radius: 0;
+ }
+
+ :host([shape='rounded']) {
+ border-radius: var(--wa-border-radius-m);
+ }
+
+ .icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ }
+
+ .initials {
+ line-height: 1;
+ text-transform: uppercase;
+ }
+
+ .image {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ overflow: hidden;
+ border-radius: inherit;
+ }
+`;
diff --git a/packages/webawesome/src/components/avatar/avatar.ts b/packages/webawesome/src/components/avatar/avatar.ts
index 7dc7a1530..4b2c983c9 100644
--- a/packages/webawesome/src/components/avatar/avatar.ts
+++ b/packages/webawesome/src/components/avatar/avatar.ts
@@ -4,7 +4,7 @@ import { WaErrorEvent } from '../../events/error.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import '../icon/icon.js';
-import styles from './avatar.css';
+import styles from './avatar.styles.js';
/**
* @summary Avatars are used to represent a person or object.
diff --git a/packages/webawesome/src/components/badge/badge.css b/packages/webawesome/src/components/badge/badge.css
deleted file mode 100644
index 6fceaac75..000000000
--- a/packages/webawesome/src/components/badge/badge.css
+++ /dev/null
@@ -1,104 +0,0 @@
-:host {
- --pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
-
- display: inline-flex;
- align-items: center;
- justify-content: center;
- padding: 0.375em 0.625em;
- color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
- font-size: max(var(--wa-font-size-2xs), 0.75em);
- font-weight: var(--wa-font-weight-semibold);
- line-height: 1;
- white-space: nowrap;
- background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
- border-color: transparent;
- border-radius: var(--wa-border-radius-s);
- border-style: var(--wa-border-style);
- border-width: var(--wa-border-width-s);
- user-select: none;
- -webkit-user-select: none;
- cursor: inherit;
-}
-
-/* Appearance modifiers */
-:host([appearance='outlined']) {
- --pulse-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
-
- color: var(--wa-color-on-quiet, var(--wa-color-brand-on-quiet));
- background-color: transparent;
- border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
-}
-
-:host([appearance='filled']) {
- --pulse-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
-
- color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
- background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
- border-color: transparent;
-}
-
-:host([appearance='filled-outlined']) {
- --pulse-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
-
- color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
- background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
- border-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
-}
-
-:host([appearance='accent']) {
- --pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
-
- color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
- background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
- border-color: transparent;
-}
-
-/* Pill modifier */
-:host([pill]) {
- border-radius: var(--wa-border-radius-pill);
-}
-
-/* Pulse attention */
-:host([attention='pulse']) {
- animation: pulse 1.5s infinite;
-}
-
-@keyframes pulse {
- 0% {
- box-shadow: 0 0 0 0 var(--pulse-color);
- }
- 70% {
- box-shadow: 0 0 0 0.5rem transparent;
- }
- 100% {
- box-shadow: 0 0 0 0 transparent;
- }
-}
-
-/* Bounce attention */
-:host([attention='bounce']) {
- animation: bounce 1s cubic-bezier(0.28, 0.84, 0.42, 1) infinite;
-}
-
-@keyframes bounce {
- 0%,
- 20%,
- 50%,
- 80%,
- 100% {
- transform: translateY(0);
- }
- 40% {
- transform: translateY(-5px);
- }
- 60% {
- transform: translateY(-2px);
- }
-}
-
-::slotted(wa-icon) {
- margin-inline-end: var(--wa-space-2xs, 0.25em);
- opacity: 90%;
- line-height: 1;
- height: 0.85em;
-}
diff --git a/packages/webawesome/src/components/badge/badge.styles.ts b/packages/webawesome/src/components/badge/badge.styles.ts
new file mode 100644
index 000000000..14147861e
--- /dev/null
+++ b/packages/webawesome/src/components/badge/badge.styles.ts
@@ -0,0 +1,108 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
+
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.375em 0.625em;
+ color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
+ font-size: max(var(--wa-font-size-2xs), 0.75em);
+ font-weight: var(--wa-font-weight-semibold);
+ line-height: 1;
+ white-space: nowrap;
+ background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
+ border-color: transparent;
+ border-radius: var(--wa-border-radius-s);
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-border-width-s);
+ user-select: none;
+ -webkit-user-select: none;
+ cursor: inherit;
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='outlined']) {
+ --pulse-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
+
+ color: var(--wa-color-on-quiet, var(--wa-color-brand-on-quiet));
+ background-color: transparent;
+ border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
+ }
+
+ :host([appearance='filled']) {
+ --pulse-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
+
+ color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
+ background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
+ border-color: transparent;
+ }
+
+ :host([appearance='filled-outlined']) {
+ --pulse-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
+
+ color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
+ background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
+ border-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
+ }
+
+ :host([appearance='accent']) {
+ --pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
+
+ color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
+ background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
+ border-color: transparent;
+ }
+
+ /* Pill modifier */
+ :host([pill]) {
+ border-radius: var(--wa-border-radius-pill);
+ }
+
+ /* Pulse attention */
+ :host([attention='pulse']) {
+ animation: pulse 1.5s infinite;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 var(--pulse-color);
+ }
+ 70% {
+ box-shadow: 0 0 0 0.5rem transparent;
+ }
+ 100% {
+ box-shadow: 0 0 0 0 transparent;
+ }
+ }
+
+ /* Bounce attention */
+ :host([attention='bounce']) {
+ animation: bounce 1s cubic-bezier(0.28, 0.84, 0.42, 1) infinite;
+ }
+
+ @keyframes bounce {
+ 0%,
+ 20%,
+ 50%,
+ 80%,
+ 100% {
+ transform: translateY(0);
+ }
+ 40% {
+ transform: translateY(-5px);
+ }
+ 60% {
+ transform: translateY(-2px);
+ }
+ }
+
+ ::slotted(wa-icon) {
+ margin-inline-end: var(--wa-space-2xs, 0.25em);
+ opacity: 90%;
+ line-height: 1;
+ height: 0.85em;
+ }
+`;
diff --git a/packages/webawesome/src/components/badge/badge.ts b/packages/webawesome/src/components/badge/badge.ts
index 13c3fa375..892eadb27 100644
--- a/packages/webawesome/src/components/badge/badge.ts
+++ b/packages/webawesome/src/components/badge/badge.ts
@@ -1,8 +1,8 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import variantStyles from '../../styles/utilities/variants.css';
-import styles from './badge.css';
+import variantStyles from '../../styles/component/variants.styles.js';
+import styles from './badge.styles.js';
/**
* @summary Badges are used to draw attention and display statuses or counts.
diff --git a/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.css b/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.css
deleted file mode 100644
index 4784fa017..000000000
--- a/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.css
+++ /dev/null
@@ -1,81 +0,0 @@
-:host {
- color: var(--wa-color-text-link);
- display: inline-flex;
- align-items: center;
- font: inherit;
- font-weight: var(--wa-font-weight-action);
- line-height: var(--wa-line-height-normal);
- white-space: nowrap;
-}
-
-:host(:last-of-type) {
- color: var(--wa-color-text-quiet);
-}
-
-.label {
- display: inline-block;
- font: inherit;
- text-decoration: none;
- color: currentColor;
- background: none;
- border: none;
- border-radius: var(--wa-border-radius-m);
- padding: 0;
- margin: 0;
- cursor: pointer;
- transition: color var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-@media (hover: hover) {
- :host(:not(:last-of-type)) .label:hover {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
- }
-}
-
-:host(:not(:last-of-type)) .label:active {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
-}
-
-.label:focus {
- outline: none;
-}
-
-.label:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-.start,
-.end {
- display: none;
- flex: 0 0 auto;
- display: flex;
- align-items: center;
-}
-
-.start,
-.end {
- display: inline-flex;
- color: var(--wa-color-text-quiet);
-}
-
-::slotted([slot='start']) {
- margin-inline-end: var(--wa-space-s);
-}
-
-::slotted([slot='end']) {
- margin-inline-start: var(--wa-space-s);
-}
-
-:host(:last-of-type) .separator {
- display: none;
-}
-
-.separator {
- color: var(--wa-color-text-quiet);
- display: inline-flex;
- align-items: center;
- margin: 0 var(--wa-space-s);
- user-select: none;
- -webkit-user-select: none;
-}
diff --git a/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.styles.ts b/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.styles.ts
new file mode 100644
index 000000000..b7370f626
--- /dev/null
+++ b/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.styles.ts
@@ -0,0 +1,85 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ color: var(--wa-color-text-link);
+ display: inline-flex;
+ align-items: center;
+ font: inherit;
+ font-weight: var(--wa-font-weight-action);
+ line-height: var(--wa-line-height-normal);
+ white-space: nowrap;
+ }
+
+ :host(:last-of-type) {
+ color: var(--wa-color-text-quiet);
+ }
+
+ .label {
+ display: inline-block;
+ font: inherit;
+ text-decoration: none;
+ color: currentColor;
+ background: none;
+ border: none;
+ border-radius: var(--wa-border-radius-m);
+ padding: 0;
+ margin: 0;
+ cursor: pointer;
+ transition: color var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ @media (hover: hover) {
+ :host(:not(:last-of-type)) .label:hover {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+ }
+
+ :host(:not(:last-of-type)) .label:active {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
+ }
+
+ .label:focus {
+ outline: none;
+ }
+
+ .label:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ .start,
+ .end {
+ display: none;
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ }
+
+ .start,
+ .end {
+ display: inline-flex;
+ color: var(--wa-color-text-quiet);
+ }
+
+ ::slotted([slot='start']) {
+ margin-inline-end: var(--wa-space-s);
+ }
+
+ ::slotted([slot='end']) {
+ margin-inline-start: var(--wa-space-s);
+ }
+
+ :host(:last-of-type) .separator {
+ display: none;
+ }
+
+ .separator {
+ color: var(--wa-color-text-quiet);
+ display: inline-flex;
+ align-items: center;
+ margin: 0 var(--wa-space-s);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+`;
diff --git a/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.ts b/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.ts
index ff9c8b29d..83ec368c5 100644
--- a/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.ts
+++ b/packages/webawesome/src/components/breadcrumb-item/breadcrumb-item.ts
@@ -3,7 +3,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './breadcrumb-item.css';
+import styles from './breadcrumb-item.styles.js';
/**
* @summary Breadcrumb Items are used inside breadcrumbs to represent different links.
diff --git a/packages/webawesome/src/components/breadcrumb/breadcrumb.css b/packages/webawesome/src/components/breadcrumb/breadcrumb.css
deleted file mode 100644
index a45d4f776..000000000
--- a/packages/webawesome/src/components/breadcrumb/breadcrumb.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.breadcrumb {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
-}
diff --git a/packages/webawesome/src/components/breadcrumb/breadcrumb.styles.ts b/packages/webawesome/src/components/breadcrumb/breadcrumb.styles.ts
new file mode 100644
index 000000000..86c0e16e0
--- /dev/null
+++ b/packages/webawesome/src/components/breadcrumb/breadcrumb.styles.ts
@@ -0,0 +1,9 @@
+import { css } from 'lit';
+
+export default css`
+ .breadcrumb {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ }
+`;
diff --git a/packages/webawesome/src/components/breadcrumb/breadcrumb.ts b/packages/webawesome/src/components/breadcrumb/breadcrumb.ts
index be3e24a24..0f2f77093 100644
--- a/packages/webawesome/src/components/breadcrumb/breadcrumb.ts
+++ b/packages/webawesome/src/components/breadcrumb/breadcrumb.ts
@@ -4,7 +4,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import type WaBreadcrumbItem from '../breadcrumb-item/breadcrumb-item.js';
import '../icon/icon.js';
-import styles from './breadcrumb.css';
+import styles from './breadcrumb.styles.js';
/**
* @summary Breadcrumbs provide a group of links so users can easily navigate a website's hierarchy.
diff --git a/packages/webawesome/src/components/button-group/button-group.css b/packages/webawesome/src/components/button-group/button-group.css
deleted file mode 100644
index ee7e152c0..000000000
--- a/packages/webawesome/src/components/button-group/button-group.css
+++ /dev/null
@@ -1,44 +0,0 @@
-:host {
- display: inline-flex;
-}
-
-.button-group {
- display: flex;
- position: relative;
- isolation: isolate;
- flex-wrap: wrap;
- gap: 1px;
-
- @media (hover: hover) {
- > :hover,
- &::slotted(:hover) {
- z-index: 1;
- }
- }
-
- /* Focus and checked are always on top */
- > :focus,
- &::slotted(:focus),
- > [aria-checked='true'],
- &::slotted([aria-checked='true']),
- > [checked],
- &::slotted([checked]) {
- z-index: 2 !important;
- }
-}
-:host([orientation='vertical']) .button-group {
- flex-direction: column;
-}
-
-/* Button groups with at least one outlined button will not have a gap and instead have borders overlap */
-.button-group.has-outlined {
- gap: 0;
-
- &:not([aria-orientation='vertical']):not(.button-group-vertical)::slotted(:not(:first-child)) {
- margin-inline-start: calc(-1 * var(--border-width));
- }
-
- &:is([aria-orientation='vertical'], .button-group-vertical)::slotted(:not(:first-child)) {
- margin-block-start: calc(-1 * var(--border-width));
- }
-}
diff --git a/packages/webawesome/src/components/button-group/button-group.styles.ts b/packages/webawesome/src/components/button-group/button-group.styles.ts
new file mode 100644
index 000000000..dfa4d85c9
--- /dev/null
+++ b/packages/webawesome/src/components/button-group/button-group.styles.ts
@@ -0,0 +1,48 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: inline-flex;
+ }
+
+ .button-group {
+ display: flex;
+ position: relative;
+ isolation: isolate;
+ flex-wrap: wrap;
+ gap: 1px;
+
+ @media (hover: hover) {
+ > :hover,
+ &::slotted(:hover) {
+ z-index: 1;
+ }
+ }
+
+ /* Focus and checked are always on top */
+ > :focus,
+ &::slotted(:focus),
+ > [aria-checked='true'],
+ &::slotted([aria-checked='true']),
+ > [checked],
+ &::slotted([checked]) {
+ z-index: 2 !important;
+ }
+ }
+ :host([orientation='vertical']) .button-group {
+ flex-direction: column;
+ }
+
+ /* Button groups with at least one outlined button will not have a gap and instead have borders overlap */
+ .button-group.has-outlined {
+ gap: 0;
+
+ &:not([aria-orientation='vertical']):not(.button-group-vertical)::slotted(:not(:first-child)) {
+ margin-inline-start: calc(-1 * var(--border-width));
+ }
+
+ &:is([aria-orientation='vertical'], .button-group-vertical)::slotted(:not(:first-child)) {
+ margin-block-start: calc(-1 * var(--border-width));
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/button-group/button-group.ts b/packages/webawesome/src/components/button-group/button-group.ts
index 0a491c3ad..cda7123c5 100644
--- a/packages/webawesome/src/components/button-group/button-group.ts
+++ b/packages/webawesome/src/components/button-group/button-group.ts
@@ -4,7 +4,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type WaButton from '../button/button.js';
-import styles from './button-group.css';
+import styles from './button-group.styles.js';
/**
* @summary Button groups can be used to group related buttons into sections.
diff --git a/packages/webawesome/src/components/button/button.css b/packages/webawesome/src/components/button/button.css
deleted file mode 100644
index 7660f5c0e..000000000
--- a/packages/webawesome/src/components/button/button.css
+++ /dev/null
@@ -1,372 +0,0 @@
-@layer wa-component {
- :host {
- display: inline-block;
-
- /* Workaround because Chrome doesn't like :host(:has()) below
- * https://issues.chromium.org/issues/40062355
- * Firefox doesn't like this nested rule, so both are needed */
- &:has(wa-badge) {
- position: relative;
- }
- }
-
- /* Apply relative positioning only when needed to position wa-badge
- * This avoids creating a new stacking context for every button */
- :host(:has(wa-badge)) {
- position: relative;
- }
-}
-
-.button {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- text-decoration: none;
- user-select: none;
- -webkit-user-select: none;
- white-space: nowrap;
- vertical-align: middle;
- transition-property: background, border, box-shadow, color;
- transition-duration: var(--wa-transition-fast);
- transition-timing-function: var(--wa-transition-easing);
- cursor: pointer;
- padding: 0 var(--wa-form-control-padding-inline);
- font-family: inherit;
- font-size: inherit;
- font-weight: var(--wa-font-weight-action);
- line-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
- height: var(--wa-form-control-height);
- width: 100%;
-
- background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
- border-color: transparent;
- color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
- border-radius: var(--wa-form-control-border-radius);
- border-style: var(--wa-border-style);
- border-width: var(--wa-border-width-s);
-}
-
-/* Appearance modifiers */
-:host([appearance='plain']) {
- .button {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: transparent;
- border-color: transparent;
- }
- @media (hover: hover) {
- .button:not(.disabled):not(.loading):hover {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
- }
- }
- .button:not(.disabled):not(.loading):active {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
- var(--wa-color-mix-active)
- );
- }
-}
-
-:host([appearance='outlined']) {
- .button {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: transparent;
- border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
- }
- @media (hover: hover) {
- .button:not(.disabled):not(.loading):hover {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
- }
- }
- .button:not(.disabled):not(.loading):active {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
- var(--wa-color-mix-active)
- );
- }
-}
-
-:host([appearance='filled']) {
- .button {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
- border-color: transparent;
- }
- @media (hover: hover) {
- .button:not(.disabled):not(.loading):hover {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
- var(--wa-color-mix-hover)
- );
- }
- }
- .button:not(.disabled):not(.loading):active {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
- var(--wa-color-mix-active)
- );
- }
-}
-
-:host([appearance='filled-outlined']) {
- .button {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
- border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
- }
- @media (hover: hover) {
- .button:not(.disabled):not(.loading):hover {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
- var(--wa-color-mix-hover)
- );
- }
- }
- .button:not(.disabled):not(.loading):active {
- color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
- var(--wa-color-mix-active)
- );
- }
-}
-
-:host([appearance='accent']) {
- .button {
- color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
- background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
- border-color: transparent;
- }
- @media (hover: hover) {
- .button:not(.disabled):not(.loading):hover {
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
- var(--wa-color-mix-hover)
- );
- }
- }
- .button:not(.disabled):not(.loading):active {
- background-color: color-mix(
- in oklab,
- var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
- var(--wa-color-mix-active)
- );
- }
-}
-
-/* Focus states */
-.button:focus {
- outline: none;
-}
-
-.button:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/* Disabled state */
-.button.disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-/* When disabled, prevent mouse events from bubbling up from children */
-.button.disabled * {
- pointer-events: none;
-}
-
-/* Keep it last so Safari doesn't stop parsing this block */
-.button::-moz-focus-inner {
- border: 0;
-}
-
-/* Icon buttons */
-.button.is-icon-button {
- outline-offset: 2px;
- width: var(--wa-form-control-height);
- aspect-ratio: 1;
-}
-
-.button.is-icon-button:has(wa-icon) {
- width: auto;
-}
-
-/* Pill modifier */
-:host([pill]) .button {
- border-radius: var(--wa-border-radius-pill);
-}
-
-/*
- * Label
- */
-
-.start,
-.end {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- pointer-events: none;
-}
-
-.label {
- display: inline-block;
-}
-
-.is-icon-button .label {
- display: flex;
-}
-
-.label::slotted(wa-icon) {
- align-self: center;
-}
-
-/*
- * Caret modifier
- */
-
-wa-icon[part='caret'] {
- display: flex;
- align-self: center;
- align-items: center;
-
- &::part(svg) {
- width: 0.875em;
- height: 0.875em;
- }
-
- .button:has(&) .end {
- display: none;
- }
-}
-
-/*
- * Loading modifier
- */
-
-.loading {
- position: relative;
- cursor: wait;
-
- .start,
- .label,
- .end,
- .caret {
- visibility: hidden;
- }
-
- wa-spinner {
- --indicator-color: currentColor;
- --track-color: color-mix(in oklab, currentColor, transparent 90%);
-
- position: absolute;
- font-size: 1em;
- height: 1em;
- width: 1em;
- top: calc(50% - 0.5em);
- left: calc(50% - 0.5em);
- }
-}
-
-/*
- * Badges
- */
-
-.button ::slotted(wa-badge) {
- border-color: var(--wa-color-surface-default);
- position: absolute;
- inset-block-start: 0;
- inset-inline-end: 0;
- translate: 50% -50%;
- pointer-events: none;
-}
-
-:host(:dir(rtl)) ::slotted(wa-badge) {
- translate: -50% -50%;
-}
-
-/*
-* Button spacing
-*/
-
-slot[name='start']::slotted(*) {
- margin-inline-end: 0.75em;
-}
-
-slot[name='end']::slotted(*),
-.button:not(.visually-hidden-label) [part='caret'] {
- margin-inline-start: 0.75em;
-}
-
-/*
- * Button group border radius modifications
- */
-
-/* Remove border radius from all grouped buttons by default */
-:host(.wa-button-group__button) .button {
- border-radius: 0;
-}
-
-/* Horizontal orientation */
-:host(.wa-button-group__horizontal.wa-button-group__button-first) .button {
- border-start-start-radius: var(--wa-form-control-border-radius);
- border-end-start-radius: var(--wa-form-control-border-radius);
-}
-
-:host(.wa-button-group__horizontal.wa-button-group__button-last) .button {
- border-start-end-radius: var(--wa-form-control-border-radius);
- border-end-end-radius: var(--wa-form-control-border-radius);
-}
-
-/* Vertical orientation */
-:host(.wa-button-group__vertical) {
- flex: 1 1 auto;
-}
-
-:host(.wa-button-group__vertical) .button {
- width: 100%;
- justify-content: start;
-}
-
-:host(.wa-button-group__vertical.wa-button-group__button-first) .button {
- border-start-start-radius: var(--wa-form-control-border-radius);
- border-start-end-radius: var(--wa-form-control-border-radius);
-}
-
-:host(.wa-button-group__vertical.wa-button-group__button-last) .button {
- border-end-start-radius: var(--wa-form-control-border-radius);
- border-end-end-radius: var(--wa-form-control-border-radius);
-}
-
-/* Handle pill modifier for button groups */
-:host([pill].wa-button-group__horizontal.wa-button-group__button-first) .button {
- border-start-start-radius: var(--wa-border-radius-pill);
- border-end-start-radius: var(--wa-border-radius-pill);
-}
-
-:host([pill].wa-button-group__horizontal.wa-button-group__button-last) .button {
- border-start-end-radius: var(--wa-border-radius-pill);
- border-end-end-radius: var(--wa-border-radius-pill);
-}
-
-:host([pill].wa-button-group__vertical.wa-button-group__button-first) .button {
- border-start-start-radius: var(--wa-border-radius-pill);
- border-start-end-radius: var(--wa-border-radius-pill);
-}
-
-:host([pill].wa-button-group__vertical.wa-button-group__button-last) .button {
- border-end-start-radius: var(--wa-border-radius-pill);
- border-end-end-radius: var(--wa-border-radius-pill);
-}
diff --git a/packages/webawesome/src/components/button/button.styles.ts b/packages/webawesome/src/components/button/button.styles.ts
new file mode 100644
index 000000000..2cd955897
--- /dev/null
+++ b/packages/webawesome/src/components/button/button.styles.ts
@@ -0,0 +1,376 @@
+import { css } from 'lit';
+
+export default css`
+ @layer wa-component {
+ :host {
+ display: inline-block;
+
+ /* Workaround because Chrome doesn't like :host(:has()) below
+ * https://issues.chromium.org/issues/40062355
+ * Firefox doesn't like this nested rule, so both are needed */
+ &:has(wa-badge) {
+ position: relative;
+ }
+ }
+
+ /* Apply relative positioning only when needed to position wa-badge
+ * This avoids creating a new stacking context for every button */
+ :host(:has(wa-badge)) {
+ position: relative;
+ }
+ }
+
+ .button {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ text-decoration: none;
+ user-select: none;
+ -webkit-user-select: none;
+ white-space: nowrap;
+ vertical-align: middle;
+ transition-property: background, border, box-shadow, color, opacity;
+ transition-duration: var(--wa-transition-fast);
+ transition-timing-function: var(--wa-transition-easing);
+ cursor: pointer;
+ padding: 0 var(--wa-form-control-padding-inline);
+ font-family: inherit;
+ font-size: inherit;
+ font-weight: var(--wa-font-weight-action);
+ line-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
+ height: var(--wa-form-control-height);
+ width: 100%;
+
+ background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
+ border-color: transparent;
+ color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
+ border-radius: var(--wa-form-control-border-radius);
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-border-width-s);
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='plain']) {
+ .button {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: transparent;
+ border-color: transparent;
+ }
+ @media (hover: hover) {
+ .button:not(.disabled):not(.loading):hover {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
+ }
+ }
+ .button:not(.disabled):not(.loading):active {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
+ var(--wa-color-mix-active)
+ );
+ }
+ }
+
+ :host([appearance='outlined']) {
+ .button {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: transparent;
+ border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
+ }
+ @media (hover: hover) {
+ .button:not(.disabled):not(.loading):hover {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
+ }
+ }
+ .button:not(.disabled):not(.loading):active {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
+ var(--wa-color-mix-active)
+ );
+ }
+ }
+
+ :host([appearance='filled']) {
+ .button {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
+ border-color: transparent;
+ }
+ @media (hover: hover) {
+ .button:not(.disabled):not(.loading):hover {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
+ var(--wa-color-mix-hover)
+ );
+ }
+ }
+ .button:not(.disabled):not(.loading):active {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
+ var(--wa-color-mix-active)
+ );
+ }
+ }
+
+ :host([appearance='filled-outlined']) {
+ .button {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
+ border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
+ }
+ @media (hover: hover) {
+ .button:not(.disabled):not(.loading):hover {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
+ var(--wa-color-mix-hover)
+ );
+ }
+ }
+ .button:not(.disabled):not(.loading):active {
+ color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
+ var(--wa-color-mix-active)
+ );
+ }
+ }
+
+ :host([appearance='accent']) {
+ .button {
+ color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
+ background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
+ border-color: transparent;
+ }
+ @media (hover: hover) {
+ .button:not(.disabled):not(.loading):hover {
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
+ var(--wa-color-mix-hover)
+ );
+ }
+ }
+ .button:not(.disabled):not(.loading):active {
+ background-color: color-mix(
+ in oklab,
+ var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
+ var(--wa-color-mix-active)
+ );
+ }
+ }
+
+ /* Focus states */
+ .button:focus {
+ outline: none;
+ }
+
+ .button:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Disabled state */
+ .button.disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ /* When disabled, prevent mouse events from bubbling up from children */
+ .button.disabled * {
+ pointer-events: none;
+ }
+
+ /* Keep it last so Safari doesn't stop parsing this block */
+ .button::-moz-focus-inner {
+ border: 0;
+ }
+
+ /* Icon buttons */
+ .button.is-icon-button {
+ outline-offset: 2px;
+ width: var(--wa-form-control-height);
+ aspect-ratio: 1;
+ }
+
+ .button.is-icon-button:has(wa-icon) {
+ width: auto;
+ }
+
+ /* Pill modifier */
+ :host([pill]) .button {
+ border-radius: var(--wa-border-radius-pill);
+ }
+
+ /*
+ * Label
+ */
+
+ .start,
+ .end {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ pointer-events: none;
+ }
+
+ .label {
+ display: inline-block;
+ }
+
+ .is-icon-button .label {
+ display: flex;
+ }
+
+ .label::slotted(wa-icon) {
+ align-self: center;
+ }
+
+ /*
+ * Caret modifier
+ */
+
+ wa-icon[part='caret'] {
+ display: flex;
+ align-self: center;
+ align-items: center;
+
+ &::part(svg) {
+ width: 0.875em;
+ height: 0.875em;
+ }
+
+ .button:has(&) .end {
+ display: none;
+ }
+ }
+
+ /*
+ * Loading modifier
+ */
+
+ .loading {
+ position: relative;
+ cursor: wait;
+
+ .start,
+ .label,
+ .end,
+ .caret {
+ visibility: hidden;
+ }
+
+ wa-spinner {
+ --indicator-color: currentColor;
+ --track-color: color-mix(in oklab, currentColor, transparent 90%);
+
+ position: absolute;
+ font-size: 1em;
+ height: 1em;
+ width: 1em;
+ top: calc(50% - 0.5em);
+ left: calc(50% - 0.5em);
+ }
+ }
+
+ /*
+ * Badges
+ */
+
+ .button ::slotted(wa-badge) {
+ border-color: var(--wa-color-surface-default);
+ position: absolute;
+ inset-block-start: 0;
+ inset-inline-end: 0;
+ translate: 50% -50%;
+ pointer-events: none;
+ }
+
+ :host(:dir(rtl)) ::slotted(wa-badge) {
+ translate: -50% -50%;
+ }
+
+ /*
+ * Button spacing
+ */
+
+ slot[name='start']::slotted(*) {
+ margin-inline-end: 0.75em;
+ }
+
+ slot[name='end']::slotted(*),
+ .button:not(.visually-hidden-label) [part='caret'] {
+ margin-inline-start: 0.75em;
+ }
+
+ /*
+ * Button group border radius modifications
+ */
+
+ /* Remove border radius from all grouped buttons by default */
+ :host(.wa-button-group__button) .button {
+ border-radius: 0;
+ }
+
+ /* Horizontal orientation */
+ :host(.wa-button-group__horizontal.wa-button-group__button-first) .button {
+ border-start-start-radius: var(--wa-form-control-border-radius);
+ border-end-start-radius: var(--wa-form-control-border-radius);
+ }
+
+ :host(.wa-button-group__horizontal.wa-button-group__button-last) .button {
+ border-start-end-radius: var(--wa-form-control-border-radius);
+ border-end-end-radius: var(--wa-form-control-border-radius);
+ }
+
+ /* Vertical orientation */
+ :host(.wa-button-group__vertical) {
+ flex: 1 1 auto;
+ }
+
+ :host(.wa-button-group__vertical) .button {
+ width: 100%;
+ justify-content: start;
+ }
+
+ :host(.wa-button-group__vertical.wa-button-group__button-first) .button {
+ border-start-start-radius: var(--wa-form-control-border-radius);
+ border-start-end-radius: var(--wa-form-control-border-radius);
+ }
+
+ :host(.wa-button-group__vertical.wa-button-group__button-last) .button {
+ border-end-start-radius: var(--wa-form-control-border-radius);
+ border-end-end-radius: var(--wa-form-control-border-radius);
+ }
+
+ /* Handle pill modifier for button groups */
+ :host([pill].wa-button-group__horizontal.wa-button-group__button-first) .button {
+ border-start-start-radius: var(--wa-border-radius-pill);
+ border-end-start-radius: var(--wa-border-radius-pill);
+ }
+
+ :host([pill].wa-button-group__horizontal.wa-button-group__button-last) .button {
+ border-start-end-radius: var(--wa-border-radius-pill);
+ border-end-end-radius: var(--wa-border-radius-pill);
+ }
+
+ :host([pill].wa-button-group__vertical.wa-button-group__button-first) .button {
+ border-start-start-radius: var(--wa-border-radius-pill);
+ border-start-end-radius: var(--wa-border-radius-pill);
+ }
+
+ :host([pill].wa-button-group__vertical.wa-button-group__button-last) .button {
+ border-end-start-radius: var(--wa-border-radius-pill);
+ border-end-end-radius: var(--wa-border-radius-pill);
+ }
+`;
diff --git a/packages/webawesome/src/components/button/button.ts b/packages/webawesome/src/components/button/button.ts
index eda53136c..b34a2a06b 100644
--- a/packages/webawesome/src/components/button/button.ts
+++ b/packages/webawesome/src/components/button/button.ts
@@ -7,13 +7,13 @@ import { HasSlotController } from '../../internal/slot.js';
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
-import variantStyles from '../../styles/utilities/variants.css';
+import sizeStyles from '../../styles/component/size.styles.js';
+import variantStyles from '../../styles/component/variants.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import type WaIcon from '../icon/icon.js';
import '../spinner/spinner.js';
-import styles from './button.css';
+import styles from './button.styles.js';
/**
* @summary Buttons represent actions that are available to the user.
diff --git a/packages/webawesome/src/components/callout/callout.css b/packages/webawesome/src/components/callout/callout.css
deleted file mode 100644
index b7118c2e4..000000000
--- a/packages/webawesome/src/components/callout/callout.css
+++ /dev/null
@@ -1,60 +0,0 @@
-:host {
- display: flex;
- position: relative;
- align-items: stretch;
- border-radius: var(--wa-panel-border-radius);
- background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
- border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
- border-style: var(--wa-panel-border-style);
- border-width: var(--wa-panel-border-width);
- color: var(--wa-color-text-normal);
- padding: 1em;
-}
-
-/* Appearance modifiers */
-:host([appearance~='plain']) {
- background-color: transparent;
- border-color: transparent;
-}
-
-:host([appearance~='outlined']) {
- background-color: transparent;
- border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
-}
-
-:host([appearance~='filled']) {
- background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
- border-color: transparent;
-}
-
-:host([appearance~='filled-outlined']) {
- border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
-}
-
-:host([appearance~='accent']) {
- color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
- background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
- border-color: transparent;
-
- [part~='icon'] {
- color: currentColor;
- }
-}
-
-[part~='icon'] {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- color: var(--wa-color-on-quiet);
- font-size: 1.25em;
-}
-
-::slotted([slot='icon']) {
- margin-inline-end: var(--wa-form-control-padding-inline);
-}
-
-[part~='message'] {
- flex: 1 1 auto;
- display: block;
- overflow: hidden;
-}
diff --git a/packages/webawesome/src/components/callout/callout.styles.ts b/packages/webawesome/src/components/callout/callout.styles.ts
new file mode 100644
index 000000000..9b3b59a54
--- /dev/null
+++ b/packages/webawesome/src/components/callout/callout.styles.ts
@@ -0,0 +1,64 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: flex;
+ position: relative;
+ align-items: stretch;
+ border-radius: var(--wa-panel-border-radius);
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
+ border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
+ border-style: var(--wa-panel-border-style);
+ border-width: var(--wa-panel-border-width);
+ color: var(--wa-color-text-normal);
+ padding: 1em;
+ }
+
+ /* Appearance modifiers */
+ :host([appearance~='plain']) {
+ background-color: transparent;
+ border-color: transparent;
+ }
+
+ :host([appearance~='outlined']) {
+ background-color: transparent;
+ border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
+ }
+
+ :host([appearance~='filled']) {
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
+ border-color: transparent;
+ }
+
+ :host([appearance~='filled-outlined']) {
+ border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
+ }
+
+ :host([appearance~='accent']) {
+ color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
+ background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
+ border-color: transparent;
+
+ [part~='icon'] {
+ color: currentColor;
+ }
+ }
+
+ [part~='icon'] {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ color: var(--wa-color-on-quiet);
+ font-size: 1.25em;
+ }
+
+ ::slotted([slot='icon']) {
+ margin-inline-end: var(--wa-form-control-padding-inline);
+ }
+
+ [part~='message'] {
+ flex: 1 1 auto;
+ display: block;
+ overflow: hidden;
+ }
+`;
diff --git a/packages/webawesome/src/components/callout/callout.ts b/packages/webawesome/src/components/callout/callout.ts
index d33f6600b..f8a2a55aa 100644
--- a/packages/webawesome/src/components/callout/callout.ts
+++ b/packages/webawesome/src/components/callout/callout.ts
@@ -1,9 +1,9 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
-import variantStyles from '../../styles/utilities/variants.css';
-import styles from './callout.css';
+import sizeStyles from '../../styles/component/size.styles.js';
+import variantStyles from '../../styles/component/variants.styles.js';
+import styles from './callout.styles.js';
/**
* @summary Callouts are used to display important messages inline.
diff --git a/packages/webawesome/src/components/card/card.css b/packages/webawesome/src/components/card/card.css
deleted file mode 100644
index cb06f19f6..000000000
--- a/packages/webawesome/src/components/card/card.css
+++ /dev/null
@@ -1,141 +0,0 @@
-:host {
- --spacing: var(--wa-space-l);
-
- /* Internal calculated properties */
- --inner-border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
-
- display: flex;
- flex-direction: column;
- background-color: var(--wa-color-surface-default);
- border-color: var(--wa-color-surface-border);
- border-radius: var(--wa-panel-border-radius);
- border-style: var(--wa-panel-border-style);
- box-shadow: var(--wa-shadow-s);
- border-width: var(--wa-panel-border-width);
- color: var(--wa-color-text-normal);
-}
-
-/* Appearance modifiers */
-:host([appearance='plain']) {
- background-color: transparent;
- border-color: transparent;
- box-shadow: none;
-}
-
-:host([appearance='outlined']) {
- background-color: var(--wa-color-surface-default);
- border-color: var(--wa-color-surface-border);
-}
-
-:host([appearance='filled']) {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: transparent;
-}
-
-:host([appearance='filled-outlined']) {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-color-surface-border);
-}
-
-:host([appearance='accent']) {
- color: var(--wa-color-neutral-on-loud);
- background-color: var(--wa-color-neutral-fill-loud);
- border-color: transparent;
-}
-
-/* Take care of top and bottom radii */
-.media,
-:host(:not([with-media])) .header,
-:host(:not([with-media], [with-header])) .body {
- border-start-start-radius: var(--inner-border-radius);
- border-start-end-radius: var(--inner-border-radius);
-}
-
-:host(:not([with-footer])) .body,
-.footer {
- border-end-start-radius: var(--inner-border-radius);
- border-end-end-radius: var(--inner-border-radius);
-}
-
-.media {
- display: flex;
- overflow: hidden;
-
- &::slotted(*) {
- display: block;
- width: 100%;
- border-radius: 0 !important;
- }
-}
-
-/* Round all corners for plain appearance */
-:host([appearance='plain']) .media {
- border-radius: var(--inner-border-radius);
-
- &::slotted(*) {
- border-radius: inherit !important;
- }
-}
-
-.header {
- display: block;
- border-block-end-style: inherit;
- border-block-end-color: var(--wa-color-surface-border);
- border-block-end-width: var(--wa-panel-border-width);
- padding: calc(var(--spacing) / 2) var(--spacing);
-}
-
-.body {
- display: block;
- padding: var(--spacing);
-}
-
-.footer {
- display: block;
- border-block-start-style: inherit;
- border-block-start-color: var(--wa-color-surface-border);
- border-block-start-width: var(--wa-panel-border-width);
- padding: var(--spacing);
-}
-
-/* Push slots to sides when the action slots renders */
-.has-actions {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-:host(:not([with-header])) .header,
-:host(:not([with-footer])) .footer,
-:host(:not([with-media])) .media {
- display: none;
-}
-
-/* Orientation Styles */
-:host([orientation='horizontal']) {
- flex-direction: row;
-
- .media {
- border-start-start-radius: var(--inner-border-radius);
- border-end-start-radius: var(--inner-border-radius);
- border-start-end-radius: 0;
-
- &::slotted(*) {
- block-size: 100%;
- inline-size: 100%;
- object-fit: cover;
- }
- }
-}
-
-:host([orientation='horizontal']) ::slotted([slot='body']) {
- display: block;
- height: 100%;
- margin: 0;
-}
-
-:host([orientation='horizontal']) ::slotted([slot='actions']) {
- display: flex;
- align-items: center;
- padding: var(--spacing);
-}
diff --git a/packages/webawesome/src/components/card/card.styles.ts b/packages/webawesome/src/components/card/card.styles.ts
new file mode 100644
index 000000000..3c8ed1ce0
--- /dev/null
+++ b/packages/webawesome/src/components/card/card.styles.ts
@@ -0,0 +1,145 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --spacing: var(--wa-space-l);
+
+ /* Internal calculated properties */
+ --inner-border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
+
+ display: flex;
+ flex-direction: column;
+ background-color: var(--wa-color-surface-default);
+ border-color: var(--wa-color-surface-border);
+ border-radius: var(--wa-panel-border-radius);
+ border-style: var(--wa-panel-border-style);
+ box-shadow: var(--wa-shadow-s);
+ border-width: var(--wa-panel-border-width);
+ color: var(--wa-color-text-normal);
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='plain']) {
+ background-color: transparent;
+ border-color: transparent;
+ box-shadow: none;
+ }
+
+ :host([appearance='outlined']) {
+ background-color: var(--wa-color-surface-default);
+ border-color: var(--wa-color-surface-border);
+ }
+
+ :host([appearance='filled']) {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: transparent;
+ }
+
+ :host([appearance='filled-outlined']) {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-color-surface-border);
+ }
+
+ :host([appearance='accent']) {
+ color: var(--wa-color-neutral-on-loud);
+ background-color: var(--wa-color-neutral-fill-loud);
+ border-color: transparent;
+ }
+
+ /* Take care of top and bottom radii */
+ .media,
+ :host(:not([with-media])) .header,
+ :host(:not([with-media], [with-header])) .body {
+ border-start-start-radius: var(--inner-border-radius);
+ border-start-end-radius: var(--inner-border-radius);
+ }
+
+ :host(:not([with-footer])) .body,
+ .footer {
+ border-end-start-radius: var(--inner-border-radius);
+ border-end-end-radius: var(--inner-border-radius);
+ }
+
+ .media {
+ display: flex;
+ overflow: hidden;
+
+ &::slotted(*) {
+ display: block;
+ width: 100%;
+ border-radius: 0 !important;
+ }
+ }
+
+ /* Round all corners for plain appearance */
+ :host([appearance='plain']) .media {
+ border-radius: var(--inner-border-radius);
+
+ &::slotted(*) {
+ border-radius: inherit !important;
+ }
+ }
+
+ .header {
+ display: block;
+ border-block-end-style: inherit;
+ border-block-end-color: var(--wa-color-surface-border);
+ border-block-end-width: var(--wa-panel-border-width);
+ padding: calc(var(--spacing) / 2) var(--spacing);
+ }
+
+ .body {
+ display: block;
+ padding: var(--spacing);
+ }
+
+ .footer {
+ display: block;
+ border-block-start-style: inherit;
+ border-block-start-color: var(--wa-color-surface-border);
+ border-block-start-width: var(--wa-panel-border-width);
+ padding: var(--spacing);
+ }
+
+ /* Push slots to sides when the action slots renders */
+ .has-actions {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ :host(:not([with-header])) .header,
+ :host(:not([with-footer])) .footer,
+ :host(:not([with-media])) .media {
+ display: none;
+ }
+
+ /* Orientation Styles */
+ :host([orientation='horizontal']) {
+ flex-direction: row;
+
+ .media {
+ border-start-start-radius: var(--inner-border-radius);
+ border-end-start-radius: var(--inner-border-radius);
+ border-start-end-radius: 0;
+
+ &::slotted(*) {
+ block-size: 100%;
+ inline-size: 100%;
+ object-fit: cover;
+ }
+ }
+ }
+
+ :host([orientation='horizontal']) ::slotted([slot='body']) {
+ display: block;
+ height: 100%;
+ margin: 0;
+ }
+
+ :host([orientation='horizontal']) ::slotted([slot='actions']) {
+ display: flex;
+ align-items: center;
+ padding: var(--spacing);
+ }
+`;
diff --git a/packages/webawesome/src/components/card/card.ts b/packages/webawesome/src/components/card/card.ts
index 58c072852..b4e0ce8e5 100644
--- a/packages/webawesome/src/components/card/card.ts
+++ b/packages/webawesome/src/components/card/card.ts
@@ -2,8 +2,8 @@ import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { HasSlotController } from '../../internal/slot.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
-import styles from './card.css';
+import sizeStyles from '../../styles/component/size.styles.js';
+import styles from './card.styles.js';
/**
* @summary Cards can be used to group related subjects in a container.
diff --git a/packages/webawesome/src/components/carousel-item/carousel-item.css b/packages/webawesome/src/components/carousel-item/carousel-item.css
deleted file mode 100644
index abc65e317..000000000
--- a/packages/webawesome/src/components/carousel-item/carousel-item.css
+++ /dev/null
@@ -1,19 +0,0 @@
-:host {
- --aspect-ratio: inherit;
-
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- width: 100%;
- max-height: 100%;
- aspect-ratio: var(--aspect-ratio);
- scroll-snap-align: start;
- scroll-snap-stop: always;
-}
-
-::slotted(img) {
- width: 100% !important;
- height: 100% !important;
- object-fit: cover;
-}
diff --git a/packages/webawesome/src/components/carousel-item/carousel-item.styles.ts b/packages/webawesome/src/components/carousel-item/carousel-item.styles.ts
new file mode 100644
index 000000000..11e07af3c
--- /dev/null
+++ b/packages/webawesome/src/components/carousel-item/carousel-item.styles.ts
@@ -0,0 +1,23 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --aspect-ratio: inherit;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ width: 100%;
+ max-height: 100%;
+ aspect-ratio: var(--aspect-ratio);
+ scroll-snap-align: start;
+ scroll-snap-stop: always;
+ }
+
+ ::slotted(img) {
+ width: 100% !important;
+ height: 100% !important;
+ object-fit: cover;
+ }
+`;
diff --git a/packages/webawesome/src/components/carousel-item/carousel-item.ts b/packages/webawesome/src/components/carousel-item/carousel-item.ts
index a655b317c..8b80fd536 100644
--- a/packages/webawesome/src/components/carousel-item/carousel-item.ts
+++ b/packages/webawesome/src/components/carousel-item/carousel-item.ts
@@ -1,7 +1,7 @@
import { html } from 'lit';
import { customElement } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './carousel-item.css';
+import styles from './carousel-item.styles.js';
/**
* @summary A carousel item represent a slide within a carousel.
diff --git a/packages/webawesome/src/components/carousel/carousel.css b/packages/webawesome/src/components/carousel/carousel.css
deleted file mode 100644
index 004d30a0a..000000000
--- a/packages/webawesome/src/components/carousel/carousel.css
+++ /dev/null
@@ -1,154 +0,0 @@
-:host {
- --aspect-ratio: 16 / 9;
- --scroll-hint: 0px;
- --slide-gap: var(--wa-space-m, 1rem); /* fallback value is necessary */
-
- display: flex;
-}
-
-.carousel {
- display: grid;
- grid-template-columns: min-content 1fr min-content;
- grid-template-rows: 1fr min-content;
- grid-template-areas:
- '. slides .'
- '. pagination .';
- gap: var(--wa-space-m);
- align-items: center;
- min-height: 100%;
- min-width: 100%;
- position: relative;
-}
-
-.pagination {
- grid-area: pagination;
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- gap: var(--wa-space-s);
-}
-
-.slides {
- grid-area: slides;
-
- display: grid;
- height: 100%;
- width: 100%;
- align-items: center;
- justify-items: center;
- overflow: auto;
- overscroll-behavior-x: contain;
- scrollbar-width: none;
- aspect-ratio: calc(var(--aspect-ratio) * var(--slides-per-page));
- border-radius: var(--wa-border-radius-m);
-
- --slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
-}
-
-@media (prefers-reduced-motion) {
- :where(.slides) {
- scroll-behavior: auto;
- }
-}
-
-.slides-horizontal {
- grid-auto-flow: column;
- grid-auto-columns: var(--slide-size);
- grid-auto-rows: 100%;
- column-gap: var(--slide-gap);
- scroll-snap-type: x mandatory;
- scroll-padding-inline: var(--scroll-hint);
- padding-inline: var(--scroll-hint);
- overflow-y: hidden;
-}
-
-.slides-vertical {
- grid-auto-flow: row;
- grid-auto-columns: 100%;
- grid-auto-rows: var(--slide-size);
- row-gap: var(--slide-gap);
- scroll-snap-type: y mandatory;
- scroll-padding-block: var(--scroll-hint);
- padding-block: var(--scroll-hint);
- overflow-x: hidden;
-}
-
-.slides-dragging,
-.slides-dropping {
- scroll-snap-type: unset;
-}
-
-:host([vertical]) ::slotted(wa-carousel-item) {
- height: 100%;
-}
-
-.slides::-webkit-scrollbar {
- display: none;
-}
-
-.navigation {
- grid-area: navigation;
- display: contents;
- font-size: var(--wa-font-size-l);
-}
-
-.navigation-button {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- background: none;
- border: none;
- border-radius: var(--wa-border-radius-m);
- font-size: inherit;
- color: var(--wa-color-text-quiet);
- padding: var(--wa-space-xs);
- cursor: pointer;
- transition: var(--wa-transition-normal) color;
- appearance: none;
-}
-
-.navigation-button-disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.navigation-button-disabled::part(base) {
- pointer-events: none;
-}
-
-.navigation-button-previous {
- grid-column: 1;
- grid-row: 1;
-}
-
-.navigation-button-next {
- grid-column: 3;
- grid-row: 1;
-}
-
-.pagination-item {
- display: block;
- cursor: pointer;
- background: none;
- border: 0;
- border-radius: var(--wa-border-radius-circle);
- width: var(--wa-space-s);
- height: var(--wa-space-s);
- background-color: var(--wa-color-neutral-fill-normal);
- padding: 0;
- margin: 0;
- transition: transform var(--wa-transition-slow);
-}
-
-.pagination-item-active {
- background-color: var(--wa-form-control-activated-color);
- transform: scale(1.25);
-}
-
-/* Focus styles */
-.slides:focus-visible,
-.navigation-button:focus-visible,
-.pagination-item:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
diff --git a/packages/webawesome/src/components/carousel/carousel.styles.ts b/packages/webawesome/src/components/carousel/carousel.styles.ts
new file mode 100644
index 000000000..7882b603c
--- /dev/null
+++ b/packages/webawesome/src/components/carousel/carousel.styles.ts
@@ -0,0 +1,158 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --aspect-ratio: 16 / 9;
+ --scroll-hint: 0px;
+ --slide-gap: var(--wa-space-m, 1rem); /* fallback value is necessary */
+
+ display: flex;
+ }
+
+ .carousel {
+ display: grid;
+ grid-template-columns: min-content 1fr min-content;
+ grid-template-rows: 1fr min-content;
+ grid-template-areas:
+ '. slides .'
+ '. pagination .';
+ gap: var(--wa-space-m);
+ align-items: center;
+ min-height: 100%;
+ min-width: 100%;
+ position: relative;
+ }
+
+ .pagination {
+ grid-area: pagination;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: var(--wa-space-s);
+ }
+
+ .slides {
+ grid-area: slides;
+
+ display: grid;
+ height: 100%;
+ width: 100%;
+ align-items: center;
+ justify-items: center;
+ overflow: auto;
+ overscroll-behavior-x: contain;
+ scrollbar-width: none;
+ aspect-ratio: calc(var(--aspect-ratio) * var(--slides-per-page));
+ border-radius: var(--wa-border-radius-m);
+
+ --slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
+ }
+
+ @media (prefers-reduced-motion) {
+ :where(.slides) {
+ scroll-behavior: auto;
+ }
+ }
+
+ .slides-horizontal {
+ grid-auto-flow: column;
+ grid-auto-columns: var(--slide-size);
+ grid-auto-rows: 100%;
+ column-gap: var(--slide-gap);
+ scroll-snap-type: x mandatory;
+ scroll-padding-inline: var(--scroll-hint);
+ padding-inline: var(--scroll-hint);
+ overflow-y: hidden;
+ }
+
+ .slides-vertical {
+ grid-auto-flow: row;
+ grid-auto-columns: 100%;
+ grid-auto-rows: var(--slide-size);
+ row-gap: var(--slide-gap);
+ scroll-snap-type: y mandatory;
+ scroll-padding-block: var(--scroll-hint);
+ padding-block: var(--scroll-hint);
+ overflow-x: hidden;
+ }
+
+ .slides-dragging,
+ .slides-dropping {
+ scroll-snap-type: unset;
+ }
+
+ :host([vertical]) ::slotted(wa-carousel-item) {
+ height: 100%;
+ }
+
+ .slides::-webkit-scrollbar {
+ display: none;
+ }
+
+ .navigation {
+ grid-area: navigation;
+ display: contents;
+ font-size: var(--wa-font-size-l);
+ }
+
+ .navigation-button {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ background: none;
+ border: none;
+ border-radius: var(--wa-border-radius-m);
+ font-size: inherit;
+ color: var(--wa-color-text-quiet);
+ padding: var(--wa-space-xs);
+ cursor: pointer;
+ transition: var(--wa-transition-normal) color;
+ appearance: none;
+ }
+
+ .navigation-button-disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ .navigation-button-disabled::part(base) {
+ pointer-events: none;
+ }
+
+ .navigation-button-previous {
+ grid-column: 1;
+ grid-row: 1;
+ }
+
+ .navigation-button-next {
+ grid-column: 3;
+ grid-row: 1;
+ }
+
+ .pagination-item {
+ display: block;
+ cursor: pointer;
+ background: none;
+ border: 0;
+ border-radius: var(--wa-border-radius-circle);
+ width: var(--wa-space-s);
+ height: var(--wa-space-s);
+ background-color: var(--wa-color-neutral-fill-normal);
+ padding: 0;
+ margin: 0;
+ transition: transform var(--wa-transition-slow);
+ }
+
+ .pagination-item-active {
+ background-color: var(--wa-form-control-activated-color);
+ transform: scale(1.25);
+ }
+
+ /* Focus styles */
+ .slides:focus-visible,
+ .navigation-button:focus-visible,
+ .pagination-item:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+`;
diff --git a/packages/webawesome/src/components/carousel/carousel.ts b/packages/webawesome/src/components/carousel/carousel.ts
index a3f369dc7..b8353dd95 100644
--- a/packages/webawesome/src/components/carousel/carousel.ts
+++ b/packages/webawesome/src/components/carousel/carousel.ts
@@ -16,7 +16,7 @@ import { LocalizeController } from '../../utilities/localize.js';
import type WaCarouselItem from '../carousel-item/carousel-item.js';
import '../icon/icon.js';
import { AutoplayController } from './autoplay-controller.js';
-import styles from './carousel.css';
+import styles from './carousel.styles.js';
/**
* @summary Carousels display an arbitrary number of content slides along a horizontal or vertical axis.
diff --git a/packages/webawesome/src/components/checkbox/checkbox.css b/packages/webawesome/src/components/checkbox/checkbox.css
deleted file mode 100644
index ae45abbd6..000000000
--- a/packages/webawesome/src/components/checkbox/checkbox.css
+++ /dev/null
@@ -1,100 +0,0 @@
-:host {
- --checked-icon-color: var(--wa-color-brand-on-loud);
- --checked-icon-scale: 0.8;
-
- display: inline-flex;
- color: var(--wa-form-control-value-color);
- font-family: inherit;
- font-weight: var(--wa-form-control-value-font-weight);
- line-height: var(--wa-form-control-value-line-height);
- user-select: none;
- -webkit-user-select: none;
-}
-
-[part~='control'] {
- display: inline-flex;
- flex: 0 0 auto;
- position: relative;
- align-items: center;
- justify-content: center;
- width: var(--wa-form-control-toggle-size);
- height: var(--wa-form-control-toggle-size);
- border-color: var(--wa-form-control-border-color);
- border-radius: min(
- calc(var(--wa-form-control-toggle-size) * 0.375),
- var(--wa-border-radius-s)
- ); /* min prevents entirely circular checkbox */
- border-style: var(--wa-border-style);
- border-width: var(--wa-form-control-border-width);
- background-color: var(--wa-form-control-background-color);
- transition:
- background var(--wa-transition-normal),
- border-color var(--wa-transition-fast),
- box-shadow var(--wa-transition-fast),
- color var(--wa-transition-fast);
- transition-timing-function: var(--wa-transition-easing);
-
- margin-inline-end: 0.5em;
-}
-
-[part~='base'] {
- display: flex;
- align-items: flex-start;
- position: relative;
- color: currentColor;
- vertical-align: middle;
- cursor: pointer;
-}
-
-[part~='label'] {
- display: inline;
-}
-
-/* Checked */
-[part~='control']:has(:checked, :indeterminate) {
- color: var(--checked-icon-color);
- border-color: var(--wa-form-control-activated-color);
- background-color: var(--wa-form-control-activated-color);
-}
-
-/* Focus */
-[part~='control']:has(> input:focus-visible:not(:disabled)) {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/* Disabled */
-:host [part~='base']:has(input:disabled) {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-input {
- position: absolute;
- padding: 0;
- margin: 0;
- height: 100%;
- width: 100%;
- opacity: 0;
- pointer-events: none;
-}
-
-[part~='icon'] {
- display: flex;
- scale: var(--checked-icon-scale);
-
- /* Without this, Safari renders the icon slightly to the left */
- &::part(svg) {
- translate: 0.0009765625em;
- }
-
- input:not(:checked, :indeterminate) + & {
- visibility: hidden;
- }
-}
-
-:host([required]) [part~='label']::after {
- content: var(--wa-form-control-required-content);
- color: var(--wa-form-control-required-content-color);
- margin-inline-start: var(--wa-form-control-required-content-offset);
-}
diff --git a/packages/webawesome/src/components/checkbox/checkbox.styles.ts b/packages/webawesome/src/components/checkbox/checkbox.styles.ts
new file mode 100644
index 000000000..77fe0c11b
--- /dev/null
+++ b/packages/webawesome/src/components/checkbox/checkbox.styles.ts
@@ -0,0 +1,104 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --checked-icon-color: var(--wa-color-brand-on-loud);
+ --checked-icon-scale: 0.8;
+
+ display: inline-flex;
+ color: var(--wa-form-control-value-color);
+ font-family: inherit;
+ font-weight: var(--wa-form-control-value-font-weight);
+ line-height: var(--wa-form-control-value-line-height);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ [part~='control'] {
+ display: inline-flex;
+ flex: 0 0 auto;
+ position: relative;
+ align-items: center;
+ justify-content: center;
+ width: var(--wa-form-control-toggle-size);
+ height: var(--wa-form-control-toggle-size);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: min(
+ calc(var(--wa-form-control-toggle-size) * 0.375),
+ var(--wa-border-radius-s)
+ ); /* min prevents entirely circular checkbox */
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-form-control-border-width);
+ background-color: var(--wa-form-control-background-color);
+ transition:
+ background var(--wa-transition-normal),
+ border-color var(--wa-transition-fast),
+ box-shadow var(--wa-transition-fast),
+ color var(--wa-transition-fast);
+ transition-timing-function: var(--wa-transition-easing);
+
+ margin-inline-end: 0.5em;
+ }
+
+ [part~='base'] {
+ display: flex;
+ align-items: flex-start;
+ position: relative;
+ color: currentColor;
+ vertical-align: middle;
+ cursor: pointer;
+ }
+
+ [part~='label'] {
+ display: inline;
+ }
+
+ /* Checked */
+ [part~='control']:has(:checked, :indeterminate) {
+ color: var(--checked-icon-color);
+ border-color: var(--wa-form-control-activated-color);
+ background-color: var(--wa-form-control-activated-color);
+ }
+
+ /* Focus */
+ [part~='control']:has(> input:focus-visible:not(:disabled)) {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Disabled */
+ :host [part~='base']:has(input:disabled) {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ input {
+ position: absolute;
+ padding: 0;
+ margin: 0;
+ height: 100%;
+ width: 100%;
+ opacity: 0;
+ pointer-events: none;
+ }
+
+ [part~='icon'] {
+ display: flex;
+ scale: var(--checked-icon-scale);
+
+ /* Without this, Safari renders the icon slightly to the left */
+ &::part(svg) {
+ translate: 0.0009765625em;
+ }
+
+ input:not(:checked, :indeterminate) + & {
+ visibility: hidden;
+ }
+ }
+
+ :host([required]) [part~='label']::after {
+ content: var(--wa-form-control-required-content);
+ color: var(--wa-form-control-required-content-color);
+ margin-inline-start: var(--wa-form-control-required-content-offset);
+ }
+`;
diff --git a/packages/webawesome/src/components/checkbox/checkbox.ts b/packages/webawesome/src/components/checkbox/checkbox.ts
index 634deb4d9..9af6d20f1 100644
--- a/packages/webawesome/src/components/checkbox/checkbox.ts
+++ b/packages/webawesome/src/components/checkbox/checkbox.ts
@@ -8,10 +8,10 @@ import { HasSlotController } from '../../internal/slot.js';
import { RequiredValidator } from '../../internal/validators/required-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import '../icon/icon.js';
-import styles from './checkbox.css';
+import styles from './checkbox.styles.js';
/**
* @summary Checkboxes allow the user to toggle an option on or off.
diff --git a/packages/webawesome/src/components/color-picker/color-picker.css b/packages/webawesome/src/components/color-picker/color-picker.css
deleted file mode 100644
index f9cd5283e..000000000
--- a/packages/webawesome/src/components/color-picker/color-picker.css
+++ /dev/null
@@ -1,341 +0,0 @@
-:host {
- --grid-width: 17em;
- --grid-height: 12em;
- --grid-handle-size: 1.25em;
- --slider-height: 1em;
- --slider-handle-size: calc(var(--slider-height) + 0.25em);
-}
-
-.color-picker {
- background-color: var(--wa-color-surface-raised);
- border-radius: var(--wa-border-radius-m);
- border-style: var(--wa-border-style);
- border-width: var(--wa-border-width-s);
- border-color: var(--wa-color-surface-border);
- box-shadow: var(--wa-shadow-m);
- color: var(--color);
- font: inherit;
- font-size: inherit;
- user-select: none;
- width: var(--grid-width);
- -webkit-user-select: none;
-}
-
-.grid {
- position: relative;
- height: var(--grid-height);
- background-image:
- linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
- linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
- border-top-left-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
- border-top-right-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
- cursor: crosshair;
- forced-color-adjust: none;
-}
-
-.grid-handle {
- position: absolute;
- width: var(--grid-handle-size);
- height: var(--grid-handle-size);
- border-radius: var(--wa-border-radius-circle);
- box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
- border: solid 0.125rem white;
- margin-top: calc(var(--grid-handle-size) / -2);
- margin-left: calc(var(--grid-handle-size) / -2);
- transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-.grid-handle-dragging {
- cursor: none;
- scale: 1.5;
-}
-
-.grid-handle:focus-visible {
- outline: var(--wa-focus-ring);
-}
-
-.controls {
- padding: 0.75em;
- display: flex;
- align-items: center;
-}
-
-.sliders {
- flex: 1 1 auto;
-}
-
-.slider {
- position: relative;
- height: var(--slider-height);
- border-radius: var(--wa-border-radius-s);
- box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
- forced-color-adjust: none;
-}
-
-.slider:not(:last-of-type) {
- margin-bottom: 0.75em;
-}
-
-.slider-handle {
- position: absolute;
- top: calc(50% - var(--slider-handle-size) / 2);
- width: var(--slider-handle-size);
- height: var(--slider-handle-size);
- border-radius: var(--wa-border-radius-circle);
- border: solid 0.125rem white;
- box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
- margin-left: calc(var(--slider-handle-size) / -2);
-}
-
-.slider-handle:focus-visible {
- outline: var(--wa-focus-ring);
-}
-
-.hue {
- background-image: linear-gradient(
- to right,
- rgb(255, 0, 0) 0%,
- rgb(255, 255, 0) 17%,
- rgb(0, 255, 0) 33%,
- rgb(0, 255, 255) 50%,
- rgb(0, 0, 255) 67%,
- rgb(255, 0, 255) 83%,
- rgb(255, 0, 0) 100%
- );
-}
-
-.alpha .alpha-gradient {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: inherit;
-}
-
-.preview {
- flex: 0 0 auto;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- position: relative;
- width: 3em;
- height: 3em;
- border: none;
- border-radius: var(--wa-border-radius-circle);
- background: none;
- font-size: inherit;
- margin-inline-start: 0.75em;
- cursor: copy;
- forced-color-adjust: none;
-}
-
-.preview:before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: inherit;
- box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
-
- /* We use a custom property in lieu of currentColor because of https://bugs.webkit.org/show_bug.cgi?id=216780 */
- background-color: var(--preview-color);
-}
-
-.preview:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-.preview-color {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border: solid 0.0625rem rgba(0, 0, 0, 0.125);
-}
-
-.preview-color-copied {
- animation: pulse 850ms;
-}
-
-@keyframes pulse {
- 0% {
- box-shadow: 0 0 0 0 var(--wa-color-brand-fill-loud);
- }
- 70% {
- box-shadow: 0 0 0 0.5rem transparent;
- }
- 100% {
- box-shadow: 0 0 0 0 transparent;
- }
-}
-
-.user-input {
- display: flex;
- align-items: center;
- padding: 0 0.75em 0.75em 0.75em;
-}
-
-.user-input wa-input {
- min-width: 0; /* fix input width in Safari */
- flex: 1 1 auto;
-
- &::part(form-control-label) {
- /* Visually hidden */
- position: absolute !important;
- width: 1px !important;
- height: 1px !important;
- clip: rect(0 0 0 0) !important;
- clip-path: inset(50%) !important;
- border: none !important;
- overflow: hidden !important;
- white-space: nowrap !important;
- padding: 0 !important;
- }
-}
-
-.user-input wa-button-group {
- margin-inline-start: 0.75em;
-
- &::part(base) {
- flex-wrap: nowrap;
- }
-}
-
-.user-input wa-button:first-of-type {
- min-width: 3em;
- max-width: 3em;
-}
-
-.swatches {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(min(1.5em, 100%), 1fr));
- grid-gap: 0.5em;
- justify-items: center;
- border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
- var(--wa-color-surface-border);
- padding: 0.5em;
- forced-color-adjust: none;
-}
-
-.swatch {
- position: relative;
- aspect-ratio: 1 / 1;
- width: 100%;
- border-radius: var(--wa-border-radius-s);
-}
-
-.swatch .swatch-color {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border: solid 0.0625rem rgba(0, 0, 0, 0.125);
- border-radius: inherit;
- cursor: pointer;
-}
-
-.swatch:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-.transparent-bg {
- background-image:
- linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
- linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
- linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
- linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%);
- background-size: 0.5rem 0.5rem;
- background-position:
- 0 0,
- 0 0,
- -0.25rem -0.25rem,
- 0.25rem 0.25rem;
-}
-
-:host([disabled]) {
- opacity: 0.5;
- cursor: not-allowed;
-
- .grid,
- .grid-handle,
- .slider,
- .slider-handle,
- .preview,
- .swatch,
- .swatch-color {
- pointer-events: none;
- }
-}
-
-/*
- * Color dropdown
- */
-
-.color-dropdown {
- display: contents;
-}
-
-.color-dropdown::part(panel) {
- max-height: none;
- background-color: var(--wa-color-surface-raised);
- border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
- border-radius: var(--wa-border-radius-m);
- overflow: visible;
-}
-
-.trigger {
- display: block;
- position: relative;
- background-color: transparent;
- border: none;
- cursor: pointer;
- font-size: inherit;
- forced-color-adjust: none;
- width: var(--wa-form-control-height);
- height: var(--wa-form-control-height);
- border-radius: var(--wa-form-control-border-radius);
-}
-
-.trigger:before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- border-radius: inherit;
- background-color: currentColor;
- box-shadow:
- inset 0 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-color),
- inset 0 0 0 calc(var(--wa-form-control-border-width) * 3) var(--wa-color-surface-default);
-}
-
-.trigger-empty:before {
- background-color: transparent;
-}
-
-.trigger:focus-visible {
- outline: none;
-}
-
-.trigger:focus-visible:not(.trigger:disabled) {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-:host([disabled]) :is(.label, .trigger) {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.form-control.form-control-has-label .label {
- cursor: pointer;
- display: inline-block;
-}
diff --git a/packages/webawesome/src/components/color-picker/color-picker.styles.ts b/packages/webawesome/src/components/color-picker/color-picker.styles.ts
new file mode 100644
index 000000000..d2eedca15
--- /dev/null
+++ b/packages/webawesome/src/components/color-picker/color-picker.styles.ts
@@ -0,0 +1,345 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --grid-width: 17em;
+ --grid-height: 12em;
+ --grid-handle-size: 1.25em;
+ --slider-height: 1em;
+ --slider-handle-size: calc(var(--slider-height) + 0.25em);
+ }
+
+ .color-picker {
+ background-color: var(--wa-color-surface-raised);
+ border-radius: var(--wa-border-radius-m);
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-border-width-s);
+ border-color: var(--wa-color-surface-border);
+ box-shadow: var(--wa-shadow-m);
+ color: var(--color);
+ font: inherit;
+ font-size: inherit;
+ user-select: none;
+ width: var(--grid-width);
+ -webkit-user-select: none;
+ }
+
+ .grid {
+ position: relative;
+ height: var(--grid-height);
+ background-image:
+ linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
+ linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
+ border-top-left-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
+ border-top-right-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
+ cursor: crosshair;
+ forced-color-adjust: none;
+ }
+
+ .grid-handle {
+ position: absolute;
+ width: var(--grid-handle-size);
+ height: var(--grid-handle-size);
+ border-radius: var(--wa-border-radius-circle);
+ box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
+ border: solid 0.125rem white;
+ margin-top: calc(var(--grid-handle-size) / -2);
+ margin-left: calc(var(--grid-handle-size) / -2);
+ transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ .grid-handle-dragging {
+ cursor: none;
+ scale: 1.5;
+ }
+
+ .grid-handle:focus-visible {
+ outline: var(--wa-focus-ring);
+ }
+
+ .controls {
+ padding: 0.75em;
+ display: flex;
+ align-items: center;
+ }
+
+ .sliders {
+ flex: 1 1 auto;
+ }
+
+ .slider {
+ position: relative;
+ height: var(--slider-height);
+ border-radius: var(--wa-border-radius-s);
+ box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
+ forced-color-adjust: none;
+ }
+
+ .slider:not(:last-of-type) {
+ margin-bottom: 0.75em;
+ }
+
+ .slider-handle {
+ position: absolute;
+ top: calc(50% - var(--slider-handle-size) / 2);
+ width: var(--slider-handle-size);
+ height: var(--slider-handle-size);
+ border-radius: var(--wa-border-radius-circle);
+ border: solid 0.125rem white;
+ box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
+ margin-left: calc(var(--slider-handle-size) / -2);
+ }
+
+ .slider-handle:focus-visible {
+ outline: var(--wa-focus-ring);
+ }
+
+ .hue {
+ background-image: linear-gradient(
+ to right,
+ rgb(255, 0, 0) 0%,
+ rgb(255, 255, 0) 17%,
+ rgb(0, 255, 0) 33%,
+ rgb(0, 255, 255) 50%,
+ rgb(0, 0, 255) 67%,
+ rgb(255, 0, 255) 83%,
+ rgb(255, 0, 0) 100%
+ );
+ }
+
+ .alpha .alpha-gradient {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: inherit;
+ }
+
+ .preview {
+ flex: 0 0 auto;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ width: 3em;
+ height: 3em;
+ border: none;
+ border-radius: var(--wa-border-radius-circle);
+ background: none;
+ font-size: inherit;
+ margin-inline-start: 0.75em;
+ cursor: copy;
+ forced-color-adjust: none;
+ }
+
+ .preview:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: inherit;
+ box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
+
+ /* We use a custom property in lieu of currentColor because of https://bugs.webkit.org/show_bug.cgi?id=216780 */
+ background-color: var(--preview-color);
+ }
+
+ .preview:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ .preview-color {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: solid 0.0625rem rgba(0, 0, 0, 0.125);
+ }
+
+ .preview-color-copied {
+ animation: pulse 850ms;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 var(--wa-color-brand-fill-loud);
+ }
+ 70% {
+ box-shadow: 0 0 0 0.5rem transparent;
+ }
+ 100% {
+ box-shadow: 0 0 0 0 transparent;
+ }
+ }
+
+ .user-input {
+ display: flex;
+ align-items: center;
+ padding: 0 0.75em 0.75em 0.75em;
+ }
+
+ .user-input wa-input {
+ min-width: 0; /* fix input width in Safari */
+ flex: 1 1 auto;
+
+ &::part(form-control-label) {
+ /* Visually hidden */
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ clip: rect(0 0 0 0) !important;
+ clip-path: inset(50%) !important;
+ border: none !important;
+ overflow: hidden !important;
+ white-space: nowrap !important;
+ padding: 0 !important;
+ }
+ }
+
+ .user-input wa-button-group {
+ margin-inline-start: 0.75em;
+
+ &::part(base) {
+ flex-wrap: nowrap;
+ }
+ }
+
+ .user-input wa-button:first-of-type {
+ min-width: 3em;
+ max-width: 3em;
+ }
+
+ .swatches {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(1.5em, 100%), 1fr));
+ grid-gap: 0.5em;
+ justify-items: center;
+ border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
+ var(--wa-color-surface-border);
+ padding: 0.5em;
+ forced-color-adjust: none;
+ }
+
+ .swatch {
+ position: relative;
+ aspect-ratio: 1 / 1;
+ width: 100%;
+ border-radius: var(--wa-border-radius-s);
+ }
+
+ .swatch .swatch-color {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: solid 0.0625rem rgba(0, 0, 0, 0.125);
+ border-radius: inherit;
+ cursor: pointer;
+ }
+
+ .swatch:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ .transparent-bg {
+ background-image:
+ linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
+ linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
+ linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%);
+ background-size: 0.5rem 0.5rem;
+ background-position:
+ 0 0,
+ 0 0,
+ -0.25rem -0.25rem,
+ 0.25rem 0.25rem;
+ }
+
+ :host([disabled]) {
+ opacity: 0.5;
+ cursor: not-allowed;
+
+ .grid,
+ .grid-handle,
+ .slider,
+ .slider-handle,
+ .preview,
+ .swatch,
+ .swatch-color {
+ pointer-events: none;
+ }
+ }
+
+ /*
+ * Color dropdown
+ */
+
+ .color-dropdown {
+ display: contents;
+ }
+
+ .color-dropdown::part(panel) {
+ max-height: none;
+ background-color: var(--wa-color-surface-raised);
+ border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
+ border-radius: var(--wa-border-radius-m);
+ overflow: visible;
+ }
+
+ .trigger {
+ display: block;
+ position: relative;
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ font-size: inherit;
+ forced-color-adjust: none;
+ width: var(--wa-form-control-height);
+ height: var(--wa-form-control-height);
+ border-radius: var(--wa-form-control-border-radius);
+ }
+
+ .trigger:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: inherit;
+ background-color: currentColor;
+ box-shadow:
+ inset 0 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-color),
+ inset 0 0 0 calc(var(--wa-form-control-border-width) * 3) var(--wa-color-surface-default);
+ }
+
+ .trigger-empty:before {
+ background-color: transparent;
+ }
+
+ .trigger:focus-visible {
+ outline: none;
+ }
+
+ .trigger:focus-visible:not(.trigger:disabled) {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ :host([disabled]) :is(.label, .trigger) {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ .form-control.form-control-has-label .label {
+ cursor: pointer;
+ display: inline-block;
+ }
+`;
diff --git a/packages/webawesome/src/components/color-picker/color-picker.ts b/packages/webawesome/src/components/color-picker/color-picker.ts
index 7c280bdee..ce897d69e 100644
--- a/packages/webawesome/src/components/color-picker/color-picker.ts
+++ b/packages/webawesome/src/components/color-picker/color-picker.ts
@@ -14,9 +14,9 @@ import { HasSlotController } from '../../internal/slot.js';
import { RequiredValidator } from '../../internal/validators/required-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
-import visuallyHidden from '../../styles/utilities/visually-hidden.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
+import visuallyHidden from '../../styles/component/visually-hidden.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../button-group/button-group.js';
import '../button/button.js';
@@ -25,7 +25,7 @@ import '../input/input.js';
import type WaInput from '../input/input.js';
import '../popup/popup.js';
import type WaPopup from '../popup/popup.js';
-import styles from './color-picker.css';
+import styles from './color-picker.styles.js';
interface EyeDropperConstructor {
new (): EyeDropperInterface;
diff --git a/packages/webawesome/src/components/comparison/comparison.css b/packages/webawesome/src/components/comparison/comparison.css
deleted file mode 100644
index 139cb3dd9..000000000
--- a/packages/webawesome/src/components/comparison/comparison.css
+++ /dev/null
@@ -1,76 +0,0 @@
-:host {
- --divider-width: 0.125rem;
- --handle-size: 2.5rem;
-
- display: block;
- position: relative;
- max-width: 100%;
- max-height: 100%;
- overflow: hidden;
-}
-
-.before,
-.after {
- display: block;
-
- &::slotted(img),
- &::slotted(svg) {
- display: block;
- max-width: 100% !important;
- height: auto;
- }
-
- &::slotted(:not(img, svg)) {
- isolation: isolate;
- }
-}
-
-.after {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
-}
-
-/* Disable pointer-events while dragging. This is especially important for iframes. */
-:host(:state(dragging)) {
- .before,
- .after {
- pointer-events: none;
- }
-}
-
-.divider {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 0;
- width: var(--divider-width);
- height: 100%;
- background-color: var(--wa-color-surface-default);
- translate: calc(var(--divider-width) / -2);
- cursor: ew-resize;
-}
-
-.handle {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: calc(50% - (var(--handle-size) / 2));
- width: var(--handle-size);
- height: var(--handle-size);
- background-color: var(--wa-color-surface-default);
- border-radius: var(--wa-border-radius-circle);
- font-size: calc(var(--handle-size) * 0.4);
- color: var(--wa-color-neutral-on-quiet);
- cursor: inherit;
- z-index: 10;
-}
-
-.handle:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
diff --git a/packages/webawesome/src/components/comparison/comparison.styles.ts b/packages/webawesome/src/components/comparison/comparison.styles.ts
new file mode 100644
index 000000000..192aee4e4
--- /dev/null
+++ b/packages/webawesome/src/components/comparison/comparison.styles.ts
@@ -0,0 +1,80 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --divider-width: 0.125rem;
+ --handle-size: 2.5rem;
+
+ display: block;
+ position: relative;
+ max-width: 100%;
+ max-height: 100%;
+ overflow: hidden;
+ }
+
+ .before,
+ .after {
+ display: block;
+
+ &::slotted(img),
+ &::slotted(svg) {
+ display: block;
+ max-width: 100% !important;
+ height: auto;
+ }
+
+ &::slotted(:not(img, svg)) {
+ isolation: isolate;
+ }
+ }
+
+ .after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ }
+
+ /* Disable pointer-events while dragging. This is especially important for iframes. */
+ :host(:state(dragging)) {
+ .before,
+ .after {
+ pointer-events: none;
+ }
+ }
+
+ .divider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 0;
+ width: var(--divider-width);
+ height: 100%;
+ background-color: var(--wa-color-surface-default);
+ translate: calc(var(--divider-width) / -2);
+ cursor: ew-resize;
+ }
+
+ .handle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: calc(50% - (var(--handle-size) / 2));
+ width: var(--handle-size);
+ height: var(--handle-size);
+ background-color: var(--wa-color-surface-default);
+ border-radius: var(--wa-border-radius-circle);
+ font-size: calc(var(--handle-size) * 0.4);
+ color: var(--wa-color-neutral-on-quiet);
+ cursor: inherit;
+ z-index: 10;
+ }
+
+ .handle:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+`;
diff --git a/packages/webawesome/src/components/comparison/comparison.ts b/packages/webawesome/src/components/comparison/comparison.ts
index 12f458fb9..8500931b3 100644
--- a/packages/webawesome/src/components/comparison/comparison.ts
+++ b/packages/webawesome/src/components/comparison/comparison.ts
@@ -7,7 +7,7 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './comparison.css';
+import styles from './comparison.styles.js';
/**
* @summary Compare visual differences between similar content with a sliding panel.
diff --git a/packages/webawesome/src/components/copy-button/copy-button.css b/packages/webawesome/src/components/copy-button/copy-button.css
deleted file mode 100644
index 7d7be5126..000000000
--- a/packages/webawesome/src/components/copy-button/copy-button.css
+++ /dev/null
@@ -1,75 +0,0 @@
-:host {
- display: inline-block;
- color: var(--wa-color-neutral-on-quiet);
-}
-
-.button {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- background-color: transparent;
- border: none;
- border-radius: var(--wa-form-control-border-radius);
- color: inherit;
- font-size: inherit;
- padding: 0.5em;
- cursor: pointer;
- transition: color var(--wa-transition-fast) var(--wa-transition-easing);
-}
-
-@media (hover: hover) {
- .button:hover:not([disabled]) {
- background-color: var(--wa-color-neutral-fill-quiet);
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
- }
-}
-
-.button:focus-visible:not([disabled]) {
- background-color: var(--wa-color-neutral-fill-quiet);
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
-}
-
-.button:active:not([disabled]) {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
-}
-
-slot[name='success-icon'] {
- color: var(--wa-color-success-on-quiet);
-}
-
-slot[name='error-icon'] {
- color: var(--wa-color-danger-on-quiet);
-}
-
-.button:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-.button[disabled] {
- opacity: 0.5;
- cursor: not-allowed !important;
-}
-
-slot {
- display: inline-flex;
-}
-
-.show {
- animation: show 100ms ease;
-}
-
-.hide {
- animation: show 100ms ease reverse;
-}
-
-@keyframes show {
- from {
- scale: 0.25;
- opacity: 0.25;
- }
- to {
- scale: 1;
- opacity: 1;
- }
-}
diff --git a/packages/webawesome/src/components/copy-button/copy-button.styles.ts b/packages/webawesome/src/components/copy-button/copy-button.styles.ts
new file mode 100644
index 000000000..97082278c
--- /dev/null
+++ b/packages/webawesome/src/components/copy-button/copy-button.styles.ts
@@ -0,0 +1,79 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: inline-block;
+ color: var(--wa-color-neutral-on-quiet);
+ }
+
+ .button {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ background-color: transparent;
+ border: none;
+ border-radius: var(--wa-form-control-border-radius);
+ color: inherit;
+ font-size: inherit;
+ padding: 0.5em;
+ cursor: pointer;
+ transition: color var(--wa-transition-fast) var(--wa-transition-easing);
+ }
+
+ @media (hover: hover) {
+ .button:hover:not([disabled]) {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+ }
+
+ .button:focus-visible:not([disabled]) {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+
+ .button:active:not([disabled]) {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
+ }
+
+ slot[name='success-icon'] {
+ color: var(--wa-color-success-on-quiet);
+ }
+
+ slot[name='error-icon'] {
+ color: var(--wa-color-danger-on-quiet);
+ }
+
+ .button:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ .button[disabled] {
+ opacity: 0.5;
+ cursor: not-allowed !important;
+ }
+
+ slot {
+ display: inline-flex;
+ }
+
+ .show {
+ animation: show 100ms ease;
+ }
+
+ .hide {
+ animation: show 100ms ease reverse;
+ }
+
+ @keyframes show {
+ from {
+ scale: 0.25;
+ opacity: 0.25;
+ }
+ to {
+ scale: 1;
+ opacity: 1;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/copy-button/copy-button.ts b/packages/webawesome/src/components/copy-button/copy-button.ts
index b29967fd6..533bb61c7 100644
--- a/packages/webawesome/src/components/copy-button/copy-button.ts
+++ b/packages/webawesome/src/components/copy-button/copy-button.ts
@@ -5,12 +5,12 @@ import { WaCopyEvent } from '../../events/copy.js';
import { WaErrorEvent } from '../../events/error.js';
import { animateWithClass } from '../../internal/animate.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import visuallyHidden from '../../styles/utilities/visually-hidden.css';
+import visuallyHidden from '../../styles/component/visually-hidden.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import '../tooltip/tooltip.js';
import type WaTooltip from '../tooltip/tooltip.js';
-import styles from './copy-button.css';
+import styles from './copy-button.styles.js';
/**
* @summary Copies text data to the clipboard when the user clicks the trigger.
diff --git a/packages/webawesome/src/components/details/details.css b/packages/webawesome/src/components/details/details.css
deleted file mode 100644
index 858fb0a89..000000000
--- a/packages/webawesome/src/components/details/details.css
+++ /dev/null
@@ -1,122 +0,0 @@
-:host {
- --spacing: var(--wa-space-m);
- --show-duration: 200ms;
- --hide-duration: 200ms;
-
- display: block;
-}
-
-details {
- display: block;
- overflow-anchor: none;
- border: var(--wa-panel-border-width) var(--wa-color-surface-border) var(--wa-panel-border-style);
- background-color: var(--wa-color-surface-default);
- border-radius: var(--wa-panel-border-radius);
- color: var(--wa-color-text-normal);
-
- /* Print styles */
- @media print {
- background: none;
- border: solid var(--wa-border-width-s) var(--wa-color-surface-border);
-
- summary {
- list-style: none;
- }
- }
-}
-
-/* Appearance modifiers */
-:host([appearance='plain']) details {
- background-color: transparent;
- border-color: transparent;
- border-radius: 0;
-}
-
-:host([appearance='outlined']) details {
- background-color: var(--wa-color-surface-default);
- border-color: var(--wa-color-surface-border);
-}
-
-:host([appearance='filled']) details {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: transparent;
-}
-
-:host([appearance='filled-outlined']) details {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-color-neutral-border-quiet);
-}
-
-:host([disabled]) details {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-summary {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: var(--spacing);
- padding: var(--spacing); /* Add padding here */
- border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
- user-select: none;
- -webkit-user-select: none;
- cursor: pointer;
-
- &::marker,
- &::-webkit-details-marker {
- display: none;
- }
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: calc(var(--wa-panel-border-width) + var(--wa-focus-ring-offset));
- }
-}
-
-:host([open]) summary {
- border-end-start-radius: 0;
- border-end-end-radius: 0;
-}
-
-/* 'Start' icon placement */
-:host([icon-placement='start']) summary {
- flex-direction: row-reverse;
- justify-content: start;
-}
-
-[part~='icon'] {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- color: var(--wa-color-text-quiet);
- transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-:host([open]) [part~='icon'] {
- rotate: 90deg;
-}
-
-:host([open]:dir(rtl)) [part~='icon'] {
- rotate: -90deg;
-}
-
-:host([open]) slot[name='expand-icon'],
-:host(:not([open])) slot[name='collapse-icon'] {
- display: none;
-}
-
-.body.animating {
- overflow: hidden;
-}
-
-.content {
- display: block;
- padding-block-start: var(--spacing);
- padding-inline: var(--spacing); /* Add horizontal padding */
- padding-block-end: var(--spacing); /* Add bottom padding */
-}
diff --git a/packages/webawesome/src/components/details/details.styles.ts b/packages/webawesome/src/components/details/details.styles.ts
new file mode 100644
index 000000000..70c4af31e
--- /dev/null
+++ b/packages/webawesome/src/components/details/details.styles.ts
@@ -0,0 +1,126 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --spacing: var(--wa-space-m);
+ --show-duration: 200ms;
+ --hide-duration: 200ms;
+
+ display: block;
+ }
+
+ details {
+ display: block;
+ overflow-anchor: none;
+ border: var(--wa-panel-border-width) var(--wa-color-surface-border) var(--wa-panel-border-style);
+ background-color: var(--wa-color-surface-default);
+ border-radius: var(--wa-panel-border-radius);
+ color: var(--wa-color-text-normal);
+
+ /* Print styles */
+ @media print {
+ background: none;
+ border: solid var(--wa-border-width-s) var(--wa-color-surface-border);
+
+ summary {
+ list-style: none;
+ }
+ }
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='plain']) details {
+ background-color: transparent;
+ border-color: transparent;
+ border-radius: 0;
+ }
+
+ :host([appearance='outlined']) details {
+ background-color: var(--wa-color-surface-default);
+ border-color: var(--wa-color-surface-border);
+ }
+
+ :host([appearance='filled']) details {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: transparent;
+ }
+
+ :host([appearance='filled-outlined']) details {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-color-neutral-border-quiet);
+ }
+
+ :host([disabled]) details {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ summary {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--spacing);
+ padding: var(--spacing); /* Add padding here */
+ border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
+ user-select: none;
+ -webkit-user-select: none;
+ cursor: pointer;
+
+ &::marker,
+ &::-webkit-details-marker {
+ display: none;
+ }
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: calc(var(--wa-panel-border-width) + var(--wa-focus-ring-offset));
+ }
+ }
+
+ :host([open]) summary {
+ border-end-start-radius: 0;
+ border-end-end-radius: 0;
+ }
+
+ /* 'Start' icon placement */
+ :host([icon-placement='start']) summary {
+ flex-direction: row-reverse;
+ justify-content: start;
+ }
+
+ [part~='icon'] {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ color: var(--wa-color-text-quiet);
+ transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ :host([open]) [part~='icon'] {
+ rotate: 90deg;
+ }
+
+ :host([open]:dir(rtl)) [part~='icon'] {
+ rotate: -90deg;
+ }
+
+ :host([open]) slot[name='expand-icon'],
+ :host(:not([open])) slot[name='collapse-icon'] {
+ display: none;
+ }
+
+ .body.animating {
+ overflow: hidden;
+ }
+
+ .content {
+ display: block;
+ padding-block-start: var(--spacing);
+ padding-inline: var(--spacing); /* Add horizontal padding */
+ padding-block-end: var(--spacing); /* Add bottom padding */
+ }
+`;
diff --git a/packages/webawesome/src/components/details/details.ts b/packages/webawesome/src/components/details/details.ts
index 416f746a7..42ccc8c34 100644
--- a/packages/webawesome/src/components/details/details.ts
+++ b/packages/webawesome/src/components/details/details.ts
@@ -13,7 +13,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './details.css';
+import styles from './details.styles.js';
/**
* @summary Details show a brief summary and expand to show additional content.
diff --git a/packages/webawesome/src/components/dialog/dialog.css b/packages/webawesome/src/components/dialog/dialog.css
deleted file mode 100644
index cb6e4f7de..000000000
--- a/packages/webawesome/src/components/dialog/dialog.css
+++ /dev/null
@@ -1,183 +0,0 @@
-:host {
- --width: 31rem;
- --spacing: var(--wa-space-l);
- --show-duration: 200ms;
- --hide-duration: 200ms;
-
- display: none;
-}
-
-:host([open]) {
- display: block;
-}
-
-.dialog {
- display: flex;
- flex-direction: column;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- width: var(--width);
- max-width: calc(100% - var(--wa-space-2xl));
- max-height: calc(100% - var(--wa-space-2xl));
- background-color: var(--wa-color-surface-raised);
- border-radius: var(--wa-panel-border-radius);
- border: none;
- box-shadow: var(--wa-shadow-l);
- padding: 0;
- margin: auto;
-
- &.show {
- animation: show-dialog var(--show-duration) ease;
-
- &::backdrop {
- animation: show-backdrop var(--show-duration, 200ms) ease;
- }
- }
-
- &.hide {
- animation: show-dialog var(--hide-duration) ease reverse;
-
- &::backdrop {
- animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
- }
- }
-
- &.pulse {
- animation: pulse 250ms ease;
- }
-}
-
-.dialog:focus {
- outline: none;
-}
-
-/* Ensure there's enough vertical padding for phones that don't update vh when chrome appears (e.g. iPhone) */
-@media screen and (max-width: 420px) {
- .dialog {
- max-height: 80vh;
- }
-}
-
-.open {
- display: flex;
- opacity: 1;
-}
-
-.header {
- flex: 0 0 auto;
- display: flex;
- flex-wrap: nowrap;
-
- padding-inline-start: var(--spacing);
- padding-block-end: 0;
-
- /* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
- padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
- padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
-}
-
-.title {
- align-self: center;
- flex: 1 1 auto;
- font-family: inherit;
- font-size: var(--wa-font-size-l);
- font-weight: var(--wa-font-weight-heading);
- line-height: var(--wa-line-height-condensed);
- margin: 0;
-}
-
-.header-actions {
- align-self: start;
- display: flex;
- flex-shrink: 0;
- flex-wrap: wrap;
- justify-content: end;
- gap: var(--wa-space-2xs);
- padding-inline-start: var(--spacing);
-}
-
-.header-actions wa-button,
-.header-actions ::slotted(wa-button) {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
-}
-
-.body {
- flex: 1 1 auto;
- display: block;
- padding: var(--spacing);
- overflow: auto;
- -webkit-overflow-scrolling: touch;
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-}
-
-.footer {
- flex: 0 0 auto;
- display: flex;
- flex-wrap: wrap;
- gap: var(--wa-space-xs);
- justify-content: end;
- padding: var(--spacing);
- padding-block-start: 0;
-}
-
-.footer ::slotted(wa-button:not(:first-of-type)) {
- margin-inline-start: var(--wa-spacing-xs);
-}
-
-.dialog::backdrop {
- /*
- NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
- remove the fallback values here.
- */
- background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
-}
-
-@keyframes pulse {
- 0% {
- scale: 1;
- }
- 50% {
- scale: 1.02;
- }
- 100% {
- scale: 1;
- }
-}
-
-@keyframes show-dialog {
- from {
- opacity: 0;
- scale: 0.8;
- }
- to {
- opacity: 1;
- scale: 1;
- }
-}
-
-@keyframes show-backdrop {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-@media (forced-colors: active) {
- .dialog {
- border: solid 1px white;
- }
-}
diff --git a/packages/webawesome/src/components/dialog/dialog.styles.ts b/packages/webawesome/src/components/dialog/dialog.styles.ts
new file mode 100644
index 000000000..1d0b730b2
--- /dev/null
+++ b/packages/webawesome/src/components/dialog/dialog.styles.ts
@@ -0,0 +1,187 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --width: 31rem;
+ --spacing: var(--wa-space-l);
+ --show-duration: 200ms;
+ --hide-duration: 200ms;
+
+ display: none;
+ }
+
+ :host([open]) {
+ display: block;
+ }
+
+ .dialog {
+ display: flex;
+ flex-direction: column;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ width: var(--width);
+ max-width: calc(100% - var(--wa-space-2xl));
+ max-height: calc(100% - var(--wa-space-2xl));
+ background-color: var(--wa-color-surface-raised);
+ border-radius: var(--wa-panel-border-radius);
+ border: none;
+ box-shadow: var(--wa-shadow-l);
+ padding: 0;
+ margin: auto;
+
+ &.show {
+ animation: show-dialog var(--show-duration) ease;
+
+ &::backdrop {
+ animation: show-backdrop var(--show-duration, 200ms) ease;
+ }
+ }
+
+ &.hide {
+ animation: show-dialog var(--hide-duration) ease reverse;
+
+ &::backdrop {
+ animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
+ }
+ }
+
+ &.pulse {
+ animation: pulse 250ms ease;
+ }
+ }
+
+ .dialog:focus {
+ outline: none;
+ }
+
+ /* Ensure there's enough vertical padding for phones that don't update vh when chrome appears (e.g. iPhone) */
+ @media screen and (max-width: 420px) {
+ .dialog {
+ max-height: 80vh;
+ }
+ }
+
+ .open {
+ display: flex;
+ opacity: 1;
+ }
+
+ .header {
+ flex: 0 0 auto;
+ display: flex;
+ flex-wrap: nowrap;
+
+ padding-inline-start: var(--spacing);
+ padding-block-end: 0;
+
+ /* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
+ padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
+ padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
+ }
+
+ .title {
+ align-self: center;
+ flex: 1 1 auto;
+ font-family: inherit;
+ font-size: var(--wa-font-size-l);
+ font-weight: var(--wa-font-weight-heading);
+ line-height: var(--wa-line-height-condensed);
+ margin: 0;
+ }
+
+ .header-actions {
+ align-self: start;
+ display: flex;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ justify-content: end;
+ gap: var(--wa-space-2xs);
+ padding-inline-start: var(--spacing);
+ }
+
+ .header-actions wa-button,
+ .header-actions ::slotted(wa-button) {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ }
+
+ .body {
+ flex: 1 1 auto;
+ display: block;
+ padding: var(--spacing);
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+ }
+
+ .footer {
+ flex: 0 0 auto;
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--wa-space-xs);
+ justify-content: end;
+ padding: var(--spacing);
+ padding-block-start: 0;
+ }
+
+ .footer ::slotted(wa-button:not(:first-of-type)) {
+ margin-inline-start: var(--wa-spacing-xs);
+ }
+
+ .dialog::backdrop {
+ /*
+ NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
+ remove the fallback values here.
+ */
+ background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
+ }
+
+ @keyframes pulse {
+ 0% {
+ scale: 1;
+ }
+ 50% {
+ scale: 1.02;
+ }
+ 100% {
+ scale: 1;
+ }
+ }
+
+ @keyframes show-dialog {
+ from {
+ opacity: 0;
+ scale: 0.8;
+ }
+ to {
+ opacity: 1;
+ scale: 1;
+ }
+ }
+
+ @keyframes show-backdrop {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
+ @media (forced-colors: active) {
+ .dialog {
+ border: solid 1px white;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/dialog/dialog.ts b/packages/webawesome/src/components/dialog/dialog.ts
index 4d0259a99..95993da1c 100644
--- a/packages/webawesome/src/components/dialog/dialog.ts
+++ b/packages/webawesome/src/components/dialog/dialog.ts
@@ -13,7 +13,7 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../button/button.js';
-import styles from './dialog.css';
+import styles from './dialog.styles.js';
/**
* @summary Dialogs, sometimes called "modals", appear above the page and require the user's immediate attention.
diff --git a/packages/webawesome/src/components/divider/divider.css b/packages/webawesome/src/components/divider/divider.css
deleted file mode 100644
index 8eeb3a599..000000000
--- a/packages/webawesome/src/components/divider/divider.css
+++ /dev/null
@@ -1,19 +0,0 @@
-:host {
- --color: var(--wa-color-surface-border);
- --width: var(--wa-border-width-s);
- --spacing: var(--wa-space-m);
-}
-
-:host(:not([orientation='vertical'])) {
- display: block;
- border-top: solid var(--width) var(--color);
- margin: var(--spacing) 0;
-}
-
-:host([orientation='vertical']) {
- display: inline-block;
- height: 100%;
- border-inline-start: solid var(--width) var(--color);
- margin: 0 var(--spacing);
- min-block-size: 1lh;
-}
diff --git a/packages/webawesome/src/components/divider/divider.styles.ts b/packages/webawesome/src/components/divider/divider.styles.ts
new file mode 100644
index 000000000..0f4d34a3b
--- /dev/null
+++ b/packages/webawesome/src/components/divider/divider.styles.ts
@@ -0,0 +1,23 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --color: var(--wa-color-surface-border);
+ --width: var(--wa-border-width-s);
+ --spacing: var(--wa-space-m);
+ }
+
+ :host(:not([orientation='vertical'])) {
+ display: block;
+ border-top: solid var(--width) var(--color);
+ margin: var(--spacing) 0;
+ }
+
+ :host([orientation='vertical']) {
+ display: inline-block;
+ height: 100%;
+ border-inline-start: solid var(--width) var(--color);
+ margin: 0 var(--spacing);
+ min-block-size: 1lh;
+ }
+`;
diff --git a/packages/webawesome/src/components/divider/divider.ts b/packages/webawesome/src/components/divider/divider.ts
index 7d24696ac..30c181a58 100644
--- a/packages/webawesome/src/components/divider/divider.ts
+++ b/packages/webawesome/src/components/divider/divider.ts
@@ -1,7 +1,7 @@
import { customElement, property } from 'lit/decorators.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './divider.css';
+import styles from './divider.styles.js';
/**
* @summary Dividers are used to visually separate or group elements.
diff --git a/packages/webawesome/src/components/drawer/drawer.css b/packages/webawesome/src/components/drawer/drawer.css
deleted file mode 100644
index b380caebf..000000000
--- a/packages/webawesome/src/components/drawer/drawer.css
+++ /dev/null
@@ -1,290 +0,0 @@
-:host {
- --size: 25rem;
- --spacing: var(--wa-space-l);
- --show-duration: 200ms;
- --hide-duration: 200ms;
-
- display: none;
-}
-
-:host([open]) {
- display: block;
-}
-
-.drawer {
- display: flex;
- flex-direction: column;
- top: 0;
- inset-inline-start: 0;
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- overflow: hidden;
- background-color: var(--wa-color-surface-raised);
- border: none;
- box-shadow: var(--wa-shadow-l);
- overflow: auto;
- padding: 0;
- margin: 0;
- animation-duration: var(--show-duration);
- animation-timing-function: ease;
-
- &.show::backdrop {
- animation: show-backdrop var(--show-duration, 200ms) ease;
- }
-
- &.hide::backdrop {
- animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
- }
-
- &.show.top {
- animation: show-drawer-from-top var(--show-duration) ease;
- }
-
- &.hide.top {
- animation: show-drawer-from-top var(--hide-duration) ease reverse;
- }
-
- &.show.end {
- animation: show-drawer-from-end var(--show-duration) ease;
-
- &:dir(rtl) {
- animation-name: show-drawer-from-start;
- }
- }
-
- &.hide.end {
- animation: show-drawer-from-end var(--hide-duration) ease reverse;
-
- &:dir(rtl) {
- animation-name: show-drawer-from-start;
- }
- }
-
- &.show.bottom {
- animation: show-drawer-from-bottom var(--show-duration) ease;
- }
-
- &.hide.bottom {
- animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
- }
-
- &.show.start {
- animation: show-drawer-from-start var(--show-duration) ease;
-
- &:dir(rtl) {
- animation-name: show-drawer-from-end;
- }
- }
-
- &.hide.start {
- animation: show-drawer-from-start var(--hide-duration) ease reverse;
-
- &:dir(rtl) {
- animation-name: show-drawer-from-end;
- }
- }
-
- &.pulse {
- animation: pulse 250ms ease;
- }
-}
-
-.drawer:focus {
- outline: none;
-}
-
-.top {
- top: 0;
- inset-inline-end: auto;
- bottom: auto;
- inset-inline-start: 0;
- width: 100%;
- height: var(--size);
-}
-
-.end {
- top: 0;
- inset-inline-end: 0;
- bottom: auto;
- inset-inline-start: auto;
- width: var(--size);
- height: 100%;
-}
-
-.bottom {
- top: auto;
- inset-inline-end: auto;
- bottom: 0;
- inset-inline-start: 0;
- width: 100%;
- height: var(--size);
-}
-
-.start {
- top: 0;
- inset-inline-end: auto;
- bottom: auto;
- inset-inline-start: 0;
- width: var(--size);
- height: 100%;
-}
-
-.header {
- display: flex;
- flex-wrap: nowrap;
- padding-inline-start: var(--spacing);
- padding-block-end: 0;
-
- /* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
- padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
- padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
-}
-
-.title {
- align-self: center;
- flex: 1 1 auto;
- font: inherit;
- font-size: var(--wa-font-size-l);
- font-weight: var(--wa-font-weight-heading);
- line-height: var(--wa-line-height-condensed);
- margin: 0;
-}
-
-.header-actions {
- align-self: start;
- display: flex;
- flex-shrink: 0;
- flex-wrap: wrap;
- justify-content: end;
- gap: var(--wa-space-2xs);
- padding-inline-start: var(--spacing);
-}
-
-.header-actions wa-button,
-.header-actions ::slotted(wa-button) {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
-}
-
-.body {
- flex: 1 1 auto;
- display: block;
- padding: var(--spacing);
- overflow: auto;
- -webkit-overflow-scrolling: touch;
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-}
-
-.footer {
- display: flex;
- flex-wrap: wrap;
- gap: var(--wa-space-xs);
- justify-content: end;
- padding: var(--spacing);
- padding-block-start: 0;
-}
-
-.footer ::slotted(wa-button:not(:last-of-type)) {
- margin-inline-end: var(--wa-spacing-xs);
-}
-
-.drawer::backdrop {
- /*
- NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
- remove the fallback values here.
- */
- background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
-}
-
-@keyframes pulse {
- 0% {
- scale: 1;
- }
- 50% {
- scale: 1.01;
- }
- 100% {
- scale: 1;
- }
-}
-
-@keyframes show-drawer {
- from {
- opacity: 0;
- scale: 0.8;
- }
- to {
- opacity: 1;
- scale: 1;
- }
-}
-
-@keyframes show-drawer-from-top {
- from {
- opacity: 0;
- translate: 0 -100%;
- }
- to {
- opacity: 1;
- translate: 0 0;
- }
-}
-
-@keyframes show-drawer-from-end {
- from {
- opacity: 0;
- translate: 100%;
- }
- to {
- opacity: 1;
- translate: 0 0;
- }
-}
-
-@keyframes show-drawer-from-bottom {
- from {
- opacity: 0;
- translate: 0 100%;
- }
- to {
- opacity: 1;
- translate: 0 0;
- }
-}
-
-@keyframes show-drawer-from-start {
- from {
- opacity: 0;
- translate: -100% 0;
- }
- to {
- opacity: 1;
- translate: 0 0;
- }
-}
-
-@keyframes show-backdrop {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-@media (forced-colors: active) {
- .drawer {
- border: solid 1px white;
- }
-}
diff --git a/packages/webawesome/src/components/drawer/drawer.styles.ts b/packages/webawesome/src/components/drawer/drawer.styles.ts
new file mode 100644
index 000000000..f2bfcf4dc
--- /dev/null
+++ b/packages/webawesome/src/components/drawer/drawer.styles.ts
@@ -0,0 +1,294 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --size: 25rem;
+ --spacing: var(--wa-space-l);
+ --show-duration: 200ms;
+ --hide-duration: 200ms;
+
+ display: none;
+ }
+
+ :host([open]) {
+ display: block;
+ }
+
+ .drawer {
+ display: flex;
+ flex-direction: column;
+ top: 0;
+ inset-inline-start: 0;
+ width: 100%;
+ height: 100%;
+ max-width: 100%;
+ max-height: 100%;
+ overflow: hidden;
+ background-color: var(--wa-color-surface-raised);
+ border: none;
+ box-shadow: var(--wa-shadow-l);
+ overflow: auto;
+ padding: 0;
+ margin: 0;
+ animation-duration: var(--show-duration);
+ animation-timing-function: ease;
+
+ &.show::backdrop {
+ animation: show-backdrop var(--show-duration, 200ms) ease;
+ }
+
+ &.hide::backdrop {
+ animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
+ }
+
+ &.show.top {
+ animation: show-drawer-from-top var(--show-duration) ease;
+ }
+
+ &.hide.top {
+ animation: show-drawer-from-top var(--hide-duration) ease reverse;
+ }
+
+ &.show.end {
+ animation: show-drawer-from-end var(--show-duration) ease;
+
+ &:dir(rtl) {
+ animation-name: show-drawer-from-start;
+ }
+ }
+
+ &.hide.end {
+ animation: show-drawer-from-end var(--hide-duration) ease reverse;
+
+ &:dir(rtl) {
+ animation-name: show-drawer-from-start;
+ }
+ }
+
+ &.show.bottom {
+ animation: show-drawer-from-bottom var(--show-duration) ease;
+ }
+
+ &.hide.bottom {
+ animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
+ }
+
+ &.show.start {
+ animation: show-drawer-from-start var(--show-duration) ease;
+
+ &:dir(rtl) {
+ animation-name: show-drawer-from-end;
+ }
+ }
+
+ &.hide.start {
+ animation: show-drawer-from-start var(--hide-duration) ease reverse;
+
+ &:dir(rtl) {
+ animation-name: show-drawer-from-end;
+ }
+ }
+
+ &.pulse {
+ animation: pulse 250ms ease;
+ }
+ }
+
+ .drawer:focus {
+ outline: none;
+ }
+
+ .top {
+ top: 0;
+ inset-inline-end: auto;
+ bottom: auto;
+ inset-inline-start: 0;
+ width: 100%;
+ height: var(--size);
+ }
+
+ .end {
+ top: 0;
+ inset-inline-end: 0;
+ bottom: auto;
+ inset-inline-start: auto;
+ width: var(--size);
+ height: 100%;
+ }
+
+ .bottom {
+ top: auto;
+ inset-inline-end: auto;
+ bottom: 0;
+ inset-inline-start: 0;
+ width: 100%;
+ height: var(--size);
+ }
+
+ .start {
+ top: 0;
+ inset-inline-end: auto;
+ bottom: auto;
+ inset-inline-start: 0;
+ width: var(--size);
+ height: 100%;
+ }
+
+ .header {
+ display: flex;
+ flex-wrap: nowrap;
+ padding-inline-start: var(--spacing);
+ padding-block-end: 0;
+
+ /* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
+ padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
+ padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
+ }
+
+ .title {
+ align-self: center;
+ flex: 1 1 auto;
+ font: inherit;
+ font-size: var(--wa-font-size-l);
+ font-weight: var(--wa-font-weight-heading);
+ line-height: var(--wa-line-height-condensed);
+ margin: 0;
+ }
+
+ .header-actions {
+ align-self: start;
+ display: flex;
+ flex-shrink: 0;
+ flex-wrap: wrap;
+ justify-content: end;
+ gap: var(--wa-space-2xs);
+ padding-inline-start: var(--spacing);
+ }
+
+ .header-actions wa-button,
+ .header-actions ::slotted(wa-button) {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ }
+
+ .body {
+ flex: 1 1 auto;
+ display: block;
+ padding: var(--spacing);
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+ }
+
+ .footer {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--wa-space-xs);
+ justify-content: end;
+ padding: var(--spacing);
+ padding-block-start: 0;
+ }
+
+ .footer ::slotted(wa-button:not(:last-of-type)) {
+ margin-inline-end: var(--wa-spacing-xs);
+ }
+
+ .drawer::backdrop {
+ /*
+ NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
+ remove the fallback values here.
+ */
+ background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
+ }
+
+ @keyframes pulse {
+ 0% {
+ scale: 1;
+ }
+ 50% {
+ scale: 1.01;
+ }
+ 100% {
+ scale: 1;
+ }
+ }
+
+ @keyframes show-drawer {
+ from {
+ opacity: 0;
+ scale: 0.8;
+ }
+ to {
+ opacity: 1;
+ scale: 1;
+ }
+ }
+
+ @keyframes show-drawer-from-top {
+ from {
+ opacity: 0;
+ translate: 0 -100%;
+ }
+ to {
+ opacity: 1;
+ translate: 0 0;
+ }
+ }
+
+ @keyframes show-drawer-from-end {
+ from {
+ opacity: 0;
+ translate: 100%;
+ }
+ to {
+ opacity: 1;
+ translate: 0 0;
+ }
+ }
+
+ @keyframes show-drawer-from-bottom {
+ from {
+ opacity: 0;
+ translate: 0 100%;
+ }
+ to {
+ opacity: 1;
+ translate: 0 0;
+ }
+ }
+
+ @keyframes show-drawer-from-start {
+ from {
+ opacity: 0;
+ translate: -100% 0;
+ }
+ to {
+ opacity: 1;
+ translate: 0 0;
+ }
+ }
+
+ @keyframes show-backdrop {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
+ @media (forced-colors: active) {
+ .drawer {
+ border: solid 1px white;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/drawer/drawer.ts b/packages/webawesome/src/components/drawer/drawer.ts
index 15131dccd..502b1561c 100644
--- a/packages/webawesome/src/components/drawer/drawer.ts
+++ b/packages/webawesome/src/components/drawer/drawer.ts
@@ -13,7 +13,7 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../button/button.js';
-import styles from './drawer.css';
+import styles from './drawer.styles.js';
/**
* @summary Drawers slide in from a container to expose additional options and information.
diff --git a/packages/webawesome/src/components/dropdown-item/dropdown-item.css b/packages/webawesome/src/components/dropdown-item/dropdown-item.css
deleted file mode 100644
index f663f0191..000000000
--- a/packages/webawesome/src/components/dropdown-item/dropdown-item.css
+++ /dev/null
@@ -1,227 +0,0 @@
-:host {
- display: flex;
- position: relative;
- align-items: center;
- padding: 0.5em 1em;
- border-radius: var(--wa-border-radius-s);
- isolation: isolate;
- color: var(--wa-color-text-normal);
- line-height: var(--wa-line-height-condensed);
- cursor: pointer;
- transition:
- var(--wa-transition-fast) background-color var(--wa-transition-easing),
- var(--wa-transition-fast) color var(--wa-transition-easing);
-}
-
-@media (hover: hover) {
- :host(:hover:not(:state(disabled))) {
- background-color: var(--wa-color-neutral-fill-normal);
- }
-}
-
-:host(:focus-visible) {
- z-index: 1;
- outline: var(--wa-focus-ring);
- background-color: var(--wa-color-neutral-fill-normal);
-}
-
-:host(:state(disabled)) {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-/* Danger variant */
-:host([variant='danger']),
-:host([variant='danger']) #details {
- color: var(--wa-color-danger-on-quiet);
-}
-
-@media (hover: hover) {
- :host([variant='danger']:hover) {
- background-color: var(--wa-color-danger-fill-normal);
- color: var(--wa-color-danger-on-normal);
- }
-}
-
-:host([variant='danger']:focus-visible) {
- background-color: var(--wa-color-danger-fill-normal);
- color: var(--wa-color-danger-on-normal);
-}
-
-:host([checkbox-adjacent]) {
- padding-inline-start: 2em;
-}
-
-/* Only add padding when item actually has a submenu */
-:host([submenu-adjacent]:not(:state(has-submenu))) #details {
- padding-inline-end: 0;
-}
-
-:host(:state(has-submenu)[submenu-adjacent]) #details {
- padding-inline-end: 1.75em;
-}
-
-#check {
- visibility: hidden;
- margin-inline-start: -1.5em;
- margin-inline-end: 0.5em;
- font-size: var(--wa-font-size-smaller);
-}
-
-:host(:state(checked)) #check {
- visibility: visible;
-}
-
-#icon ::slotted(*) {
- display: flex;
- flex: 0 0 auto;
- align-items: center;
- margin-inline-end: 0.75em !important;
- font-size: var(--wa-font-size-smaller);
-}
-
-#label {
- flex: 1 1 auto;
- min-width: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-#details {
- display: flex;
- flex: 0 0 auto;
- align-items: center;
- justify-content: end;
- color: var(--wa-color-text-quiet);
- font-size: var(--wa-font-size-smaller) !important;
-}
-
-#details ::slotted(*) {
- margin-inline-start: 2em !important;
-}
-
-/* Submenu indicator icon */
-#submenu-indicator {
- position: absolute;
- inset-inline-end: 1em;
- color: var(--wa-color-neutral-on-quiet);
- font-size: var(--wa-font-size-smaller);
-}
-
-/* Flip chevron icon when RTL */
-:host(:dir(rtl)) #submenu-indicator {
- transform: scaleX(-1);
-}
-
-/* Submenu styles */
-#submenu {
- display: flex;
- z-index: 10;
- position: absolute;
- top: 0;
- left: 0;
- flex-direction: column;
- width: max-content;
- margin: 0;
- padding: 0.25em;
- border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
- border-radius: var(--wa-border-radius-m);
- background-color: var(--wa-color-surface-raised);
- box-shadow: var(--wa-shadow-m);
- color: var(--wa-color-text-normal);
- text-align: start;
- user-select: none;
-
- /* Override default popover styles */
- &[popover] {
- margin: 0;
- inset: auto;
- padding: 0.25em;
- overflow: visible;
- border-radius: var(--wa-border-radius-m);
- }
-
- &.show {
- animation: submenu-show var(--show-duration, 50ms) ease;
- }
-
- &.hide {
- animation: submenu-show var(--show-duration, 50ms) ease reverse;
- }
-
- /* Submenu placement transform origins */
- &[data-placement^='top'] {
- transform-origin: bottom;
- }
-
- &[data-placement^='bottom'] {
- transform-origin: top;
- }
-
- &[data-placement^='left'] {
- transform-origin: right;
- }
-
- &[data-placement^='right'] {
- transform-origin: left;
- }
-
- &[data-placement='left-start'] {
- transform-origin: right top;
- }
-
- &[data-placement='left-end'] {
- transform-origin: right bottom;
- }
-
- &[data-placement='right-start'] {
- transform-origin: left top;
- }
-
- &[data-placement='right-end'] {
- transform-origin: left bottom;
- }
-
- /* Safe triangle styling */
- &::before {
- display: none;
- z-index: 9;
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- background-color: transparent;
- content: '';
- clip-path: polygon(
- var(--safe-triangle-cursor-x, 0) var(--safe-triangle-cursor-y, 0),
- var(--safe-triangle-submenu-start-x, 0) var(--safe-triangle-submenu-start-y, 0),
- var(--safe-triangle-submenu-end-x, 0) var(--safe-triangle-submenu-end-y, 0)
- );
- pointer-events: auto; /* Enable mouse events on the triangle */
- }
-
- &[data-visible]::before {
- display: block;
- }
-}
-
-::slotted(wa-dropdown-item) {
- font-size: inherit;
-}
-
-::slotted(wa-divider) {
- --spacing: 0.25em;
-}
-
-@keyframes submenu-show {
- from {
- scale: 0.9;
- opacity: 0;
- }
- to {
- scale: 1;
- opacity: 1;
- }
-}
diff --git a/packages/webawesome/src/components/dropdown-item/dropdown-item.styles.ts b/packages/webawesome/src/components/dropdown-item/dropdown-item.styles.ts
new file mode 100644
index 000000000..f88aa9d03
--- /dev/null
+++ b/packages/webawesome/src/components/dropdown-item/dropdown-item.styles.ts
@@ -0,0 +1,231 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: flex;
+ position: relative;
+ align-items: center;
+ padding: 0.5em 1em;
+ border-radius: var(--wa-border-radius-s);
+ isolation: isolate;
+ color: var(--wa-color-text-normal);
+ line-height: var(--wa-line-height-condensed);
+ cursor: pointer;
+ transition:
+ var(--wa-transition-fast) background-color var(--wa-transition-easing),
+ var(--wa-transition-fast) color var(--wa-transition-easing);
+ }
+
+ @media (hover: hover) {
+ :host(:hover:not(:state(disabled))) {
+ background-color: var(--wa-color-neutral-fill-normal);
+ }
+ }
+
+ :host(:focus-visible) {
+ z-index: 1;
+ outline: var(--wa-focus-ring);
+ background-color: var(--wa-color-neutral-fill-normal);
+ }
+
+ :host(:state(disabled)) {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ /* Danger variant */
+ :host([variant='danger']),
+ :host([variant='danger']) #details {
+ color: var(--wa-color-danger-on-quiet);
+ }
+
+ @media (hover: hover) {
+ :host([variant='danger']:hover) {
+ background-color: var(--wa-color-danger-fill-normal);
+ color: var(--wa-color-danger-on-normal);
+ }
+ }
+
+ :host([variant='danger']:focus-visible) {
+ background-color: var(--wa-color-danger-fill-normal);
+ color: var(--wa-color-danger-on-normal);
+ }
+
+ :host([checkbox-adjacent]) {
+ padding-inline-start: 2em;
+ }
+
+ /* Only add padding when item actually has a submenu */
+ :host([submenu-adjacent]:not(:state(has-submenu))) #details {
+ padding-inline-end: 0;
+ }
+
+ :host(:state(has-submenu)[submenu-adjacent]) #details {
+ padding-inline-end: 1.75em;
+ }
+
+ #check {
+ visibility: hidden;
+ margin-inline-start: -1.5em;
+ margin-inline-end: 0.5em;
+ font-size: var(--wa-font-size-smaller);
+ }
+
+ :host(:state(checked)) #check {
+ visibility: visible;
+ }
+
+ #icon ::slotted(*) {
+ display: flex;
+ flex: 0 0 auto;
+ align-items: center;
+ margin-inline-end: 0.75em !important;
+ font-size: var(--wa-font-size-smaller);
+ }
+
+ #label {
+ flex: 1 1 auto;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ #details {
+ display: flex;
+ flex: 0 0 auto;
+ align-items: center;
+ justify-content: end;
+ color: var(--wa-color-text-quiet);
+ font-size: var(--wa-font-size-smaller) !important;
+ }
+
+ #details ::slotted(*) {
+ margin-inline-start: 2em !important;
+ }
+
+ /* Submenu indicator icon */
+ #submenu-indicator {
+ position: absolute;
+ inset-inline-end: 1em;
+ color: var(--wa-color-neutral-on-quiet);
+ font-size: var(--wa-font-size-smaller);
+ }
+
+ /* Flip chevron icon when RTL */
+ :host(:dir(rtl)) #submenu-indicator {
+ transform: scaleX(-1);
+ }
+
+ /* Submenu styles */
+ #submenu {
+ display: flex;
+ z-index: 10;
+ position: absolute;
+ top: 0;
+ left: 0;
+ flex-direction: column;
+ width: max-content;
+ margin: 0;
+ padding: 0.25em;
+ border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
+ border-radius: var(--wa-border-radius-m);
+ background-color: var(--wa-color-surface-raised);
+ box-shadow: var(--wa-shadow-m);
+ color: var(--wa-color-text-normal);
+ text-align: start;
+ user-select: none;
+
+ /* Override default popover styles */
+ &[popover] {
+ margin: 0;
+ inset: auto;
+ padding: 0.25em;
+ overflow: visible;
+ border-radius: var(--wa-border-radius-m);
+ }
+
+ &.show {
+ animation: submenu-show var(--show-duration, 50ms) ease;
+ }
+
+ &.hide {
+ animation: submenu-show var(--show-duration, 50ms) ease reverse;
+ }
+
+ /* Submenu placement transform origins */
+ &[data-placement^='top'] {
+ transform-origin: bottom;
+ }
+
+ &[data-placement^='bottom'] {
+ transform-origin: top;
+ }
+
+ &[data-placement^='left'] {
+ transform-origin: right;
+ }
+
+ &[data-placement^='right'] {
+ transform-origin: left;
+ }
+
+ &[data-placement='left-start'] {
+ transform-origin: right top;
+ }
+
+ &[data-placement='left-end'] {
+ transform-origin: right bottom;
+ }
+
+ &[data-placement='right-start'] {
+ transform-origin: left top;
+ }
+
+ &[data-placement='right-end'] {
+ transform-origin: left bottom;
+ }
+
+ /* Safe triangle styling */
+ &::before {
+ display: none;
+ z-index: 9;
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-color: transparent;
+ content: '';
+ clip-path: polygon(
+ var(--safe-triangle-cursor-x, 0) var(--safe-triangle-cursor-y, 0),
+ var(--safe-triangle-submenu-start-x, 0) var(--safe-triangle-submenu-start-y, 0),
+ var(--safe-triangle-submenu-end-x, 0) var(--safe-triangle-submenu-end-y, 0)
+ );
+ pointer-events: auto; /* Enable mouse events on the triangle */
+ }
+
+ &[data-visible]::before {
+ display: block;
+ }
+ }
+
+ ::slotted(wa-dropdown-item) {
+ font-size: inherit;
+ }
+
+ ::slotted(wa-divider) {
+ --spacing: 0.25em;
+ }
+
+ @keyframes submenu-show {
+ from {
+ scale: 0.9;
+ opacity: 0;
+ }
+ to {
+ scale: 1;
+ opacity: 1;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/dropdown-item/dropdown-item.ts b/packages/webawesome/src/components/dropdown-item/dropdown-item.ts
index 4e43f5d6f..b773662bb 100644
--- a/packages/webawesome/src/components/dropdown-item/dropdown-item.ts
+++ b/packages/webawesome/src/components/dropdown-item/dropdown-item.ts
@@ -4,7 +4,8 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import { animateWithClass } from '../../internal/animate.js';
import { HasSlotController } from '../../internal/slot.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './dropdown-item.css';
+import '../icon/icon.js';
+import styles from './dropdown-item.styles.js';
/**
* @summary Represents an individual item within a dropdown menu, supporting standard items, checkboxes, and submenus.
diff --git a/packages/webawesome/src/components/dropdown/dropdown.css b/packages/webawesome/src/components/dropdown/dropdown.css
deleted file mode 100644
index 693bdc013..000000000
--- a/packages/webawesome/src/components/dropdown/dropdown.css
+++ /dev/null
@@ -1,93 +0,0 @@
-:host {
- --show-duration: 50ms;
- --hide-duration: 50ms;
- display: contents;
-}
-
-#menu {
- display: flex;
- flex-direction: column;
- width: max-content;
- margin: 0;
- padding: 0.25em;
- border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
- border-radius: var(--wa-border-radius-m);
- background-color: var(--wa-color-surface-raised);
- box-shadow: var(--wa-shadow-m);
- color: var(--wa-color-text-normal);
- text-align: start;
- user-select: none;
- overflow: auto;
- max-width: var(--auto-size-available-width) !important;
- max-height: var(--auto-size-available-height) !important;
-
- &.show {
- animation: show var(--show-duration) ease;
- }
-
- &.hide {
- animation: show var(--hide-duration) ease reverse;
- }
-
- ::slotted(h1),
- ::slotted(h2),
- ::slotted(h3),
- ::slotted(h4),
- ::slotted(h5),
- ::slotted(h6) {
- display: block !important;
- margin: 0.25em 0 !important;
- padding: 0.25em 0.75em !important;
- color: var(--wa-color-text-quiet) !important;
- font-family: var(--wa-font-family-body) !important;
- font-weight: var(--wa-font-weight-semibold) !important;
- font-size: var(--wa-font-size-smaller) !important;
- }
-
- ::slotted(wa-divider) {
- --spacing: 0.25em; /* Component-specific, left as-is */
- }
-}
-
-wa-popup[data-current-placement^='top'] #menu {
- transform-origin: bottom;
-}
-
-wa-popup[data-current-placement^='bottom'] #menu {
- transform-origin: top;
-}
-
-wa-popup[data-current-placement^='left'] #menu {
- transform-origin: right;
-}
-
-wa-popup[data-current-placement^='right'] #menu {
- transform-origin: left;
-}
-
-wa-popup[data-current-placement='left-start'] #menu {
- transform-origin: right top;
-}
-
-wa-popup[data-current-placement='left-end'] #menu {
- transform-origin: right bottom;
-}
-
-wa-popup[data-current-placement='right-start'] #menu {
- transform-origin: left top;
-}
-
-wa-popup[data-current-placement='right-end'] #menu {
- transform-origin: left bottom;
-}
-
-@keyframes show {
- from {
- scale: 0.9;
- opacity: 0;
- }
- to {
- scale: 1;
- opacity: 1;
- }
-}
diff --git a/packages/webawesome/src/components/dropdown/dropdown.styles.ts b/packages/webawesome/src/components/dropdown/dropdown.styles.ts
new file mode 100644
index 000000000..11d247602
--- /dev/null
+++ b/packages/webawesome/src/components/dropdown/dropdown.styles.ts
@@ -0,0 +1,97 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --show-duration: 50ms;
+ --hide-duration: 50ms;
+ display: contents;
+ }
+
+ #menu {
+ display: flex;
+ flex-direction: column;
+ width: max-content;
+ margin: 0;
+ padding: 0.25em;
+ border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
+ border-radius: var(--wa-border-radius-m);
+ background-color: var(--wa-color-surface-raised);
+ box-shadow: var(--wa-shadow-m);
+ color: var(--wa-color-text-normal);
+ text-align: start;
+ user-select: none;
+ overflow: auto;
+ max-width: var(--auto-size-available-width) !important;
+ max-height: var(--auto-size-available-height) !important;
+
+ &.show {
+ animation: show var(--show-duration) ease;
+ }
+
+ &.hide {
+ animation: show var(--hide-duration) ease reverse;
+ }
+
+ ::slotted(h1),
+ ::slotted(h2),
+ ::slotted(h3),
+ ::slotted(h4),
+ ::slotted(h5),
+ ::slotted(h6) {
+ display: block !important;
+ margin: 0.25em 0 !important;
+ padding: 0.25em 0.75em !important;
+ color: var(--wa-color-text-quiet) !important;
+ font-family: var(--wa-font-family-body) !important;
+ font-weight: var(--wa-font-weight-semibold) !important;
+ font-size: var(--wa-font-size-smaller) !important;
+ }
+
+ ::slotted(wa-divider) {
+ --spacing: 0.25em; /* Component-specific, left as-is */
+ }
+ }
+
+ wa-popup[data-current-placement^='top'] #menu {
+ transform-origin: bottom;
+ }
+
+ wa-popup[data-current-placement^='bottom'] #menu {
+ transform-origin: top;
+ }
+
+ wa-popup[data-current-placement^='left'] #menu {
+ transform-origin: right;
+ }
+
+ wa-popup[data-current-placement^='right'] #menu {
+ transform-origin: left;
+ }
+
+ wa-popup[data-current-placement='left-start'] #menu {
+ transform-origin: right top;
+ }
+
+ wa-popup[data-current-placement='left-end'] #menu {
+ transform-origin: right bottom;
+ }
+
+ wa-popup[data-current-placement='right-start'] #menu {
+ transform-origin: left top;
+ }
+
+ wa-popup[data-current-placement='right-end'] #menu {
+ transform-origin: left bottom;
+ }
+
+ @keyframes show {
+ from {
+ scale: 0.9;
+ opacity: 0;
+ }
+ to {
+ scale: 1;
+ opacity: 1;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/dropdown/dropdown.ts b/packages/webawesome/src/components/dropdown/dropdown.ts
index a8d03f4fc..b3a1a70e9 100644
--- a/packages/webawesome/src/components/dropdown/dropdown.ts
+++ b/packages/webawesome/src/components/dropdown/dropdown.ts
@@ -12,13 +12,13 @@ import { activeElements } from '../../internal/active-elements.js';
import { animateWithClass } from '../../internal/animate.js';
import { uniqueId } from '../../internal/math.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
+import sizeStyles from '../../styles/component/size.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import type WaButton from '../button/button.js';
import '../dropdown-item/dropdown-item.js';
import type WaDropdownItem from '../dropdown-item/dropdown-item.js';
import WaPopup from '../popup/popup.js'; // Added import for wa-popup
-import styles from './dropdown.css';
+import styles from './dropdown.styles.js';
const openDropdowns = new Set();
diff --git a/packages/webawesome/src/components/icon/icon.css b/packages/webawesome/src/components/icon/icon.css
deleted file mode 100644
index 9a90c004f..000000000
--- a/packages/webawesome/src/components/icon/icon.css
+++ /dev/null
@@ -1,40 +0,0 @@
-:host {
- --primary-color: currentColor;
- --primary-opacity: 1;
- --secondary-color: currentColor;
- --secondary-opacity: 0.4;
-
- box-sizing: content-box;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- vertical-align: -0.125em;
-}
-
-/* Standard */
-:host(:not([auto-width])) {
- width: 1.25em;
- height: 1em;
-}
-
-/* Auto-width */
-:host([auto-width]) {
- width: auto;
- height: 1em;
-}
-
-svg {
- height: 1em;
- overflow: visible;
-
- /* Duotone colors with path-specific opacity fallback */
- path[data-duotone-primary] {
- color: var(--primary-color);
- opacity: var(--path-opacity, var(--primary-opacity));
- }
-
- path[data-duotone-secondary] {
- color: var(--secondary-color);
- opacity: var(--path-opacity, var(--secondary-opacity));
- }
-}
diff --git a/packages/webawesome/src/components/icon/icon.styles.ts b/packages/webawesome/src/components/icon/icon.styles.ts
new file mode 100644
index 000000000..30c656645
--- /dev/null
+++ b/packages/webawesome/src/components/icon/icon.styles.ts
@@ -0,0 +1,44 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --primary-color: currentColor;
+ --primary-opacity: 1;
+ --secondary-color: currentColor;
+ --secondary-opacity: 0.4;
+
+ box-sizing: content-box;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ vertical-align: -0.125em;
+ }
+
+ /* Standard */
+ :host(:not([auto-width])) {
+ width: 1.25em;
+ height: 1em;
+ }
+
+ /* Auto-width */
+ :host([auto-width]) {
+ width: auto;
+ height: 1em;
+ }
+
+ svg {
+ height: 1em;
+ overflow: visible;
+
+ /* Duotone colors with path-specific opacity fallback */
+ path[data-duotone-primary] {
+ color: var(--primary-color);
+ opacity: var(--path-opacity, var(--primary-opacity));
+ }
+
+ path[data-duotone-secondary] {
+ color: var(--secondary-color);
+ opacity: var(--path-opacity, var(--secondary-opacity));
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/icon/icon.ts b/packages/webawesome/src/components/icon/icon.ts
index b30ac07f6..85dbe554d 100644
--- a/packages/webawesome/src/components/icon/icon.ts
+++ b/packages/webawesome/src/components/icon/icon.ts
@@ -5,7 +5,7 @@ import { WaErrorEvent } from '../../events/error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './icon.css';
+import styles from './icon.styles.js';
import { getDefaultIconFamily, getIconLibrary, unwatchIcon, watchIcon, type IconLibrary } from './library.js';
import type { HTMLTemplateResult, PropertyValues } from 'lit';
diff --git a/packages/webawesome/src/components/include/include.css b/packages/webawesome/src/components/include/include.css
deleted file mode 100644
index 5d4e87f30..000000000
--- a/packages/webawesome/src/components/include/include.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:host {
- display: block;
-}
diff --git a/packages/webawesome/src/components/include/include.styles.ts b/packages/webawesome/src/components/include/include.styles.ts
new file mode 100644
index 000000000..940a1557b
--- /dev/null
+++ b/packages/webawesome/src/components/include/include.styles.ts
@@ -0,0 +1,7 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: block;
+ }
+`;
diff --git a/packages/webawesome/src/components/include/include.ts b/packages/webawesome/src/components/include/include.ts
index 267047801..8f9c661f8 100644
--- a/packages/webawesome/src/components/include/include.ts
+++ b/packages/webawesome/src/components/include/include.ts
@@ -4,7 +4,7 @@ import { WaIncludeErrorEvent } from '../../events/include-error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './include.css';
+import styles from './include.styles.js';
import { requestInclude } from './request.js';
/**
diff --git a/packages/webawesome/src/components/input/input.css b/packages/webawesome/src/components/input/input.css
deleted file mode 100644
index be657138a..000000000
--- a/packages/webawesome/src/components/input/input.css
+++ /dev/null
@@ -1,227 +0,0 @@
-:host {
- border-width: 0;
-}
-
-.text-field {
- flex: auto;
- display: flex;
- align-items: stretch;
- justify-content: start;
- position: relative;
- transition: inherit;
- height: var(--wa-form-control-height);
- border-color: var(--wa-form-control-border-color);
- border-radius: var(--wa-form-control-border-radius);
- border-style: var(--wa-form-control-border-style);
- border-width: var(--wa-form-control-border-width);
- cursor: text;
- color: var(--wa-form-control-value-color);
- font-size: var(--wa-form-control-value-font-size);
- font-family: inherit;
- font-weight: var(--wa-form-control-value-font-weight);
- line-height: var(--wa-form-control-value-line-height);
- vertical-align: middle;
- width: 100%;
- transition:
- background-color var(--wa-transition-normal),
- border var(--wa-transition-normal),
- outline var(--wa-transition-fast);
- transition-timing-function: var(--wa-transition-easing);
- background-color: var(--wa-form-control-background-color);
- box-shadow: var(--box-shadow);
- padding: 0 var(--wa-form-control-padding-inline);
-
- &:focus-within {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-
- /* Style disabled inputs */
- &:has(:disabled) {
- cursor: not-allowed;
- opacity: 0.5;
- }
-}
-
-/* Appearance modifiers */
-:host([appearance='outlined']) .text-field {
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
-}
-
-:host([appearance='filled']) .text-field {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-color-neutral-fill-quiet);
-}
-
-:host([appearance='filled-outlined']) .text-field {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-form-control-border-color);
-}
-
-:host([pill]) .text-field {
- border-radius: var(--wa-border-radius-pill) !important;
-}
-
-.text-field {
- /* Show autofill styles over the entire text field, not just the native */
- &:has(:autofill),
- &:has(:-webkit-autofill) {
- background-color: var(--wa-color-brand-fill-quiet) !important;
- }
-
- input,
- textarea {
- /*
- Fixes an alignment issue with placeholders.
- https://github.com/shoelace-style/webawesome/issues/342
- */
- height: 100%;
-
- padding: 0;
- border: none;
- outline: none;
- box-shadow: none;
- margin: 0;
- cursor: inherit;
- -webkit-appearance: none;
- font: inherit;
-
- /* Turn off Safari's autofill styles */
- &:-webkit-autofill,
- &:-webkit-autofill:hover,
- &:-webkit-autofill:focus,
- &:-webkit-autofill:active {
- -webkit-background-clip: text;
- background-color: transparent;
- -webkit-text-fill-color: inherit;
- }
- }
-}
-
-input {
- flex: 1 1 auto;
- min-width: 0;
- height: 100%;
- transition: inherit;
-
- /* prettier-ignore */
- background-color: rgb(118 118 118 / 0); /* ensures proper placeholder styles in webkit's date input */
- height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
- padding-block: 0;
- color: inherit;
-
- &:autofill {
- &,
- &:hover,
- &:focus,
- &:active {
- box-shadow: none;
- caret-color: var(--wa-form-control-value-color);
- }
- }
-
- &::placeholder {
- color: var(--wa-form-control-placeholder-color);
- user-select: none;
- -webkit-user-select: none;
- }
-
- &::-webkit-search-decoration,
- &::-webkit-search-cancel-button,
- &::-webkit-search-results-button,
- &::-webkit-search-results-decoration {
- -webkit-appearance: none;
- }
-
- &:focus {
- outline: none;
- }
-}
-
-textarea {
- &:autofill {
- &,
- &:hover,
- &:focus,
- &:active {
- box-shadow: none;
- caret-color: var(--wa-form-control-value-color);
- }
- }
-
- &::placeholder {
- color: var(--wa-form-control-placeholder-color);
- user-select: none;
- -webkit-user-select: none;
- }
-}
-
-.start,
-.end {
- display: inline-flex;
- flex: 0 0 auto;
- align-items: center;
- cursor: default;
-
- &::slotted(wa-icon) {
- color: var(--wa-color-neutral-on-quiet);
- }
-}
-
-.start::slotted(*) {
- margin-inline-end: var(--wa-form-control-padding-inline);
-}
-
-.end::slotted(*) {
- margin-inline-start: var(--wa-form-control-padding-inline);
-}
-
-/*
- * Clearable + Password Toggle
- */
-
-.clear,
-.password-toggle {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- font-size: inherit;
- color: var(--wa-color-neutral-on-quiet);
- border: none;
- background: none;
- padding: 0;
- transition: var(--wa-transition-normal) color;
- cursor: pointer;
- margin-inline-start: var(--wa-form-control-padding-inline);
-
- @media (hover: hover) {
- &:hover {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
- }
- }
-
- &:active {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
- }
-
- &:focus {
- outline: none;
- }
-}
-
-/* Don't show the browser's password toggle in Edge */
-::-ms-reveal {
- display: none;
-}
-
-/* Hide the built-in number spinner */
-:host([without-spin-buttons]) input[type='number'] {
- -moz-appearance: textfield;
-
- &::-webkit-outer-spin-button,
- &::-webkit-inner-spin-button {
- -webkit-appearance: none;
- display: none;
- }
-}
diff --git a/packages/webawesome/src/components/input/input.styles.ts b/packages/webawesome/src/components/input/input.styles.ts
new file mode 100644
index 000000000..5332a7d69
--- /dev/null
+++ b/packages/webawesome/src/components/input/input.styles.ts
@@ -0,0 +1,231 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ border-width: 0;
+ }
+
+ .text-field {
+ flex: auto;
+ display: flex;
+ align-items: stretch;
+ justify-content: start;
+ position: relative;
+ transition: inherit;
+ height: var(--wa-form-control-height);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: var(--wa-form-control-border-radius);
+ border-style: var(--wa-form-control-border-style);
+ border-width: var(--wa-form-control-border-width);
+ cursor: text;
+ color: var(--wa-form-control-value-color);
+ font-size: var(--wa-form-control-value-font-size);
+ font-family: inherit;
+ font-weight: var(--wa-form-control-value-font-weight);
+ line-height: var(--wa-form-control-value-line-height);
+ vertical-align: middle;
+ width: 100%;
+ transition:
+ background-color var(--wa-transition-normal),
+ border var(--wa-transition-normal),
+ outline var(--wa-transition-fast);
+ transition-timing-function: var(--wa-transition-easing);
+ background-color: var(--wa-form-control-background-color);
+ box-shadow: var(--box-shadow);
+ padding: 0 var(--wa-form-control-padding-inline);
+
+ &:focus-within {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Style disabled inputs */
+ &:has(:disabled) {
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='outlined']) .text-field {
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ :host([appearance='filled']) .text-field {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-color-neutral-fill-quiet);
+ }
+
+ :host([appearance='filled-outlined']) .text-field {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ :host([pill]) .text-field {
+ border-radius: var(--wa-border-radius-pill) !important;
+ }
+
+ .text-field {
+ /* Show autofill styles over the entire text field, not just the native */
+ &:has(:autofill),
+ &:has(:-webkit-autofill) {
+ background-color: var(--wa-color-brand-fill-quiet) !important;
+ }
+
+ input,
+ textarea {
+ /*
+ Fixes an alignment issue with placeholders.
+ https://github.com/shoelace-style/webawesome/issues/342
+ */
+ height: 100%;
+
+ padding: 0;
+ border: none;
+ outline: none;
+ box-shadow: none;
+ margin: 0;
+ cursor: inherit;
+ -webkit-appearance: none;
+ font: inherit;
+
+ /* Turn off Safari's autofill styles */
+ &:-webkit-autofill,
+ &:-webkit-autofill:hover,
+ &:-webkit-autofill:focus,
+ &:-webkit-autofill:active {
+ -webkit-background-clip: text;
+ background-color: transparent;
+ -webkit-text-fill-color: inherit;
+ }
+ }
+ }
+
+ input {
+ flex: 1 1 auto;
+ min-width: 0;
+ height: 100%;
+ transition: inherit;
+
+ /* prettier-ignore */
+ background-color: rgb(118 118 118 / 0); /* ensures proper placeholder styles in webkit's date input */
+ height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
+ padding-block: 0;
+ color: inherit;
+
+ &:autofill {
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ box-shadow: none;
+ caret-color: var(--wa-form-control-value-color);
+ }
+ }
+
+ &::placeholder {
+ color: var(--wa-form-control-placeholder-color);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ &::-webkit-search-decoration,
+ &::-webkit-search-cancel-button,
+ &::-webkit-search-results-button,
+ &::-webkit-search-results-decoration {
+ -webkit-appearance: none;
+ }
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ textarea {
+ &:autofill {
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ box-shadow: none;
+ caret-color: var(--wa-form-control-value-color);
+ }
+ }
+
+ &::placeholder {
+ color: var(--wa-form-control-placeholder-color);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+ }
+
+ .start,
+ .end {
+ display: inline-flex;
+ flex: 0 0 auto;
+ align-items: center;
+ cursor: default;
+
+ &::slotted(wa-icon) {
+ color: var(--wa-color-neutral-on-quiet);
+ }
+ }
+
+ .start::slotted(*) {
+ margin-inline-end: var(--wa-form-control-padding-inline);
+ }
+
+ .end::slotted(*) {
+ margin-inline-start: var(--wa-form-control-padding-inline);
+ }
+
+ /*
+ * Clearable + Password Toggle
+ */
+
+ .clear,
+ .password-toggle {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: inherit;
+ color: var(--wa-color-neutral-on-quiet);
+ border: none;
+ background: none;
+ padding: 0;
+ transition: var(--wa-transition-normal) color;
+ cursor: pointer;
+ margin-inline-start: var(--wa-form-control-padding-inline);
+
+ @media (hover: hover) {
+ &:hover {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+ }
+
+ &:active {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
+ }
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ /* Don't show the browser's password toggle in Edge */
+ ::-ms-reveal {
+ display: none;
+ }
+
+ /* Hide the built-in number spinner */
+ :host([without-spin-buttons]) input[type='number'] {
+ -moz-appearance: textfield;
+
+ &::-webkit-outer-spin-button,
+ &::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ display: none;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/input/input.ts b/packages/webawesome/src/components/input/input.ts
index 72953995d..930b85ee7 100644
--- a/packages/webawesome/src/components/input/input.ts
+++ b/packages/webawesome/src/components/input/input.ts
@@ -9,11 +9,11 @@ import { submitOnEnter } from '../../internal/submit-on-enter.js';
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './input.css';
+import styles from './input.styles.js';
/**
* @summary Inputs collect data from the user.
diff --git a/packages/webawesome/src/components/intersection-observer/intersection-observer.css b/packages/webawesome/src/components/intersection-observer/intersection-observer.css
deleted file mode 100644
index 92d692cdd..000000000
--- a/packages/webawesome/src/components/intersection-observer/intersection-observer.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:host {
- display: contents;
-}
diff --git a/packages/webawesome/src/components/intersection-observer/intersection-observer.styles.ts b/packages/webawesome/src/components/intersection-observer/intersection-observer.styles.ts
new file mode 100644
index 000000000..1ef4bf6f3
--- /dev/null
+++ b/packages/webawesome/src/components/intersection-observer/intersection-observer.styles.ts
@@ -0,0 +1,7 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: contents;
+ }
+`;
diff --git a/packages/webawesome/src/components/intersection-observer/intersection-observer.ts b/packages/webawesome/src/components/intersection-observer/intersection-observer.ts
index e703be0d0..5dbdb1eae 100644
--- a/packages/webawesome/src/components/intersection-observer/intersection-observer.ts
+++ b/packages/webawesome/src/components/intersection-observer/intersection-observer.ts
@@ -5,7 +5,7 @@ import { clamp } from '../../internal/math.js';
import { parseSpaceDelimitedTokens } from '../../internal/parse.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './intersection-observer.css';
+import styles from './intersection-observer.styles.js';
/**
* @summary Tracks immediate child elements and fires events as they move in and out of view.
diff --git a/packages/webawesome/src/components/mutation-observer/mutation-observer.css b/packages/webawesome/src/components/mutation-observer/mutation-observer.css
deleted file mode 100644
index 92d692cdd..000000000
--- a/packages/webawesome/src/components/mutation-observer/mutation-observer.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:host {
- display: contents;
-}
diff --git a/packages/webawesome/src/components/mutation-observer/mutation-observer.styles.ts b/packages/webawesome/src/components/mutation-observer/mutation-observer.styles.ts
new file mode 100644
index 000000000..1ef4bf6f3
--- /dev/null
+++ b/packages/webawesome/src/components/mutation-observer/mutation-observer.styles.ts
@@ -0,0 +1,7 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: contents;
+ }
+`;
diff --git a/packages/webawesome/src/components/mutation-observer/mutation-observer.ts b/packages/webawesome/src/components/mutation-observer/mutation-observer.ts
index 5c0ad0c6b..28fe4b97d 100644
--- a/packages/webawesome/src/components/mutation-observer/mutation-observer.ts
+++ b/packages/webawesome/src/components/mutation-observer/mutation-observer.ts
@@ -3,7 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
import { WaMutationEvent } from '../../events/mutation.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './mutation-observer.css';
+import styles from './mutation-observer.styles.js';
/**
* @summary The Mutation Observer component offers a thin, declarative interface to the [`MutationObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).
diff --git a/packages/webawesome/src/components/option/option.css b/packages/webawesome/src/components/option/option.css
deleted file mode 100644
index 31ec2647a..000000000
--- a/packages/webawesome/src/components/option/option.css
+++ /dev/null
@@ -1,80 +0,0 @@
-:host {
- display: block;
- color: var(--wa-color-text-normal);
- -webkit-user-select: none;
- user-select: none;
-
- position: relative;
- display: flex;
- align-items: center;
- font: inherit;
- padding: 0.5em 1em 0.5em 0.25em;
- line-height: var(--wa-line-height-condensed);
- transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
- cursor: pointer;
-}
-
-:host(:focus) {
- outline: none;
-}
-
-@media (hover: hover) {
- :host(:not([disabled], :state(current)):is(:state(hover), :hover)) {
- background-color: var(--wa-color-neutral-fill-normal);
- color: var(--wa-color-neutral-on-normal);
- }
-}
-
-:host(:state(current)),
-:host([disabled]:state(current)) {
- background-color: var(--wa-color-brand-fill-loud);
- color: var(--wa-color-brand-on-loud);
- opacity: 1;
-}
-
-:host([disabled]) {
- outline: none;
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.label {
- flex: 1 1 auto;
- display: inline-block;
-}
-
-.check {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: var(--wa-font-size-smaller);
- visibility: hidden;
- width: 2em;
-}
-
-:host(:state(selected)) .check {
- visibility: visible;
-}
-
-.start,
-.end {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
-}
-
-.start::slotted(*) {
- margin-inline-end: 0.5em;
-}
-
-.end::slotted(*) {
- margin-inline-start: 0.5em;
-}
-
-@media (forced-colors: active) {
- :host(:hover:not([aria-disabled='true'])) {
- outline: dashed 1px SelectedItem;
- outline-offset: -1px;
- }
-}
diff --git a/packages/webawesome/src/components/option/option.styles.ts b/packages/webawesome/src/components/option/option.styles.ts
new file mode 100644
index 000000000..a0779c251
--- /dev/null
+++ b/packages/webawesome/src/components/option/option.styles.ts
@@ -0,0 +1,84 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: block;
+ color: var(--wa-color-text-normal);
+ -webkit-user-select: none;
+ user-select: none;
+
+ position: relative;
+ display: flex;
+ align-items: center;
+ font: inherit;
+ padding: 0.5em 1em 0.5em 0.25em;
+ line-height: var(--wa-line-height-condensed);
+ transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
+ cursor: pointer;
+ }
+
+ :host(:focus) {
+ outline: none;
+ }
+
+ @media (hover: hover) {
+ :host(:not([disabled], :state(current)):is(:state(hover), :hover)) {
+ background-color: var(--wa-color-neutral-fill-normal);
+ color: var(--wa-color-neutral-on-normal);
+ }
+ }
+
+ :host(:state(current)),
+ :host([disabled]:state(current)) {
+ background-color: var(--wa-color-brand-fill-loud);
+ color: var(--wa-color-brand-on-loud);
+ opacity: 1;
+ }
+
+ :host([disabled]) {
+ outline: none;
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ .label {
+ flex: 1 1 auto;
+ display: inline-block;
+ }
+
+ .check {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--wa-font-size-smaller);
+ visibility: hidden;
+ width: 2em;
+ }
+
+ :host(:state(selected)) .check {
+ visibility: visible;
+ }
+
+ .start,
+ .end {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ }
+
+ .start::slotted(*) {
+ margin-inline-end: 0.5em;
+ }
+
+ .end::slotted(*) {
+ margin-inline-start: 0.5em;
+ }
+
+ @media (forced-colors: active) {
+ :host(:hover:not([aria-disabled='true'])) {
+ outline: dashed 1px SelectedItem;
+ outline-offset: -1px;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/option/option.ts b/packages/webawesome/src/components/option/option.ts
index 5c0f10957..2bbf69242 100644
--- a/packages/webawesome/src/components/option/option.ts
+++ b/packages/webawesome/src/components/option/option.ts
@@ -5,7 +5,8 @@ import getText from '../../internal/get-text.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './option.css';
+import type WaSelect from '../select/select.js';
+import styles from './option.styles.js';
/**
* @summary Options define the selectable items within a select component.
@@ -109,7 +110,7 @@ export default class WaOption extends WebAwesomeElement {
this.updateDefaultLabel();
if (this.isInitialized) {
- // When the label changes, tell the controller to update
+ // When the label changes, tell the parent to update
customElements.whenDefined('wa-select').then(() => {
const controller = this.closest('wa-select');
if (controller) {
@@ -117,6 +118,16 @@ export default class WaOption extends WebAwesomeElement {
controller.selectionChanged?.();
}
});
+
+ // When the label changes, tell the parent to update
+ customElements.whenDefined('wa-combobox').then(() => {
+ // We cast to because it shares the same API as combobox
+ const controller = this.closest('wa-combobox');
+ if (controller) {
+ controller.handleDefaultSlotChange();
+ controller.selectionChanged?.();
+ }
+ });
} else {
this.isInitialized = true;
}
@@ -134,7 +145,8 @@ export default class WaOption extends WebAwesomeElement {
protected willUpdate(changedProperties: PropertyValues): void {
if (changedProperties.has('defaultSelected')) {
- if (!this.closest('wa-select')?.hasInteracted) {
+ // We cast to because it shares the same API as combobox
+ if (!this.closest('wa-combobox, wa-select')?.hasInteracted) {
const oldVal = this.selected;
this.selected = this.defaultSelected;
this.requestUpdate('selected', oldVal);
diff --git a/packages/webawesome/src/components/popover/popover.css b/packages/webawesome/src/components/popover/popover.css
deleted file mode 100644
index 1afa32574..000000000
--- a/packages/webawesome/src/components/popover/popover.css
+++ /dev/null
@@ -1,91 +0,0 @@
-:host {
- --arrow-size: 0.375rem;
- --max-width: 25rem;
- --show-duration: 100ms;
- --hide-duration: 100ms;
-
- /* Internal calculated properties */
- --arrow-diagonal-size: calc((var(--arrow-size) * sin(45deg)));
-
- display: contents;
-
- /** Defaults for inherited CSS properties */
- font-size: var(--wa-font-size-m);
- line-height: var(--wa-line-height-normal);
- text-align: start;
- white-space: normal;
-}
-
-/* The native dialog element */
-.dialog {
- display: none;
- position: fixed;
- inset: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- border: none;
- background: transparent;
- overflow: visible;
- pointer-events: none;
-
- &:focus {
- outline: none;
- }
-
- &[open] {
- display: block;
- }
-}
-
-/* The element */
-.popover {
- --arrow-size: inherit;
- --show-duration: inherit;
- --hide-duration: inherit;
-
- pointer-events: auto;
-
- &::part(arrow) {
- background-color: var(--wa-color-surface-default);
- border-top: none;
- border-left: none;
- border-bottom: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
- border-right: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
- box-shadow: none;
- }
-}
-
-.popover[placement^='top']::part(popup) {
- transform-origin: bottom;
-}
-
-.popover[placement^='bottom']::part(popup) {
- transform-origin: top;
-}
-
-.popover[placement^='left']::part(popup) {
- transform-origin: right;
-}
-
-.popover[placement^='right']::part(popup) {
- transform-origin: left;
-}
-
-/* Body */
-.body {
- display: flex;
- flex-direction: column;
- width: max-content;
- max-width: var(--max-width);
- padding: var(--wa-space-l);
- background-color: var(--wa-color-surface-default);
- border: var(--wa-panel-border-width) solid var(--wa-color-surface-border);
- border-radius: var(--wa-panel-border-radius);
- border-style: var(--wa-panel-border-style);
- box-shadow: var(--wa-shadow-l);
- color: var(--wa-color-text-normal);
- user-select: none;
- -webkit-user-select: none;
-}
diff --git a/packages/webawesome/src/components/popover/popover.styles.ts b/packages/webawesome/src/components/popover/popover.styles.ts
new file mode 100644
index 000000000..f2163e8e2
--- /dev/null
+++ b/packages/webawesome/src/components/popover/popover.styles.ts
@@ -0,0 +1,95 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --arrow-size: 0.375rem;
+ --max-width: 25rem;
+ --show-duration: 100ms;
+ --hide-duration: 100ms;
+
+ /* Internal calculated properties */
+ --arrow-diagonal-size: calc((var(--arrow-size) * sin(45deg)));
+
+ display: contents;
+
+ /** Defaults for inherited CSS properties */
+ font-size: var(--wa-font-size-m);
+ line-height: var(--wa-line-height-normal);
+ text-align: start;
+ white-space: normal;
+ }
+
+ /* The native dialog element */
+ .dialog {
+ display: none;
+ position: fixed;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ border: none;
+ background: transparent;
+ overflow: visible;
+ pointer-events: none;
+
+ &:focus {
+ outline: none;
+ }
+
+ &[open] {
+ display: block;
+ }
+ }
+
+ /* The element */
+ .popover {
+ --arrow-size: inherit;
+ --show-duration: inherit;
+ --hide-duration: inherit;
+
+ pointer-events: auto;
+
+ &::part(arrow) {
+ background-color: var(--wa-color-surface-default);
+ border-top: none;
+ border-left: none;
+ border-bottom: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
+ border-right: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
+ box-shadow: none;
+ }
+ }
+
+ .popover[placement^='top']::part(popup) {
+ transform-origin: bottom;
+ }
+
+ .popover[placement^='bottom']::part(popup) {
+ transform-origin: top;
+ }
+
+ .popover[placement^='left']::part(popup) {
+ transform-origin: right;
+ }
+
+ .popover[placement^='right']::part(popup) {
+ transform-origin: left;
+ }
+
+ /* Body */
+ .body {
+ display: flex;
+ flex-direction: column;
+ width: max-content;
+ max-width: var(--max-width);
+ padding: var(--wa-space-l);
+ background-color: var(--wa-color-surface-default);
+ border: var(--wa-panel-border-width) solid var(--wa-color-surface-border);
+ border-radius: var(--wa-panel-border-radius);
+ border-style: var(--wa-panel-border-style);
+ box-shadow: var(--wa-shadow-l);
+ color: var(--wa-color-text-normal);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+`;
diff --git a/packages/webawesome/src/components/popover/popover.ts b/packages/webawesome/src/components/popover/popover.ts
index 63ed3a14a..60eaeba84 100644
--- a/packages/webawesome/src/components/popover/popover.ts
+++ b/packages/webawesome/src/components/popover/popover.ts
@@ -12,7 +12,7 @@ import { uniqueId } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import WaPopup from '../popup/popup.js';
-import styles from './popover.css';
+import styles from './popover.styles.js';
const openPopovers = new Set();
diff --git a/packages/webawesome/src/components/popup/popup.css b/packages/webawesome/src/components/popup/popup.css
deleted file mode 100644
index 7db983610..000000000
--- a/packages/webawesome/src/components/popup/popup.css
+++ /dev/null
@@ -1,121 +0,0 @@
-:host {
- --arrow-color: black;
- --arrow-size: var(--wa-tooltip-arrow-size);
- --show-duration: 100ms;
- --hide-duration: 100ms;
-
- /*
- * These properties are computed to account for the arrow's dimensions after being rotated 45º. The constant
- * 0.7071 is derived from sin(45), which is the diagonal size of the arrow's container after rotating.
- */
- --arrow-size-diagonal: calc(var(--arrow-size) * 0.7071);
- --arrow-padding-offset: calc(var(--arrow-size-diagonal) - var(--arrow-size));
-
- display: contents;
-}
-
-.popup {
- position: absolute;
- isolation: isolate;
- max-width: var(--auto-size-available-width, none);
- max-height: var(--auto-size-available-height, none);
-
- /* Clear UA styles for [popover] */
- :where(&) {
- inset: unset;
- padding: unset;
- margin: unset;
- width: unset;
- height: unset;
- color: unset;
- background: unset;
- border: unset;
- overflow: unset;
- }
-}
-
-.popup-fixed {
- position: fixed;
-}
-
-.popup:not(.popup-active) {
- display: none;
-}
-
-.arrow {
- position: absolute;
- width: calc(var(--arrow-size-diagonal) * 2);
- height: calc(var(--arrow-size-diagonal) * 2);
- rotate: 45deg;
- background: var(--arrow-color);
- z-index: 3;
-}
-
-:host([data-current-placement~='left']) .arrow {
- rotate: -45deg;
-}
-
-:host([data-current-placement~='right']) .arrow {
- rotate: 135deg;
-}
-
-:host([data-current-placement~='bottom']) .arrow {
- rotate: 225deg;
-}
-
-/* Hover bridge */
-.popup-hover-bridge:not(.popup-hover-bridge-visible) {
- display: none;
-}
-
-.popup-hover-bridge {
- position: fixed;
- z-index: 899;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- clip-path: polygon(
- var(--hover-bridge-top-left-x, 0) var(--hover-bridge-top-left-y, 0),
- var(--hover-bridge-top-right-x, 0) var(--hover-bridge-top-right-y, 0),
- var(--hover-bridge-bottom-right-x, 0) var(--hover-bridge-bottom-right-y, 0),
- var(--hover-bridge-bottom-left-x, 0) var(--hover-bridge-bottom-left-y, 0)
- );
-}
-
-/* Built-in animations */
-.show {
- animation: show var(--show-duration) ease;
-}
-
-.hide {
- animation: show var(--hide-duration) ease reverse;
-}
-
-@keyframes show {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
-}
-
-.show-with-scale {
- animation: show-with-scale var(--show-duration) ease;
-}
-
-.hide-with-scale {
- animation: show-with-scale var(--hide-duration) ease reverse;
-}
-
-@keyframes show-with-scale {
- from {
- opacity: 0;
- scale: 0.8;
- }
- to {
- opacity: 1;
- scale: 1;
- }
-}
diff --git a/packages/webawesome/src/components/popup/popup.styles.ts b/packages/webawesome/src/components/popup/popup.styles.ts
new file mode 100644
index 000000000..92932f04c
--- /dev/null
+++ b/packages/webawesome/src/components/popup/popup.styles.ts
@@ -0,0 +1,125 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --arrow-color: black;
+ --arrow-size: var(--wa-tooltip-arrow-size);
+ --show-duration: 100ms;
+ --hide-duration: 100ms;
+
+ /*
+ * These properties are computed to account for the arrow's dimensions after being rotated 45º. The constant
+ * 0.7071 is derived from sin(45), which is the diagonal size of the arrow's container after rotating.
+ */
+ --arrow-size-diagonal: calc(var(--arrow-size) * 0.7071);
+ --arrow-padding-offset: calc(var(--arrow-size-diagonal) - var(--arrow-size));
+
+ display: contents;
+ }
+
+ .popup {
+ position: absolute;
+ isolation: isolate;
+ max-width: var(--auto-size-available-width, none);
+ max-height: var(--auto-size-available-height, none);
+
+ /* Clear UA styles for [popover] */
+ :where(&) {
+ inset: unset;
+ padding: unset;
+ margin: unset;
+ width: unset;
+ height: unset;
+ color: unset;
+ background: unset;
+ border: unset;
+ overflow: unset;
+ }
+ }
+
+ .popup-fixed {
+ position: fixed;
+ }
+
+ .popup:not(.popup-active) {
+ display: none;
+ }
+
+ .arrow {
+ position: absolute;
+ width: calc(var(--arrow-size-diagonal) * 2);
+ height: calc(var(--arrow-size-diagonal) * 2);
+ rotate: 45deg;
+ background: var(--arrow-color);
+ z-index: 3;
+ }
+
+ :host([data-current-placement~='left']) .arrow {
+ rotate: -45deg;
+ }
+
+ :host([data-current-placement~='right']) .arrow {
+ rotate: 135deg;
+ }
+
+ :host([data-current-placement~='bottom']) .arrow {
+ rotate: 225deg;
+ }
+
+ /* Hover bridge */
+ .popup-hover-bridge:not(.popup-hover-bridge-visible) {
+ display: none;
+ }
+
+ .popup-hover-bridge {
+ position: fixed;
+ z-index: 899;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ clip-path: polygon(
+ var(--hover-bridge-top-left-x, 0) var(--hover-bridge-top-left-y, 0),
+ var(--hover-bridge-top-right-x, 0) var(--hover-bridge-top-right-y, 0),
+ var(--hover-bridge-bottom-right-x, 0) var(--hover-bridge-bottom-right-y, 0),
+ var(--hover-bridge-bottom-left-x, 0) var(--hover-bridge-bottom-left-y, 0)
+ );
+ }
+
+ /* Built-in animations */
+ .show {
+ animation: show var(--show-duration) ease;
+ }
+
+ .hide {
+ animation: show var(--hide-duration) ease reverse;
+ }
+
+ @keyframes show {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+
+ .show-with-scale {
+ animation: show-with-scale var(--show-duration) ease;
+ }
+
+ .hide-with-scale {
+ animation: show-with-scale var(--hide-duration) ease reverse;
+ }
+
+ @keyframes show-with-scale {
+ from {
+ opacity: 0;
+ scale: 0.8;
+ }
+ to {
+ opacity: 1;
+ scale: 1;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/popup/popup.ts b/packages/webawesome/src/components/popup/popup.ts
index 80ec2f254..cd95780e5 100644
--- a/packages/webawesome/src/components/popup/popup.ts
+++ b/packages/webawesome/src/components/popup/popup.ts
@@ -17,7 +17,7 @@ import { classMap } from 'lit/directives/class-map.js';
import { WaRepositionEvent } from '../../events/reposition.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './popup.css';
+import styles from './popup.styles.js';
export interface VirtualElement {
getBoundingClientRect: () => DOMRect;
diff --git a/packages/webawesome/src/components/progress-bar/progress-bar.css b/packages/webawesome/src/components/progress-bar/progress-bar.css
deleted file mode 100644
index 821320cc4..000000000
--- a/packages/webawesome/src/components/progress-bar/progress-bar.css
+++ /dev/null
@@ -1,66 +0,0 @@
-:host {
- --track-height: 1rem;
- --track-color: var(--wa-color-neutral-fill-normal);
- --indicator-color: var(--wa-color-brand-fill-loud);
-
- display: flex;
-}
-
-.progress-bar {
- flex: 1 1 auto;
- display: flex;
- position: relative;
- overflow: hidden;
- height: var(--track-height);
- border-radius: var(--wa-border-radius-pill);
- background-color: var(--track-color);
- color: var(--wa-color-brand-on-loud);
- font-size: var(--wa-font-size-s);
-}
-
-.indicator {
- width: var(--percentage);
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: var(--indicator-color);
- text-align: center;
- white-space: nowrap;
- overflow: hidden;
- line-height: 1;
- font-weight: var(--wa-font-weight-semibold);
- transition: all var(--wa-transition-slow, 200ms) var(--wa-transition-easing, ease);
- user-select: none;
- -webkit-user-select: none;
-}
-
-/* Indeterminate */
-:host([indeterminate]) .indicator {
- position: absolute;
- inset-block: 0;
- inline-size: 50%;
- animation: wa-progress-indeterminate 2.5s infinite cubic-bezier(0.37, 0, 0.63, 1);
-}
-
-@media (forced-colors: active) {
- .progress-bar {
- outline: solid 1px SelectedItem;
- background-color: var(--wa-color-surface-default);
- }
-
- .indicator {
- outline: solid 1px SelectedItem;
- background-color: SelectedItem;
- }
-}
-
-@keyframes wa-progress-indeterminate {
- 0% {
- inset-inline-start: -50%;
- }
-
- 75%,
- 100% {
- inset-inline-start: 100%;
- }
-}
diff --git a/packages/webawesome/src/components/progress-bar/progress-bar.styles.ts b/packages/webawesome/src/components/progress-bar/progress-bar.styles.ts
new file mode 100644
index 000000000..b2ed39885
--- /dev/null
+++ b/packages/webawesome/src/components/progress-bar/progress-bar.styles.ts
@@ -0,0 +1,70 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --track-height: 1rem;
+ --track-color: var(--wa-color-neutral-fill-normal);
+ --indicator-color: var(--wa-color-brand-fill-loud);
+
+ display: flex;
+ }
+
+ .progress-bar {
+ flex: 1 1 auto;
+ display: flex;
+ position: relative;
+ overflow: hidden;
+ height: var(--track-height);
+ border-radius: var(--wa-border-radius-pill);
+ background-color: var(--track-color);
+ color: var(--wa-color-brand-on-loud);
+ font-size: var(--wa-font-size-s);
+ }
+
+ .indicator {
+ width: var(--percentage);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--indicator-color);
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
+ line-height: 1;
+ font-weight: var(--wa-font-weight-semibold);
+ transition: all var(--wa-transition-slow, 200ms) var(--wa-transition-easing, ease);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ /* Indeterminate */
+ :host([indeterminate]) .indicator {
+ position: absolute;
+ inset-block: 0;
+ inline-size: 50%;
+ animation: wa-progress-indeterminate 2.5s infinite cubic-bezier(0.37, 0, 0.63, 1);
+ }
+
+ @media (forced-colors: active) {
+ .progress-bar {
+ outline: solid 1px SelectedItem;
+ background-color: var(--wa-color-surface-default);
+ }
+
+ .indicator {
+ outline: solid 1px SelectedItem;
+ background-color: SelectedItem;
+ }
+ }
+
+ @keyframes wa-progress-indeterminate {
+ 0% {
+ inset-inline-start: -50%;
+ }
+
+ 75%,
+ 100% {
+ inset-inline-start: 100%;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/progress-bar/progress-bar.ts b/packages/webawesome/src/components/progress-bar/progress-bar.ts
index 7ef5a3dce..708c72f3a 100644
--- a/packages/webawesome/src/components/progress-bar/progress-bar.ts
+++ b/packages/webawesome/src/components/progress-bar/progress-bar.ts
@@ -5,7 +5,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { clamp } from '../../internal/math.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './progress-bar.css';
+import styles from './progress-bar.styles.js';
/**
* @summary Progress bars are used to show the status of an ongoing operation.
diff --git a/packages/webawesome/src/components/progress-ring/progress-ring.css b/packages/webawesome/src/components/progress-ring/progress-ring.css
deleted file mode 100644
index 19f95b903..000000000
--- a/packages/webawesome/src/components/progress-ring/progress-ring.css
+++ /dev/null
@@ -1,64 +0,0 @@
-:host {
- --size: 8rem;
- --track-width: 0.25em; /* avoid using rems here */
- --track-color: var(--wa-color-neutral-fill-normal);
- --indicator-width: var(--track-width);
- --indicator-color: var(--wa-color-brand-fill-loud);
- --indicator-transition-duration: 0.35s;
-
- display: inline-flex;
-}
-
-.progress-ring {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- position: relative;
-}
-
-.image {
- width: var(--size);
- height: var(--size);
- rotate: -90deg;
- transform-origin: 50% 50%;
-}
-
-.track,
-.indicator {
- --radius: calc(var(--size) / 2 - max(var(--track-width), var(--indicator-width)) * 0.5);
- --circumference: calc(var(--radius) * 2 * 3.141592654);
-
- fill: none;
- r: var(--radius);
- cx: calc(var(--size) / 2);
- cy: calc(var(--size) / 2);
-}
-
-.track {
- stroke: var(--track-color);
- stroke-width: var(--track-width);
-}
-
-.indicator {
- stroke: var(--indicator-color);
- stroke-width: var(--indicator-width);
- stroke-linecap: round;
- transition-property: stroke-dashoffset;
- transition-duration: var(--indicator-transition-duration);
- stroke-dasharray: var(--circumference) var(--circumference);
- stroke-dashoffset: calc(var(--circumference) - var(--percentage) * var(--circumference));
-}
-
-.label {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- text-align: center;
- user-select: none;
- -webkit-user-select: none;
-}
diff --git a/packages/webawesome/src/components/progress-ring/progress-ring.styles.ts b/packages/webawesome/src/components/progress-ring/progress-ring.styles.ts
new file mode 100644
index 000000000..9af84ea77
--- /dev/null
+++ b/packages/webawesome/src/components/progress-ring/progress-ring.styles.ts
@@ -0,0 +1,68 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --size: 8rem;
+ --track-width: 0.25em; /* avoid using rems here */
+ --track-color: var(--wa-color-neutral-fill-normal);
+ --indicator-width: var(--track-width);
+ --indicator-color: var(--wa-color-brand-fill-loud);
+ --indicator-transition-duration: 0.35s;
+
+ display: inline-flex;
+ }
+
+ .progress-ring {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ }
+
+ .image {
+ width: var(--size);
+ height: var(--size);
+ rotate: -90deg;
+ transform-origin: 50% 50%;
+ }
+
+ .track,
+ .indicator {
+ --radius: calc(var(--size) / 2 - max(var(--track-width), var(--indicator-width)) * 0.5);
+ --circumference: calc(var(--radius) * 2 * 3.141592654);
+
+ fill: none;
+ r: var(--radius);
+ cx: calc(var(--size) / 2);
+ cy: calc(var(--size) / 2);
+ }
+
+ .track {
+ stroke: var(--track-color);
+ stroke-width: var(--track-width);
+ }
+
+ .indicator {
+ stroke: var(--indicator-color);
+ stroke-width: var(--indicator-width);
+ stroke-linecap: round;
+ transition-property: stroke-dashoffset;
+ transition-duration: var(--indicator-transition-duration);
+ stroke-dasharray: var(--circumference) var(--circumference);
+ stroke-dashoffset: calc(var(--circumference) - var(--percentage) * var(--circumference));
+ }
+
+ .label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ user-select: none;
+ -webkit-user-select: none;
+ }
+`;
diff --git a/packages/webawesome/src/components/progress-ring/progress-ring.ts b/packages/webawesome/src/components/progress-ring/progress-ring.ts
index 53ef182a8..93187de19 100644
--- a/packages/webawesome/src/components/progress-ring/progress-ring.ts
+++ b/packages/webawesome/src/components/progress-ring/progress-ring.ts
@@ -3,7 +3,7 @@ import { html } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './progress-ring.css';
+import styles from './progress-ring.styles.js';
/**
* @summary Progress rings are used to show the progress of a determinate operation in a circular fashion.
diff --git a/packages/webawesome/src/components/qr-code/qr-code.css b/packages/webawesome/src/components/qr-code/qr-code.css
deleted file mode 100644
index 2777d853f..000000000
--- a/packages/webawesome/src/components/qr-code/qr-code.css
+++ /dev/null
@@ -1,12 +0,0 @@
-:host {
- --size: 128px;
- display: inline-block;
-}
-
-:host,
-canvas {
- max-width: var(--size);
- max-height: var(--size);
- width: var(--size);
- height: var(--size);
-}
diff --git a/packages/webawesome/src/components/qr-code/qr-code.styles.ts b/packages/webawesome/src/components/qr-code/qr-code.styles.ts
new file mode 100644
index 000000000..b790cc3b0
--- /dev/null
+++ b/packages/webawesome/src/components/qr-code/qr-code.styles.ts
@@ -0,0 +1,16 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --size: 128px;
+ display: inline-block;
+ }
+
+ :host,
+ canvas {
+ max-width: var(--size);
+ max-height: var(--size);
+ width: var(--size);
+ height: var(--size);
+ }
+`;
diff --git a/packages/webawesome/src/components/qr-code/qr-code.ts b/packages/webawesome/src/components/qr-code/qr-code.ts
index dcc211857..a4247d394 100644
--- a/packages/webawesome/src/components/qr-code/qr-code.ts
+++ b/packages/webawesome/src/components/qr-code/qr-code.ts
@@ -4,7 +4,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import type _QrCreator from 'qr-creator';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './qr-code.css';
+import styles from './qr-code.styles.js';
let QrCreator: _QrCreator.default;
diff --git a/packages/webawesome/src/components/radio-group/radio-group.css b/packages/webawesome/src/components/radio-group/radio-group.css
deleted file mode 100644
index 8b60d8ab2..000000000
--- a/packages/webawesome/src/components/radio-group/radio-group.css
+++ /dev/null
@@ -1,36 +0,0 @@
-:host {
- display: block;
-}
-
-.form-control {
- position: relative;
- border: none;
- padding: 0;
- margin: 0;
-}
-
-.label {
- padding: 0;
-}
-
-.radio-group-required .label::after {
- content: var(--wa-form-control-required-content);
- margin-inline-start: var(--wa-form-control-required-content-offset);
-}
-
-[part~='form-control-input'] {
- display: flex;
- flex-direction: column;
- flex-wrap: wrap;
- gap: 0; /* Radios handle their own spacing */
-}
-
-/* Horizontal */
-:host([orientation='horizontal']) [part~='form-control-input'] {
- flex-direction: row;
-}
-
-/* Help text */
-[part~='hint'] {
- margin-block-start: 0.5em;
-}
diff --git a/packages/webawesome/src/components/radio-group/radio-group.styles.ts b/packages/webawesome/src/components/radio-group/radio-group.styles.ts
new file mode 100644
index 000000000..e06ca4067
--- /dev/null
+++ b/packages/webawesome/src/components/radio-group/radio-group.styles.ts
@@ -0,0 +1,40 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: block;
+ }
+
+ .form-control {
+ position: relative;
+ border: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ .label {
+ padding: 0;
+ }
+
+ .radio-group-required .label::after {
+ content: var(--wa-form-control-required-content);
+ margin-inline-start: var(--wa-form-control-required-content-offset);
+ }
+
+ [part~='form-control-input'] {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ gap: 0; /* Radios handle their own spacing */
+ }
+
+ /* Horizontal */
+ :host([orientation='horizontal']) [part~='form-control-input'] {
+ flex-direction: row;
+ }
+
+ /* Help text */
+ [part~='hint'] {
+ margin-block-start: 0.5em;
+ }
+`;
diff --git a/packages/webawesome/src/components/radio-group/radio-group.ts b/packages/webawesome/src/components/radio-group/radio-group.ts
index 7e39a0872..b202a226d 100644
--- a/packages/webawesome/src/components/radio-group/radio-group.ts
+++ b/packages/webawesome/src/components/radio-group/radio-group.ts
@@ -6,11 +6,11 @@ import { uniqueId } from '../../internal/math.js';
import { HasSlotController } from '../../internal/slot.js';
import { RequiredValidator } from '../../internal/validators/required-validator.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import '../radio/radio.js';
import type WaRadio from '../radio/radio.js';
-import styles from './radio-group.css';
+import styles from './radio-group.styles.js';
/**
* @summary Radio groups are used to group multiple [radios](/docs/components/radio) so they function as a single form control.
diff --git a/packages/webawesome/src/components/radio/radio.css b/packages/webawesome/src/components/radio/radio.css
deleted file mode 100644
index 159237479..000000000
--- a/packages/webawesome/src/components/radio/radio.css
+++ /dev/null
@@ -1,199 +0,0 @@
-:host {
- --checked-icon-color: var(--wa-form-control-activated-color);
- --checked-icon-scale: 0.7;
-
- color: var(--wa-form-control-value-color);
- display: inline-flex;
- flex-direction: row;
- align-items: top;
- font-family: inherit;
- font-weight: var(--wa-form-control-value-font-weight);
- line-height: var(--wa-form-control-value-line-height);
- cursor: pointer;
- user-select: none;
- -webkit-user-select: none;
-}
-
-:host(:focus) {
- outline: none;
-}
-
-/* When the control isn't checked, hide the circle for Windows High Contrast mode a11y */
-:host(:not(:state(checked))) svg circle {
- opacity: 0;
-}
-
-[part~='label'] {
- display: inline;
-}
-
-[part~='hint'] {
- margin-block-start: 0.5em;
-}
-
-/* Default spacing for default appearance radios */
-:host([appearance='default']) {
- margin-block: 0.375em; /* Half of the original 0.75em gap on each side */
-}
-
-:host([appearance='default'][data-wa-radio-horizontal]) {
- margin-block: 0;
- margin-inline: 0.5em; /* Half of the original 1em gap on each side */
-}
-
-/* Remove margin from first/last items to prevent extra space */
-:host([appearance='default'][data-wa-radio-first]) {
- margin-block-start: 0;
- margin-inline-start: 0;
-}
-
-:host([appearance='default'][data-wa-radio-last]) {
- margin-block-end: 0;
- margin-inline-end: 0;
-}
-
-/* Button appearance have no spacing, they get handled by the overlap margins below */
-:host([appearance='button']) {
- margin: 0;
- align-items: center;
- min-height: var(--wa-form-control-height);
- background-color: var(--wa-color-surface-default);
- border: var(--wa-form-control-border-width) var(--wa-form-control-border-style) var(--wa-form-control-border-color);
- border-radius: var(--wa-border-radius-m);
- padding: 0 var(--wa-form-control-padding-inline);
- transition:
- background-color var(--wa-transition-fast),
- border-color var(--wa-transition-fast);
-}
-
-/* Default appearance */
-:host([appearance='default']) {
- .control {
- flex: 0 0 auto;
- position: relative;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: var(--wa-form-control-toggle-size);
- height: var(--wa-form-control-toggle-size);
- border-color: var(--wa-form-control-border-color);
- border-radius: 50%;
- border-style: var(--wa-form-control-border-style);
- border-width: var(--wa-form-control-border-width);
- background-color: var(--wa-form-control-background-color);
- color: transparent;
- transition:
- background var(--wa-transition-normal),
- border-color var(--wa-transition-fast),
- box-shadow var(--wa-transition-fast),
- color var(--wa-transition-fast);
- transition-timing-function: var(--wa-transition-easing);
-
- margin-inline-end: 0.5em;
- }
-
- .checked-icon {
- display: flex;
- fill: currentColor;
- width: var(--wa-form-control-toggle-size);
- height: var(--wa-form-control-toggle-size);
- scale: var(--checked-icon-scale);
- }
-}
-
-/* Button appearance */
-:host([appearance='button']) {
- .control {
- display: none;
- }
-}
-
-/* Checked */
-:host(:state(checked)) .control {
- color: var(--checked-icon-color);
- border-color: var(--wa-form-control-activated-color);
- background-color: var(--wa-form-control-background-color);
-}
-
-/* Focus */
-:host(:focus-visible) .control {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/* Disabled */
-:host(:state(disabled)) {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-/* Horizontal grouping - remove inner border radius */
-:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-inner]) {
- border-radius: 0;
-}
-
-:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-first]) {
- border-start-end-radius: 0;
- border-end-end-radius: 0;
-}
-
-:host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-last]) {
- border-start-start-radius: 0;
- border-end-start-radius: 0;
-}
-
-/* Vertical grouping - remove inner border radius */
-:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-inner]) {
- border-radius: 0;
-}
-
-:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-first]) {
- border-end-start-radius: 0;
- border-end-end-radius: 0;
-}
-
-:host([appearance='button'][data-wa-radio-vertical][data-wa-radio-last]) {
- border-start-start-radius: 0;
- border-start-end-radius: 0;
-}
-
-@media (hover: hover) {
- :host([appearance='button']:hover:not(:state(disabled), :state(checked))) {
- background-color: color-mix(in srgb, var(--wa-color-surface-default) 95%, var(--wa-color-mix-hover));
- }
-}
-
-:host([appearance='button']:focus-visible) {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-:host([appearance='button']:state(checked)) {
- border-color: var(--wa-form-control-activated-color);
- background-color: var(--wa-color-brand-fill-quiet);
-}
-
-:host([appearance='button']:state(checked):focus-visible) {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/* Button overlap margins */
-:host([appearance='button'][data-wa-radio-horizontal]:not([data-wa-radio-first])) {
- margin-inline-start: calc(-1 * var(--wa-form-control-border-width));
-}
-
-:host([appearance='button'][data-wa-radio-vertical]:not([data-wa-radio-first])) {
- margin-block-start: calc(-1 * var(--wa-form-control-border-width));
-}
-
-/* Ensure interactive states are visible above adjacent buttons */
-:host([appearance='button']:hover),
-:host([appearance='button']:state(checked)) {
- position: relative;
- z-index: 1;
-}
-
-:host([appearance='button']:focus-visible) {
- z-index: 2;
-}
diff --git a/packages/webawesome/src/components/radio/radio.styles.ts b/packages/webawesome/src/components/radio/radio.styles.ts
new file mode 100644
index 000000000..2ec3bcfdc
--- /dev/null
+++ b/packages/webawesome/src/components/radio/radio.styles.ts
@@ -0,0 +1,203 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --checked-icon-color: var(--wa-form-control-activated-color);
+ --checked-icon-scale: 0.7;
+
+ color: var(--wa-form-control-value-color);
+ display: inline-flex;
+ flex-direction: row;
+ align-items: top;
+ font-family: inherit;
+ font-weight: var(--wa-form-control-value-font-weight);
+ line-height: var(--wa-form-control-value-line-height);
+ cursor: pointer;
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ :host(:focus) {
+ outline: none;
+ }
+
+ /* When the control isn't checked, hide the circle for Windows High Contrast mode a11y */
+ :host(:not(:state(checked))) svg circle {
+ opacity: 0;
+ }
+
+ [part~='label'] {
+ display: inline;
+ }
+
+ [part~='hint'] {
+ margin-block-start: 0.5em;
+ }
+
+ /* Default spacing for default appearance radios */
+ :host([appearance='default']) {
+ margin-block: 0.375em; /* Half of the original 0.75em gap on each side */
+ }
+
+ :host([appearance='default'][data-wa-radio-horizontal]) {
+ margin-block: 0;
+ margin-inline: 0.5em; /* Half of the original 1em gap on each side */
+ }
+
+ /* Remove margin from first/last items to prevent extra space */
+ :host([appearance='default'][data-wa-radio-first]) {
+ margin-block-start: 0;
+ margin-inline-start: 0;
+ }
+
+ :host([appearance='default'][data-wa-radio-last]) {
+ margin-block-end: 0;
+ margin-inline-end: 0;
+ }
+
+ /* Button appearance have no spacing, they get handled by the overlap margins below */
+ :host([appearance='button']) {
+ margin: 0;
+ align-items: center;
+ min-height: var(--wa-form-control-height);
+ background-color: var(--wa-color-surface-default);
+ border: var(--wa-form-control-border-width) var(--wa-form-control-border-style) var(--wa-form-control-border-color);
+ border-radius: var(--wa-border-radius-m);
+ padding: 0 var(--wa-form-control-padding-inline);
+ transition:
+ background-color var(--wa-transition-fast),
+ border-color var(--wa-transition-fast);
+ }
+
+ /* Default appearance */
+ :host([appearance='default']) {
+ .control {
+ flex: 0 0 auto;
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: var(--wa-form-control-toggle-size);
+ height: var(--wa-form-control-toggle-size);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: 50%;
+ border-style: var(--wa-form-control-border-style);
+ border-width: var(--wa-form-control-border-width);
+ background-color: var(--wa-form-control-background-color);
+ color: transparent;
+ transition:
+ background var(--wa-transition-normal),
+ border-color var(--wa-transition-fast),
+ box-shadow var(--wa-transition-fast),
+ color var(--wa-transition-fast);
+ transition-timing-function: var(--wa-transition-easing);
+
+ margin-inline-end: 0.5em;
+ }
+
+ .checked-icon {
+ display: flex;
+ fill: currentColor;
+ width: var(--wa-form-control-toggle-size);
+ height: var(--wa-form-control-toggle-size);
+ scale: var(--checked-icon-scale);
+ }
+ }
+
+ /* Button appearance */
+ :host([appearance='button']) {
+ .control {
+ display: none;
+ }
+ }
+
+ /* Checked */
+ :host(:state(checked)) .control {
+ color: var(--checked-icon-color);
+ border-color: var(--wa-form-control-activated-color);
+ background-color: var(--wa-form-control-background-color);
+ }
+
+ /* Focus */
+ :host(:focus-visible) .control {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Disabled */
+ :host(:state(disabled)) {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ /* Horizontal grouping - remove inner border radius */
+ :host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-inner]) {
+ border-radius: 0;
+ }
+
+ :host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-first]) {
+ border-start-end-radius: 0;
+ border-end-end-radius: 0;
+ }
+
+ :host([appearance='button'][data-wa-radio-horizontal][data-wa-radio-last]) {
+ border-start-start-radius: 0;
+ border-end-start-radius: 0;
+ }
+
+ /* Vertical grouping - remove inner border radius */
+ :host([appearance='button'][data-wa-radio-vertical][data-wa-radio-inner]) {
+ border-radius: 0;
+ }
+
+ :host([appearance='button'][data-wa-radio-vertical][data-wa-radio-first]) {
+ border-end-start-radius: 0;
+ border-end-end-radius: 0;
+ }
+
+ :host([appearance='button'][data-wa-radio-vertical][data-wa-radio-last]) {
+ border-start-start-radius: 0;
+ border-start-end-radius: 0;
+ }
+
+ @media (hover: hover) {
+ :host([appearance='button']:hover:not(:state(disabled), :state(checked))) {
+ background-color: color-mix(in srgb, var(--wa-color-surface-default) 95%, var(--wa-color-mix-hover));
+ }
+ }
+
+ :host([appearance='button']:focus-visible) {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ :host([appearance='button']:state(checked)) {
+ border-color: var(--wa-form-control-activated-color);
+ background-color: var(--wa-color-brand-fill-quiet);
+ }
+
+ :host([appearance='button']:state(checked):focus-visible) {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Button overlap margins */
+ :host([appearance='button'][data-wa-radio-horizontal]:not([data-wa-radio-first])) {
+ margin-inline-start: calc(-1 * var(--wa-form-control-border-width));
+ }
+
+ :host([appearance='button'][data-wa-radio-vertical]:not([data-wa-radio-first])) {
+ margin-block-start: calc(-1 * var(--wa-form-control-border-width));
+ }
+
+ /* Ensure interactive states are visible above adjacent buttons */
+ :host([appearance='button']:hover),
+ :host([appearance='button']:state(checked)) {
+ position: relative;
+ z-index: 1;
+ }
+
+ :host([appearance='button']:focus-visible) {
+ z-index: 2;
+ }
+`;
diff --git a/packages/webawesome/src/components/radio/radio.ts b/packages/webawesome/src/components/radio/radio.ts
index c910226c1..0f7d6f991 100644
--- a/packages/webawesome/src/components/radio/radio.ts
+++ b/packages/webawesome/src/components/radio/radio.ts
@@ -2,10 +2,10 @@ import type { PropertyValues } from 'lit';
import { html, isServer } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import '../icon/icon.js';
-import styles from './radio.css';
+import styles from './radio.styles.js';
/**
* @summary Radios allow the user to select a single option from a group.
diff --git a/packages/webawesome/src/components/rating/rating.css b/packages/webawesome/src/components/rating/rating.css
deleted file mode 100644
index 606a2f263..000000000
--- a/packages/webawesome/src/components/rating/rating.css
+++ /dev/null
@@ -1,85 +0,0 @@
-:host {
- --symbol-color: var(--wa-color-neutral-on-quiet);
- --symbol-color-active: var(--wa-color-yellow-70);
- --symbol-spacing: 0.125em;
-
- display: inline-flex;
-}
-
-.rating {
- position: relative;
- display: inline-flex;
- border-radius: var(--wa-border-radius-m);
- vertical-align: middle;
-}
-
-.rating:focus {
- outline: none;
-}
-
-.rating:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-.symbols {
- display: inline-flex;
- gap: 0.125em;
- position: relative;
- line-height: 0;
- color: var(--symbol-color);
- white-space: nowrap;
- cursor: pointer;
-}
-
-.symbols > * {
- padding: var(--symbol-spacing);
-}
-
-.symbol-active,
-.partial-filled {
- color: var(--symbol-color-active);
-}
-
-.partial-symbol-container {
- position: relative;
-}
-
-.partial-filled {
- position: absolute;
- top: var(--symbol-spacing);
- left: var(--symbol-spacing);
-}
-
-.symbol {
- transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
- pointer-events: none;
-}
-
-.symbol-hover {
- scale: 1.2;
-}
-
-.rating-readonly .symbols {
- cursor: default;
-}
-
-:host([disabled]) .symbol-hover,
-.rating-readonly .symbol-hover {
- scale: none;
-}
-
-:host([disabled]) {
- opacity: 0.5;
-}
-
-:host([disabled]) .symbols {
- cursor: not-allowed;
-}
-
-/* Forced colors mode */
-@media (forced-colors: active) {
- .symbol-active {
- color: SelectedItem;
- }
-}
diff --git a/packages/webawesome/src/components/rating/rating.styles.ts b/packages/webawesome/src/components/rating/rating.styles.ts
new file mode 100644
index 000000000..7c6eeecab
--- /dev/null
+++ b/packages/webawesome/src/components/rating/rating.styles.ts
@@ -0,0 +1,89 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --symbol-color: var(--wa-color-neutral-on-quiet);
+ --symbol-color-active: var(--wa-color-yellow-70);
+ --symbol-spacing: 0.125em;
+
+ display: inline-flex;
+ }
+
+ .rating {
+ position: relative;
+ display: inline-flex;
+ border-radius: var(--wa-border-radius-m);
+ vertical-align: middle;
+ }
+
+ .rating:focus {
+ outline: none;
+ }
+
+ .rating:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ .symbols {
+ display: inline-flex;
+ gap: 0.125em;
+ position: relative;
+ line-height: 0;
+ color: var(--symbol-color);
+ white-space: nowrap;
+ cursor: pointer;
+ }
+
+ .symbols > * {
+ padding: var(--symbol-spacing);
+ }
+
+ .symbol-active,
+ .partial-filled {
+ color: var(--symbol-color-active);
+ }
+
+ .partial-symbol-container {
+ position: relative;
+ }
+
+ .partial-filled {
+ position: absolute;
+ top: var(--symbol-spacing);
+ left: var(--symbol-spacing);
+ }
+
+ .symbol {
+ transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
+ pointer-events: none;
+ }
+
+ .symbol-hover {
+ scale: 1.2;
+ }
+
+ .rating-readonly .symbols {
+ cursor: default;
+ }
+
+ :host([disabled]) .symbol-hover,
+ .rating-readonly .symbol-hover {
+ scale: none;
+ }
+
+ :host([disabled]) {
+ opacity: 0.5;
+ }
+
+ :host([disabled]) .symbols {
+ cursor: not-allowed;
+ }
+
+ /* Forced colors mode */
+ @media (forced-colors: active) {
+ .symbol-active {
+ color: SelectedItem;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/rating/rating.ts b/packages/webawesome/src/components/rating/rating.ts
index d8615dd58..ebbbe3de4 100644
--- a/packages/webawesome/src/components/rating/rating.ts
+++ b/packages/webawesome/src/components/rating/rating.ts
@@ -7,10 +7,10 @@ import { WaHoverEvent } from '../../events/hover.js';
import { clamp } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
+import sizeStyles from '../../styles/component/size.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
-import styles from './rating.css';
+import styles from './rating.styles.js';
/**
* @summary Ratings give users a way to quickly view and provide feedback.
diff --git a/packages/webawesome/src/components/resize-observer/resize-observer.css b/packages/webawesome/src/components/resize-observer/resize-observer.css
deleted file mode 100644
index 92d692cdd..000000000
--- a/packages/webawesome/src/components/resize-observer/resize-observer.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:host {
- display: contents;
-}
diff --git a/packages/webawesome/src/components/resize-observer/resize-observer.styles.ts b/packages/webawesome/src/components/resize-observer/resize-observer.styles.ts
new file mode 100644
index 000000000..1ef4bf6f3
--- /dev/null
+++ b/packages/webawesome/src/components/resize-observer/resize-observer.styles.ts
@@ -0,0 +1,7 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: contents;
+ }
+`;
diff --git a/packages/webawesome/src/components/resize-observer/resize-observer.ts b/packages/webawesome/src/components/resize-observer/resize-observer.ts
index b26d0e5e9..e77727abb 100644
--- a/packages/webawesome/src/components/resize-observer/resize-observer.ts
+++ b/packages/webawesome/src/components/resize-observer/resize-observer.ts
@@ -3,7 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
import { WaResizeEvent } from '../../events/resize.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './resize-observer.css';
+import styles from './resize-observer.styles.js';
/**
* @summary The Resize Observer component offers a thin, declarative interface to the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
diff --git a/packages/webawesome/src/components/scroller/scroller.css b/packages/webawesome/src/components/scroller/scroller.css
deleted file mode 100644
index 3b4080c9e..000000000
--- a/packages/webawesome/src/components/scroller/scroller.css
+++ /dev/null
@@ -1,125 +0,0 @@
-:host {
- --shadow-color: var(--wa-color-surface-default);
- --shadow-size: 2rem;
-
- /* private (defined dynamically) */
- --start-shadow-opacity: 0;
- --end-shadow-opacity: 0;
-
- display: block;
- position: relative;
- max-width: 100%;
- isolation: isolate;
-}
-
-:host([orientation='vertical']) {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-#content {
- z-index: 1; /* below shadows */
- border-radius: inherit;
- scroll-behavior: smooth;
- scrollbar-width: thin;
-
- /* Prevent text in mobile Safari from being larger when the container width larger than the viewport */
- -webkit-text-size-adjust: 100%;
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-}
-
-:host([without-scrollbar]) #content {
- scrollbar-width: none;
-}
-
-:host([orientation='horizontal']) #content {
- overflow-x: auto;
- overflow-y: hidden;
-}
-
-:host([orientation='vertical']) #content {
- flex: 1 1 auto;
- min-height: 0; /* This is crucial for flex children to respect overflow */
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-#start-shadow,
-#end-shadow {
- z-index: 2;
-}
-
-#start-shadow {
- opacity: var(--start-shadow-opacity);
-}
-
-#end-shadow {
- opacity: var(--end-shadow-opacity);
-}
-
-/* Horizontal shadows */
-:host([orientation='horizontal']) {
- #start-shadow,
- #end-shadow {
- position: absolute;
- top: 0;
- bottom: 0;
- width: var(--shadow-size);
- pointer-events: none;
- }
-
- #start-shadow {
- &:dir(ltr) {
- left: 0;
- background: linear-gradient(to right, var(--shadow-color), transparent 100%);
- }
-
- &:dir(rtl) {
- right: 0;
- background: linear-gradient(to left, var(--shadow-color), transparent 100%);
- }
- }
-
- #end-shadow {
- &:dir(ltr) {
- right: 0;
- background: linear-gradient(to left, var(--shadow-color), transparent 100%);
- }
-
- &:dir(rtl) {
- left: 0;
- background: linear-gradient(to right, var(--shadow-color), transparent 100%);
- }
- }
-}
-
-/* Vertical shadows */
-:host([orientation='vertical']) {
- #start-shadow,
- #end-shadow {
- position: absolute;
- right: 0;
- left: 0;
- height: var(--shadow-size);
- pointer-events: none;
- }
-
- #start-shadow {
- top: 0;
- background: linear-gradient(to bottom, var(--shadow-color), transparent 100%);
- }
-
- #end-shadow {
- bottom: 0;
- background: linear-gradient(to top, var(--shadow-color), transparent 100%);
- }
-}
diff --git a/packages/webawesome/src/components/scroller/scroller.styles.ts b/packages/webawesome/src/components/scroller/scroller.styles.ts
new file mode 100644
index 000000000..a57493291
--- /dev/null
+++ b/packages/webawesome/src/components/scroller/scroller.styles.ts
@@ -0,0 +1,129 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --shadow-color: var(--wa-color-surface-default);
+ --shadow-size: 2rem;
+
+ /* private (defined dynamically) */
+ --start-shadow-opacity: 0;
+ --end-shadow-opacity: 0;
+
+ display: block;
+ position: relative;
+ max-width: 100%;
+ isolation: isolate;
+ }
+
+ :host([orientation='vertical']) {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ }
+
+ #content {
+ z-index: 1; /* below shadows */
+ border-radius: inherit;
+ scroll-behavior: smooth;
+ scrollbar-width: thin;
+
+ /* Prevent text in mobile Safari from being larger when the container width larger than the viewport */
+ -webkit-text-size-adjust: 100%;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+ }
+
+ :host([without-scrollbar]) #content {
+ scrollbar-width: none;
+ }
+
+ :host([orientation='horizontal']) #content {
+ overflow-x: auto;
+ overflow-y: hidden;
+ }
+
+ :host([orientation='vertical']) #content {
+ flex: 1 1 auto;
+ min-height: 0; /* This is crucial for flex children to respect overflow */
+ overflow-x: hidden;
+ overflow-y: auto;
+ }
+
+ #start-shadow,
+ #end-shadow {
+ z-index: 2;
+ }
+
+ #start-shadow {
+ opacity: var(--start-shadow-opacity);
+ }
+
+ #end-shadow {
+ opacity: var(--end-shadow-opacity);
+ }
+
+ /* Horizontal shadows */
+ :host([orientation='horizontal']) {
+ #start-shadow,
+ #end-shadow {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: var(--shadow-size);
+ pointer-events: none;
+ }
+
+ #start-shadow {
+ &:dir(ltr) {
+ left: 0;
+ background: linear-gradient(to right, var(--shadow-color), transparent 100%);
+ }
+
+ &:dir(rtl) {
+ right: 0;
+ background: linear-gradient(to left, var(--shadow-color), transparent 100%);
+ }
+ }
+
+ #end-shadow {
+ &:dir(ltr) {
+ right: 0;
+ background: linear-gradient(to left, var(--shadow-color), transparent 100%);
+ }
+
+ &:dir(rtl) {
+ left: 0;
+ background: linear-gradient(to right, var(--shadow-color), transparent 100%);
+ }
+ }
+ }
+
+ /* Vertical shadows */
+ :host([orientation='vertical']) {
+ #start-shadow,
+ #end-shadow {
+ position: absolute;
+ right: 0;
+ left: 0;
+ height: var(--shadow-size);
+ pointer-events: none;
+ }
+
+ #start-shadow {
+ top: 0;
+ background: linear-gradient(to bottom, var(--shadow-color), transparent 100%);
+ }
+
+ #end-shadow {
+ bottom: 0;
+ background: linear-gradient(to top, var(--shadow-color), transparent 100%);
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/scroller/scroller.ts b/packages/webawesome/src/components/scroller/scroller.ts
index 6f0db2e5b..8c5f7dff8 100644
--- a/packages/webawesome/src/components/scroller/scroller.ts
+++ b/packages/webawesome/src/components/scroller/scroller.ts
@@ -2,7 +2,7 @@ import { html } from 'lit';
import { customElement, eventOptions, property, query, state } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './scroller.css';
+import styles from './scroller.styles.js';
/**
* @summary Scrollers create an accessible container while providing visual cues that help users identify and navigate
diff --git a/packages/webawesome/src/components/select/select.css b/packages/webawesome/src/components/select/select.css
deleted file mode 100644
index 6318fb590..000000000
--- a/packages/webawesome/src/components/select/select.css
+++ /dev/null
@@ -1,272 +0,0 @@
-:host {
- --tag-max-size: 10ch;
- --show-duration: 100ms;
- --hide-duration: 100ms;
-}
-
-/* Add ellipses to multi select options */
-:host wa-tag::part(content) {
- display: initial;
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
- max-width: var(--tag-max-size);
-}
-
-:host .disabled [part~='combobox'] {
- opacity: 0.5;
- cursor: not-allowed;
- outline: none;
-}
-
-:host .enabled:is(.open, :focus-within) [part~='combobox'] {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/** The popup */
-.select {
- flex: 1 1 auto;
- display: inline-flex;
- width: 100%;
- position: relative;
- vertical-align: middle;
-
- /* Pass through from select to the popup */
- --show-duration: inherit;
- --hide-duration: inherit;
-
- &::part(popup) {
- z-index: 900;
- }
-
- &[data-current-placement^='top']::part(popup) {
- transform-origin: bottom;
- }
-
- &[data-current-placement^='bottom']::part(popup) {
- transform-origin: top;
- }
-}
-
-/* Combobox */
-.combobox {
- flex: 1;
- display: flex;
- width: 100%;
- min-width: 0;
- align-items: center;
- justify-content: start;
-
- min-height: var(--wa-form-control-height);
-
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
- border-radius: var(--wa-form-control-border-radius);
- border-style: var(--wa-form-control-border-style);
- border-width: var(--wa-form-control-border-width);
- color: var(--wa-form-control-value-color);
- cursor: pointer;
- font-family: inherit;
- font-weight: var(--wa-form-control-value-font-weight);
- line-height: var(--wa-form-control-value-line-height);
- overflow: hidden;
- padding: 0 var(--wa-form-control-padding-inline);
- position: relative;
- vertical-align: middle;
- transition:
- background-color var(--wa-transition-normal),
- border var(--wa-transition-normal),
- outline var(--wa-transition-fast);
- transition-timing-function: var(--wa-transition-easing);
-
- :host([multiple]) .select:not(.placeholder-visible) & {
- padding-inline-start: 0;
- padding-block: calc(var(--wa-form-control-height) * 0.1 - var(--wa-form-control-border-width));
- }
-
- /* Pills */
- :host([pill]) & {
- border-radius: var(--wa-border-radius-pill);
- }
-}
-
-/* Appearance modifiers */
-:host([appearance='outlined']) .combobox {
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
-}
-
-:host([appearance='filled']) .combobox {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-color-neutral-fill-quiet);
-}
-
-:host([appearance='filled-outlined']) .combobox {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-form-control-border-color);
-}
-
-.display-input {
- position: relative;
- width: 100%;
- font: inherit;
- border: none;
- background: none;
- line-height: var(--wa-form-control-value-line-height);
- color: var(--wa-form-control-value-color);
- cursor: inherit;
- overflow: hidden;
- padding: 0;
- margin: 0;
- -webkit-appearance: none;
-
- &:focus {
- outline: none;
- }
-
- &::placeholder {
- color: var(--wa-form-control-placeholder-color);
- }
-}
-
-/* Visually hide the display input when multiple is enabled */
-:host([multiple]) .select:not(.placeholder-visible) .display-input {
- position: absolute;
- z-index: -1;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
-}
-
-.value-input {
- position: absolute;
- z-index: -1;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- padding: 0;
- margin: 0;
-}
-
-.tags {
- display: flex;
- flex: 1;
- align-items: center;
- flex-wrap: wrap;
- margin-inline-start: 0.25em;
- gap: 0.25em;
-
- &::slotted(wa-tag) {
- cursor: pointer !important;
- }
-
- .disabled &,
- .disabled &::slotted(wa-tag) {
- cursor: not-allowed !important;
- }
-}
-
-/* Start and End */
-
-.start,
-.end {
- flex: 0;
- display: inline-flex;
- align-items: center;
- color: var(--wa-color-neutral-on-quiet);
-}
-
-.end::slotted(*) {
- margin-inline-start: var(--wa-form-control-padding-inline);
-}
-
-.start::slotted(*) {
- margin-inline-end: var(--wa-form-control-padding-inline);
-}
-
-:host([multiple]) .start::slotted(*) {
- margin-inline: var(--wa-form-control-padding-inline);
-}
-
-/* Clear button */
-[part~='clear-button'] {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- font-size: inherit;
- color: var(--wa-color-neutral-on-quiet);
- border: none;
- background: none;
- padding: 0;
- transition: color var(--wa-transition-normal);
- cursor: pointer;
- margin-inline-start: var(--wa-form-control-padding-inline);
-
- &:focus {
- outline: none;
- }
-
- @media (hover: hover) {
- &:hover {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
- }
- }
-
- &:active {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
- }
-}
-
-/* Expand icon */
-.expand-icon {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- color: var(--wa-color-neutral-on-quiet);
- transition: rotate var(--wa-transition-slow) ease;
- rotate: 0deg;
- margin-inline-start: var(--wa-form-control-padding-inline);
-
- .open & {
- rotate: -180deg;
- }
-}
-
-/* Listbox */
-.listbox {
- display: block;
- position: relative;
- font: inherit;
- box-shadow: var(--wa-shadow-m);
- background: var(--wa-color-surface-raised);
- border-color: var(--wa-color-surface-border);
- border-radius: var(--wa-border-radius-m);
- border-style: var(--wa-border-style);
- border-width: var(--wa-border-width-s);
- padding-block: 0.5em;
- padding-inline: 0;
- overflow: auto;
- overscroll-behavior: none;
-
- /* Make sure it adheres to the popup's auto size */
- max-width: var(--auto-size-available-width);
- max-height: var(--auto-size-available-height);
-
- &::slotted(wa-divider) {
- --spacing: 0.5em;
- }
-}
-
-slot:not([name])::slotted(small) {
- display: block;
- font-size: var(--wa-font-size-smaller);
- font-weight: var(--wa-font-weight-semibold);
- color: var(--wa-color-text-quiet);
- padding-block: 0.5em;
- padding-inline: 2.25em;
-}
diff --git a/packages/webawesome/src/components/select/select.styles.ts b/packages/webawesome/src/components/select/select.styles.ts
new file mode 100644
index 000000000..b837ebd5b
--- /dev/null
+++ b/packages/webawesome/src/components/select/select.styles.ts
@@ -0,0 +1,276 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --tag-max-size: 10ch;
+ --show-duration: 100ms;
+ --hide-duration: 100ms;
+ }
+
+ /* Add ellipses to multi select options */
+ :host wa-tag::part(content) {
+ display: initial;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ max-width: var(--tag-max-size);
+ }
+
+ :host .disabled [part~='combobox'] {
+ opacity: 0.5;
+ cursor: not-allowed;
+ outline: none;
+ }
+
+ :host .enabled:is(.open, :focus-within) [part~='combobox'] {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /** The popup */
+ .select {
+ flex: 1 1 auto;
+ display: inline-flex;
+ width: 100%;
+ position: relative;
+ vertical-align: middle;
+
+ /* Pass through from select to the popup */
+ --show-duration: inherit;
+ --hide-duration: inherit;
+
+ &::part(popup) {
+ z-index: 900;
+ }
+
+ &[data-current-placement^='top']::part(popup) {
+ transform-origin: bottom;
+ }
+
+ &[data-current-placement^='bottom']::part(popup) {
+ transform-origin: top;
+ }
+ }
+
+ /* Combobox */
+ .combobox {
+ flex: 1;
+ display: flex;
+ width: 100%;
+ min-width: 0;
+ align-items: center;
+ justify-content: start;
+
+ min-height: var(--wa-form-control-height);
+
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: var(--wa-form-control-border-radius);
+ border-style: var(--wa-form-control-border-style);
+ border-width: var(--wa-form-control-border-width);
+ color: var(--wa-form-control-value-color);
+ cursor: pointer;
+ font-family: inherit;
+ font-weight: var(--wa-form-control-value-font-weight);
+ line-height: var(--wa-form-control-value-line-height);
+ overflow: hidden;
+ padding: 0 var(--wa-form-control-padding-inline);
+ position: relative;
+ vertical-align: middle;
+ transition:
+ background-color var(--wa-transition-normal),
+ border var(--wa-transition-normal),
+ outline var(--wa-transition-fast);
+ transition-timing-function: var(--wa-transition-easing);
+
+ :host([multiple]) .select:not(.placeholder-visible) & {
+ padding-inline-start: 0;
+ padding-block: calc(var(--wa-form-control-height) * 0.1 - var(--wa-form-control-border-width));
+ }
+
+ /* Pills */
+ :host([pill]) & {
+ border-radius: var(--wa-border-radius-pill);
+ }
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='outlined']) .combobox {
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ :host([appearance='filled']) .combobox {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-color-neutral-fill-quiet);
+ }
+
+ :host([appearance='filled-outlined']) .combobox {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ .display-input {
+ position: relative;
+ width: 100%;
+ font: inherit;
+ border: none;
+ background: none;
+ line-height: var(--wa-form-control-value-line-height);
+ color: var(--wa-form-control-value-color);
+ cursor: inherit;
+ overflow: hidden;
+ padding: 0;
+ margin: 0;
+ -webkit-appearance: none;
+
+ &:focus {
+ outline: none;
+ }
+
+ &::placeholder {
+ color: var(--wa-form-control-placeholder-color);
+ }
+ }
+
+ /* Visually hide the display input when multiple is enabled */
+ :host([multiple]) .select:not(.placeholder-visible) .display-input {
+ position: absolute;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ }
+
+ .value-input {
+ position: absolute;
+ z-index: -1;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ padding: 0;
+ margin: 0;
+ }
+
+ .tags {
+ display: flex;
+ flex: 1;
+ align-items: center;
+ flex-wrap: wrap;
+ margin-inline-start: 0.25em;
+ gap: 0.25em;
+
+ &::slotted(wa-tag) {
+ cursor: pointer !important;
+ }
+
+ .disabled &,
+ .disabled &::slotted(wa-tag) {
+ cursor: not-allowed !important;
+ }
+ }
+
+ /* Start and End */
+
+ .start,
+ .end {
+ flex: 0;
+ display: inline-flex;
+ align-items: center;
+ color: var(--wa-color-neutral-on-quiet);
+ }
+
+ .end::slotted(*) {
+ margin-inline-start: var(--wa-form-control-padding-inline);
+ }
+
+ .start::slotted(*) {
+ margin-inline-end: var(--wa-form-control-padding-inline);
+ }
+
+ :host([multiple]) .start::slotted(*) {
+ margin-inline: var(--wa-form-control-padding-inline);
+ }
+
+ /* Clear button */
+ [part~='clear-button'] {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: inherit;
+ color: var(--wa-color-neutral-on-quiet);
+ border: none;
+ background: none;
+ padding: 0;
+ transition: color var(--wa-transition-normal);
+ cursor: pointer;
+ margin-inline-start: var(--wa-form-control-padding-inline);
+
+ &:focus {
+ outline: none;
+ }
+
+ @media (hover: hover) {
+ &:hover {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+ }
+
+ &:active {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
+ }
+ }
+
+ /* Expand icon */
+ .expand-icon {
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ color: var(--wa-color-neutral-on-quiet);
+ transition: rotate var(--wa-transition-slow) ease;
+ rotate: 0deg;
+ margin-inline-start: var(--wa-form-control-padding-inline);
+
+ .open & {
+ rotate: -180deg;
+ }
+ }
+
+ /* Listbox */
+ .listbox {
+ display: block;
+ position: relative;
+ font: inherit;
+ box-shadow: var(--wa-shadow-m);
+ background: var(--wa-color-surface-raised);
+ border-color: var(--wa-color-surface-border);
+ border-radius: var(--wa-border-radius-m);
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-border-width-s);
+ padding-block: 0.5em;
+ padding-inline: 0;
+ overflow: auto;
+ overscroll-behavior: none;
+
+ /* Make sure it adheres to the popup's auto size */
+ max-width: var(--auto-size-available-width);
+ max-height: var(--auto-size-available-height);
+
+ &::slotted(wa-divider) {
+ --spacing: 0.5em;
+ }
+ }
+
+ slot:not([name])::slotted(small) {
+ display: block;
+ font-size: var(--wa-font-size-smaller);
+ font-weight: var(--wa-font-weight-semibold);
+ color: var(--wa-color-text-quiet);
+ padding-block: 0.5em;
+ padding-inline: 2.25em;
+ }
+`;
diff --git a/packages/webawesome/src/components/select/select.ts b/packages/webawesome/src/components/select/select.ts
index ced89618d..46d1b8cf6 100644
--- a/packages/webawesome/src/components/select/select.ts
+++ b/packages/webawesome/src/components/select/select.ts
@@ -7,7 +7,7 @@ import { WaAfterHideEvent } from '../../events/after-hide.js';
import { WaAfterShowEvent } from '../../events/after-show.js';
import { WaClearEvent } from '../../events/clear.js';
import { WaHideEvent } from '../../events/hide.js';
-import type { WaRemoveEvent } from '../../events/remove.js';
+import { WaRemoveEvent } from '../../events/remove.js';
import { WaShowEvent } from '../../events/show.js';
import { animateWithClass } from '../../internal/animate.js';
import { waitForEvent } from '../../internal/event.js';
@@ -16,8 +16,8 @@ import { HasSlotController } from '../../internal/slot.js';
import { RequiredValidator } from '../../internal/validators/required-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import '../option/option.js';
@@ -25,7 +25,7 @@ import type WaOption from '../option/option.js';
import '../popup/popup.js';
import type WaPopup from '../popup/popup.js';
import '../tag/tag.js';
-import styles from './select.css';
+import styles from './select.styles.js';
/**
* @summary Selects allow you to choose items from a menu of predefined options.
@@ -99,6 +99,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
private readonly hasSlotController = new HasSlotController(this, 'hint', 'label');
private readonly localize = new LocalizeController(this);
+ private selectionOrder: Map = new Map();
private typeToSelectString = '';
private typeToSelectTimeout: number;
@@ -278,6 +279,8 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
?pill=${this.pill}
size=${this.size}
with-remove
+ data-value=${option.value}
+ @wa-remove=${(event: WaRemoveEvent) => this.handleTagRemove(event, option)}
>
${option.label}
@@ -513,6 +516,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
event.stopPropagation();
if (this.value !== null) {
+ this.selectionOrder.clear();
this.setSelectedOptions([]);
this.displayInput.focus({ preventScroll: true });
@@ -596,24 +600,20 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
if (this.disabled) return;
+ // Mark as interacted so selectionChanged() uses the correct filter logic
+ this.hasInteracted = true;
+ this.valueHasChanged = true;
+
// Use the directly provided option if available (from getTag method)
let option = directOption;
- // If no direct option was provided, find the option from the event path
+ // If no direct option was provided, find the option from the data-value attribute
if (!option) {
- const tagElement = (event.target as Element).closest('wa-tag[part~=tag]');
+ const tagElement = (event.target as Element).closest('wa-tag[data-value]') as HTMLElement | null;
if (tagElement) {
- // Find the index of this tag among all tags
- const tagsContainer = this.shadowRoot?.querySelector('[part="tags"]');
- if (tagsContainer) {
- const allTags = Array.from(tagsContainer.children);
- const index = allTags.indexOf(tagElement as HTMLElement);
-
- if (index >= 0 && index < this.selectedOptions.length) {
- option = this.selectedOptions[index];
- }
- }
+ const value = tagElement.dataset.value;
+ option = this.selectedOptions.find(opt => opt.value === value);
}
}
@@ -700,7 +700,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
const options = this.getAllOptions();
// Update selected options cache
- this.selectedOptions = options.filter(el => {
+ const newSelectedOptions = options.filter(el => {
if (!this.hasInteracted && !this.valueHasChanged) {
const defaultValue = this.defaultValue;
const defaultValues = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
@@ -710,6 +710,32 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
return el.selected;
});
+ // Update the selection order map
+ const newSelectedValues = new Set(newSelectedOptions.map(el => el.value));
+
+ // Remove deselected options from the order map
+ for (const value of this.selectionOrder.keys()) {
+ if (!newSelectedValues.has(value)) {
+ this.selectionOrder.delete(value);
+ }
+ }
+
+ // Add newly selected options
+ const maxOrder = this.selectionOrder.size > 0 ? Math.max(...this.selectionOrder.values()) : -1;
+ let nextOrder = maxOrder + 1;
+ for (const option of newSelectedOptions) {
+ if (!this.selectionOrder.has(option.value)) {
+ this.selectionOrder.set(option.value, nextOrder++);
+ }
+ }
+
+ // Sort options by selection order
+ this.selectedOptions = newSelectedOptions.sort((a, b) => {
+ const orderA = this.selectionOrder.get(a.value) ?? 0;
+ const orderB = this.selectionOrder.get(b.value) ?? 0;
+ return orderA - orderB;
+ });
+
let selectedValues = new Set(this.selectedOptions.map(el => el.value));
// Toggle values present in the DOM from this.value, while preserving options NOT present in the DOM (for lazy loading)
@@ -881,6 +907,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
}
formResetCallback() {
+ this.selectionOrder.clear();
this.value = this.defaultValue;
super.formResetCallback();
this.handleValueChange();
diff --git a/packages/webawesome/src/components/skeleton/skeleton.css b/packages/webawesome/src/components/skeleton/skeleton.css
deleted file mode 100644
index 65a7f794a..000000000
--- a/packages/webawesome/src/components/skeleton/skeleton.css
+++ /dev/null
@@ -1,54 +0,0 @@
-:host {
- --color: var(--wa-color-neutral-fill-normal);
- --sheen-color: color-mix(in oklab, var(--color), var(--wa-color-surface-raised));
-
- display: flex;
- position: relative;
- width: 100%;
- height: 100%;
- min-height: 1rem;
-}
-
-.indicator {
- flex: 1 1 auto;
- background: var(--color);
- border-radius: var(--wa-border-radius-pill);
-}
-
-:host([effect='sheen']) .indicator {
- background: linear-gradient(270deg, var(--sheen-color), var(--color), var(--color), var(--sheen-color));
- background-size: 400% 100%;
- animation: sheen 8s ease-in-out infinite;
-}
-
-:host([effect='pulse']) .indicator {
- animation: pulse 2s ease-in-out 0.5s infinite;
-}
-
-/* Forced colors mode */
-@media (forced-colors: active) {
- :host {
- --color: GrayText;
- }
-}
-
-@keyframes sheen {
- 0% {
- background-position: 200% 0;
- }
- to {
- background-position: -200% 0;
- }
-}
-
-@keyframes pulse {
- 0% {
- opacity: 1;
- }
- 50% {
- opacity: 0.4;
- }
- 100% {
- opacity: 1;
- }
-}
diff --git a/packages/webawesome/src/components/skeleton/skeleton.styles.ts b/packages/webawesome/src/components/skeleton/skeleton.styles.ts
new file mode 100644
index 000000000..9fd766ede
--- /dev/null
+++ b/packages/webawesome/src/components/skeleton/skeleton.styles.ts
@@ -0,0 +1,58 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --color: var(--wa-color-neutral-fill-normal);
+ --sheen-color: color-mix(in oklab, var(--color), var(--wa-color-surface-raised));
+
+ display: flex;
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 1rem;
+ }
+
+ .indicator {
+ flex: 1 1 auto;
+ background: var(--color);
+ border-radius: var(--wa-border-radius-pill);
+ }
+
+ :host([effect='sheen']) .indicator {
+ background: linear-gradient(270deg, var(--sheen-color), var(--color), var(--color), var(--sheen-color));
+ background-size: 400% 100%;
+ animation: sheen 8s ease-in-out infinite;
+ }
+
+ :host([effect='pulse']) .indicator {
+ animation: pulse 2s ease-in-out 0.5s infinite;
+ }
+
+ /* Forced colors mode */
+ @media (forced-colors: active) {
+ :host {
+ --color: GrayText;
+ }
+ }
+
+ @keyframes sheen {
+ 0% {
+ background-position: 200% 0;
+ }
+ to {
+ background-position: -200% 0;
+ }
+ }
+
+ @keyframes pulse {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.4;
+ }
+ 100% {
+ opacity: 1;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/skeleton/skeleton.ts b/packages/webawesome/src/components/skeleton/skeleton.ts
index b22178fd9..2b4723d77 100644
--- a/packages/webawesome/src/components/skeleton/skeleton.ts
+++ b/packages/webawesome/src/components/skeleton/skeleton.ts
@@ -1,7 +1,7 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './skeleton.css';
+import styles from './skeleton.styles.js';
/**
* @summary Skeletons are used to provide a visual representation of where content will eventually be drawn.
diff --git a/packages/webawesome/src/components/slider/slider.css b/packages/webawesome/src/components/slider/slider.css
deleted file mode 100644
index efb206130..000000000
--- a/packages/webawesome/src/components/slider/slider.css
+++ /dev/null
@@ -1,229 +0,0 @@
-:host {
- --track-size: 0.5em;
- --thumb-width: 1.4em;
- --thumb-height: 1.4em;
- --marker-width: 0.1875em;
- --marker-height: 0.1875em;
-}
-
-:host([orientation='vertical']) {
- width: auto;
-}
-
-#label:has(~ .vertical) {
- display: block;
- order: 2;
- max-width: none;
- text-align: center;
-}
-
-#description:has(~ .vertical) {
- order: 3;
- text-align: center;
-}
-
-/* Add extra space between slider and label, when present */
-#label:has(*:not(:empty)) ~ #slider {
- &.horizontal {
- margin-block-start: 0.5em;
- }
- &.vertical {
- margin-block-end: 0.5em;
- }
-}
-
-#slider {
- touch-action: none;
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible:not(.disabled) #thumb,
- &:focus-visible:not(.disabled) #thumb-min,
- &:focus-visible:not(.disabled) #thumb-max {
- outline: var(--wa-focus-ring);
- /* intentionally no offset due to border */
- }
-}
-
-#track {
- position: relative;
- border-radius: 9999px;
- background: var(--wa-color-neutral-fill-normal);
- isolation: isolate;
-}
-
-/* Orientation */
-.horizontal #track {
- height: var(--track-size);
-}
-
-.vertical #track {
- order: 1;
- width: var(--track-size);
- height: 200px;
-}
-
-/* Disabled */
-.disabled #track {
- cursor: not-allowed;
- opacity: 0.5;
-}
-
-/* Indicator */
-#indicator {
- position: absolute;
- border-radius: inherit;
- background-color: var(--wa-form-control-activated-color);
-
- &:dir(ltr) {
- right: calc(100% - max(var(--start), var(--end)));
- left: min(var(--start), var(--end));
- }
-
- &:dir(rtl) {
- right: min(var(--start), var(--end));
- left: calc(100% - max(var(--start), var(--end)));
- }
-}
-
-.horizontal #indicator {
- top: 0;
- height: 100%;
-}
-
-.vertical #indicator {
- top: calc(100% - var(--end));
- bottom: var(--start);
- left: 0;
- width: 100%;
-}
-
-/* Thumbs */
-#thumb,
-#thumb-min,
-#thumb-max {
- z-index: 3;
- position: absolute;
- width: var(--thumb-width);
- height: var(--thumb-height);
- border: solid 0.125em var(--wa-color-surface-default);
- border-radius: 50%;
- background-color: var(--wa-form-control-activated-color);
- cursor: pointer;
-}
-
-.disabled #thumb,
-.disabled #thumb-min,
-.disabled #thumb-max {
- cursor: inherit;
-}
-
-.horizontal #thumb,
-.horizontal #thumb-min,
-.horizontal #thumb-max {
- top: calc(50% - var(--thumb-height) / 2);
-
- &:dir(ltr) {
- right: auto;
- left: calc(var(--position) - var(--thumb-width) / 2);
- }
-
- &:dir(rtl) {
- right: calc(var(--position) - var(--thumb-width) / 2);
- left: auto;
- }
-}
-
-.vertical #thumb,
-.vertical #thumb-min,
-.vertical #thumb-max {
- bottom: calc(var(--position) - var(--thumb-height) / 2);
- left: calc(50% - var(--thumb-width) / 2);
-}
-
-/* Range-specific thumb styles */
-:host([range]) {
- #thumb-min:focus-visible,
- #thumb-max:focus-visible {
- z-index: 4; /* Ensure focused thumb appears on top */
- outline: var(--wa-focus-ring);
- /* intentionally no offset due to border */
- }
-}
-
-/* Markers */
-#markers {
- pointer-events: none;
-}
-
-.marker {
- z-index: 2;
- position: absolute;
- width: var(--marker-width);
- height: var(--marker-height);
- border-radius: 50%;
- background-color: var(--wa-color-surface-default);
-}
-
-.marker:first-of-type,
-.marker:last-of-type {
- display: none;
-}
-
-.horizontal .marker {
- top: calc(50% - var(--marker-height) / 2);
- left: calc(var(--position) - var(--marker-width) / 2);
-}
-
-.vertical .marker {
- top: calc(var(--position) - var(--marker-height) / 2);
- left: calc(50% - var(--marker-width) / 2);
-}
-
-/* Marker labels */
-#references {
- position: relative;
-
- slot {
- display: flex;
- justify-content: space-between;
- height: 100%;
- }
-
- ::slotted(*) {
- color: var(--wa-color-text-quiet);
- font-size: 0.875em;
- line-height: 1;
- }
-}
-
-.horizontal {
- #references {
- margin-block-start: 0.5em;
- }
-}
-
-.vertical {
- display: flex;
- margin-inline: auto;
-
- #track {
- order: 1;
- }
-
- #references {
- order: 2;
- width: min-content;
- margin-inline-start: 0.75em;
-
- slot {
- flex-direction: column;
- }
- }
-}
-
-.vertical #references slot {
- flex-direction: column;
-}
diff --git a/packages/webawesome/src/components/slider/slider.styles.ts b/packages/webawesome/src/components/slider/slider.styles.ts
new file mode 100644
index 000000000..5e3b5a6c7
--- /dev/null
+++ b/packages/webawesome/src/components/slider/slider.styles.ts
@@ -0,0 +1,233 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --track-size: 0.5em;
+ --thumb-width: 1.4em;
+ --thumb-height: 1.4em;
+ --marker-width: 0.1875em;
+ --marker-height: 0.1875em;
+ }
+
+ :host([orientation='vertical']) {
+ width: auto;
+ }
+
+ #label:has(~ .vertical) {
+ display: block;
+ order: 2;
+ max-width: none;
+ text-align: center;
+ }
+
+ #description:has(~ .vertical) {
+ order: 3;
+ text-align: center;
+ }
+
+ /* Add extra space between slider and label, when present */
+ #label:has(*:not(:empty)) ~ #slider {
+ &.horizontal {
+ margin-block-start: 0.5em;
+ }
+ &.vertical {
+ margin-block-end: 0.5em;
+ }
+ }
+
+ #slider {
+ touch-action: none;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible:not(.disabled) #thumb,
+ &:focus-visible:not(.disabled) #thumb-min,
+ &:focus-visible:not(.disabled) #thumb-max {
+ outline: var(--wa-focus-ring);
+ /* intentionally no offset due to border */
+ }
+ }
+
+ #track {
+ position: relative;
+ border-radius: 9999px;
+ background: var(--wa-color-neutral-fill-normal);
+ isolation: isolate;
+ }
+
+ /* Orientation */
+ .horizontal #track {
+ height: var(--track-size);
+ }
+
+ .vertical #track {
+ order: 1;
+ width: var(--track-size);
+ height: 200px;
+ }
+
+ /* Disabled */
+ .disabled #track {
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+
+ /* Indicator */
+ #indicator {
+ position: absolute;
+ border-radius: inherit;
+ background-color: var(--wa-form-control-activated-color);
+
+ &:dir(ltr) {
+ right: calc(100% - max(var(--start), var(--end)));
+ left: min(var(--start), var(--end));
+ }
+
+ &:dir(rtl) {
+ right: min(var(--start), var(--end));
+ left: calc(100% - max(var(--start), var(--end)));
+ }
+ }
+
+ .horizontal #indicator {
+ top: 0;
+ height: 100%;
+ }
+
+ .vertical #indicator {
+ top: calc(100% - var(--end));
+ bottom: var(--start);
+ left: 0;
+ width: 100%;
+ }
+
+ /* Thumbs */
+ #thumb,
+ #thumb-min,
+ #thumb-max {
+ z-index: 3;
+ position: absolute;
+ width: var(--thumb-width);
+ height: var(--thumb-height);
+ border: solid 0.125em var(--wa-color-surface-default);
+ border-radius: 50%;
+ background-color: var(--wa-form-control-activated-color);
+ cursor: pointer;
+ }
+
+ .disabled #thumb,
+ .disabled #thumb-min,
+ .disabled #thumb-max {
+ cursor: inherit;
+ }
+
+ .horizontal #thumb,
+ .horizontal #thumb-min,
+ .horizontal #thumb-max {
+ top: calc(50% - var(--thumb-height) / 2);
+
+ &:dir(ltr) {
+ right: auto;
+ left: calc(var(--position) - var(--thumb-width) / 2);
+ }
+
+ &:dir(rtl) {
+ right: calc(var(--position) - var(--thumb-width) / 2);
+ left: auto;
+ }
+ }
+
+ .vertical #thumb,
+ .vertical #thumb-min,
+ .vertical #thumb-max {
+ bottom: calc(var(--position) - var(--thumb-height) / 2);
+ left: calc(50% - var(--thumb-width) / 2);
+ }
+
+ /* Range-specific thumb styles */
+ :host([range]) {
+ #thumb-min:focus-visible,
+ #thumb-max:focus-visible {
+ z-index: 4; /* Ensure focused thumb appears on top */
+ outline: var(--wa-focus-ring);
+ /* intentionally no offset due to border */
+ }
+ }
+
+ /* Markers */
+ #markers {
+ pointer-events: none;
+ }
+
+ .marker {
+ z-index: 2;
+ position: absolute;
+ width: var(--marker-width);
+ height: var(--marker-height);
+ border-radius: 50%;
+ background-color: var(--wa-color-surface-default);
+ }
+
+ .marker:first-of-type,
+ .marker:last-of-type {
+ display: none;
+ }
+
+ .horizontal .marker {
+ top: calc(50% - var(--marker-height) / 2);
+ left: calc(var(--position) - var(--marker-width) / 2);
+ }
+
+ .vertical .marker {
+ top: calc(var(--position) - var(--marker-height) / 2);
+ left: calc(50% - var(--marker-width) / 2);
+ }
+
+ /* Marker labels */
+ #references {
+ position: relative;
+
+ slot {
+ display: flex;
+ justify-content: space-between;
+ height: 100%;
+ }
+
+ ::slotted(*) {
+ color: var(--wa-color-text-quiet);
+ font-size: 0.875em;
+ line-height: 1;
+ }
+ }
+
+ .horizontal {
+ #references {
+ margin-block-start: 0.5em;
+ }
+ }
+
+ .vertical {
+ display: flex;
+ margin-inline: auto;
+
+ #track {
+ order: 1;
+ }
+
+ #references {
+ order: 2;
+ width: min-content;
+ margin-inline-start: 0.75em;
+
+ slot {
+ flex-direction: column;
+ }
+ }
+ }
+
+ .vertical #references slot {
+ flex-direction: column;
+ }
+`;
diff --git a/packages/webawesome/src/components/slider/slider.ts b/packages/webawesome/src/components/slider/slider.ts
index e4dabdc0d..e896e6174 100644
--- a/packages/webawesome/src/components/slider/slider.ts
+++ b/packages/webawesome/src/components/slider/slider.ts
@@ -8,12 +8,12 @@ import { HasSlotController } from '../../internal/slot.js';
import { submitOnEnter } from '../../internal/submit-on-enter.js';
import { SliderValidator } from '../../internal/validators/slider-validator.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../tooltip/tooltip.js';
import type WaTooltip from '../tooltip/tooltip.js';
-import styles from './slider.css';
+import styles from './slider.styles.js';
/**
*
diff --git a/packages/webawesome/src/components/spinner/spinner.css b/packages/webawesome/src/components/spinner/spinner.css
deleted file mode 100644
index cc28a04c8..000000000
--- a/packages/webawesome/src/components/spinner/spinner.css
+++ /dev/null
@@ -1,59 +0,0 @@
-:host {
- --track-width: 2px;
- --track-color: var(--wa-color-neutral-fill-normal);
- --indicator-color: var(--wa-color-brand-fill-loud);
- --speed: 2s;
-
- /* Resizing a spinner element using anything but font-size will break the animation because the animation uses em units.
- Therefore, if a spinner is used in a flex container without `flex: none` applied, the spinner can grow/shrink and
- break the animation. The use of `flex: none` on the host element prevents this by always having the spinner sized
- according to its actual dimensions.
- */
- flex: none;
- display: inline-flex;
- width: 1em;
- height: 1em;
-}
-
-svg {
- width: 100%;
- height: 100%;
- aspect-ratio: 1;
- animation: spin var(--speed) linear infinite;
-}
-
-.track {
- stroke: var(--track-color);
-}
-
-.indicator {
- stroke: var(--indicator-color);
- stroke-dasharray: 75, 100;
- stroke-dashoffset: -5;
- animation: dash 1.5s ease-in-out infinite;
- stroke-linecap: round;
-}
-
-@keyframes spin {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
-}
-
-@keyframes dash {
- 0% {
- stroke-dasharray: 1, 150;
- stroke-dashoffset: 0;
- }
- 50% {
- stroke-dasharray: 90, 150;
- stroke-dashoffset: -35;
- }
- 100% {
- stroke-dasharray: 90, 150;
- stroke-dashoffset: -124;
- }
-}
diff --git a/packages/webawesome/src/components/spinner/spinner.styles.ts b/packages/webawesome/src/components/spinner/spinner.styles.ts
new file mode 100644
index 000000000..f965c6fd9
--- /dev/null
+++ b/packages/webawesome/src/components/spinner/spinner.styles.ts
@@ -0,0 +1,64 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --track-width: 2px;
+ --track-color: var(--wa-color-neutral-fill-normal);
+ --indicator-color: var(--wa-color-brand-fill-loud);
+ --speed: 2s;
+
+ /*
+ Resizing a spinner element using anything but font-size will break the animation because the animation uses em
+ units. Therefore, if a spinner is used in a flex container without \`flex: none\` applied, the spinner can
+ grow/shrink and break the animation. The use of \`flex: none\` on the host element prevents this by always having
+ the spinner sized according to its actual dimensions.
+ */
+ flex: none;
+ display: inline-flex;
+ width: 1em;
+ height: 1em;
+ }
+
+ svg {
+ width: 100%;
+ height: 100%;
+ aspect-ratio: 1;
+ animation: spin var(--speed) linear infinite;
+ }
+
+ .track {
+ stroke: var(--track-color);
+ }
+
+ .indicator {
+ stroke: var(--indicator-color);
+ stroke-dasharray: 75, 100;
+ stroke-dashoffset: -5;
+ animation: dash 1.5s ease-in-out infinite;
+ stroke-linecap: round;
+ }
+
+ @keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+ }
+
+ @keyframes dash {
+ 0% {
+ stroke-dasharray: 1, 150;
+ stroke-dashoffset: 0;
+ }
+ 50% {
+ stroke-dasharray: 90, 150;
+ stroke-dashoffset: -35;
+ }
+ 100% {
+ stroke-dasharray: 90, 150;
+ stroke-dashoffset: -124;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/spinner/spinner.ts b/packages/webawesome/src/components/spinner/spinner.ts
index ca3d2b45d..9985a492c 100644
--- a/packages/webawesome/src/components/spinner/spinner.ts
+++ b/packages/webawesome/src/components/spinner/spinner.ts
@@ -2,7 +2,7 @@ import { html } from 'lit';
import { customElement } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './spinner.css';
+import styles from './spinner.styles.js';
/**
* @summary Spinners are used to show the progress of an indeterminate operation.
diff --git a/packages/webawesome/src/components/split-panel/split-panel.css b/packages/webawesome/src/components/split-panel/split-panel.css
deleted file mode 100644
index 4c9187b7e..000000000
--- a/packages/webawesome/src/components/split-panel/split-panel.css
+++ /dev/null
@@ -1,73 +0,0 @@
-:host {
- --divider-width: 0.25rem;
- --divider-hit-area: 0.75rem;
- --min: 0%;
- --max: 100%;
-
- display: grid;
-}
-
-.start,
-.end {
- overflow: hidden;
-}
-
-.divider {
- flex: 0 0 var(--divider-width);
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
- background-color: var(--wa-color-neutral-border-normal);
- color: var(--wa-color-neutral-on-normal);
- z-index: 1;
-}
-
-.divider:focus {
- outline: none;
-}
-
-:host(:not([disabled])) .divider:focus-visible {
- outline: var(--wa-focus-ring);
-}
-
-:host([disabled]) .divider {
- cursor: not-allowed;
-}
-
-/* Horizontal */
-:host(:not([orientation='vertical'], [disabled])) .divider {
- cursor: col-resize;
-}
-
-:host(:not([orientation='vertical'])) .divider::after {
- display: flex;
- content: '';
- position: absolute;
- height: 100%;
- left: calc(var(--divider-hit-area) / -2 + var(--divider-width) / 2);
- width: var(--divider-hit-area);
-}
-
-/* Vertical */
-:host([orientation='vertical']) {
- flex-direction: column;
-}
-
-:host([orientation='vertical']:not([disabled])) .divider {
- cursor: row-resize;
-}
-
-:host([orientation='vertical']) .divider::after {
- content: '';
- position: absolute;
- width: 100%;
- top: calc(var(--divider-hit-area) / -2 + var(--divider-width) / 2);
- height: var(--divider-hit-area);
-}
-
-@media (forced-colors: active) {
- .divider {
- outline: solid 1px transparent;
- }
-}
diff --git a/packages/webawesome/src/components/split-panel/split-panel.styles.ts b/packages/webawesome/src/components/split-panel/split-panel.styles.ts
new file mode 100644
index 000000000..aada89211
--- /dev/null
+++ b/packages/webawesome/src/components/split-panel/split-panel.styles.ts
@@ -0,0 +1,77 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --divider-width: 0.25rem;
+ --divider-hit-area: 0.75rem;
+ --min: 0%;
+ --max: 100%;
+
+ display: grid;
+ }
+
+ .start,
+ .end {
+ overflow: hidden;
+ }
+
+ .divider {
+ flex: 0 0 var(--divider-width);
+ display: flex;
+ position: relative;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--wa-color-neutral-border-normal);
+ color: var(--wa-color-neutral-on-normal);
+ z-index: 1;
+ }
+
+ .divider:focus {
+ outline: none;
+ }
+
+ :host(:not([disabled])) .divider:focus-visible {
+ outline: var(--wa-focus-ring);
+ }
+
+ :host([disabled]) .divider {
+ cursor: not-allowed;
+ }
+
+ /* Horizontal */
+ :host(:not([orientation='vertical'], [disabled])) .divider {
+ cursor: col-resize;
+ }
+
+ :host(:not([orientation='vertical'])) .divider::after {
+ display: flex;
+ content: '';
+ position: absolute;
+ height: 100%;
+ left: calc(var(--divider-hit-area) / -2 + var(--divider-width) / 2);
+ width: var(--divider-hit-area);
+ }
+
+ /* Vertical */
+ :host([orientation='vertical']) {
+ flex-direction: column;
+ }
+
+ :host([orientation='vertical']:not([disabled])) .divider {
+ cursor: row-resize;
+ }
+
+ :host([orientation='vertical']) .divider::after {
+ content: '';
+ position: absolute;
+ width: 100%;
+ top: calc(var(--divider-hit-area) / -2 + var(--divider-width) / 2);
+ height: var(--divider-hit-area);
+ }
+
+ @media (forced-colors: active) {
+ .divider {
+ outline: solid 1px transparent;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/split-panel/split-panel.ts b/packages/webawesome/src/components/split-panel/split-panel.ts
index 7e83bb90b..e3930db79 100644
--- a/packages/webawesome/src/components/split-panel/split-panel.ts
+++ b/packages/webawesome/src/components/split-panel/split-panel.ts
@@ -7,7 +7,7 @@ import { clamp } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './split-panel.css';
+import styles from './split-panel.styles.js';
/**
* @summary Split panels display two adjacent panels, allowing the user to reposition them.
diff --git a/packages/webawesome/src/components/switch/switch.css b/packages/webawesome/src/components/switch/switch.css
deleted file mode 100644
index 941bf017c..000000000
--- a/packages/webawesome/src/components/switch/switch.css
+++ /dev/null
@@ -1,98 +0,0 @@
-:host {
- --height: var(--wa-form-control-toggle-size);
- --width: calc(var(--height) * 1.75);
- --thumb-size: 0.75em;
-
- display: inline-flex;
- line-height: var(--wa-form-control-value-line-height);
-}
-
-label {
- position: relative;
- display: flex;
- align-items: center;
- font: inherit;
- color: var(--wa-form-control-value-color);
- vertical-align: middle;
- cursor: pointer;
-}
-
-.switch {
- flex: 0 0 auto;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- width: var(--width);
- height: var(--height);
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
- border-radius: var(--height);
- border-style: var(--wa-form-control-border-style);
- border-width: var(--wa-form-control-border-width);
- transition-property: translate, background, border-color, box-shadow;
- transition-duration: var(--wa-transition-normal);
- transition-timing-function: var(--wa-transition-easing);
-}
-
-.switch .thumb {
- aspect-ratio: 1 / 1;
- width: var(--thumb-size);
- height: var(--thumb-size);
- background-color: var(--wa-form-control-border-color);
- border-radius: 50%;
- translate: calc((var(--width) - var(--height)) / -2);
- transition: inherit;
-}
-
-.input {
- position: absolute;
- opacity: 0;
- padding: 0;
- margin: 0;
- pointer-events: none;
-}
-
-/* Focus */
-label:not(.disabled) .input:focus-visible ~ .switch .thumb {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
-}
-
-/* Checked */
-.checked .switch {
- background-color: var(--wa-form-control-activated-color);
- border-color: var(--wa-form-control-activated-color);
-}
-
-.checked .switch .thumb {
- background-color: var(--wa-color-surface-default);
- translate: calc((var(--width) - var(--height)) / 2);
-}
-
-/* Disabled */
-label:has(> :disabled) {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-[part~='label'] {
- display: inline-block;
- line-height: var(--height);
- margin-inline-start: 0.5em;
- user-select: none;
- -webkit-user-select: none;
-}
-
-:host([required]) [part~='label']::after {
- content: var(--wa-form-control-required-content);
- color: var(--wa-form-control-required-content-color);
- margin-inline-start: var(--wa-form-control-required-content-offset);
-}
-
-@media (forced-colors: active) {
- :checked:enabled + .switch:hover .thumb,
- :checked + .switch .thumb {
- background-color: ButtonText;
- }
-}
diff --git a/packages/webawesome/src/components/switch/switch.styles.ts b/packages/webawesome/src/components/switch/switch.styles.ts
new file mode 100644
index 000000000..f1b689e57
--- /dev/null
+++ b/packages/webawesome/src/components/switch/switch.styles.ts
@@ -0,0 +1,102 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --height: var(--wa-form-control-toggle-size);
+ --width: calc(var(--height) * 1.75);
+ --thumb-size: 0.75em;
+
+ display: inline-flex;
+ line-height: var(--wa-form-control-value-line-height);
+ }
+
+ label {
+ position: relative;
+ display: flex;
+ align-items: center;
+ font: inherit;
+ color: var(--wa-form-control-value-color);
+ vertical-align: middle;
+ cursor: pointer;
+ }
+
+ .switch {
+ flex: 0 0 auto;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: var(--width);
+ height: var(--height);
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: var(--height);
+ border-style: var(--wa-form-control-border-style);
+ border-width: var(--wa-form-control-border-width);
+ transition-property: translate, background, border-color, box-shadow;
+ transition-duration: var(--wa-transition-normal);
+ transition-timing-function: var(--wa-transition-easing);
+ }
+
+ .switch .thumb {
+ aspect-ratio: 1 / 1;
+ width: var(--thumb-size);
+ height: var(--thumb-size);
+ background-color: var(--wa-form-control-border-color);
+ border-radius: 50%;
+ translate: calc((var(--width) - var(--height)) / -2);
+ transition: inherit;
+ }
+
+ .input {
+ position: absolute;
+ opacity: 0;
+ padding: 0;
+ margin: 0;
+ pointer-events: none;
+ }
+
+ /* Focus */
+ label:not(.disabled) .input:focus-visible ~ .switch .thumb {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ /* Checked */
+ .checked .switch {
+ background-color: var(--wa-form-control-activated-color);
+ border-color: var(--wa-form-control-activated-color);
+ }
+
+ .checked .switch .thumb {
+ background-color: var(--wa-color-surface-default);
+ translate: calc((var(--width) - var(--height)) / 2);
+ }
+
+ /* Disabled */
+ label:has(> :disabled) {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ [part~='label'] {
+ display: inline-block;
+ line-height: var(--height);
+ margin-inline-start: 0.5em;
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ :host([required]) [part~='label']::after {
+ content: var(--wa-form-control-required-content);
+ color: var(--wa-form-control-required-content-color);
+ margin-inline-start: var(--wa-form-control-required-content-offset);
+ }
+
+ @media (forced-colors: active) {
+ :checked:enabled + .switch:hover .thumb,
+ :checked + .switch .thumb {
+ background-color: ButtonText;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/switch/switch.ts b/packages/webawesome/src/components/switch/switch.ts
index 0c472519c..99e3b8de0 100644
--- a/packages/webawesome/src/components/switch/switch.ts
+++ b/packages/webawesome/src/components/switch/switch.ts
@@ -8,9 +8,9 @@ import { HasSlotController } from '../../internal/slot.js';
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
-import styles from './switch.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
+import styles from './switch.styles.js';
/**
* @summary Switches allow the user to toggle an option on or off.
diff --git a/packages/webawesome/src/components/tab-group/tab-group.css b/packages/webawesome/src/components/tab-group/tab-group.css
deleted file mode 100644
index 6606fa163..000000000
--- a/packages/webawesome/src/components/tab-group/tab-group.css
+++ /dev/null
@@ -1,224 +0,0 @@
-:host {
- --indicator-color: var(--wa-color-brand-fill-loud);
- --track-color: var(--wa-color-neutral-fill-normal);
- --track-width: 0.125rem;
-
- display: block;
-}
-
-.tab-group {
- display: flex;
- border-radius: 0;
-}
-
-.tabs {
- display: flex;
- position: relative;
-}
-
-.indicator {
- position: absolute;
-}
-
-.tab-group-has-scroll-controls .nav-container {
- position: relative;
- padding: 0 1.5em;
-}
-
-.body {
- display: block;
-}
-
-.scroll-button {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 0;
- bottom: 0;
- width: 1.5em;
-}
-
-.scroll-button-start {
- inset-inline-start: 0;
-}
-
-.scroll-button-end {
- inset-inline-end: 0;
-}
-
-/*
- * Top
- */
-
-.tab-group-top {
- flex-direction: column;
-}
-
-.tab-group-top .nav-container {
- order: 1;
-}
-
-.tab-group-top .nav {
- display: flex;
- overflow-x: auto;
-
- /* Hide scrollbar in Firefox */
- scrollbar-width: none;
-}
-
-/* Hide scrollbar in Chrome/Safari */
-.tab-group-top .nav::-webkit-scrollbar {
- width: 0;
- height: 0;
-}
-
-.tab-group-top .tabs {
- flex: 1 1 auto;
- position: relative;
- flex-direction: row;
- border-bottom: solid var(--track-width) var(--track-color);
-}
-
-.tab-group-top .indicator {
- bottom: calc(-1 * var(--track-width));
- border-bottom: solid var(--track-width) var(--indicator-color);
-}
-
-.tab-group-top .body {
- order: 2;
-}
-
-.tab-group-top ::slotted(wa-tab[active]) {
- border-block-end: solid var(--track-width) var(--indicator-color);
- margin-block-end: calc(-1 * var(--track-width));
-}
-
-.tab-group-top ::slotted(wa-tab-panel) {
- --padding: var(--wa-space-xl) 0;
-}
-
-/*
- * Bottom
- */
-
-.tab-group-bottom {
- flex-direction: column;
-}
-
-.tab-group-bottom .nav-container {
- order: 2;
-}
-
-.tab-group-bottom .nav {
- display: flex;
- overflow-x: auto;
-
- /* Hide scrollbar in Firefox */
- scrollbar-width: none;
-}
-
-/* Hide scrollbar in Chrome/Safari */
-.tab-group-bottom .nav::-webkit-scrollbar {
- width: 0;
- height: 0;
-}
-
-.tab-group-bottom .tabs {
- flex: 1 1 auto;
- position: relative;
- flex-direction: row;
- border-top: solid var(--track-width) var(--track-color);
-}
-
-.tab-group-bottom .indicator {
- top: calc(-1 * var(--track-width));
- border-top: solid var(--track-width) var(--indicator-color);
-}
-
-.tab-group-bottom .body {
- order: 1;
-}
-
-.tab-group-bottom ::slotted(wa-tab[active]) {
- border-block-start: solid var(--track-width) var(--indicator-color);
- margin-block-start: calc(-1 * var(--track-width));
-}
-
-.tab-group-bottom ::slotted(wa-tab-panel) {
- --padding: var(--wa-space-xl) 0;
-}
-
-/*
- * Start
- */
-
-.tab-group-start {
- flex-direction: row;
-}
-
-.tab-group-start .nav-container {
- order: 1;
-}
-
-.tab-group-start .tabs {
- flex: 0 0 auto;
- flex-direction: column;
- border-inline-end: solid var(--track-width) var(--track-color);
-}
-
-.tab-group-start .indicator {
- inset-inline-end: calc(-1 * var(--track-width));
- border-right: solid var(--track-width) var(--indicator-color);
-}
-
-.tab-group-start .body {
- flex: 1 1 auto;
- order: 2;
-}
-
-.tab-group-start ::slotted(wa-tab[active]) {
- border-inline-end: solid var(--track-width) var(--indicator-color);
- margin-inline-end: calc(-1 * var(--track-width));
-}
-
-.tab-group-start ::slotted(wa-tab-panel) {
- --padding: 0 var(--wa-space-xl);
-}
-
-/*
- * End
- */
-
-.tab-group-end {
- flex-direction: row;
-}
-
-.tab-group-end .nav-container {
- order: 2;
-}
-
-.tab-group-end .tabs {
- flex: 0 0 auto;
- flex-direction: column;
- border-left: solid var(--track-width) var(--track-color);
-}
-
-.tab-group-end .indicator {
- inset-inline-start: calc(-1 * var(--track-width));
- border-inline-start: solid var(--track-width) var(--indicator-color);
-}
-
-.tab-group-end .body {
- flex: 1 1 auto;
- order: 1;
-}
-
-.tab-group-end ::slotted(wa-tab[active]) {
- border-inline-start: solid var(--track-width) var(--indicator-color);
- margin-inline-start: calc(-1 * var(--track-width));
-}
-
-.tab-group-end ::slotted(wa-tab-panel) {
- --padding: 0 var(--wa-space-xl);
-}
diff --git a/packages/webawesome/src/components/tab-group/tab-group.styles.ts b/packages/webawesome/src/components/tab-group/tab-group.styles.ts
new file mode 100644
index 000000000..ce98145fb
--- /dev/null
+++ b/packages/webawesome/src/components/tab-group/tab-group.styles.ts
@@ -0,0 +1,228 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --indicator-color: var(--wa-color-brand-fill-loud);
+ --track-color: var(--wa-color-neutral-fill-normal);
+ --track-width: 0.125rem;
+
+ display: block;
+ }
+
+ .tab-group {
+ display: flex;
+ border-radius: 0;
+ }
+
+ .tabs {
+ display: flex;
+ position: relative;
+ }
+
+ .indicator {
+ position: absolute;
+ }
+
+ .tab-group-has-scroll-controls .nav-container {
+ position: relative;
+ padding: 0 1.5em;
+ }
+
+ .body {
+ display: block;
+ }
+
+ .scroll-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 1.5em;
+ }
+
+ .scroll-button-start {
+ inset-inline-start: 0;
+ }
+
+ .scroll-button-end {
+ inset-inline-end: 0;
+ }
+
+ /*
+ * Top
+ */
+
+ .tab-group-top {
+ flex-direction: column;
+ }
+
+ .tab-group-top .nav-container {
+ order: 1;
+ }
+
+ .tab-group-top .nav {
+ display: flex;
+ overflow-x: auto;
+
+ /* Hide scrollbar in Firefox */
+ scrollbar-width: none;
+ }
+
+ /* Hide scrollbar in Chrome/Safari */
+ .tab-group-top .nav::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ }
+
+ .tab-group-top .tabs {
+ flex: 1 1 auto;
+ position: relative;
+ flex-direction: row;
+ border-bottom: solid var(--track-width) var(--track-color);
+ }
+
+ .tab-group-top .indicator {
+ bottom: calc(-1 * var(--track-width));
+ border-bottom: solid var(--track-width) var(--indicator-color);
+ }
+
+ .tab-group-top .body {
+ order: 2;
+ }
+
+ .tab-group-top ::slotted(wa-tab[active]) {
+ border-block-end: solid var(--track-width) var(--indicator-color);
+ margin-block-end: calc(-1 * var(--track-width));
+ }
+
+ .tab-group-top ::slotted(wa-tab-panel) {
+ --padding: var(--wa-space-xl) 0;
+ }
+
+ /*
+ * Bottom
+ */
+
+ .tab-group-bottom {
+ flex-direction: column;
+ }
+
+ .tab-group-bottom .nav-container {
+ order: 2;
+ }
+
+ .tab-group-bottom .nav {
+ display: flex;
+ overflow-x: auto;
+
+ /* Hide scrollbar in Firefox */
+ scrollbar-width: none;
+ }
+
+ /* Hide scrollbar in Chrome/Safari */
+ .tab-group-bottom .nav::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ }
+
+ .tab-group-bottom .tabs {
+ flex: 1 1 auto;
+ position: relative;
+ flex-direction: row;
+ border-top: solid var(--track-width) var(--track-color);
+ }
+
+ .tab-group-bottom .indicator {
+ top: calc(-1 * var(--track-width));
+ border-top: solid var(--track-width) var(--indicator-color);
+ }
+
+ .tab-group-bottom .body {
+ order: 1;
+ }
+
+ .tab-group-bottom ::slotted(wa-tab[active]) {
+ border-block-start: solid var(--track-width) var(--indicator-color);
+ margin-block-start: calc(-1 * var(--track-width));
+ }
+
+ .tab-group-bottom ::slotted(wa-tab-panel) {
+ --padding: var(--wa-space-xl) 0;
+ }
+
+ /*
+ * Start
+ */
+
+ .tab-group-start {
+ flex-direction: row;
+ }
+
+ .tab-group-start .nav-container {
+ order: 1;
+ }
+
+ .tab-group-start .tabs {
+ flex: 0 0 auto;
+ flex-direction: column;
+ border-inline-end: solid var(--track-width) var(--track-color);
+ }
+
+ .tab-group-start .indicator {
+ inset-inline-end: calc(-1 * var(--track-width));
+ border-right: solid var(--track-width) var(--indicator-color);
+ }
+
+ .tab-group-start .body {
+ flex: 1 1 auto;
+ order: 2;
+ }
+
+ .tab-group-start ::slotted(wa-tab[active]) {
+ border-inline-end: solid var(--track-width) var(--indicator-color);
+ margin-inline-end: calc(-1 * var(--track-width));
+ }
+
+ .tab-group-start ::slotted(wa-tab-panel) {
+ --padding: 0 var(--wa-space-xl);
+ }
+
+ /*
+ * End
+ */
+
+ .tab-group-end {
+ flex-direction: row;
+ }
+
+ .tab-group-end .nav-container {
+ order: 2;
+ }
+
+ .tab-group-end .tabs {
+ flex: 0 0 auto;
+ flex-direction: column;
+ border-left: solid var(--track-width) var(--track-color);
+ }
+
+ .tab-group-end .indicator {
+ inset-inline-start: calc(-1 * var(--track-width));
+ border-inline-start: solid var(--track-width) var(--indicator-color);
+ }
+
+ .tab-group-end .body {
+ flex: 1 1 auto;
+ order: 1;
+ }
+
+ .tab-group-end ::slotted(wa-tab[active]) {
+ border-inline-start: solid var(--track-width) var(--indicator-color);
+ margin-inline-start: calc(-1 * var(--track-width));
+ }
+
+ .tab-group-end ::slotted(wa-tab-panel) {
+ --padding: 0 var(--wa-space-xl);
+ }
+`;
diff --git a/packages/webawesome/src/components/tab-group/tab-group.ts b/packages/webawesome/src/components/tab-group/tab-group.ts
index abd684f9f..2421cd96c 100644
--- a/packages/webawesome/src/components/tab-group/tab-group.ts
+++ b/packages/webawesome/src/components/tab-group/tab-group.ts
@@ -12,7 +12,7 @@ import '../tab-panel/tab-panel.js';
import type WaTabPanel from '../tab-panel/tab-panel.js';
import '../tab/tab.js';
import type WaTab from '../tab/tab.js';
-import styles from './tab-group.css';
+import styles from './tab-group.styles.js';
/**
* @summary Tab groups organize content into a container that shows one section at a time.
diff --git a/packages/webawesome/src/components/tab-panel/tab-panel.css b/packages/webawesome/src/components/tab-panel/tab-panel.css
deleted file mode 100644
index cc74c9f1c..000000000
--- a/packages/webawesome/src/components/tab-panel/tab-panel.css
+++ /dev/null
@@ -1,14 +0,0 @@
-:host {
- --padding: 0;
-
- display: none;
-}
-
-:host([active]) {
- display: block;
-}
-
-.tab-panel {
- display: block;
- padding: var(--padding);
-}
diff --git a/packages/webawesome/src/components/tab-panel/tab-panel.styles.ts b/packages/webawesome/src/components/tab-panel/tab-panel.styles.ts
new file mode 100644
index 000000000..e0c9f2142
--- /dev/null
+++ b/packages/webawesome/src/components/tab-panel/tab-panel.styles.ts
@@ -0,0 +1,18 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --padding: 0;
+
+ display: none;
+ }
+
+ :host([active]) {
+ display: block;
+ }
+
+ .tab-panel {
+ display: block;
+ padding: var(--padding);
+ }
+`;
diff --git a/packages/webawesome/src/components/tab-panel/tab-panel.ts b/packages/webawesome/src/components/tab-panel/tab-panel.ts
index 1974f92f8..53d9b239d 100644
--- a/packages/webawesome/src/components/tab-panel/tab-panel.ts
+++ b/packages/webawesome/src/components/tab-panel/tab-panel.ts
@@ -3,7 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './tab-panel.css';
+import styles from './tab-panel.styles.js';
let id = 0;
diff --git a/packages/webawesome/src/components/tab/tab.css b/packages/webawesome/src/components/tab/tab.css
deleted file mode 100644
index ef87dd807..000000000
--- a/packages/webawesome/src/components/tab/tab.css
+++ /dev/null
@@ -1,56 +0,0 @@
-:host {
- display: inline-block;
- color: var(--wa-color-neutral-on-quiet);
- font-weight: var(--wa-font-weight-action);
-}
-
-.tab {
- display: inline-flex;
- align-items: center;
- font: inherit;
- padding: 1em 1.5em;
- white-space: nowrap;
- user-select: none;
- -webkit-user-select: none;
- cursor: pointer;
- transition: color var(--wa-transition-fast) var(--wa-transition-easing);
-
- ::slotted(wa-icon:first-child) {
- margin-inline-end: 0.5em;
- }
-
- ::slotted(wa-icon:last-child) {
- margin-inline-start: 0.5em;
- }
-}
-
-@media (hover: hover) {
- :host(:hover:not([disabled])) .tab {
- color: currentColor;
- }
-}
-
-:host(:focus) {
- outline: transparent;
-}
-
-:host(:focus-visible) .tab {
- outline: var(--wa-focus-ring);
- outline-offset: calc(-1 * var(--wa-border-width-l) - var(--wa-focus-ring-offset));
-}
-
-:host([active]:not([disabled])) {
- color: var(--wa-color-brand-on-quiet);
-}
-
-:host([disabled]) .tab {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-@media (forced-colors: active) {
- :host([active]:not([disabled])) {
- outline: solid 1px transparent;
- outline-offset: -3px;
- }
-}
diff --git a/packages/webawesome/src/components/tab/tab.styles.ts b/packages/webawesome/src/components/tab/tab.styles.ts
new file mode 100644
index 000000000..61977cff2
--- /dev/null
+++ b/packages/webawesome/src/components/tab/tab.styles.ts
@@ -0,0 +1,60 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: inline-block;
+ color: var(--wa-color-neutral-on-quiet);
+ font-weight: var(--wa-font-weight-action);
+ }
+
+ .tab {
+ display: inline-flex;
+ align-items: center;
+ font: inherit;
+ padding: 1em 1.5em;
+ white-space: nowrap;
+ user-select: none;
+ -webkit-user-select: none;
+ cursor: pointer;
+ transition: color var(--wa-transition-fast) var(--wa-transition-easing);
+
+ ::slotted(wa-icon:first-child) {
+ margin-inline-end: 0.5em;
+ }
+
+ ::slotted(wa-icon:last-child) {
+ margin-inline-start: 0.5em;
+ }
+ }
+
+ @media (hover: hover) {
+ :host(:hover:not([disabled])) .tab {
+ color: currentColor;
+ }
+ }
+
+ :host(:focus) {
+ outline: transparent;
+ }
+
+ :host(:focus-visible) .tab {
+ outline: var(--wa-focus-ring);
+ outline-offset: calc(-1 * var(--wa-border-width-l) - var(--wa-focus-ring-offset));
+ }
+
+ :host([active]:not([disabled])) {
+ color: var(--wa-color-brand-on-quiet);
+ }
+
+ :host([disabled]) .tab {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ @media (forced-colors: active) {
+ :host([active]:not([disabled])) {
+ outline: solid 1px transparent;
+ outline-offset: -3px;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/tab/tab.ts b/packages/webawesome/src/components/tab/tab.ts
index aedb2f988..546d41a45 100644
--- a/packages/webawesome/src/components/tab/tab.ts
+++ b/packages/webawesome/src/components/tab/tab.ts
@@ -3,7 +3,7 @@ import { customElement, property, query } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import styles from './tab.css';
+import styles from './tab.styles.js';
let id = 0;
diff --git a/packages/webawesome/src/components/tag/tag.css b/packages/webawesome/src/components/tag/tag.css
deleted file mode 100644
index 6289ad822..000000000
--- a/packages/webawesome/src/components/tag/tag.css
+++ /dev/null
@@ -1,78 +0,0 @@
-@layer wa-component {
- :host {
- display: inline-flex;
- gap: 0.5em;
- border-radius: var(--wa-border-radius-m);
- align-items: center;
- background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
- border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
- border-style: var(--wa-border-style);
- border-width: var(--wa-border-width-s);
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- font-size: inherit;
- line-height: 1;
- white-space: nowrap;
- user-select: none;
- -webkit-user-select: none;
- height: calc(var(--wa-form-control-height) * 0.8);
- line-height: calc(var(--wa-form-control-height) - var(--wa-form-control-border-width) * 2);
- padding: 0 0.75em;
- }
-
- /* Appearance modifiers */
- :host([appearance='outlined']) {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: transparent;
- border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
- }
-
- :host([appearance='filled']) {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
- border-color: transparent;
- }
-
- :host([appearance='filled-outlined']) {
- color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
- background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
- border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
- }
-
- :host([appearance='accent']) {
- color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
- background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
- border-color: transparent;
- }
-}
-
-.content {
- font-size: var(--wa-font-size-smaller);
-}
-
-[part='remove-button'] {
- color: inherit;
- line-height: 1;
-}
-
-[part='remove-button']::part(base) {
- padding: 0;
- height: 1em;
- width: 1em;
-}
-
-@media (hover: hover) {
- :host(:hover) > [part='remove-button']::part(base) {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
- }
-}
-
-:host(:active) > [part='remove-button']::part(base) {
- color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
-}
-
-/*
- * Pill modifier
- */
-:host([pill]) {
- border-radius: var(--wa-border-radius-pill);
-}
diff --git a/packages/webawesome/src/components/tag/tag.styles.ts b/packages/webawesome/src/components/tag/tag.styles.ts
new file mode 100644
index 000000000..17d91c99c
--- /dev/null
+++ b/packages/webawesome/src/components/tag/tag.styles.ts
@@ -0,0 +1,82 @@
+import { css } from 'lit';
+
+export default css`
+ @layer wa-component {
+ :host {
+ display: inline-flex;
+ gap: 0.5em;
+ border-radius: var(--wa-border-radius-m);
+ align-items: center;
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
+ border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
+ border-style: var(--wa-border-style);
+ border-width: var(--wa-border-width-s);
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ font-size: inherit;
+ line-height: 1;
+ white-space: nowrap;
+ user-select: none;
+ -webkit-user-select: none;
+ height: calc(var(--wa-form-control-height) * 0.8);
+ line-height: calc(var(--wa-form-control-height) - var(--wa-form-control-border-width) * 2);
+ padding: 0 0.75em;
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='outlined']) {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: transparent;
+ border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
+ }
+
+ :host([appearance='filled']) {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
+ border-color: transparent;
+ }
+
+ :host([appearance='filled-outlined']) {
+ color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
+ background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
+ border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
+ }
+
+ :host([appearance='accent']) {
+ color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
+ background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
+ border-color: transparent;
+ }
+ }
+
+ .content {
+ font-size: var(--wa-font-size-smaller);
+ }
+
+ [part='remove-button'] {
+ color: inherit;
+ line-height: 1;
+ }
+
+ [part='remove-button']::part(base) {
+ padding: 0;
+ height: 1em;
+ width: 1em;
+ }
+
+ @media (hover: hover) {
+ :host(:hover) > [part='remove-button']::part(base) {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
+ }
+ }
+
+ :host(:active) > [part='remove-button']::part(base) {
+ color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
+ }
+
+ /*
+ * Pill modifier
+ */
+ :host([pill]) {
+ border-radius: var(--wa-border-radius-pill);
+ }
+`;
diff --git a/packages/webawesome/src/components/tag/tag.ts b/packages/webawesome/src/components/tag/tag.ts
index d2d1fbbe2..f72bf5b14 100644
--- a/packages/webawesome/src/components/tag/tag.ts
+++ b/packages/webawesome/src/components/tag/tag.ts
@@ -2,11 +2,11 @@ import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { WaRemoveEvent } from '../../events/remove.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
-import sizeStyles from '../../styles/utilities/size.css';
-import variantStyles from '../../styles/utilities/variants.css';
+import sizeStyles from '../../styles/component/size.styles.js';
+import variantStyles from '../../styles/component/variants.styles.js';
import { LocalizeController } from '../../utilities/localize.js';
import '../button/button.js';
-import styles from './tag.css';
+import styles from './tag.styles.js';
/**
* @summary Tags are used as labels to organize things or to indicate a selection.
diff --git a/packages/webawesome/src/components/textarea/textarea.css b/packages/webawesome/src/components/textarea/textarea.css
deleted file mode 100644
index da7091971..000000000
--- a/packages/webawesome/src/components/textarea/textarea.css
+++ /dev/null
@@ -1,120 +0,0 @@
-:host {
- border-width: 0;
-}
-
-.textarea {
- display: grid;
- align-items: center;
- margin: 0;
- border: none;
- outline: none;
- cursor: inherit;
- font: inherit;
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
- border-radius: var(--wa-form-control-border-radius);
- border-style: var(--wa-form-control-border-style);
- border-width: var(--wa-form-control-border-width);
- -webkit-appearance: none;
-
- &:focus-within {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-}
-
-/* Appearance modifiers */
-:host([appearance='outlined']) .textarea {
- background-color: var(--wa-form-control-background-color);
- border-color: var(--wa-form-control-border-color);
-}
-
-:host([appearance='filled']) .textarea {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-color-neutral-fill-quiet);
-}
-
-:host([appearance='filled-outlined']) .textarea {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-color: var(--wa-form-control-border-color);
-}
-
-textarea {
- display: block;
- width: 100%;
- border: none;
- background: transparent;
- font: inherit;
- color: inherit;
- padding: calc(var(--wa-form-control-padding-block) - ((1lh - 1em) / 2)) var(--wa-form-control-padding-inline); /* accounts for the larger line height of textarea content */
- min-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
- box-shadow: none;
- margin: 0;
-
- &::placeholder {
- color: var(--wa-form-control-placeholder-color);
- user-select: none;
- -webkit-user-select: none;
- }
-
- &:autofill {
- &,
- &:hover,
- &:focus,
- &:active {
- box-shadow: none;
- caret-color: var(--wa-form-control-value-color);
- }
- }
-
- &:focus {
- outline: none;
- }
-}
-
-/* Shared textarea and size-adjuster positioning */
-.control,
-.size-adjuster {
- grid-area: 1 / 1 / 2 / 2;
-}
-
-.size-adjuster {
- visibility: hidden;
- pointer-events: none;
- opacity: 0;
- padding: 0;
-}
-
-textarea::-webkit-search-decoration,
-textarea::-webkit-search-cancel-button,
-textarea::-webkit-search-results-button,
-textarea::-webkit-search-results-decoration {
- -webkit-appearance: none;
-}
-
-/*
- * Resize types
- */
-
-:host([resize='none']) textarea {
- resize: none;
-}
-
-textarea,
-:host([resize='vertical']) textarea {
- resize: vertical;
-}
-
-:host([resize='horizontal']) textarea {
- resize: horizontal;
-}
-
-:host([resize='both']) textarea {
- resize: both;
-}
-
-:host([resize='auto']) textarea {
- height: auto;
- resize: none;
- overflow-y: hidden;
-}
diff --git a/packages/webawesome/src/components/textarea/textarea.styles.ts b/packages/webawesome/src/components/textarea/textarea.styles.ts
new file mode 100644
index 000000000..4db3e6e16
--- /dev/null
+++ b/packages/webawesome/src/components/textarea/textarea.styles.ts
@@ -0,0 +1,124 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ border-width: 0;
+ }
+
+ .textarea {
+ display: grid;
+ align-items: center;
+ margin: 0;
+ border: none;
+ outline: none;
+ cursor: inherit;
+ font: inherit;
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ border-radius: var(--wa-form-control-border-radius);
+ border-style: var(--wa-form-control-border-style);
+ border-width: var(--wa-form-control-border-width);
+ -webkit-appearance: none;
+
+ &:focus-within {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+ }
+
+ /* Appearance modifiers */
+ :host([appearance='outlined']) .textarea {
+ background-color: var(--wa-form-control-background-color);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ :host([appearance='filled']) .textarea {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-color-neutral-fill-quiet);
+ }
+
+ :host([appearance='filled-outlined']) .textarea {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-color: var(--wa-form-control-border-color);
+ }
+
+ textarea {
+ display: block;
+ width: 100%;
+ border: none;
+ background: transparent;
+ font: inherit;
+ color: inherit;
+ padding: calc(var(--wa-form-control-padding-block) - ((1lh - 1em) / 2)) var(--wa-form-control-padding-inline); /* accounts for the larger line height of textarea content */
+ min-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
+ box-shadow: none;
+ margin: 0;
+
+ &::placeholder {
+ color: var(--wa-form-control-placeholder-color);
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ &:autofill {
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ box-shadow: none;
+ caret-color: var(--wa-form-control-value-color);
+ }
+ }
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ /* Shared textarea and size-adjuster positioning */
+ .control,
+ .size-adjuster {
+ grid-area: 1 / 1 / 2 / 2;
+ }
+
+ .size-adjuster {
+ visibility: hidden;
+ pointer-events: none;
+ opacity: 0;
+ padding: 0;
+ }
+
+ textarea::-webkit-search-decoration,
+ textarea::-webkit-search-cancel-button,
+ textarea::-webkit-search-results-button,
+ textarea::-webkit-search-results-decoration {
+ -webkit-appearance: none;
+ }
+
+ /*
+ * Resize types
+ */
+
+ :host([resize='none']) textarea {
+ resize: none;
+ }
+
+ textarea,
+ :host([resize='vertical']) textarea {
+ resize: vertical;
+ }
+
+ :host([resize='horizontal']) textarea {
+ resize: horizontal;
+ }
+
+ :host([resize='both']) textarea {
+ resize: both;
+ }
+
+ :host([resize='auto']) textarea {
+ height: auto;
+ resize: none;
+ overflow-y: hidden;
+ }
+`;
diff --git a/packages/webawesome/src/components/textarea/textarea.ts b/packages/webawesome/src/components/textarea/textarea.ts
index 774980f9d..3e7870f7d 100644
--- a/packages/webawesome/src/components/textarea/textarea.ts
+++ b/packages/webawesome/src/components/textarea/textarea.ts
@@ -8,9 +8,9 @@ import { HasSlotController } from '../../internal/slot.js';
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
-import formControlStyles from '../../styles/component/form-control.css';
-import sizeStyles from '../../styles/utilities/size.css';
-import styles from './textarea.css';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import sizeStyles from '../../styles/component/size.styles.js';
+import styles from './textarea.styles.js';
/**
* @summary Textareas collect data from the user and allow multiple lines of text.
diff --git a/packages/webawesome/src/components/tooltip/tooltip.css b/packages/webawesome/src/components/tooltip/tooltip.css
deleted file mode 100644
index 6dc3d2ebc..000000000
--- a/packages/webawesome/src/components/tooltip/tooltip.css
+++ /dev/null
@@ -1,56 +0,0 @@
-:host {
- --max-width: 30ch;
-
- /** These styles are added so we don't interfere in the DOM. */
- display: inline-block;
- position: absolute;
-
- /** Defaults for inherited CSS properties */
- color: var(--wa-tooltip-content-color);
- font-size: var(--wa-tooltip-font-size);
- line-height: var(--wa-tooltip-line-height);
- text-align: start;
- white-space: normal;
-}
-
-.tooltip {
- --arrow-size: var(--wa-tooltip-arrow-size);
- --arrow-color: var(--wa-tooltip-background-color);
-}
-
-.tooltip::part(popup) {
- z-index: 1000;
-}
-
-.tooltip[placement^='top']::part(popup) {
- transform-origin: bottom;
-}
-
-.tooltip[placement^='bottom']::part(popup) {
- transform-origin: top;
-}
-
-.tooltip[placement^='left']::part(popup) {
- transform-origin: right;
-}
-
-.tooltip[placement^='right']::part(popup) {
- transform-origin: left;
-}
-
-.body {
- display: block;
- width: max-content;
- max-width: var(--max-width);
- border-radius: var(--wa-tooltip-border-radius);
- background-color: var(--wa-tooltip-background-color);
- border: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
- padding: 0.25em 0.5em;
- user-select: none;
- -webkit-user-select: none;
-}
-
-.tooltip::part(arrow) {
- border-bottom: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
- border-right: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
-}
diff --git a/packages/webawesome/src/components/tooltip/tooltip.styles.ts b/packages/webawesome/src/components/tooltip/tooltip.styles.ts
new file mode 100644
index 000000000..6bb5be759
--- /dev/null
+++ b/packages/webawesome/src/components/tooltip/tooltip.styles.ts
@@ -0,0 +1,60 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --max-width: 30ch;
+
+ /** These styles are added so we don't interfere in the DOM. */
+ display: inline-block;
+ position: absolute;
+
+ /** Defaults for inherited CSS properties */
+ color: var(--wa-tooltip-content-color);
+ font-size: var(--wa-tooltip-font-size);
+ line-height: var(--wa-tooltip-line-height);
+ text-align: start;
+ white-space: normal;
+ }
+
+ .tooltip {
+ --arrow-size: var(--wa-tooltip-arrow-size);
+ --arrow-color: var(--wa-tooltip-background-color);
+ }
+
+ .tooltip::part(popup) {
+ z-index: 1000;
+ }
+
+ .tooltip[placement^='top']::part(popup) {
+ transform-origin: bottom;
+ }
+
+ .tooltip[placement^='bottom']::part(popup) {
+ transform-origin: top;
+ }
+
+ .tooltip[placement^='left']::part(popup) {
+ transform-origin: right;
+ }
+
+ .tooltip[placement^='right']::part(popup) {
+ transform-origin: left;
+ }
+
+ .body {
+ display: block;
+ width: max-content;
+ max-width: var(--max-width);
+ border-radius: var(--wa-tooltip-border-radius);
+ background-color: var(--wa-tooltip-background-color);
+ border: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
+ padding: 0.25em 0.5em;
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ .tooltip::part(arrow) {
+ border-bottom: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
+ border-right: var(--wa-tooltip-border-width) var(--wa-tooltip-border-style) var(--wa-tooltip-border-color);
+ }
+`;
diff --git a/packages/webawesome/src/components/tooltip/tooltip.ts b/packages/webawesome/src/components/tooltip/tooltip.ts
index abbbcfd85..db5d6bebd 100644
--- a/packages/webawesome/src/components/tooltip/tooltip.ts
+++ b/packages/webawesome/src/components/tooltip/tooltip.ts
@@ -11,7 +11,7 @@ import { uniqueId } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import WaPopup from '../popup/popup.js';
-import styles from './tooltip.css';
+import styles from './tooltip.styles.js';
/**
* @summary Tooltips display additional information based on a specific action.
diff --git a/packages/webawesome/src/components/tree-item/tree-item.css b/packages/webawesome/src/components/tree-item/tree-item.css
deleted file mode 100644
index a34ed4d3d..000000000
--- a/packages/webawesome/src/components/tree-item/tree-item.css
+++ /dev/null
@@ -1,150 +0,0 @@
-:host {
- --show-duration: 200ms;
- --hide-duration: 200ms;
-
- display: block;
- color: var(--wa-color-text-normal);
- outline: 0;
- z-index: 0;
-}
-
-:host(:focus) {
- outline: none;
-}
-
-slot:not([name])::slotted(wa-icon) {
- margin-inline-end: var(--wa-space-xs);
-}
-
-.tree-item {
- position: relative;
- display: flex;
- align-items: stretch;
- flex-direction: column;
- cursor: default;
- user-select: none;
- -webkit-user-select: none;
-}
-
-.checkbox {
- line-height: var(--wa-form-control-value-line-height);
- pointer-events: none;
-}
-
-.expand-button,
-.checkbox,
-.label {
- font-family: inherit;
- font-size: var(--wa-font-size-m);
- font-weight: inherit;
-}
-
-.checkbox::part(base) {
- display: flex;
- align-items: center;
-}
-
-.indentation {
- display: block;
- width: 1em;
- flex-shrink: 0;
-}
-
-.expand-button {
- display: flex;
- align-items: center;
- justify-content: center;
- color: var(--wa-color-text-quiet);
- width: 2em;
- height: 2em;
- flex-shrink: 0;
- cursor: pointer;
-}
-
-.expand-button {
- transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-.tree-item-expanded .expand-button {
- rotate: 90deg;
-}
-
-.tree-item-expanded:dir(rtl) .expand-button {
- rotate: -90deg;
-}
-
-.tree-item-expanded:not(.tree-item-loading) slot[name='expand-icon'],
-.tree-item:not(.tree-item-expanded) slot[name='collapse-icon'] {
- display: none;
-}
-
-.tree-item:not(.tree-item-has-expand-button):not(.tree-item-loading) .expand-icon-slot {
- display: none;
-}
-
-.tree-item-loading .expand-icon-slot wa-icon {
- display: none;
-}
-
-.expand-button-visible {
- cursor: pointer;
-}
-
-.item {
- display: flex;
- align-items: center;
- border-inline-start: solid 3px transparent;
-}
-
-:host([disabled]) .item {
- opacity: 0.5;
- outline: none;
- cursor: not-allowed;
-}
-
-:host(:focus-visible) .item {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- z-index: 2;
-}
-
-:host(:not([aria-disabled='true'])) .tree-item-selected .item {
- background-color: var(--wa-color-neutral-fill-quiet);
- border-inline-start-color: var(--wa-color-brand-fill-loud);
-}
-
-:host(:not([aria-disabled='true'])) .expand-button {
- color: var(--wa-color-text-quiet);
-}
-
-.label {
- display: flex;
- align-items: center;
- transition: color var(--wa-transition-normal) var(--wa-transition-easing);
-}
-
-.children {
- display: block;
- font-size: calc(1em + var(--indent-size, var(--wa-space-m)));
-}
-
-/* Indentation lines */
-.children {
- position: relative;
-}
-
-.children::before {
- content: '';
- position: absolute;
- top: var(--indent-guide-offset);
- bottom: var(--indent-guide-offset);
- inset-inline-start: calc(1em - (var(--indent-guide-width) / 2) - 1px);
- border-inline-end: var(--indent-guide-width) var(--indent-guide-style) var(--indent-guide-color);
- z-index: 1;
-}
-
-@media (forced-colors: active) {
- :host(:not([aria-disabled='true'])) .tree-item-selected .item {
- outline: dashed 1px SelectedItem;
- }
-}
diff --git a/packages/webawesome/src/components/tree-item/tree-item.styles.ts b/packages/webawesome/src/components/tree-item/tree-item.styles.ts
new file mode 100644
index 000000000..e2c49c6fc
--- /dev/null
+++ b/packages/webawesome/src/components/tree-item/tree-item.styles.ts
@@ -0,0 +1,154 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ --show-duration: 200ms;
+ --hide-duration: 200ms;
+
+ display: block;
+ color: var(--wa-color-text-normal);
+ outline: 0;
+ z-index: 0;
+ }
+
+ :host(:focus) {
+ outline: none;
+ }
+
+ slot:not([name])::slotted(wa-icon) {
+ margin-inline-end: var(--wa-space-xs);
+ }
+
+ .tree-item {
+ position: relative;
+ display: flex;
+ align-items: stretch;
+ flex-direction: column;
+ cursor: default;
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ .checkbox {
+ line-height: var(--wa-form-control-value-line-height);
+ pointer-events: none;
+ }
+
+ .expand-button,
+ .checkbox,
+ .label {
+ font-family: inherit;
+ font-size: var(--wa-font-size-m);
+ font-weight: inherit;
+ }
+
+ .checkbox::part(base) {
+ display: flex;
+ align-items: center;
+ }
+
+ .indentation {
+ display: block;
+ width: 1em;
+ flex-shrink: 0;
+ }
+
+ .expand-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--wa-color-text-quiet);
+ width: 2em;
+ height: 2em;
+ flex-shrink: 0;
+ cursor: pointer;
+ }
+
+ .expand-button {
+ transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ .tree-item-expanded .expand-button {
+ rotate: 90deg;
+ }
+
+ .tree-item-expanded:dir(rtl) .expand-button {
+ rotate: -90deg;
+ }
+
+ .tree-item-expanded:not(.tree-item-loading) slot[name='expand-icon'],
+ .tree-item:not(.tree-item-expanded) slot[name='collapse-icon'] {
+ display: none;
+ }
+
+ .tree-item:not(.tree-item-has-expand-button):not(.tree-item-loading) .expand-icon-slot {
+ display: none;
+ }
+
+ .tree-item-loading .expand-icon-slot wa-icon {
+ display: none;
+ }
+
+ .expand-button-visible {
+ cursor: pointer;
+ }
+
+ .item {
+ display: flex;
+ align-items: center;
+ border-inline-start: solid 3px transparent;
+ }
+
+ :host([disabled]) .item {
+ opacity: 0.5;
+ outline: none;
+ cursor: not-allowed;
+ }
+
+ :host(:focus-visible) .item {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ z-index: 2;
+ }
+
+ :host(:not([aria-disabled='true'])) .tree-item-selected .item {
+ background-color: var(--wa-color-neutral-fill-quiet);
+ border-inline-start-color: var(--wa-color-brand-fill-loud);
+ }
+
+ :host(:not([aria-disabled='true'])) .expand-button {
+ color: var(--wa-color-text-quiet);
+ }
+
+ .label {
+ display: flex;
+ align-items: center;
+ transition: color var(--wa-transition-normal) var(--wa-transition-easing);
+ }
+
+ .children {
+ display: block;
+ font-size: calc(1em + var(--indent-size, var(--wa-space-m)));
+ }
+
+ /* Indentation lines */
+ .children {
+ position: relative;
+ }
+
+ .children::before {
+ content: '';
+ position: absolute;
+ top: var(--indent-guide-offset);
+ bottom: var(--indent-guide-offset);
+ inset-inline-start: calc(1em - (var(--indent-guide-width) / 2) - 1px);
+ border-inline-end: var(--indent-guide-width) var(--indent-guide-style) var(--indent-guide-color);
+ z-index: 1;
+ }
+
+ @media (forced-colors: active) {
+ :host(:not([aria-disabled='true'])) .tree-item-selected .item {
+ outline: dashed 1px SelectedItem;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/tree-item/tree-item.ts b/packages/webawesome/src/components/tree-item/tree-item.ts
index dc15888d6..2a1ff4cf0 100644
--- a/packages/webawesome/src/components/tree-item/tree-item.ts
+++ b/packages/webawesome/src/components/tree-item/tree-item.ts
@@ -17,7 +17,7 @@ import { LocalizeController } from '../../utilities/localize.js';
import '../checkbox/checkbox.js';
import '../icon/icon.js';
import '../spinner/spinner.js';
-import styles from './tree-item.css';
+import styles from './tree-item.styles.js';
/**
* @summary A tree item serves as a hierarchical node that lives inside a [tree](/docs/components/tree).
diff --git a/packages/webawesome/src/components/tree/tree.css b/packages/webawesome/src/components/tree/tree.styles.ts
similarity index 53%
rename from packages/webawesome/src/components/tree/tree.css
rename to packages/webawesome/src/components/tree/tree.styles.ts
index b5ca3878e..666100ae2 100644
--- a/packages/webawesome/src/components/tree/tree.css
+++ b/packages/webawesome/src/components/tree/tree.styles.ts
@@ -1,19 +1,23 @@
-:host {
- /*
+import { css } from 'lit';
+
+export default css`
+ :host {
+ /*
* These are actually used by tree item, but we define them here so they can more easily be set and all tree items
* stay consistent.
*/
- --indent-guide-color: var(--wa-color-surface-border);
- --indent-guide-offset: 0;
- --indent-guide-style: solid;
- --indent-guide-width: 0;
- --indent-size: var(--wa-space-l);
+ --indent-guide-color: var(--wa-color-surface-border);
+ --indent-guide-offset: 0;
+ --indent-guide-style: solid;
+ --indent-guide-width: 0;
+ --indent-size: var(--wa-space-l);
- display: block;
+ display: block;
- /*
+ /*
* Tree item indentation uses the "em" unit to increment its width on each level, so setting the font size to zero
* here removes the indentation for all the nodes on the first level.
*/
- font-size: 0;
-}
+ font-size: 0;
+ }
+`;
diff --git a/packages/webawesome/src/components/tree/tree.ts b/packages/webawesome/src/components/tree/tree.ts
index e82dab664..762cb7d44 100644
--- a/packages/webawesome/src/components/tree/tree.ts
+++ b/packages/webawesome/src/components/tree/tree.ts
@@ -6,7 +6,7 @@ import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import WaTreeItem from '../tree-item/tree-item.js';
-import styles from './tree.css';
+import styles from './tree.styles.js';
function syncCheckboxes(changedTreeItem: WaTreeItem, initialSync = false) {
function syncParentItem(treeItem: WaTreeItem) {
diff --git a/packages/webawesome/src/components/zoomable-frame/zoomable-frame.css b/packages/webawesome/src/components/zoomable-frame/zoomable-frame.css
deleted file mode 100644
index fbd1af03b..000000000
--- a/packages/webawesome/src/components/zoomable-frame/zoomable-frame.css
+++ /dev/null
@@ -1,82 +0,0 @@
-:host {
- display: block;
- position: relative;
- aspect-ratio: 16 / 9;
- width: 100%;
- overflow: hidden;
- border-radius: var(--wa-border-radius-m);
-}
-
-#frame-container {
- position: absolute;
- top: 0;
- left: 0;
- width: calc(100% / var(--zoom));
- height: calc(100% / var(--zoom));
- transform: scale(var(--zoom));
- transform-origin: 0 0;
-}
-
-#iframe {
- width: 100%;
- height: 100%;
- border: none;
- border-radius: inherit;
- /* Prevent the iframe from being selected, e.g. by a double click. Doesn't affect selection withing the iframe. */
- user-select: none;
- -webkit-user-select: none;
-}
-
-#controls {
- display: flex;
- position: absolute;
- bottom: 0.5em;
- align-items: center;
- font-weight: var(--wa-font-weight-semibold);
- padding: 0.25em 0.5em;
- gap: 0.5em;
- border-radius: var(--wa-border-radius-s);
- background: #000b;
- color: white;
- font-size: min(12px, 0.75em);
- user-select: none;
- -webkit-user-select: none;
-
- &:dir(ltr) {
- right: 0.5em;
- }
-
- &:dir(rtl) {
- left: 0.5em;
- }
-
- button {
- display: flex;
- align-items: center;
- padding: 0.25em;
- border: none;
- background: none;
- color: inherit;
- cursor: pointer;
-
- &:focus {
- outline: none;
- }
-
- &:focus-visible {
- outline: var(--wa-focus-ring);
- outline-offset: var(--wa-focus-ring-offset);
- }
-
- &:disabled {
- cursor: not-allowed;
- opacity: 0.5;
- }
- }
-
- span {
- min-width: 4.5ch; /* extra space so numbers don't shift */
- font-variant-numeric: tabular-nums;
- text-align: center;
- }
-}
diff --git a/packages/webawesome/src/components/zoomable-frame/zoomable-frame.styles.ts b/packages/webawesome/src/components/zoomable-frame/zoomable-frame.styles.ts
new file mode 100644
index 000000000..a40151dec
--- /dev/null
+++ b/packages/webawesome/src/components/zoomable-frame/zoomable-frame.styles.ts
@@ -0,0 +1,86 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: block;
+ position: relative;
+ aspect-ratio: 16 / 9;
+ width: 100%;
+ overflow: hidden;
+ border-radius: var(--wa-border-radius-m);
+ }
+
+ #frame-container {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: calc(100% / var(--zoom));
+ height: calc(100% / var(--zoom));
+ transform: scale(var(--zoom));
+ transform-origin: 0 0;
+ }
+
+ #iframe {
+ width: 100%;
+ height: 100%;
+ border: none;
+ border-radius: inherit;
+ /* Prevent the iframe from being selected, e.g. by a double click. Doesn't affect selection withing the iframe. */
+ user-select: none;
+ -webkit-user-select: none;
+ }
+
+ #controls {
+ display: flex;
+ position: absolute;
+ bottom: 0.5em;
+ align-items: center;
+ font-weight: var(--wa-font-weight-semibold);
+ padding: 0.25em 0.5em;
+ gap: 0.5em;
+ border-radius: var(--wa-border-radius-s);
+ background: #000b;
+ color: white;
+ font-size: min(12px, 0.75em);
+ user-select: none;
+ -webkit-user-select: none;
+
+ &:dir(ltr) {
+ right: 0.5em;
+ }
+
+ &:dir(rtl) {
+ left: 0.5em;
+ }
+
+ button {
+ display: flex;
+ align-items: center;
+ padding: 0.25em;
+ border: none;
+ background: none;
+ color: inherit;
+ cursor: pointer;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:focus-visible {
+ outline: var(--wa-focus-ring);
+ outline-offset: var(--wa-focus-ring-offset);
+ }
+
+ &:disabled {
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+ }
+
+ span {
+ min-width: 4.5ch; /* extra space so numbers don't shift */
+ font-variant-numeric: tabular-nums;
+ text-align: center;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/components/zoomable-frame/zoomable-frame.ts b/packages/webawesome/src/components/zoomable-frame/zoomable-frame.ts
index 6414d6313..1b2854e87 100644
--- a/packages/webawesome/src/components/zoomable-frame/zoomable-frame.ts
+++ b/packages/webawesome/src/components/zoomable-frame/zoomable-frame.ts
@@ -5,7 +5,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { parseSpaceDelimitedTokens } from '../../internal/parse.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
-import styles from './zoomable-frame.css';
+import styles from './zoomable-frame.styles.js';
/**
* @summary Zoomable frames render iframe content with zoom and interaction controls.
diff --git a/packages/webawesome/src/internal/webawesome-element.ts b/packages/webawesome/src/internal/webawesome-element.ts
index 68faf36e1..ef0e54fd5 100644
--- a/packages/webawesome/src/internal/webawesome-element.ts
+++ b/packages/webawesome/src/internal/webawesome-element.ts
@@ -1,13 +1,13 @@
-import type { CSSResult, CSSResultGroup, PropertyValues } from 'lit';
-import { LitElement, isServer, unsafeCSS } from 'lit';
+import type { CSSResultGroup, PropertyValues } from 'lit';
+import { LitElement, isServer } from 'lit';
import { property } from 'lit/decorators.js';
-import hostStyles from '../styles/component/host.css';
+import hostStyles from '../styles/component/host.styles.js';
// Augment Lit's module
declare module 'lit' {
interface PropertyDeclaration {
/**
- * Specifies the property’s default value
+ * Specifies the property's default value
*/
default?: any;
initial?: any;
@@ -15,20 +15,13 @@ declare module 'lit' {
}
export default class WebAwesomeElement extends LitElement {
- /**
- * One or more CSS files to include in the component's shadow root. Host styles are automatically prepended. We use
- * this instead of Lit's styles property because we're importing CSS files as strings and need to convert them using
- * unsafeCSS.
- */
- static css?: CSSResultGroup | CSSResult | string | (CSSResult | string)[];
+ /** One or more CSSResultGroup to include in the component's shadow root. Host styles are automatically prepended. */
+ static css?: CSSResultGroup;
- /**
- * Override the default styles property to fetch and convert string CSS files. Components can override this behavior
- * by setting their own `static styles = []` property.
- */
+ /** Prepends host styles to the component's styles. */
static get styles(): CSSResultGroup {
const styles = Array.isArray(this.css) ? this.css : this.css ? [this.css] : [];
- return [hostStyles, ...styles].map(style => (typeof style === 'string' ? unsafeCSS(style) : style));
+ return [hostStyles, ...styles];
}
#hasRecordedInitialProperties = false;
diff --git a/packages/webawesome/src/styles/component/form-control.css b/packages/webawesome/src/styles/component/form-control.css
deleted file mode 100644
index f9e1efb77..000000000
--- a/packages/webawesome/src/styles/component/form-control.css
+++ /dev/null
@@ -1,34 +0,0 @@
-:host {
- display: flex;
- flex-direction: column;
-}
-
-/* Label */
-:is([part~='form-control-label'], [part~='label']):has(*:not(:empty)) {
- display: inline-flex;
- color: var(--wa-form-control-label-color);
- font-weight: var(--wa-form-control-label-font-weight);
- line-height: var(--wa-form-control-label-line-height);
- margin-block-end: 0.5em;
-}
-
-:host([required]) :is([part~='form-control-label'], [part~='label'])::after {
- content: var(--wa-form-control-required-content);
- margin-inline-start: var(--wa-form-control-required-content-offset);
- color: var(--wa-form-control-required-content-color);
-}
-
-/* Help text */
-[part~='hint'] {
- display: block;
- color: var(--wa-form-control-hint-color);
- font-weight: var(--wa-form-control-hint-font-weight);
- line-height: var(--wa-form-control-hint-line-height);
- margin-block-start: 0.5em;
- font-size: var(--wa-font-size-smaller);
- line-height: var(--wa-form-control-label-line-height);
-
- &:not(.has-slotted) {
- display: none;
- }
-}
diff --git a/packages/webawesome/src/styles/component/form-control.styles.ts b/packages/webawesome/src/styles/component/form-control.styles.ts
new file mode 100644
index 000000000..461d732e5
--- /dev/null
+++ b/packages/webawesome/src/styles/component/form-control.styles.ts
@@ -0,0 +1,38 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* Label */
+ :is([part~='form-control-label'], [part~='label']):has(*:not(:empty)) {
+ display: inline-flex;
+ color: var(--wa-form-control-label-color);
+ font-weight: var(--wa-form-control-label-font-weight);
+ line-height: var(--wa-form-control-label-line-height);
+ margin-block-end: 0.5em;
+ }
+
+ :host([required]) :is([part~='form-control-label'], [part~='label'])::after {
+ content: var(--wa-form-control-required-content);
+ margin-inline-start: var(--wa-form-control-required-content-offset);
+ color: var(--wa-form-control-required-content-color);
+ }
+
+ /* Help text */
+ [part~='hint'] {
+ display: block;
+ color: var(--wa-form-control-hint-color);
+ font-weight: var(--wa-form-control-hint-font-weight);
+ line-height: var(--wa-form-control-hint-line-height);
+ margin-block-start: 0.5em;
+ font-size: var(--wa-font-size-smaller);
+ line-height: var(--wa-form-control-label-line-height);
+
+ &:not(.has-slotted) {
+ display: none;
+ }
+ }
+`;
diff --git a/packages/webawesome/src/styles/component/host.css b/packages/webawesome/src/styles/component/host.css
deleted file mode 100644
index 7239526e1..000000000
--- a/packages/webawesome/src/styles/component/host.css
+++ /dev/null
@@ -1,13 +0,0 @@
-:host {
- box-sizing: border-box !important;
-}
-
-:host *,
-:host *::before,
-:host *::after {
- box-sizing: inherit !important;
-}
-
-[hidden] {
- display: none !important;
-}
diff --git a/packages/webawesome/src/styles/component/host.styles.ts b/packages/webawesome/src/styles/component/host.styles.ts
new file mode 100644
index 000000000..510b37dbd
--- /dev/null
+++ b/packages/webawesome/src/styles/component/host.styles.ts
@@ -0,0 +1,17 @@
+import { css } from 'lit';
+
+export default css`
+ :host {
+ box-sizing: border-box !important;
+ }
+
+ :host *,
+ :host *::before,
+ :host *::after {
+ box-sizing: inherit !important;
+ }
+
+ [hidden] {
+ display: none !important;
+ }
+`;
diff --git a/packages/webawesome/src/styles/component/size.styles.ts b/packages/webawesome/src/styles/component/size.styles.ts
new file mode 100644
index 000000000..2b06e5862
--- /dev/null
+++ b/packages/webawesome/src/styles/component/size.styles.ts
@@ -0,0 +1,18 @@
+import { css } from 'lit';
+
+export default css`
+ :host([size='small']),
+ .wa-size-s {
+ font-size: var(--wa-font-size-s);
+ }
+
+ :host([size='medium']),
+ .wa-size-m {
+ font-size: var(--wa-font-size-m);
+ }
+
+ :host([size='large']),
+ .wa-size-l {
+ font-size: var(--wa-font-size-l);
+ }
+`;
diff --git a/packages/webawesome/src/styles/component/variants.styles.ts b/packages/webawesome/src/styles/component/variants.styles.ts
new file mode 100644
index 000000000..2498610ad
--- /dev/null
+++ b/packages/webawesome/src/styles/component/variants.styles.ts
@@ -0,0 +1,69 @@
+import { css } from 'lit';
+
+export default css`
+ :where(:root),
+ .wa-neutral,
+ :host([variant='neutral']) {
+ --wa-color-fill-loud: var(--wa-color-neutral-fill-loud);
+ --wa-color-fill-normal: var(--wa-color-neutral-fill-normal);
+ --wa-color-fill-quiet: var(--wa-color-neutral-fill-quiet);
+ --wa-color-border-loud: var(--wa-color-neutral-border-loud);
+ --wa-color-border-normal: var(--wa-color-neutral-border-normal);
+ --wa-color-border-quiet: var(--wa-color-neutral-border-quiet);
+ --wa-color-on-loud: var(--wa-color-neutral-on-loud);
+ --wa-color-on-normal: var(--wa-color-neutral-on-normal);
+ --wa-color-on-quiet: var(--wa-color-neutral-on-quiet);
+ }
+
+ .wa-brand,
+ :host([variant='brand']) {
+ --wa-color-fill-loud: var(--wa-color-brand-fill-loud);
+ --wa-color-fill-normal: var(--wa-color-brand-fill-normal);
+ --wa-color-fill-quiet: var(--wa-color-brand-fill-quiet);
+ --wa-color-border-loud: var(--wa-color-brand-border-loud);
+ --wa-color-border-normal: var(--wa-color-brand-border-normal);
+ --wa-color-border-quiet: var(--wa-color-brand-border-quiet);
+ --wa-color-on-loud: var(--wa-color-brand-on-loud);
+ --wa-color-on-normal: var(--wa-color-brand-on-normal);
+ --wa-color-on-quiet: var(--wa-color-brand-on-quiet);
+ }
+
+ .wa-success,
+ :host([variant='success']) {
+ --wa-color-fill-loud: var(--wa-color-success-fill-loud);
+ --wa-color-fill-normal: var(--wa-color-success-fill-normal);
+ --wa-color-fill-quiet: var(--wa-color-success-fill-quiet);
+ --wa-color-border-loud: var(--wa-color-success-border-loud);
+ --wa-color-border-normal: var(--wa-color-success-border-normal);
+ --wa-color-border-quiet: var(--wa-color-success-border-quiet);
+ --wa-color-on-loud: var(--wa-color-success-on-loud);
+ --wa-color-on-normal: var(--wa-color-success-on-normal);
+ --wa-color-on-quiet: var(--wa-color-success-on-quiet);
+ }
+
+ .wa-warning,
+ :host([variant='warning']) {
+ --wa-color-fill-loud: var(--wa-color-warning-fill-loud);
+ --wa-color-fill-normal: var(--wa-color-warning-fill-normal);
+ --wa-color-fill-quiet: var(--wa-color-warning-fill-quiet);
+ --wa-color-border-loud: var(--wa-color-warning-border-loud);
+ --wa-color-border-normal: var(--wa-color-warning-border-normal);
+ --wa-color-border-quiet: var(--wa-color-warning-border-quiet);
+ --wa-color-on-loud: var(--wa-color-warning-on-loud);
+ --wa-color-on-normal: var(--wa-color-warning-on-normal);
+ --wa-color-on-quiet: var(--wa-color-warning-on-quiet);
+ }
+
+ .wa-danger,
+ :host([variant='danger']) {
+ --wa-color-fill-loud: var(--wa-color-danger-fill-loud);
+ --wa-color-fill-normal: var(--wa-color-danger-fill-normal);
+ --wa-color-fill-quiet: var(--wa-color-danger-fill-quiet);
+ --wa-color-border-loud: var(--wa-color-danger-border-loud);
+ --wa-color-border-normal: var(--wa-color-danger-border-normal);
+ --wa-color-border-quiet: var(--wa-color-danger-border-quiet);
+ --wa-color-on-loud: var(--wa-color-danger-on-loud);
+ --wa-color-on-normal: var(--wa-color-danger-on-normal);
+ --wa-color-on-quiet: var(--wa-color-danger-on-quiet);
+ }
+`;
diff --git a/packages/webawesome/src/styles/component/visually-hidden.styles.ts b/packages/webawesome/src/styles/component/visually-hidden.styles.ts
new file mode 100644
index 000000000..866bae7a7
--- /dev/null
+++ b/packages/webawesome/src/styles/component/visually-hidden.styles.ts
@@ -0,0 +1,18 @@
+import { css } from 'lit';
+
+export default css`
+ .wa-visually-hidden:not(:focus-within),
+ .wa-visually-hidden-force,
+ .wa-visually-hidden-hint::part(hint),
+ .wa-visually-hidden-label::part(label) {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ clip: rect(0 0 0 0) !important;
+ clip-path: inset(50%) !important;
+ border: none !important;
+ overflow: hidden !important;
+ white-space: nowrap !important;
+ padding: 0 !important;
+ }
+`;
diff --git a/packages/webawesome/src/styles/utilities/size.css b/packages/webawesome/src/styles/utilities/size.css
index ca8a43f36..6ad984091 100644
--- a/packages/webawesome/src/styles/utilities/size.css
+++ b/packages/webawesome/src/styles/utilities/size.css
@@ -1,15 +1,12 @@
@layer wa-utilities {
- :host([size='small']),
.wa-size-s {
font-size: var(--wa-font-size-s);
}
- :host([size='medium']),
.wa-size-m {
font-size: var(--wa-font-size-m);
}
- :host([size='large']),
.wa-size-l {
font-size: var(--wa-font-size-l);
}
diff --git a/packages/webawesome/src/styles/utilities/variants.css b/packages/webawesome/src/styles/utilities/variants.css
index df7eb08ec..b93da35a3 100644
--- a/packages/webawesome/src/styles/utilities/variants.css
+++ b/packages/webawesome/src/styles/utilities/variants.css
@@ -1,7 +1,6 @@
@layer wa-utilities {
:where(:root),
- .wa-neutral,
- :host([variant='neutral']) {
+ .wa-neutral {
--wa-color-fill-loud: var(--wa-color-neutral-fill-loud);
--wa-color-fill-normal: var(--wa-color-neutral-fill-normal);
--wa-color-fill-quiet: var(--wa-color-neutral-fill-quiet);
@@ -13,8 +12,7 @@
--wa-color-on-quiet: var(--wa-color-neutral-on-quiet);
}
- .wa-brand,
- :host([variant='brand']) {
+ .wa-brand {
--wa-color-fill-loud: var(--wa-color-brand-fill-loud);
--wa-color-fill-normal: var(--wa-color-brand-fill-normal);
--wa-color-fill-quiet: var(--wa-color-brand-fill-quiet);
@@ -26,8 +24,7 @@
--wa-color-on-quiet: var(--wa-color-brand-on-quiet);
}
- .wa-success,
- :host([variant='success']) {
+ .wa-success {
--wa-color-fill-loud: var(--wa-color-success-fill-loud);
--wa-color-fill-normal: var(--wa-color-success-fill-normal);
--wa-color-fill-quiet: var(--wa-color-success-fill-quiet);
@@ -39,8 +36,7 @@
--wa-color-on-quiet: var(--wa-color-success-on-quiet);
}
- .wa-warning,
- :host([variant='warning']) {
+ .wa-warning {
--wa-color-fill-loud: var(--wa-color-warning-fill-loud);
--wa-color-fill-normal: var(--wa-color-warning-fill-normal);
--wa-color-fill-quiet: var(--wa-color-warning-fill-quiet);
@@ -52,8 +48,7 @@
--wa-color-on-quiet: var(--wa-color-warning-on-quiet);
}
- .wa-danger,
- :host([variant='danger']) {
+ .wa-danger {
--wa-color-fill-loud: var(--wa-color-danger-fill-loud);
--wa-color-fill-normal: var(--wa-color-danger-fill-normal);
--wa-color-fill-quiet: var(--wa-color-danger-fill-quiet);