Compare commits

..

3 Commits

Author SHA1 Message Date
Lea Verou
4a7fd7964f Update callout.css 2024-12-11 17:35:01 -05:00
Lea Verou
5a683300b2 Convert viewport-demo and callout styles 2024-12-11 16:56:49 -05:00
Lea Verou
20321f84d9 Start integrating esbuild-plugin-lit-css 2024-12-11 16:56:01 -05:00
178 changed files with 8659 additions and 5960 deletions

10
.eslintignore Normal file
View File

@@ -0,0 +1,10 @@
.cache
docs/dist
docs/search.json
docs/**/*.min.js
dist
examples
node_modules
src/react
scripts

213
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,213 @@
/* eslint-env node */
module.exports = {
plugins: [
'@typescript-eslint',
'wc',
'lit',
'lit-a11y',
'chai-expect',
'chai-friendly',
'import',
'sort-imports-es6-autofix'
],
extends: [
'eslint:recommended',
'plugin:wc/recommended',
'plugin:wc/best-practice',
'plugin:lit/recommended',
'plugin:lit-a11y/recommended'
],
env: {
es2021: true,
browser: true
},
parserOptions: {
sourceType: 'module'
},
overrides: [
{
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking'
],
parser: '@typescript-eslint/parser',
parserOptions: {
sourceType: 'module',
project: './tsconfig.json',
tsconfigRootDir: __dirname
},
files: ['*.ts'],
rules: {
'default-param-last': 'off',
'@typescript-eslint/default-param-last': 'error',
'no-console': 'warn',
'no-empty-function': 'off',
'@typescript-eslint/no-empty-function': 'warn',
'no-implied-eval': 'off',
'no-invalid-this': 'off',
'no-shadow': 'off',
'no-throw-literal': 'off',
'no-unused-expressions': 'off',
'lit-a11y/no-autofocus': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-invalid-this': 'error',
'@typescript-eslint/no-throw-literal': 'error',
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/prefer-regexp-exec': 'off',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: false
}
],
'@typescript-eslint/consistent-type-assertions': [
'warn',
{
assertionStyle: 'as',
objectLiteralTypeAssertions: 'never'
}
],
'@typescript-eslint/consistent-type-imports': 'warn',
'@typescript-eslint/no-base-to-string': 'error',
'@typescript-eslint/no-confusing-non-null-assertion': 'error',
'@typescript-eslint/no-invalid-void-type': 'error',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn',
'@typescript-eslint/no-unnecessary-condition': 'off',
'@typescript-eslint/no-unnecessary-qualifier': 'warn',
'@typescript-eslint/non-nullable-type-assertion-style': 'warn',
'@typescript-eslint/prefer-for-of': 'warn',
'@typescript-eslint/prefer-optional-chain': 'warn',
'@typescript-eslint/prefer-ts-expect-error': 'warn',
'@typescript-eslint/prefer-return-this-type': 'error',
'@typescript-eslint/prefer-string-starts-ends-with': 'warn',
'@typescript-eslint/require-array-sort-compare': 'error',
'@typescript-eslint/unified-signatures': 'warn',
'@typescript-eslint/array-type': 'warn',
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
'@typescript-eslint/member-delimiter-style': 'warn',
'@typescript-eslint/method-signature-style': 'warn',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/parameter-properties': 'error',
'@typescript-eslint/strict-boolean-expressions': 'off'
}
},
{
files: ['**/*.cjs'],
env: {
node: true
}
},
{
extends: ['plugin:chai-expect/recommended', 'plugin:chai-friendly/recommended'],
files: ['*.test.ts'],
rules: {
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unused-expressions': 'off'
}
}
],
rules: {
'no-template-curly-in-string': 'error',
'array-callback-return': 'error',
'comma-dangle': 'off',
'consistent-return': 'error',
curly: 'off',
'default-param-last': 'error',
eqeqeq: 'error',
'lit-a11y/click-events-have-key-events': 'off',
'no-constructor-return': 'error',
'no-empty-function': 'warn',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-floating-decimal': 'error',
'no-implicit-coercion': 'off',
'no-implicit-globals': 'error',
'no-implied-eval': 'error',
'no-invalid-this': 'off',
'no-labels': 'error',
'no-lone-blocks': 'error',
'no-new': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-return-assign': 'warn',
'no-script-url': 'error',
'no-self-compare': 'warn',
'no-sequences': 'warn',
'no-throw-literal': 'error',
'no-unmodified-loop-condition': 'error',
'no-unused-expressions': 'warn',
'no-useless-call': 'error',
'no-useless-concat': 'error',
'no-useless-return': 'warn',
'prefer-promise-reject-errors': 'error',
radix: 'off',
'require-await': 'error',
'wrap-iife': ['warn', 'inside'],
'no-shadow': 'error',
'no-array-constructor': 'error',
'no-bitwise': 'error',
'no-multi-assign': 'warn',
'no-new-object': 'error',
'no-useless-computed-key': 'warn',
'no-useless-rename': 'warn',
'no-var': 'error',
'prefer-const': 'warn',
'prefer-numeric-literals': 'warn',
'prefer-object-spread': 'warn',
'prefer-rest-params': 'warn',
'prefer-spread': 'warn',
'prefer-template': 'off',
'no-else-return': 'off',
'func-names': ['warn', 'never'],
'one-var': ['warn', 'never'],
'operator-assignment': 'warn',
'prefer-arrow-callback': 'warn',
'no-restricted-imports': [
'warn',
{
paths: [
{
name: '.',
message: 'Usage of local index imports is not allowed.'
},
{
name: './index',
message: 'Import from the source file instead.'
}
]
}
],
'import/extensions': [
'error',
'always',
{
ignorePackages: true,
pattern: {
js: 'always',
ts: 'never'
}
}
],
'import/no-duplicates': 'warn',
'sort-imports-es6-autofix/sort-imports-es6': [
2,
{
ignoreCase: true,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single']
}
],
'wc/guard-super-call': 'off'
}
};

View File

@@ -455,7 +455,6 @@ wa-page > main:has(> .index-grid) {
.table-scroll {
overflow-x: auto;
margin-block-end: var(--wa-flow-spacing);
}
/** mobile */

View File

@@ -103,11 +103,11 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
<a href="#conservation">Conservation</a>
</nav>
<nav slot="navigation-footer">
<a href="#" class="wa-flank">
<a href="#" class="wa-flank" style="--flank-size: 1.25em;">
<wa-icon name="camera"></wa-icon>
<span>Photo Gallery</span>
</a>
<a href="#" class="wa-flank">
<a href="#" class="wa-flank" style="--flank-size: 1.25em;">
<wa-icon name="map-location-dot"></wa-icon>
<span>Interactive Range Map</span>
</a>
@@ -227,26 +227,18 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
--menu-width: 15rem;
--aside-width: 15rem;
}
wa-page[view='desktop'] {
[data-toggle-nav] {
display: none;
}
[slot*='navigation'] {
border-inline-end: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
wa-page[view='desktop'] [data-toggle-nav] {
display: none;
}
wa-page[view='mobile'] {
--menu-width: auto;
--aside-width: auto;
[slot='aside'],
#brand-name,
#search {
display: none;
}
}
wa-page[view='mobile'] [slot='aside'],
wa-page[view='mobile'] #brand-name,
wa-page[view='mobile'] #search {
display: none;
}
[slot='banner'] {
--wa-color-text-link: var(--wa-color-neutral-on-loud);
background-color: var(--wa-color-neutral-fill-loud);
@@ -265,16 +257,15 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
[slot='navigation-header'] {
border-block-end: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
wa-page[view='desktop'] [slot*='navigation'] {
border-inline-end: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
[slot*='navigation'] a {
--wa-color-text-link: var(--wa-color-text-normal);
}
[slot='navigation-footer'] {
border-block-start: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
[slot='navigation-footer'] .wa-flank {
--flank-size: 1.25em;
}
[slot='main-header'],
main,
[slot='main-footer'] {
@@ -290,11 +281,6 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
font-size: var(--wa-font-size-s);
}
</style>
<script>
const sectionAnchors = document.querySelectorAll("[slot*='navigation'] a[href*='#']");
sectionAnchors.forEach((sectionAnchor) => sectionAnchor.setAttribute("data-drawer", "close"));
</script>
```
### Media
@@ -608,22 +594,18 @@ A sample media app page using `header`, `navigation-header`, `main-header`, and
--wa-tooltip-arrow-size: 0;
background-color: var(--wa-color-surface-lowered);
}
wa-page[view='desktop'] {
:is([data-toggle-nav], #search-nav-drawer) {
display: none;
}
wa-page[view='desktop'] :is([data-toggle-nav], #search-nav-drawer) {
display: none;
}
wa-page[view='mobile'] {
--menu-width: auto;
#search-header {
display: none;
}
[slot*='main'], main {
padding: var(--wa-space-xl);
}
}
wa-page[view='mobile'] #search-header {
display: none;
}
wa-page[view='mobile'] :is([slot*='main'], main) {
padding: var(--wa-space-xl);
}
wa-page,
[slot='header'],
wa-page[view='desktop'] [slot*='navigation'] {
@@ -643,41 +625,37 @@ A sample media app page using `header`, `navigation-header`, `main-header`, and
padding-block-end: 0 !important;
padding-block-start: var(--wa-space-3xl);
}
[slot='navigation'] {
a {
--wa-color-text-link: var(--wa-color-text-normal);
--wa-link-decoration-default: none;
--wa-link-decoration-hover: none;
--flank-size: 2rem;
font-weight: var(--wa-font-weight-action);
gap: 0.5rem;
}
ul {
list-style: none;
margin: 0;
a {
border-radius: var(--wa-border-radius-s);
padding: var(--wa-space-xs);
&:hover {
background-color: color-mix(in oklab, var(--wa-color-surface-default), var(--wa-color-brand-fill-quiet));
}
}
}
wa-icon {
align-items: center;
aspect-ratio: 1;
color: var(--wa-color-brand-fill-loud);
display: flex;
height: var(--flank-size);
justify-content: center;
}
#recent wa-icon {
border-radius: var(--wa-border-radius-xs);
}
[slot='navigation'] a {
--wa-color-text-link: var(--wa-color-text-normal);
--wa-link-decoration-default: none;
--wa-link-decoration-hover: none;
--flank-size: 2rem;
font-weight: var(--wa-font-weight-action);
gap: 0.5rem;
}
[slot='navigation'] ul {
list-style: none;
margin: 0;
}
[slot='navigation'] ul a {
border-radius: var(--wa-border-radius-s);
padding: var(--wa-space-xs);
}
[slot='navigation'] ul a:hover,
main ol li:hover {
background-color: color-mix(in oklab, var(--wa-color-surface-default), var(--wa-color-brand-fill-quiet));
}
[slot='navigation'] wa-icon {
align-items: center;
aspect-ratio: 1;
color: var(--wa-color-brand-fill-loud);
display: flex;
height: var(--flank-size);
justify-content: center;
}
[slot='navigation'] #recent wa-icon {
border-radius: var(--wa-border-radius-xs);
}
[slot='main-header'] {
border-block-start: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
border-inline: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
@@ -689,18 +667,12 @@ A sample media app page using `header`, `navigation-header`, `main-header`, and
}
main ol li {
padding: var(--wa-space-m);
&:hover {
background-color: color-mix(in oklab, var(--wa-color-surface-default), var(--wa-color-brand-fill-quiet));
}
&:not(:first-child) {
border-block-start: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
.wa-flank {
--flank-size: 2rem;
}
}
main ol li .wa-flank {
--flank-size: 2rem;
}
main ol li:not(:first-child) {
border-block-start: var(--wa-border-width-s) var(--wa-border-style) var(--wa-color-surface-border);
}
main,
[slot='main-footer'] {
@@ -726,11 +698,6 @@ A sample media app page using `header`, `navigation-header`, `main-header`, and
max-inline-size: 30ch;
}
</style>
<script>
const sectionAnchors = document.querySelectorAll("[slot*='navigation'] a[href*='#']");
sectionAnchors.forEach((sectionAnchor) => sectionAnchor.setAttribute("data-drawer", "close"));
</script>
```
@@ -794,29 +761,11 @@ You can override the default display and flex properties for each slot with your
#### Responsive Navigation
When you use the `navigation` slot, your slotted content automatically collapses into a drawer on smaller screens.
The breakpoint at which this occurs is `768px` by default, but you can change it using the `mobile-breakpoint` attribute,
which takes either a number or a [CSS length](https://developer.mozilla.org/en-US/docs/Web/CSS/length).
The breakpoint at which this occurs is `768px` by default, but you can change it using the `mobile-breakpoint` attribute.
```html
<wa-page mobile-breakpoint="600"> ... </wa-page>
```
```html {.example viewport}
<wa-page mobile-breakpoint="50ch">
<div slot=navigation>Nav</div>
<header slot=header>
<div style="width: 50ch; background: gold">Im 50ch wide</div>
</header>
</wa-page>
<style>
html,
body {
min-height: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
```
By default, a "hamburger" button appears in the `header` slot to toggle the navigation menu on smaller screens.
You can customize what this looks like by slotting your own button in the `toggle-navigation` slot,
@@ -860,10 +809,9 @@ You can use a similar approach for `--aside-width` to hide the `aside` slot on s
```css
wa-page[view='mobile'] {
--aside-width: auto;
[slot='aside'] {
display: none;
}
}
wa-page[view='mobile'] [slot='aside'] {
display: none;
}
```

2350
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -76,13 +76,14 @@
"devDependencies": {
"@11ty/eleventy": "3.0.0-alpha.5",
"@custom-elements-manifest/analyzer": "^0.9.4",
"@konnorr/esbuild-plugin-lit-css": "^1.0.1",
"@lit-labs/eleventy-plugin-lit": "^1.0.3",
"@lit-labs/testing": "^0.2.4",
"@lit/react": "^1.0.0",
"@open-wc/testing": "^3.2.0",
"@types/mocha": "^10.0.2",
"@types/react": "^18.2.28",
"@typescript-eslint/eslint-plugin": "^6.7.5",
"@typescript-eslint/parser": "^6.7.5",
"@web/dev-server-esbuild": "^0.3.6",
"@web/test-runner": "^0.18.1",
"@web/test-runner-commands": "^0.9.0",
@@ -100,7 +101,17 @@
"del": "^7.1.0",
"download": "^8.0.0",
"esbuild": "^0.19.4",
"esbuild-plugin-lit-css": "^3.0.1",
"esbuild-plugin-replace": "^1.4.0",
"eslint": "^8.51.0",
"eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-friendly": "^0.7.2",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-lit": "^1.9.1",
"eslint-plugin-lit-a11y": "^4.1.0",
"eslint-plugin-markdown": "^3.0.1",
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
"eslint-plugin-wc": "^2.0.4",
"front-matter": "^4.0.2",
"get-port": "^7.0.0",
"globby": "^13.2.2",

View File

@@ -14,9 +14,7 @@ const config = {
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
useTabs: false,
organizeImportsSkipDestructiveCodeActions: true,
plugins: ['prettier-plugin-organize-imports']
useTabs: false
};
export default config;

View File

@@ -10,10 +10,10 @@ import browserSync from 'browser-sync';
import chalk from 'chalk';
import copy from 'recursive-copy';
import esbuild from 'esbuild';
import { litCssPlugin } from 'esbuild-plugin-lit-css';
import getPort, { portNumbers } from 'get-port';
import ora from 'ora';
import process from 'process';
import { litCssPlugin } from '@konnorr/esbuild-plugin-lit-css';
const __dirname = dirname(fileURLToPath(import.meta.url));
const isDeveloping = process.argv.includes('--develop');
@@ -172,10 +172,7 @@ async function generateBundle() {
bundle: true,
splitting: true,
minify: false,
plugins: [replace({ __WEBAWESOME_VERSION__: version }), litCssPlugin()],
loader: {
'.css': 'text'
}
plugins: [replace({ __WEBAWESOME_VERSION__: version }), litCssPlugin()]
};
const unbundledConfig = {

View File

@@ -1,50 +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;
}
.animated-image__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);
}
:host([play]:hover) .animated-image__control-box {
opacity: 1;
}
:host([play]:not(:hover)) .animated-image__control-box {
opacity: 0;
}
:host([play]) slot[name='play-icon'],
:host(:not([play])) slot[name='pause-icon'] {
display: none;
}

View File

@@ -0,0 +1,54 @@
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;
}
.animated-image__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);
}
:host([play]:hover) .animated-image__control-box {
opacity: 1;
}
:host([play]:not(:hover)) .animated-image__control-box {
opacity: 0;
}
:host([play]) slot[name='play-icon'],
:host(:not([play])) slot[name='pause-icon'] {
display: none;
}
`;

View File

@@ -4,8 +4,10 @@ import { html } from 'lit';
import { WaErrorEvent } from '../../events/error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import styles from './animated-image.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './animated-image.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
@@ -28,7 +30,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-animated-image')
export default class WaAnimatedImage extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('.animated-image__animated') animatedImage: HTMLImageElement;

View File

@@ -1,3 +0,0 @@
:host {
display: contents;
}

View File

@@ -0,0 +1,7 @@
import { css } from 'lit';
export default css`
:host {
display: contents;
}
`;

View File

@@ -5,8 +5,10 @@ import { WaCancelEvent } from '../../events/cancel.js';
import { WaFinishEvent } from '../../events/finish.js';
import { WaStartEvent } from '../../events/start.js';
import { watch } from '../../internal/watch.js';
import styles from './animation.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './animation.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Animate elements declaratively with nearly 100 baked-in presets, or roll your own with custom keyframes. Powered by the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
@@ -23,7 +25,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-animation')
export default class WaAnimation extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private animation?: Animation;
private hasStarted = false;

View File

@@ -1,63 +0,0 @@
:host {
--background-color: var(--wa-color-neutral-fill-normal);
--content-color: var(--wa-color-neutral-on-normal);
--size: 3rem;
display: inline-block;
}
.avatar {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
width: var(--size);
height: var(--size);
background-color: var(--background-color);
font: inherit;
font-size: calc(var(--size) * 0.4);
color: var(--content-color);
user-select: none;
-webkit-user-select: none;
vertical-align: middle;
}
.avatar--circle,
.avatar--circle .avatar__image {
border-radius: var(--wa-border-radius-circle);
}
.avatar--rounded,
.avatar--rounded .avatar__image {
border-radius: var(--wa-border-radius-s);
}
.avatar--square {
border-radius: 0;
}
.avatar__icon {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.avatar__initials {
line-height: 1;
text-transform: uppercase;
}
.avatar__image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
overflow: hidden;
}

View File

@@ -0,0 +1,67 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-color-neutral-fill-normal);
--content-color: var(--wa-color-neutral-on-normal);
--size: 3rem;
display: inline-block;
}
.avatar {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
width: var(--size);
height: var(--size);
background-color: var(--background-color);
font: inherit;
font-size: calc(var(--size) * 0.4);
color: var(--content-color);
user-select: none;
-webkit-user-select: none;
vertical-align: middle;
}
.avatar--circle,
.avatar--circle .avatar__image {
border-radius: var(--wa-border-radius-circle);
}
.avatar--rounded,
.avatar--rounded .avatar__image {
border-radius: var(--wa-border-radius-s);
}
.avatar--square {
border-radius: 0;
}
.avatar__icon {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.avatar__initials {
line-height: 1;
text-transform: uppercase;
}
.avatar__image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
overflow: hidden;
}
`;

View File

@@ -4,8 +4,10 @@ import { customElement, property, state } from 'lit/decorators.js';
import { html } from 'lit';
import { WaErrorEvent } from '../../events/error.js';
import { watch } from '../../internal/watch.js';
import styles from './avatar.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './avatar.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Avatars are used to represent a person or object.
@@ -31,7 +33,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-avatar')
export default class WaAvatar extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@state() private hasError = false;

View File

@@ -1,77 +0,0 @@
:host {
--border-color: var(--background-color);
--border-radius: var(--wa-border-radius-xs);
--border-style: var(--wa-border-style);
--border-width: var(--wa-border-width-s);
display: inline-flex;
}
:host([variant='brand']) {
--background-color: var(--wa-color-brand-fill-loud);
--content-color: var(--wa-color-brand-on-loud);
}
:host([variant='success']) {
--background-color: var(--wa-color-success-fill-loud);
--content-color: var(--wa-color-success-on-loud);
}
:host([variant='warning']) {
--background-color: var(--wa-color-warning-fill-loud);
--content-color: var(--wa-color-warning-on-loud);
}
:host([variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-loud);
--content-color: var(--wa-color-neutral-on-loud);
}
:host([variant='danger']) {
--background-color: var(--wa-color-danger-fill-loud);
--content-color: var(--wa-color-danger-on-loud);
}
.badge {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: max(var(--wa-font-size-2xs), 0.75em);
font-weight: var(--wa-font-weight-semibold);
line-height: 1;
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
color: var(--content-color);
white-space: nowrap;
padding: 0.375em 0.625em;
user-select: none;
-webkit-user-select: none;
cursor: inherit;
}
/* Pill modifier */
.badge--pill {
border-radius: var(--wa-border-radius-pill);
}
/* Pulse modifier */
.badge--pulse {
--pulse-color: var(--background-color);
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;
}
}

View File

@@ -0,0 +1,81 @@
import { css } from 'lit';
export default css`
:host {
--border-color: var(--background-color);
--border-radius: var(--wa-border-radius-xs);
--border-style: var(--wa-border-style);
--border-width: var(--wa-border-width-s);
display: inline-flex;
}
:host([variant='brand']) {
--background-color: var(--wa-color-brand-fill-loud);
--content-color: var(--wa-color-brand-on-loud);
}
:host([variant='success']) {
--background-color: var(--wa-color-success-fill-loud);
--content-color: var(--wa-color-success-on-loud);
}
:host([variant='warning']) {
--background-color: var(--wa-color-warning-fill-loud);
--content-color: var(--wa-color-warning-on-loud);
}
:host([variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-loud);
--content-color: var(--wa-color-neutral-on-loud);
}
:host([variant='danger']) {
--background-color: var(--wa-color-danger-fill-loud);
--content-color: var(--wa-color-danger-on-loud);
}
.badge {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: max(var(--wa-font-size-2xs), 0.75em);
font-weight: var(--wa-font-weight-semibold);
line-height: 1;
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
color: var(--content-color);
white-space: nowrap;
padding: 0.375em 0.625em;
user-select: none;
-webkit-user-select: none;
cursor: inherit;
}
/* Pill modifier */
.badge--pill {
border-radius: var(--wa-border-radius-pill);
}
/* Pulse modifier */
.badge--pulse {
--pulse-color: var(--background-color);
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;
}
}
`;

View File

@@ -1,8 +1,10 @@
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property } from 'lit/decorators.js';
import { html } from 'lit';
import styles from './badge.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './badge.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Badges are used to draw attention and display statuses or counts.
@@ -23,7 +25,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-badge')
export default class WaBadge extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/** The badge's theme variant. */
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' = 'brand';

View File

@@ -1,83 +0,0 @@
:host {
color: var(--wa-color-text-link);
display: inline-flex;
}
:host(:last-of-type) {
color: var(--wa-color-text-quiet);
}
.breadcrumb-item {
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;
}
.breadcrumb-item__label {
display: inline-block;
font: inherit;
text-decoration: none;
color: currentColor;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
padding: 0;
margin: 0;
cursor: pointer;
transition: color var(--wa-transition-normal) var(--wa-transition-easing);
}
:host(:not(:last-of-type)) .breadcrumb-item__label:hover {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
:host(:not(:last-of-type)) .breadcrumb-item__label:active {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.breadcrumb-item__label:focus {
outline: none;
}
.breadcrumb-item__label:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.breadcrumb-item__prefix,
.breadcrumb-item__suffix {
display: none;
flex: 0 0 auto;
display: flex;
align-items: center;
}
.breadcrumb-item__prefix,
.breadcrumb-item__suffix {
display: inline-flex;
color: var(--wa-color-text-quiet);
}
::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-s);
}
::slotted([slot='suffix']) {
margin-inline-start: var(--wa-space-s);
}
:host(:last-of-type) .breadcrumb-item__separator {
display: none;
}
.breadcrumb-item__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;
}

View File

@@ -0,0 +1,87 @@
import { css } from 'lit';
export default css`
:host {
color: var(--wa-color-text-link);
display: inline-flex;
}
:host(:last-of-type) {
color: var(--wa-color-text-quiet);
}
.breadcrumb-item {
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;
}
.breadcrumb-item__label {
display: inline-block;
font: inherit;
text-decoration: none;
color: currentColor;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
padding: 0;
margin: 0;
cursor: pointer;
transition: color var(--wa-transition-normal) var(--wa-transition-easing);
}
:host(:not(:last-of-type)) .breadcrumb-item__label:hover {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
:host(:not(:last-of-type)) .breadcrumb-item__label:active {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.breadcrumb-item__label:focus {
outline: none;
}
.breadcrumb-item__label:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.breadcrumb-item__prefix,
.breadcrumb-item__suffix {
display: none;
flex: 0 0 auto;
display: flex;
align-items: center;
}
.breadcrumb-item__prefix,
.breadcrumb-item__suffix {
display: inline-flex;
color: var(--wa-color-text-quiet);
}
::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-s);
}
::slotted([slot='suffix']) {
margin-inline-start: var(--wa-space-s);
}
:host(:last-of-type) .breadcrumb-item__separator {
display: none;
}
.breadcrumb-item__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;
}
`;

View File

@@ -2,8 +2,10 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { watch } from '../../internal/watch.js';
import styles from './breadcrumb-item.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './breadcrumb-item.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Breadcrumb Items are used inside [breadcrumbs](/docs/components/breadcrumb) to represent different links.
@@ -25,7 +27,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-breadcrumb-item')
export default class WaBreadcrumbItem extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('slot:not([name])') defaultSlot: HTMLSlotElement;

View File

@@ -1,5 +0,0 @@
.breadcrumb {
display: flex;
align-items: center;
flex-wrap: wrap;
}

View File

@@ -0,0 +1,9 @@
import { css } from 'lit';
export default css`
.breadcrumb {
display: flex;
align-items: center;
flex-wrap: wrap;
}
`;

View File

@@ -2,8 +2,10 @@ import '../icon/icon.js';
import { customElement, property, query } from 'lit/decorators.js';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import styles from './breadcrumb.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './breadcrumb.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
import type WaBreadcrumbItem from '../breadcrumb-item/breadcrumb-item.js';
/**
@@ -21,7 +23,7 @@ import type WaBreadcrumbItem from '../breadcrumb-item/breadcrumb-item.js';
*/
@customElement('wa-breadcrumb')
export default class WaBreadcrumb extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);
private separatorDir = this.localize.dir();

View File

@@ -1,19 +0,0 @@
:host {
display: inline-flex;
}
.button-group {
display: flex;
position: relative;
flex-wrap: wrap;
isolation: isolate;
}
:host([orientation='vertical']) .button-group {
flex-direction: column;
}
/* Show the focus indicator above other buttons */
::slotted(:focus) {
z-index: 1 !important;
}

View File

@@ -0,0 +1,23 @@
import { css } from 'lit';
export default css`
:host {
display: inline-flex;
}
.button-group {
display: flex;
position: relative;
flex-wrap: wrap;
isolation: isolate;
}
:host([orientation='vertical']) .button-group {
flex-direction: column;
}
/* Show the focus indicator above other buttons */
::slotted(:focus) {
z-index: 1 !important;
}
`;

View File

@@ -1,7 +1,9 @@
import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';
import styles from './button-group.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './button-group.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Button groups can be used to group related buttons into sections.
@@ -15,7 +17,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-button-group')
export default class WaButtonGroup extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('slot') defaultSlot: HTMLSlotElement;

View File

@@ -1,545 +0,0 @@
:host {
--background-color-hover: color-mix(in oklab, var(--background-color), var(--wa-color-mix-hover));
--background-color-active: color-mix(in oklab, var(--background-color), var(--wa-color-mix-active));
--border-color: initial;
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
--label-color-hover: var(--label-color);
--label-color-active: var(--label-color);
display: inline-block;
position: relative;
width: auto;
cursor: pointer;
}
/*
* Filled buttons
*/
:host([appearance='filled'][variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-loud);
--label-color: var(--wa-color-neutral-on-loud);
}
:host([appearance='filled'][variant='brand']) {
--background-color: var(--wa-color-brand-fill-loud);
--label-color: var(--wa-color-brand-on-loud);
}
:host([appearance='filled'][variant='success']) {
--background-color: var(--wa-color-success-fill-loud);
--label-color: var(--wa-color-success-on-loud);
}
:host([appearance='filled'][variant='warning']) {
--background-color: var(--wa-color-warning-fill-loud);
--label-color: var(--wa-color-warning-on-loud);
}
:host([appearance='filled'][variant='danger']) {
--background-color: var(--wa-color-danger-fill-loud);
--label-color: var(--wa-color-danger-on-loud);
}
/*
* Tinted buttons
*/
:host([appearance='tinted']) {
--background-color-hover: color-mix(in oklab, var(--background-color), transparent 10%);
--background-color-active: color-mix(in oklab, var(--background-color), transparent 20%);
}
:host([appearance='tinted'][variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-normal);
--label-color: var(--wa-color-neutral-on-normal);
}
:host([appearance='tinted'][variant='brand']) {
--background-color: var(--wa-color-brand-fill-normal);
--label-color: var(--wa-color-brand-on-normal);
}
:host([appearance='tinted'][variant='success']) {
--background-color: var(--wa-color-success-fill-normal);
--label-color: var(--wa-color-success-on-normal);
}
:host([appearance='tinted'][variant='warning']) {
--background-color: var(--wa-color-warning-fill-normal);
--label-color: var(--wa-color-warning-on-normal);
}
:host([appearance='tinted'][variant='danger']) {
--background-color: var(--wa-color-danger-fill-normal);
--label-color: var(--wa-color-danger-on-normal);
}
/*
* Outlined buttons
*/
:host([appearance='outlined']),
:host(.wa-button-group__button--radio:not([checked])) {
--background-color: transparent;
--background-color-active: color-mix(in oklab, var(--background-color-hover), transparent 20%);
}
:host([appearance='outlined'][variant='neutral']),
:host(.wa-button-group__button--radio:not([checked])) {
--background-color-hover: var(--wa-color-neutral-fill-quiet);
--border-color: var(--wa-color-neutral-border-loud);
--label-color: var(--wa-color-neutral-on-quiet);
}
:host([appearance='outlined'][variant='brand']) {
--background-color-hover: var(--wa-color-brand-fill-quiet);
--border-color: var(--wa-color-brand-border-loud);
--label-color: var(--wa-color-brand-on-quiet);
}
:host([appearance='outlined'][variant='success']) {
--background-color-hover: var(--wa-color-success-fill-quiet);
--border-color: var(--wa-color-success-border-loud);
--label-color: var(--wa-color-success-on-quiet);
}
:host([appearance='outlined'][variant='warning']) {
--background-color-hover: var(--wa-color-warning-fill-quiet);
--border-color: var(--wa-color-warning-border-loud);
--label-color: var(--wa-color-warning-on-quiet);
}
:host([appearance='outlined'][variant='danger']) {
--background-color-hover: var(--wa-color-danger-fill-quiet);
--border-color: var(--wa-color-danger-border-loud);
--label-color: var(--wa-color-danger-on-quiet);
}
/*
* Text buttons
*/
:host([appearance='text']) {
--background-color: transparent;
--background-color-active: color-mix(in oklab, var(--background-color-hover), transparent 20%);
}
:host([appearance='text'][variant='neutral']) {
--label-color: var(--wa-color-neutral-on-quiet);
--background-color-hover: var(--wa-color-neutral-fill-quiet);
}
:host([appearance='text'][variant='brand']) {
--label-color: var(--wa-color-brand-on-quiet);
--background-color-hover: var(--wa-color-brand-fill-quiet);
}
:host([appearance='text'][variant='success']) {
--label-color: var(--wa-color-success-on-quiet);
--background-color-hover: var(--wa-color-success-fill-quiet);
}
:host([appearance='text'][variant='warning']) {
--label-color: var(--wa-color-warning-on-quiet);
--background-color-hover: var(--wa-color-warning-fill-quiet);
}
:host([appearance='text'][variant='danger']) {
--label-color: var(--wa-color-danger-on-quiet);
--background-color-hover: var(--wa-color-danger-fill-quiet);
}
/*
* Checked buttons
*/
:host([checked]) {
--background-color: var(--wa-color-brand-fill-quiet);
--background-color-hover: var(--background-color);
--border-color: var(--wa-form-control-activated-color);
--label-color: var(--wa-color-brand-on-normal);
--indicator-color: var(--border-color);
--indicator-width: var(--wa-border-width-s);
}
/*
* Sizes
*/
:host([size='small']) {
font-size: var(--wa-font-size-s);
}
:host([size='medium']) {
font-size: var(--wa-font-size-m);
}
:host([size='large']) {
font-size: var(--wa-font-size-l);
}
/*
* Internal
*/
.button {
background-color: var(--background-color);
border-color: var(--border-color, var(--background-color));
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: max(1px, var(--border-width));
box-shadow: var(--box-shadow);
color: var(--label-color);
display: inline-flex;
align-items: stretch;
justify-content: center;
width: 100%;
font: inherit;
font-weight: var(--wa-font-weight-action);
text-decoration: none;
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
vertical-align: middle;
padding: 0;
transition:
background var(--wa-transition-fast) var(--wa-transition-easing),
border var(--wa-transition-fast) var(--wa-transition-easing),
box-shadow var(--wa-transition-fast) var(--wa-transition-easing),
color var(--wa-transition-fast) var(--wa-transition-easing);
cursor: inherit;
}
.button--checked {
box-shadow:
var(--box-shadow, 0 0 transparent),
inset 0 0 0 var(--indicator-width) var(--indicator-color);
}
/*
* States
*/
.button::-moz-focus-inner {
border: 0;
}
.button:focus {
outline: none;
}
.button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* When disabled, prevent mouse events from bubbling up from children */
.button--disabled * {
pointer-events: none;
}
.button:hover:not(.button--disabled, .button--loading) {
background-color: var(--background-color-hover, var(--background-color, none));
border-color: var(--border-color-hover, var(--border-color, var(--background-color-hover)));
color: var(--label-color-hover, var(--label-color));
}
.button:active:not(.button--disabled, .button--loading) {
background-color: var(--background-color-active, var(--background-color, none));
border-color: var(--border-color-active, var(--border-color, var(--background-color-active)));
color: var(--label-color-active, var(--label-color));
}
@media (forced-colors: active) {
.button.button--outlined.button--checked:not(.button--disabled) {
outline: solid 2px transparent;
}
}
/*
* Label
*/
.button__prefix,
.button__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
pointer-events: none;
}
.button__label {
display: inline-block;
}
.button__label::slotted(wa-icon) {
vertical-align: -2px;
}
/*
* Size modifiers
*/
.button--small {
height: var(--wa-form-control-height-s);
line-height: calc(var(--wa-form-control-height-s) - var(--border-width) * 2);
}
.button--medium {
height: var(--wa-form-control-height-m);
line-height: calc(var(--wa-form-control-height-m) - var(--border-width) * 2);
}
.button--large {
height: var(--wa-form-control-height-l);
line-height: calc(var(--wa-form-control-height-l) - var(--border-width) * 2);
}
/*
* Pill modifier
*/
.button--pill.button--small {
border-radius: var(--wa-border-radius-pill);
}
.button--pill.button--medium {
border-radius: var(--wa-border-radius-pill);
}
.button--pill.button--large {
border-radius: var(--wa-border-radius-pill);
}
/*
* Caret modifier
*/
.button--caret .button__suffix {
display: none;
}
.button--caret .button__caret {
display: flex;
align-self: center;
align-items: center;
}
.button--caret .button__caret::part(svg) {
width: 0.875em;
height: 0.875em;
}
/*
* Loading modifier
*/
.button--loading {
position: relative;
cursor: wait;
}
.button--loading .button__prefix,
.button--loading .button__label,
.button--loading .button__suffix,
.button--loading .button__caret {
visibility: hidden;
}
.button--loading 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;
top: 0;
right: 0;
translate: 50% -50%;
pointer-events: none;
}
.button--rtl ::slotted(wa-badge) {
right: auto;
left: 0;
translate: -50% -50%;
}
/*
* Button spacing
*/
.button--small {
padding: 0 var(--wa-space-s);
}
.button--medium {
padding: 0 var(--wa-space-m);
}
.button--large {
padding: 0 var(--wa-space-l);
}
.button--small ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-s);
}
.button--medium ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-m);
}
.button--large ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-l);
}
.button--small ::slotted([slot='suffix']),
.button--small.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-s);
}
.button--medium ::slotted([slot='suffix']),
.button--medium.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-m);
}
.button--large ::slotted([slot='suffix']),
.button--large.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-l);
}
/*
* Button groups support a variety of button types (e.g. buttons with tooltips, buttons as dropdown triggers, etc.).
* This means buttons aren't always direct descendants of the button group, thus we can't target them with the
* ::slotted selector. To work around this, the button group component does some magic to add these special classes to
* buttons and we style them here instead.
*/
/*
:host([data-button-group-middle]) #button {
border-radius: 0;
}
:host([data-button-group-horizontal][data-button-group-first]) #button {
border-start-end-radius: 0;
border-end-end-radius: 0;
}
:host([data-button-group-horizontal][data-button-group-last]) #button {
border-start-start-radius: 0;
border-end-start-radius: 0;
}
:host([data-button-group-vertical][data-button-group-first]) #button {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
:host([data-button-group-vertical][data-button-group-last]) #button {
border-start-start-radius: 0;
border-start-end-radius: 0;
}
*/
:host(.wa-button-group__button--inner) .button {
border-radius: 0;
}
:host(.wa-button-group-horizontal.wa-button-group__button--first:not(.wa-button-group__button--last)) .button {
border-start-end-radius: 0;
border-end-end-radius: 0;
}
:host(.wa-button-group-horizontal.wa-button-group__button--last:not(.wa-button-group__button--first)) .button {
border-start-start-radius: 0;
border-end-start-radius: 0;
}
:host(.wa-button-group-vertical.wa-button-group__button--first:not(.wa-button-group__button--last)) .button {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
:host(.wa-button-group-vertical.wa-button-group__button--last:not(.wa-button-group__button--first)) .button {
border-start-start-radius: 0;
border-start-end-radius: 0;
}
/* All except the first */
:host(
.wa-button-group-horizontal.wa-button-group-horizontal.wa-button-group__button:not(.wa-button-group__button--first)
) {
margin-inline-start: calc(-1 * var(--border-width));
}
:host(
.wa-button-group-vertical.wa-button-group-horizontal.wa-button-group__button:not(.wa-button-group__button--first)
) {
margin-block-start: calc(-1 * var(--border-width));
}
/* Add a visual separator between filled buttons */
:host(.wa-button-group__button:not(.wa-button-group__button--first, .wa-button-group__button--radio)) .button:after {
content: '';
position: absolute;
z-index: 2; /* Keep separators visible on hover */
}
:host(
.wa-button-group-horizontal.wa-button-group__button:not(
.wa-button-group__button--first,
.wa-button-group__button--radio
)
)
.button:after {
top: 0;
bottom: 0;
inset-inline-start: 0;
border-left: solid max(var(--border-width), 1px) var(--border-color, rgb(0 0 0 / 0.3));
}
:host(
.wa-button-group-vertical.wa-button-group__button:not(
.wa-button-group__button--first,
.wa-button-group__button--radio
)
)
.button:after {
left: 0;
right: 0;
inset-block-start: 0;
border-top: solid max(var(--border-width), 1px) var(--border-color, rgb(0 0 0 / 0.3));
}
/* Bump hovered, focused, and checked buttons up so their focus ring isn't clipped */
:host(.wa-button-group__button--hover) {
z-index: 1;
}
/* Focus and checked are always on top */
:host(.wa-button-group__button--focus),
:host(.wa-button-group__button[checked]) {
z-index: 2;
}

View File

@@ -0,0 +1,551 @@
import { css } from 'lit';
export default css`
:host {
--background-color-hover: color-mix(in oklab, var(--background-color), var(--wa-color-mix-hover));
--background-color-active: color-mix(in oklab, var(--background-color), var(--wa-color-mix-active));
--border-color: initial;
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
--label-color-hover: var(--label-color);
--label-color-active: var(--label-color);
display: inline-block;
position: relative;
width: auto;
cursor: pointer;
}
/*
* Filled buttons
*/
:host([appearance='filled'][variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-loud);
--label-color: var(--wa-color-neutral-on-loud);
}
:host([appearance='filled'][variant='brand']) {
--background-color: var(--wa-color-brand-fill-loud);
--label-color: var(--wa-color-brand-on-loud);
}
:host([appearance='filled'][variant='success']) {
--background-color: var(--wa-color-success-fill-loud);
--label-color: var(--wa-color-success-on-loud);
}
:host([appearance='filled'][variant='warning']) {
--background-color: var(--wa-color-warning-fill-loud);
--label-color: var(--wa-color-warning-on-loud);
}
:host([appearance='filled'][variant='danger']) {
--background-color: var(--wa-color-danger-fill-loud);
--label-color: var(--wa-color-danger-on-loud);
}
/*
* Tinted buttons
*/
:host([appearance='tinted']) {
--background-color-hover: color-mix(in oklab, var(--background-color), transparent 10%);
--background-color-active: color-mix(in oklab, var(--background-color), transparent 20%);
}
:host([appearance='tinted'][variant='neutral']) {
--background-color: var(--wa-color-neutral-fill-normal);
--label-color: var(--wa-color-neutral-on-normal);
}
:host([appearance='tinted'][variant='brand']) {
--background-color: var(--wa-color-brand-fill-normal);
--label-color: var(--wa-color-brand-on-normal);
}
:host([appearance='tinted'][variant='success']) {
--background-color: var(--wa-color-success-fill-normal);
--label-color: var(--wa-color-success-on-normal);
}
:host([appearance='tinted'][variant='warning']) {
--background-color: var(--wa-color-warning-fill-normal);
--label-color: var(--wa-color-warning-on-normal);
}
:host([appearance='tinted'][variant='danger']) {
--background-color: var(--wa-color-danger-fill-normal);
--label-color: var(--wa-color-danger-on-normal);
}
/*
* Outlined buttons
*/
:host([appearance='outlined']),
:host(.wa-button-group__button--radio:not([checked])) {
--background-color: transparent;
--background-color-active: color-mix(in oklab, var(--background-color-hover), transparent 20%);
}
:host([appearance='outlined'][variant='neutral']),
:host(.wa-button-group__button--radio:not([checked])) {
--background-color-hover: var(--wa-color-neutral-fill-quiet);
--border-color: var(--wa-color-neutral-border-loud);
--label-color: var(--wa-color-neutral-on-quiet);
}
:host([appearance='outlined'][variant='brand']) {
--background-color-hover: var(--wa-color-brand-fill-quiet);
--border-color: var(--wa-color-brand-border-loud);
--label-color: var(--wa-color-brand-on-quiet);
}
:host([appearance='outlined'][variant='success']) {
--background-color-hover: var(--wa-color-success-fill-quiet);
--border-color: var(--wa-color-success-border-loud);
--label-color: var(--wa-color-success-on-quiet);
}
:host([appearance='outlined'][variant='warning']) {
--background-color-hover: var(--wa-color-warning-fill-quiet);
--border-color: var(--wa-color-warning-border-loud);
--label-color: var(--wa-color-warning-on-quiet);
}
:host([appearance='outlined'][variant='danger']) {
--background-color-hover: var(--wa-color-danger-fill-quiet);
--border-color: var(--wa-color-danger-border-loud);
--label-color: var(--wa-color-danger-on-quiet);
}
/*
* Text buttons
*/
:host([appearance='text']) {
--background-color: transparent;
--background-color-active: color-mix(in oklab, var(--background-color-hover), transparent 20%);
}
:host([appearance='text'][variant='neutral']) {
--label-color: var(--wa-color-neutral-on-quiet);
--background-color-hover: var(--wa-color-neutral-fill-quiet);
}
:host([appearance='text'][variant='brand']) {
--label-color: var(--wa-color-brand-on-quiet);
--background-color-hover: var(--wa-color-brand-fill-quiet);
}
:host([appearance='text'][variant='success']) {
--label-color: var(--wa-color-success-on-quiet);
--background-color-hover: var(--wa-color-success-fill-quiet);
}
:host([appearance='text'][variant='warning']) {
--label-color: var(--wa-color-warning-on-quiet);
--background-color-hover: var(--wa-color-warning-fill-quiet);
}
:host([appearance='text'][variant='danger']) {
--label-color: var(--wa-color-danger-on-quiet);
--background-color-hover: var(--wa-color-danger-fill-quiet);
}
/*
* Checked buttons
*/
:host([checked]) {
--background-color: var(--wa-color-brand-fill-quiet);
--background-color-hover: var(--background-color);
--border-color: var(--wa-form-control-activated-color);
--label-color: var(--wa-color-brand-on-normal);
--indicator-color: var(--border-color);
--indicator-width: var(--wa-border-width-s);
}
/*
* Sizes
*/
:host([size='small']) {
font-size: var(--wa-font-size-s);
}
:host([size='medium']) {
font-size: var(--wa-font-size-m);
}
:host([size='large']) {
font-size: var(--wa-font-size-l);
}
/*
* Internal
*/
.button {
background-color: var(--background-color);
border-color: var(--border-color, var(--background-color));
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: max(1px, var(--border-width));
box-shadow: var(--box-shadow);
color: var(--label-color);
display: inline-flex;
align-items: stretch;
justify-content: center;
width: 100%;
font: inherit;
font-weight: var(--wa-font-weight-action);
text-decoration: none;
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
vertical-align: middle;
padding: 0;
transition:
background var(--wa-transition-fast) var(--wa-transition-easing),
border var(--wa-transition-fast) var(--wa-transition-easing),
box-shadow var(--wa-transition-fast) var(--wa-transition-easing),
color var(--wa-transition-fast) var(--wa-transition-easing);
cursor: inherit;
}
.button--checked {
box-shadow:
var(--box-shadow, 0 0 transparent),
inset 0 0 0 var(--indicator-width) var(--indicator-color);
}
/*
* States
*/
.button::-moz-focus-inner {
border: 0;
}
.button:focus {
outline: none;
}
.button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* When disabled, prevent mouse events from bubbling up from children */
.button--disabled * {
pointer-events: none;
}
.button:hover:not(.button--disabled, .button--loading) {
background-color: var(--background-color-hover, var(--background-color, none));
border-color: var(--border-color-hover, var(--border-color, var(--background-color-hover)));
color: var(--label-color-hover, var(--label-color));
}
.button:active:not(.button--disabled, .button--loading) {
background-color: var(--background-color-active, var(--background-color, none));
border-color: var(--border-color-active, var(--border-color, var(--background-color-active)));
color: var(--label-color-active, var(--label-color));
}
@media (forced-colors: active) {
.button.button--outlined.button--checked:not(.button--disabled) {
outline: solid 2px transparent;
}
}
/*
* Label
*/
.button__prefix,
.button__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
pointer-events: none;
}
.button__label {
display: inline-block;
}
.button__label::slotted(wa-icon) {
vertical-align: -2px;
}
/*
* Size modifiers
*/
.button--small {
height: var(--wa-form-control-height-s);
line-height: calc(var(--wa-form-control-height-s) - var(--border-width) * 2);
}
.button--medium {
height: var(--wa-form-control-height-m);
line-height: calc(var(--wa-form-control-height-m) - var(--border-width) * 2);
}
.button--large {
height: var(--wa-form-control-height-l);
line-height: calc(var(--wa-form-control-height-l) - var(--border-width) * 2);
}
/*
* Pill modifier
*/
.button--pill.button--small {
border-radius: var(--wa-border-radius-pill);
}
.button--pill.button--medium {
border-radius: var(--wa-border-radius-pill);
}
.button--pill.button--large {
border-radius: var(--wa-border-radius-pill);
}
/*
* Caret modifier
*/
.button--caret .button__suffix {
display: none;
}
.button--caret .button__caret {
display: flex;
align-self: center;
align-items: center;
}
.button--caret .button__caret::part(svg) {
width: 0.875em;
height: 0.875em;
}
/*
* Loading modifier
*/
.button--loading {
position: relative;
cursor: wait;
}
.button--loading .button__prefix,
.button--loading .button__label,
.button--loading .button__suffix,
.button--loading .button__caret {
visibility: hidden;
}
.button--loading 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;
top: 0;
right: 0;
translate: 50% -50%;
pointer-events: none;
}
.button--rtl ::slotted(wa-badge) {
right: auto;
left: 0;
translate: -50% -50%;
}
/*
* Button spacing
*/
.button--small {
padding: 0 var(--wa-space-s);
}
.button--medium {
padding: 0 var(--wa-space-m);
}
.button--large {
padding: 0 var(--wa-space-l);
}
.button--small ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-s);
}
.button--medium ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-m);
}
.button--large ::slotted([slot='prefix']) {
margin-inline-end: var(--wa-space-l);
}
.button--small ::slotted([slot='suffix']),
.button--small.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-s);
}
.button--medium ::slotted([slot='suffix']),
.button--medium.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-m);
}
.button--large ::slotted([slot='suffix']),
.button--large.button--caret:not(.button--visually-hidden-label) .button__caret {
margin-inline-start: var(--wa-space-l);
}
/*
* Button groups support a variety of button types (e.g. buttons with tooltips, buttons as dropdown triggers, etc.).
* This means buttons aren't always direct descendants of the button group, thus we can't target them with the
* ::slotted selector. To work around this, the button group component does some magic to add these special classes to
* buttons and we style them here instead.
*/
/*
:host([data-button-group-middle]) #button {
border-radius: 0;
}
:host([data-button-group-horizontal][data-button-group-first]) #button {
border-start-end-radius: 0;
border-end-end-radius: 0;
}
:host([data-button-group-horizontal][data-button-group-last]) #button {
border-start-start-radius: 0;
border-end-start-radius: 0;
}
:host([data-button-group-vertical][data-button-group-first]) #button {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
:host([data-button-group-vertical][data-button-group-last]) #button {
border-start-start-radius: 0;
border-start-end-radius: 0;
}
*/
:host(.wa-button-group__button--inner) .button {
border-radius: 0;
}
:host(.wa-button-group-horizontal.wa-button-group__button--first:not(.wa-button-group__button--last)) .button {
border-start-end-radius: 0;
border-end-end-radius: 0;
}
:host(.wa-button-group-horizontal.wa-button-group__button--last:not(.wa-button-group__button--first)) .button {
border-start-start-radius: 0;
border-end-start-radius: 0;
}
:host(.wa-button-group-vertical.wa-button-group__button--first:not(.wa-button-group__button--last)) .button {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
:host(.wa-button-group-vertical.wa-button-group__button--last:not(.wa-button-group__button--first)) .button {
border-start-start-radius: 0;
border-start-end-radius: 0;
}
/* All except the first */
:host(
.wa-button-group-horizontal.wa-button-group-horizontal.wa-button-group__button:not(
.wa-button-group__button--first
)
) {
margin-inline-start: calc(-1 * var(--border-width));
}
:host(
.wa-button-group-vertical.wa-button-group-horizontal.wa-button-group__button:not(.wa-button-group__button--first)
) {
margin-block-start: calc(-1 * var(--border-width));
}
/* Add a visual separator between filled buttons */
:host(.wa-button-group__button:not(.wa-button-group__button--first, .wa-button-group__button--radio)) .button:after {
content: '';
position: absolute;
z-index: 2; /* Keep separators visible on hover */
}
:host(
.wa-button-group-horizontal.wa-button-group__button:not(
.wa-button-group__button--first,
.wa-button-group__button--radio
)
)
.button:after {
top: 0;
bottom: 0;
inset-inline-start: 0;
border-left: solid max(var(--border-width), 1px) var(--border-color, rgb(0 0 0 / 0.3));
}
:host(
.wa-button-group-vertical.wa-button-group__button:not(
.wa-button-group__button--first,
.wa-button-group__button--radio
)
)
.button:after {
left: 0;
right: 0;
inset-block-start: 0;
border-top: solid max(var(--border-width), 1px) var(--border-color, rgb(0 0 0 / 0.3));
}
/* Bump hovered, focused, and checked buttons up so their focus ring isn't clipped */
:host(.wa-button-group__button--hover) {
z-index: 1;
}
/* Focus and checked are always on top */
:host(.wa-button-group__button--focus),
:host(.wa-button-group__button[checked]) {
z-index: 2;
}
`;

View File

@@ -11,7 +11,9 @@ import { WaFocusEvent } from '../../events/focus.js';
import { WaInvalidEvent } from '../../events/invalid.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import styles from './button.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './button.styles.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Buttons represent actions that are available to the user.
@@ -53,7 +55,7 @@ import styles from './button.css';
*/
@customElement('wa-button')
export default class WaButton extends WebAwesomeFormAssociatedElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
static get validators() {
return [...super.validators, MirrorValidator()];

View File

@@ -1,7 +1,9 @@
import { customElement, property } from 'lit/decorators.js';
import { html } from 'lit';
import componentStyles from '../../styles/component.styles.js';
import styles from './callout.css';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Callouts are used to display important messages inline.
@@ -21,7 +23,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-callout')
export default class WaCallout extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/** The callout's theme variant. */
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' = 'brand';

View File

@@ -1,75 +0,0 @@
:host {
--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);
--border-width: var(--wa-panel-border-width);
--box-shadow: var(--wa-shadow-s);
--spacing: var(--wa-space-xl);
display: inline-block;
}
.card {
display: flex;
flex-direction: column;
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
color: var(--wa-color-text-normal);
font: inherit;
}
.card__image {
display: flex;
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
margin: calc(-1 * var(--border-width));
overflow: hidden;
}
.card__image::slotted(img) {
display: block;
width: 100%;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.card:not(.card--has-image) .card__image {
display: none;
}
.card__header {
display: block;
border-bottom: inherit;
padding: calc(var(--spacing) / 2) var(--spacing);
}
.card:not(.card--has-header) .card__header {
display: none;
}
.card:not(.card--has-image) .card__header {
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
}
.card__body {
display: block;
padding: var(--spacing);
}
.card--has-footer .card__footer {
display: block;
border-top: inherit;
border-bottom-left-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
padding: var(--spacing);
}
.card:not(.card--has-footer) .card__footer {
display: none;
}

View File

@@ -0,0 +1,79 @@
import { css } from 'lit';
export default css`
:host {
--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);
--border-width: var(--wa-panel-border-width);
--box-shadow: var(--wa-shadow-s);
--spacing: var(--wa-space-xl);
display: inline-block;
}
.card {
display: flex;
flex-direction: column;
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
color: var(--wa-color-text-normal);
font: inherit;
}
.card__image {
display: flex;
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
margin: calc(-1 * var(--border-width));
overflow: hidden;
}
.card__image::slotted(img) {
display: block;
width: 100%;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.card:not(.card--has-image) .card__image {
display: none;
}
.card__header {
display: block;
border-bottom: inherit;
padding: calc(var(--spacing) / 2) var(--spacing);
}
.card:not(.card--has-header) .card__header {
display: none;
}
.card:not(.card--has-image) .card__header {
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
}
.card__body {
display: block;
padding: var(--spacing);
}
.card--has-footer .card__footer {
display: block;
border-top: inherit;
border-bottom-left-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
padding: var(--spacing);
}
.card:not(.card--has-footer) .card__footer {
display: none;
}
`;

View File

@@ -1,8 +1,10 @@
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property } from 'lit/decorators.js';
import { html } from 'lit';
import styles from './card.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './card.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Cards can be used to group related subjects in a container.
@@ -31,7 +33,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-card')
export default class WaCard extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/** Renders the card with a header */
@property({ attribute: 'with-header', type: Boolean }) withHeader = false;

View File

@@ -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;
}

View File

@@ -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;
}
`;

View File

@@ -1,7 +1,9 @@
import { customElement } from 'lit/decorators.js';
import { html } from 'lit';
import styles from './carousel-item.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './carousel-item.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary A carousel item represent a slide within a [carousel](/docs/components/carousel).
@@ -16,7 +18,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-carousel-item')
export default class WaCarouselItem extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
connectedCallback() {
super.connectedCallback();

View File

@@ -1,157 +0,0 @@
:host {
--aspect-ratio: 16 / 9;
--navigation-color: var(--wa-color-text-quiet);
--pagination-color: var(--wa-form-control-resting-color);
--pagination-color-active: var(--wa-form-control-activated-color);
--scroll-hint: 0px;
--slide-gap: var(--wa-space-m, 1rem);
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;
}
.carousel__pagination {
grid-area: pagination;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--wa-space-s);
}
.carousel__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-s);
--slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
}
@media (prefers-reduced-motion) {
:where(.carousel__slides) {
scroll-behavior: auto;
}
}
.carousel__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;
}
.carousel__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;
}
.carousel__slides--dragging,
.carousel__slides--dropping {
scroll-snap-type: unset;
}
:host([vertical]) ::slotted(wa-carousel-item) {
height: 100%;
}
.carousel__slides::-webkit-scrollbar {
display: none;
}
.carousel__navigation {
grid-area: navigation;
display: contents;
font-size: var(--wa-font-size-l);
}
.carousel__navigation-button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
font-size: inherit;
color: var(--navigation-color);
padding: var(--wa-space-xs);
cursor: pointer;
transition: var(--wa-transition-normal) color;
appearance: none;
}
.carousel__navigation-button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.carousel__navigation-button--disabled::part(base) {
pointer-events: none;
}
.carousel__navigation-button--previous {
grid-column: 1;
grid-row: 1;
}
.carousel__navigation-button--next {
grid-column: 3;
grid-row: 1;
}
.carousel__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(--pagination-color);
padding: 0;
margin: 0;
transition: transform var(--wa-transition-slow);
}
.carousel__pagination-item--active {
background-color: var(--pagination-color-active);
transform: scale(1.25);
}
/* Focus styles */
.carousel__slides:focus-visible,
.carousel__navigation-button:focus-visible,
.carousel__pagination-item:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}

View File

@@ -0,0 +1,161 @@
import { css } from 'lit';
export default css`
:host {
--aspect-ratio: 16 / 9;
--navigation-color: var(--wa-color-text-quiet);
--pagination-color: var(--wa-form-control-resting-color);
--pagination-color-active: var(--wa-form-control-activated-color);
--scroll-hint: 0px;
--slide-gap: var(--wa-space-m, 1rem);
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;
}
.carousel__pagination {
grid-area: pagination;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--wa-space-s);
}
.carousel__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-s);
--slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
}
@media (prefers-reduced-motion) {
:where(.carousel__slides) {
scroll-behavior: auto;
}
}
.carousel__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;
}
.carousel__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;
}
.carousel__slides--dragging,
.carousel__slides--dropping {
scroll-snap-type: unset;
}
:host([vertical]) ::slotted(wa-carousel-item) {
height: 100%;
}
.carousel__slides::-webkit-scrollbar {
display: none;
}
.carousel__navigation {
grid-area: navigation;
display: contents;
font-size: var(--wa-font-size-l);
}
.carousel__navigation-button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
font-size: inherit;
color: var(--navigation-color);
padding: var(--wa-space-xs);
cursor: pointer;
transition: var(--wa-transition-normal) color;
appearance: none;
}
.carousel__navigation-button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.carousel__navigation-button--disabled::part(base) {
pointer-events: none;
}
.carousel__navigation-button--previous {
grid-column: 1;
grid-row: 1;
}
.carousel__navigation-button--next {
grid-column: 3;
grid-row: 1;
}
.carousel__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(--pagination-color);
padding: 0;
margin: 0;
transition: transform var(--wa-transition-slow);
}
.carousel__pagination-item--active {
background-color: var(--pagination-color-active);
transform: scale(1.25);
}
/* Focus styles */
.carousel__slides:focus-visible,
.carousel__navigation-button:focus-visible,
.carousel__pagination-item:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
`;

View File

@@ -13,9 +13,10 @@ import { range } from 'lit/directives/range.js';
import { waitForEvent } from '../../internal/event.js';
import { WaSlideChangeEvent } from '../../events/slide-change.js';
import { watch } from '../../internal/watch.js';
import styles from './carousel.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './carousel.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { PropertyValueMap } from 'lit';
import type { CSSResultGroup, PropertyValueMap } from 'lit';
import type WaCarouselItem from '../carousel-item/carousel-item.js';
/**
@@ -52,7 +53,7 @@ import type WaCarouselItem from '../carousel-item/carousel-item.js';
*/
@customElement('wa-carousel')
export default class WaCarousel extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/** When set, allows the user to navigate the carousel in the same direction indefinitely. */
@property({ type: Boolean, reflect: true }) loop = false;

View File

@@ -1,121 +0,0 @@
:host {
--background-color: var(--wa-form-control-background-color);
--background-color-checked: var(--wa-form-control-activated-color);
--border-color: var(--wa-form-control-resting-color);
--border-color-checked: var(--wa-form-control-activated-color);
--border-radius: min(
calc(var(--toggle-size) * 0.375),
var(--wa-border-radius-xs)
); /* min so it doesn't look like a circle/radio */
--border-style: var(--wa-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: none;
--checked-icon-color: var(--wa-color-brand-on-loud);
--toggle-size: calc(1em * var(--wa-form-control-value-line-height));
display: inline-block;
}
.checkbox {
position: relative;
display: flex;
align-items: flex-start;
font: inherit;
color: var(--wa-form-control-value-color);
vertical-align: middle;
cursor: pointer;
}
.checkbox--small {
font-size: var(--wa-font-size-s);
}
.checkbox--medium {
font-size: var(--wa-font-size-m);
}
.checkbox--large {
font-size: var(--wa-font-size-l);
}
.checkbox__control {
flex: 0 0 auto;
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: var(--toggle-size);
height: var(--toggle-size);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
background-color: var(--background-color);
box-shadow: var(--box-shadow);
color: var(--wa-form-control-value-color);
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border-color var(--wa-transition-fast) var(--wa-transition-easing),
box-shadow var(--wa-transition-fast) var(--wa-transition-easing),
color var(--wa-transition-fast) var(--wa-transition-easing);
}
.checkbox__input {
position: absolute;
opacity: 0;
padding: 0;
margin: 0;
pointer-events: none;
height: 100%;
width: 100%;
}
.checkbox__icon--invisible {
visibility: hidden;
}
.checkbox__checked-icon,
.checkbox__indeterminate-icon {
display: inline-flex;
}
/* Focus */
.checkbox:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Checked/indeterminate */
.checkbox--checked .checkbox__control,
.checkbox--indeterminate .checkbox__control {
color: var(--checked-icon-color);
border-color: var(--border-color-checked);
background-color: var(--background-color-checked);
}
/* Checked/indeterminate + focus */
.checkbox.checkbox--checked:not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible),
.checkbox.checkbox--indeterminate:not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Disabled */
.checkbox--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.checkbox__label {
display: inline-block;
line-height: var(--toggle-size);
margin-inline-start: var(--wa-space-xs);
user-select: none;
-webkit-user-select: none;
}
:host([required]) .checkbox__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);
}

View File

@@ -0,0 +1,125 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-form-control-background-color);
--background-color-checked: var(--wa-form-control-activated-color);
--border-color: var(--wa-form-control-resting-color);
--border-color-checked: var(--wa-form-control-activated-color);
--border-radius: min(
calc(var(--toggle-size) * 0.375),
var(--wa-border-radius-xs)
); /* min so it doesn't look like a circle/radio */
--border-style: var(--wa-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: none;
--checked-icon-color: var(--wa-color-brand-on-loud);
--toggle-size: calc(1em * var(--wa-form-control-value-line-height));
display: inline-block;
}
.checkbox {
position: relative;
display: flex;
align-items: flex-start;
font: inherit;
color: var(--wa-form-control-value-color);
vertical-align: middle;
cursor: pointer;
}
.checkbox--small {
font-size: var(--wa-font-size-s);
}
.checkbox--medium {
font-size: var(--wa-font-size-m);
}
.checkbox--large {
font-size: var(--wa-font-size-l);
}
.checkbox__control {
flex: 0 0 auto;
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: var(--toggle-size);
height: var(--toggle-size);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
background-color: var(--background-color);
box-shadow: var(--box-shadow);
color: var(--wa-form-control-value-color);
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border-color var(--wa-transition-fast) var(--wa-transition-easing),
box-shadow var(--wa-transition-fast) var(--wa-transition-easing),
color var(--wa-transition-fast) var(--wa-transition-easing);
}
.checkbox__input {
position: absolute;
opacity: 0;
padding: 0;
margin: 0;
pointer-events: none;
height: 100%;
width: 100%;
}
.checkbox__icon--invisible {
visibility: hidden;
}
.checkbox__checked-icon,
.checkbox__indeterminate-icon {
display: inline-flex;
}
/* Focus */
.checkbox:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Checked/indeterminate */
.checkbox--checked .checkbox__control,
.checkbox--indeterminate .checkbox__control {
color: var(--checked-icon-color);
border-color: var(--border-color-checked);
background-color: var(--background-color-checked);
}
/* Checked/indeterminate + focus */
.checkbox.checkbox--checked:not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible),
.checkbox.checkbox--indeterminate:not(.checkbox--disabled) .checkbox__control:has(> input:focus-visible) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Disabled */
.checkbox--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.checkbox__label {
display: inline-block;
line-height: var(--toggle-size);
margin-inline-start: var(--wa-space-xs);
user-select: none;
-webkit-user-select: none;
}
:host([required]) .checkbox__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);
}
`;

View File

@@ -12,9 +12,10 @@ import { WaFocusEvent } from '../../events/focus.js';
import { WaInputEvent } from '../../events/input.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import componentStyles from '../../styles/component.styles.js';
import formControlStyles from '../../styles/form-control.styles.js';
import styles from './checkbox.css';
import type { PropertyValues } from 'lit';
import styles from './checkbox.styles.js';
import type { CSSResultGroup, PropertyValues } from 'lit';
/**
* @summary Checkboxes allow the user to toggle an option on or off.
@@ -55,7 +56,7 @@ import type { PropertyValues } from 'lit';
*/
@customElement('wa-checkbox')
export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
static shadowStyle = [formControlStyles, styles];
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };

View File

@@ -1,193 +0,0 @@
:host {
--preview-background: var(--wa-color-surface-default, canvas);
--preview-backdrop: var(--wa-color-surface-lowered, rgb(0 0 0 / 0.25));
--preview-resize: inline;
--preview-min-width: 10em;
--preview-max-width: 100%;
--preview-padding: var(--wa-space-2xl, 2rem);
--divider-width: var(--wa-border-width-s, 1px);
--viewport-initial-aspect-ratio: 16 / 9;
--viewport-bezel-width: 0.25em;
--code-expand-duration: var(--wa-transition-fast, 0.3s);
--code-collapse-duration: var(--wa-transition-normal, 0.3s);
display: flex;
flex-flow: column;
border: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
border-radius: var(--wa-code-demo-rounding, var(--wa-border-radius-m));
color: var(--wa-color-text-normal);
margin-block-end: var(--wa-flow-spacing);
background: var(--preview-backdrop);
interpolate-size: allow-keywords;
}
/* Different defaults for isolated demos */
:host([viewport]) {
--preview-resize: none; /* handled by wa-viewport-demo */
--preview-padding: var(--wa-space-l, 1rem);
}
#preview {
display: block;
padding: var(--preview-padding);
border-block-end: inherit;
border-block-end-width: var(--divider-width);
border-start-start-radius: inherit;
border-start-end-radius: inherit;
background: var(--preview-background);
resize: var(--preview-resize);
contain: inline-size; /* Safari chokes on scaled down viewports without this */
:host(:not([viewport])) & {
max-width: min(var(--preview-max-width), 100%);
min-width: var(--preview-min-width);
overflow: auto;
@container style(--preview-resize: none) {
overflow: visible;
}
}
> :first-child {
margin-block-start: 0;
}
> :last-child {
margin-block-end: 0;
}
}
wa-viewport-demo + slot[name='preview'].has-slotted {
display: none;
}
#source {
border-block-end: inherit;
overflow: hidden;
transition-property: height, display;
transition-behavior: allow-discrete;
display: block;
&::slotted(pre) {
position: relative;
border-radius: 0 !important;
margin: 0;
white-space: normal;
}
&:has(+ #buttons) {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
&:not(:has(+ #buttons)) {
border-bottom: none;
}
/* Collapsed */
&:not(:host([open]) *) {
height: 0px;
display: none;
}
/* Expanded */
&:is(:host([open]) *) {
height: auto;
display: block;
}
}
[part~='toggle-button'] wa-icon {
transition-property: rotate;
&:is(:host([open]) *) {
rotate: 180deg;
}
}
#source,
[part~='toggle-button'] wa-icon {
&:not(:host([open]) *) {
transition-duration: var(--code-collapse-duration);
}
&:is(:host([open]) *) {
transition-duration: var(--code-expand-duration);
}
}
#buttons {
display: flex;
align-items: stretch;
background: var(--controls-background, var(--wa-color-surface-default, canvas));
border-end-start-radius: inherit;
border-end-end-radius: inherit;
border: inherit;
/* so that we don't get a visible border
border-style: none would be better but it affects how the others cascade :(
*/
border-width: 0;
button {
--padding-block: 0.5em;
--padding-inline: 1.5em;
all: unset;
padding-block: var(--padding-block);
padding-inline: var(--padding-inline);
cursor: pointer;
white-space: nowrap;
font-size: 0.875rem;
color: var(--wa-color-text-quiet);
text-align: center;
&:not(#preview:active ~ #buttons *) {
/* Interactive states should not apply while the preview is being resized */
&:hover {
background: oklab(from var(--wa-color-surface-lowered, rgb(0 0 0 / 0.05)) l a b / 50%);
}
&:active {
box-shadow: var(--wa-shadow-s) inset;
padding-block: calc(var(--padding-block) + 1px) calc(var(--padding-block) - 1px);
}
}
&:first-child {
/* bottom left in en */
border-end-start-radius: inherit;
}
&:last-child {
/* bottom right in en */
border-end-end-radius: inherit;
}
&:not(:first-child) {
/* bottom left in en */
border-end-start-radius: 0;
border-inline-start: inherit;
border-inline-start-width: var(--divider-width);
}
&:not(:last-child) {
/* bottom right in en */
border-end-end-radius: 0;
}
&:focus-visible {
outline: var(--wa-focus-ring);
}
&[part~='toggle-button'] {
flex: 1;
}
}
wa-icon {
width: 1em;
height: 1em;
vertical-align: -0.1em;
}
}

View File

@@ -0,0 +1,197 @@
import { css } from 'lit';
export default css`
:host {
--preview-background: var(--wa-color-surface-default, canvas);
--preview-backdrop: var(--wa-color-surface-lowered, rgb(0 0 0 / 0.25));
--preview-resize: inline;
--preview-min-width: 10em;
--preview-max-width: 100%;
--preview-padding: var(--wa-space-2xl, 2rem);
--divider-width: var(--wa-border-width-s, 1px);
--viewport-initial-aspect-ratio: 16 / 9;
--viewport-bezel-width: 0.25em;
--code-expand-duration: var(--wa-transition-fast, 0.3s);
--code-collapse-duration: var(--wa-transition-normal, 0.3s);
display: flex;
flex-flow: column;
border: var(--wa-border-style) var(--wa-panel-border-width) var(--wa-color-neutral-border-quiet);
border-radius: var(--wa-code-demo-rounding, var(--wa-border-radius-m));
color: var(--wa-color-text-normal);
margin-block-end: var(--wa-flow-spacing);
background: var(--preview-backdrop);
interpolate-size: allow-keywords;
}
/* Different defaults for isolated demos */
:host([viewport]) {
--preview-resize: none; /* handled by wa-viewport-demo */
--preview-padding: var(--wa-space-l, 1rem);
}
#preview {
display: block;
padding: var(--preview-padding);
border-block-end: inherit;
border-block-end-width: var(--divider-width);
border-start-start-radius: inherit;
border-start-end-radius: inherit;
background: var(--preview-background);
resize: var(--preview-resize);
contain: inline-size; /* Safari chokes on scaled down viewports without this */
:host(:not([viewport])) & {
max-width: min(var(--preview-max-width), 100%);
min-width: var(--preview-min-width);
overflow: auto;
@container style(--preview-resize: none) {
overflow: visible;
}
}
> :first-child {
margin-block-start: 0;
}
> :last-child {
margin-block-end: 0;
}
}
wa-viewport-demo + slot[name='preview'].has-slotted {
display: none;
}
#source {
border-block-end: inherit;
overflow: hidden;
transition-property: height, display;
transition-behavior: allow-discrete;
display: block;
&::slotted(pre) {
position: relative;
border-radius: 0 !important;
margin: 0;
white-space: normal;
}
&:has(+ #buttons) {
border-end-start-radius: 0;
border-end-end-radius: 0;
}
&:not(:has(+ #buttons)) {
border-bottom: none;
}
/* Collapsed */
&:not(:host([open]) *) {
height: 0px;
display: none;
}
/* Expanded */
&:is(:host([open]) *) {
height: auto;
display: block;
}
}
[part~='toggle-button'] wa-icon {
transition-property: rotate;
&:is(:host([open]) *) {
rotate: 180deg;
}
}
#source,
[part~='toggle-button'] wa-icon {
&:not(:host([open]) *) {
transition-duration: var(--code-collapse-duration);
}
&:is(:host([open]) *) {
transition-duration: var(--code-expand-duration);
}
}
#buttons {
display: flex;
align-items: stretch;
background: var(--controls-background, var(--wa-color-surface-default, canvas));
border-end-start-radius: inherit;
border-end-end-radius: inherit;
border: inherit;
/* so that we don't get a visible border
border-style: none would be better but it affects how the others cascade :(
*/
border-width: 0;
button {
--padding-block: 0.5em;
--padding-inline: 1.5em;
all: unset;
padding-block: var(--padding-block);
padding-inline: var(--padding-inline);
cursor: pointer;
white-space: nowrap;
font-size: 0.875rem;
color: var(--wa-color-text-quiet);
text-align: center;
&:not(#preview:active ~ #buttons *) {
/* Interactive states should not apply while the preview is being resized */
&:hover {
background: oklab(from var(--wa-color-surface-lowered, rgb(0 0 0 / 0.05)) l a b / 50%);
}
&:active {
box-shadow: var(--wa-shadow-s) inset;
padding-block: calc(var(--padding-block) + 1px) calc(var(--padding-block) - 1px);
}
}
&:first-child {
/* bottom left in en */
border-end-start-radius: inherit;
}
&:last-child {
/* bottom right in en */
border-end-end-radius: inherit;
}
&:not(:first-child) {
/* bottom left in en */
border-end-start-radius: 0;
border-inline-start: inherit;
border-inline-start-width: var(--divider-width);
}
&:not(:last-child) {
/* bottom right in en */
border-end-end-radius: 0;
}
&:focus-visible {
outline: var(--wa-focus-ring);
}
&[part~='toggle-button'] {
flex: 1;
}
}
wa-icon {
width: 1em;
height: 1em;
vertical-align: -0.1em;
}
}
`;

View File

@@ -4,10 +4,11 @@ import { customElement, property, query } from 'lit/decorators.js';
import { getInnerHTML, HasSlotController } from '../../internal/slot.js';
import { html } from 'lit';
import { viewportPropertyConverter } from '../viewport-demo/viewport-demo.js';
import styles from './code-demo.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './code-demo.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { TemplateResult } from 'lit';
import type { CSSResultGroup, TemplateResult } from 'lit';
import type { ViewportDimensions } from '../viewport-demo/viewport-demo.js';
interface DemoHTMLOptions {
@@ -57,7 +58,7 @@ const URL_ATTRIBUTES = ['src', 'href'];
*/
@customElement('wa-code-demo')
export default class WaCodeDemo extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('slot[name=preview]')
private previewSlot: HTMLSlotElement;

View File

@@ -1,342 +0,0 @@
:host {
--background-color: var(--wa-color-surface-raised);
--border-color: var(--wa-color-surface-border);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-form-control-border-style);
--border-width: var(--wa-form-control-border-width);
--grid-width: 17rem;
--grid-height: 12rem;
--grid-handle-size: 1.25rem;
--spacing: var(--wa-space-s);
--preview-size: 2.25rem;
--preview-border-radius: var(--wa-border-radius-circle);
--slider-height: 1rem;
--slider-handle-size: calc(var(--slider-height) + 0.25rem);
--swatch-border-radius: var(--wa-border-radius-s);
--swatch-size: 1.5rem;
--trigger-border-radius: var(--wa-border-radius-circle);
display: inline-block;
}
.color-picker {
background-color: var(--background-color);
border-radius: var(--border-radius);
color: var(--color);
font: inherit;
user-select: none;
width: var(--grid-width);
-webkit-user-select: none;
}
.color-picker__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(--border-radius) - var(--border-width));
border-top-right-radius: calc(var(--border-radius) - var(--border-width));
cursor: crosshair;
forced-color-adjust: none;
}
.color-picker__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);
}
.color-picker__grid-handle--dragging {
cursor: none;
scale: 1.5;
}
.color-picker__grid-handle:focus-visible {
outline: var(--wa-focus-ring);
}
.color-picker__controls {
padding: var(--spacing);
display: flex;
align-items: center;
}
.color-picker__sliders {
flex: 1 1 auto;
}
.color-picker__slider {
position: relative;
height: var(--slider-height);
border-radius: var(--wa-border-radius-xs);
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
forced-color-adjust: none;
}
.color-picker__slider:not(:last-of-type) {
margin-bottom: var(--wa-space-s);
}
.color-picker__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);
}
.color-picker__slider-handle:focus-visible {
outline: var(--wa-focus-ring);
}
.color-picker__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%
);
}
.color-picker__alpha .color-picker__alpha-gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
}
.color-picker__preview {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
width: var(--preview-size);
height: var(--preview-size);
border: none;
border-radius: var(--preview-border-radius);
background: none;
margin-inline-start: var(--spacing);
cursor: copy;
forced-color-adjust: none;
}
.color-picker__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);
}
.color-picker__preview:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.color-picker__preview-color {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
}
.color-picker__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;
}
}
.color-picker__user-input {
display: flex;
padding: 0 var(--spacing) var(--spacing) var(--spacing);
}
.color-picker__user-input wa-input {
min-width: 0; /* fix input width in Safari */
flex: 1 1 auto;
}
.color-picker__user-input wa-button-group {
margin-inline-start: var(--spacing);
}
.color-picker__user-input wa-button:first-of-type {
min-width: 3rem;
max-width: 3rem;
}
.color-picker__swatches {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(var(--swatch-size), 100%), 1fr));
grid-gap: var(--wa-space-xs);
justify-items: center;
border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
var(--wa-color-surface-border);
padding: var(--spacing);
forced-color-adjust: none;
}
.color-picker__swatch {
position: relative;
aspect-ratio: 1 / 1;
width: 100%;
border-radius: var(--swatch-border-radius);
}
.color-picker__swatch .color-picker__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;
}
.color-picker__swatch:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.color-picker__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;
}
.color-picker--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.color-picker--disabled .color-picker__grid,
.color-picker--disabled .color-picker__grid-handle,
.color-picker--disabled .color-picker__slider,
.color-picker--disabled .color-picker__slider-handle,
.color-picker--disabled .color-picker__preview,
.color-picker--disabled .color-picker__swatch,
.color-picker--disabled .color-picker__swatch-color {
pointer-events: none;
}
/*
* Color dropdown
*/
.color-dropdown {
display: flex;
}
.color-dropdown::part(panel) {
max-height: none;
background-color: var(--background-color);
border: var(--border-style) var(--border-width) var(--border-color);
border-radius: var(--border-radius);
overflow: visible;
}
.color-dropdown__trigger {
display: block;
position: relative;
background-color: transparent;
border: none;
cursor: pointer;
forced-color-adjust: none;
}
.color-dropdown__trigger.color-dropdown__trigger--small {
width: var(--wa-form-control-height-s);
height: var(--wa-form-control-height-s);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__trigger.color-dropdown__trigger--medium {
width: var(--wa-form-control-height-m);
height: var(--wa-form-control-height-m);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__trigger.color-dropdown__trigger--large {
width: var(--wa-form-control-height-l);
height: var(--wa-form-control-height-l);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__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 0.0625rem var(--wa-form-control-resting-color),
inset 0 0 0 0.25rem var(--wa-color-surface-default);
}
.color-dropdown__trigger--empty:before {
background-color: transparent;
}
.color-dropdown__trigger:focus-visible {
outline: none;
}
.color-dropdown__trigger:focus-visible:not(.color-dropdown__trigger--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
:host(:disabled) :is(.color-dropdown__label, .color-dropdown__trigger) {
opacity: 0.5;
cursor: not-allowed;
}
.form-control.form-control--has-label .form-control__label {
cursor: pointer;
display: inline-block;
}

View File

@@ -0,0 +1,346 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-color-surface-raised);
--border-color: var(--wa-color-surface-border);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-form-control-border-style);
--border-width: var(--wa-form-control-border-width);
--grid-width: 17rem;
--grid-height: 12rem;
--grid-handle-size: 1.25rem;
--spacing: var(--wa-space-s);
--preview-size: 2.25rem;
--preview-border-radius: var(--wa-border-radius-circle);
--slider-height: 1rem;
--slider-handle-size: calc(var(--slider-height) + 0.25rem);
--swatch-border-radius: var(--wa-border-radius-s);
--swatch-size: 1.5rem;
--trigger-border-radius: var(--wa-border-radius-circle);
display: inline-block;
}
.color-picker {
background-color: var(--background-color);
border-radius: var(--border-radius);
color: var(--color);
font: inherit;
user-select: none;
width: var(--grid-width);
-webkit-user-select: none;
}
.color-picker__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(--border-radius) - var(--border-width));
border-top-right-radius: calc(var(--border-radius) - var(--border-width));
cursor: crosshair;
forced-color-adjust: none;
}
.color-picker__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);
}
.color-picker__grid-handle--dragging {
cursor: none;
scale: 1.5;
}
.color-picker__grid-handle:focus-visible {
outline: var(--wa-focus-ring);
}
.color-picker__controls {
padding: var(--spacing);
display: flex;
align-items: center;
}
.color-picker__sliders {
flex: 1 1 auto;
}
.color-picker__slider {
position: relative;
height: var(--slider-height);
border-radius: var(--wa-border-radius-xs);
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
forced-color-adjust: none;
}
.color-picker__slider:not(:last-of-type) {
margin-bottom: var(--wa-space-s);
}
.color-picker__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);
}
.color-picker__slider-handle:focus-visible {
outline: var(--wa-focus-ring);
}
.color-picker__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%
);
}
.color-picker__alpha .color-picker__alpha-gradient {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: inherit;
}
.color-picker__preview {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
width: var(--preview-size);
height: var(--preview-size);
border: none;
border-radius: var(--preview-border-radius);
background: none;
margin-inline-start: var(--spacing);
cursor: copy;
forced-color-adjust: none;
}
.color-picker__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);
}
.color-picker__preview:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.color-picker__preview-color {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
}
.color-picker__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;
}
}
.color-picker__user-input {
display: flex;
padding: 0 var(--spacing) var(--spacing) var(--spacing);
}
.color-picker__user-input wa-input {
min-width: 0; /* fix input width in Safari */
flex: 1 1 auto;
}
.color-picker__user-input wa-button-group {
margin-inline-start: var(--spacing);
}
.color-picker__user-input wa-button:first-of-type {
min-width: 3rem;
max-width: 3rem;
}
.color-picker__swatches {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(var(--swatch-size), 100%), 1fr));
grid-gap: var(--wa-space-xs);
justify-items: center;
border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
var(--wa-color-surface-border);
padding: var(--spacing);
forced-color-adjust: none;
}
.color-picker__swatch {
position: relative;
aspect-ratio: 1 / 1;
width: 100%;
border-radius: var(--swatch-border-radius);
}
.color-picker__swatch .color-picker__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;
}
.color-picker__swatch:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.color-picker__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;
}
.color-picker--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.color-picker--disabled .color-picker__grid,
.color-picker--disabled .color-picker__grid-handle,
.color-picker--disabled .color-picker__slider,
.color-picker--disabled .color-picker__slider-handle,
.color-picker--disabled .color-picker__preview,
.color-picker--disabled .color-picker__swatch,
.color-picker--disabled .color-picker__swatch-color {
pointer-events: none;
}
/*
* Color dropdown
*/
.color-dropdown {
display: flex;
}
.color-dropdown::part(panel) {
max-height: none;
background-color: var(--background-color);
border: var(--border-style) var(--border-width) var(--border-color);
border-radius: var(--border-radius);
overflow: visible;
}
.color-dropdown__trigger {
display: block;
position: relative;
background-color: transparent;
border: none;
cursor: pointer;
forced-color-adjust: none;
}
.color-dropdown__trigger.color-dropdown__trigger--small {
width: var(--wa-form-control-height-s);
height: var(--wa-form-control-height-s);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__trigger.color-dropdown__trigger--medium {
width: var(--wa-form-control-height-m);
height: var(--wa-form-control-height-m);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__trigger.color-dropdown__trigger--large {
width: var(--wa-form-control-height-l);
height: var(--wa-form-control-height-l);
border-radius: var(--trigger-border-radius);
}
.color-dropdown__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 0.0625rem var(--wa-form-control-resting-color),
inset 0 0 0 0.25rem var(--wa-color-surface-default);
}
.color-dropdown__trigger--empty:before {
background-color: transparent;
}
.color-dropdown__trigger:focus-visible {
outline: none;
}
.color-dropdown__trigger:focus-visible:not(.color-dropdown__trigger--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
:host(:disabled) :is(.color-dropdown__label, .color-dropdown__trigger) {
opacity: 0.5;
cursor: not-allowed;
}
.form-control.form-control--has-label .form-control__label {
cursor: pointer;
display: inline-block;
}
`;

View File

@@ -22,9 +22,10 @@ import { WaInputEvent } from '../../events/input.js';
import { WaInvalidEvent } from '../../events/invalid.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import componentStyles from '../../styles/component.styles.js';
import formControlStyles from '../../styles/form-control.styles.js';
import styles from './color-picker.css';
import type { PropertyValues } from 'lit';
import styles from './color-picker.styles.js';
import type { CSSResultGroup, PropertyValues } from 'lit';
import type WaDropdown from '../dropdown/dropdown.js';
import type WaInput from '../input/input.js';
@@ -105,7 +106,7 @@ declare const EyeDropper: EyeDropperConstructor;
*/
@customElement('wa-color-picker')
export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
static shadowStyle = [formControlStyles, styles];
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };

View File

@@ -1,74 +0,0 @@
:host {
--background-color: transparent;
--background-color-hover: var(--wa-color-neutral-fill-quiet);
--error-color: var(--wa-color-danger-fill-loud);
--success-color: var(--wa-color-success-fill-loud);
display: inline-block;
color: var(--wa-color-text-quiet);
}
.copy-button__button {
flex: 0 0 auto;
display: flex;
align-items: center;
background-color: var(--background-color);
border: none;
border-radius: var(--wa-border-radius-s);
color: inherit;
font-size: inherit;
padding: var(--wa-space-xs);
cursor: pointer;
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
}
.copy-button__button:hover:not([disabled]),
.copy-button__button:focus-visible:not([disabled]) {
background-color: var(--background-color-hover);
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.copy-button__button:active:not([disabled]) {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
slot[name='success-icon'] {
color: var(--success-color);
}
slot[name='error-icon'] {
color: var(--error-color);
}
.copy-button__button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.copy-button__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;
}
}

View File

@@ -0,0 +1,78 @@
import { css } from 'lit';
export default css`
:host {
--background-color: transparent;
--background-color-hover: var(--wa-color-neutral-fill-quiet);
--error-color: var(--wa-color-danger-fill-loud);
--success-color: var(--wa-color-success-fill-loud);
display: inline-block;
color: var(--wa-color-text-quiet);
}
.copy-button__button {
flex: 0 0 auto;
display: flex;
align-items: center;
background-color: var(--background-color);
border: none;
border-radius: var(--wa-border-radius-s);
color: inherit;
font-size: inherit;
padding: var(--wa-space-xs);
cursor: pointer;
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
}
.copy-button__button:hover:not([disabled]),
.copy-button__button:focus-visible:not([disabled]) {
background-color: var(--background-color-hover);
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.copy-button__button:active:not([disabled]) {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
slot[name='success-icon'] {
color: var(--success-color);
}
slot[name='error-icon'] {
color: var(--error-color);
}
.copy-button__button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.copy-button__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;
}
}
`;

View File

@@ -8,8 +8,10 @@ import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import { WaCopyEvent } from '../../events/copy.js';
import { WaErrorEvent } from '../../events/error.js';
import styles from './copy-button.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './copy-button.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
import type WaTooltip from '../tooltip/tooltip.js';
/**
@@ -44,7 +46,7 @@ import type WaTooltip from '../tooltip/tooltip.js';
*/
@customElement('wa-copy-button')
export default class WaCopyButton extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);

View File

@@ -1,107 +0,0 @@
:host {
--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);
--border-width: var(--wa-panel-border-width);
--icon-color: var(--wa-color-text-quiet);
--spacing: var(--wa-space-m);
--show-duration: 200ms;
--hide-duration: 200ms;
display: block;
}
.details {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
overflow-anchor: none;
}
.details--disabled {
opacity: 0.5;
}
.details__header {
display: flex;
align-items: center;
padding: var(--spacing);
user-select: none;
-webkit-user-select: none;
cursor: pointer;
}
.details__header::-webkit-details-marker {
display: none;
}
.details__header:focus {
outline: none;
}
.details__header:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: calc(1px + var(--wa-focus-ring-offset));
}
.details--disabled .details__header {
cursor: not-allowed;
}
.details--disabled .details__header:focus-visible {
outline: none;
box-shadow: none;
}
.details__summary {
flex: 1 1 auto;
display: flex;
align-items: center;
}
.details__summary-icon {
flex: 0 0 auto;
display: flex;
align-items: center;
color: var(--icon-color);
transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
}
.details--open .details__summary-icon {
rotate: 90deg;
}
.details--open.details--rtl .details__summary-icon {
rotate: -90deg;
}
.details--open slot[name='expand-icon'],
.details:not(.details--open) slot[name='collapse-icon'] {
display: none;
}
/* Overflows get clipped during the closing animation if we don't wait until the close is gone. */
:not(.details--open) .details__body {
overflow: hidden;
}
.details__content {
display: block;
padding: var(--spacing);
}
.show {
}
.hide {
}
@keyframes show {
from {
}
to {
}
}

View File

@@ -0,0 +1,111 @@
import { css } from 'lit';
export default css`
:host {
--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);
--border-width: var(--wa-panel-border-width);
--icon-color: var(--wa-color-text-quiet);
--spacing: var(--wa-space-m);
--show-duration: 200ms;
--hide-duration: 200ms;
display: block;
}
.details {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
overflow-anchor: none;
}
.details--disabled {
opacity: 0.5;
}
.details__header {
display: flex;
align-items: center;
padding: var(--spacing);
user-select: none;
-webkit-user-select: none;
cursor: pointer;
}
.details__header::-webkit-details-marker {
display: none;
}
.details__header:focus {
outline: none;
}
.details__header:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: calc(1px + var(--wa-focus-ring-offset));
}
.details--disabled .details__header {
cursor: not-allowed;
}
.details--disabled .details__header:focus-visible {
outline: none;
box-shadow: none;
}
.details__summary {
flex: 1 1 auto;
display: flex;
align-items: center;
}
.details__summary-icon {
flex: 0 0 auto;
display: flex;
align-items: center;
color: var(--icon-color);
transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
}
.details--open .details__summary-icon {
rotate: 90deg;
}
.details--open.details--rtl .details__summary-icon {
rotate: -90deg;
}
.details--open slot[name='expand-icon'],
.details:not(.details--open) slot[name='collapse-icon'] {
display: none;
}
/* Overflows get clipped during the closing animation if we don't wait until the close is gone. */
:not(.details--open) .details__body {
overflow: hidden;
}
.details__content {
display: block;
padding: var(--spacing);
}
.show {
}
.hide {
}
@keyframes show {
from {
}
to {
}
}
`;

View File

@@ -10,8 +10,10 @@ import { WaHideEvent } from '../../events/hide.js';
import { waitForEvent } from '../../internal/event.js';
import { WaShowEvent } from '../../events/show.js';
import { watch } from '../../internal/watch.js';
import styles from './details.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './details.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Details show a brief summary and expand to show additional content.
@@ -49,7 +51,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-details')
export default class WaDetails extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private detailsObserver: MutationObserver;
private readonly localize = new LocalizeController(this);

View File

@@ -1,173 +0,0 @@
:host {
--background-color: var(--wa-color-surface-raised);
--border-radius: var(--wa-panel-border-radius);
--box-shadow: var(--wa-shadow-l);
--width: 31rem;
--spacing: var(--wa-space-xl);
--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(--background-color);
border-radius: var(--border-radius);
border: none;
box-shadow: var(--box-shadow);
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;
}
}
.dialog--open {
display: flex;
opacity: 1;
}
.dialog__header {
flex: 0 0 auto;
display: flex;
flex-wrap: nowrap;
padding: var(--spacing);
padding-block-end: 0;
}
.dialog__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;
}
.dialog__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);
}
.dialog__header-actions wa-icon-button,
.dialog__header-actions ::slotted(wa-icon-button) {
flex: 0 0 auto;
display: flex;
align-items: center;
font-size: var(--wa-font-size-m);
}
.dialog__body {
flex: 1 1 auto;
display: block;
padding: var(--spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.dialog__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;
}
.dialog__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;
}
}

View File

@@ -0,0 +1,177 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-color-surface-raised);
--border-radius: var(--wa-panel-border-radius);
--box-shadow: var(--wa-shadow-l);
--width: 31rem;
--spacing: var(--wa-space-xl);
--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(--background-color);
border-radius: var(--border-radius);
border: none;
box-shadow: var(--box-shadow);
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;
}
}
.dialog--open {
display: flex;
opacity: 1;
}
.dialog__header {
flex: 0 0 auto;
display: flex;
flex-wrap: nowrap;
padding: var(--spacing);
padding-block-end: 0;
}
.dialog__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;
}
.dialog__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);
}
.dialog__header-actions wa-icon-button,
.dialog__header-actions ::slotted(wa-icon-button) {
flex: 0 0 auto;
display: flex;
align-items: center;
font-size: var(--wa-font-size-m);
}
.dialog__body {
flex: 1 1 auto;
display: block;
padding: var(--spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.dialog__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;
}
.dialog__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;
}
}
`;

View File

@@ -10,8 +10,10 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
import { WaHideEvent } from '../../events/hide.js';
import { WaShowEvent } from '../../events/show.js';
import { watch } from '../../internal/watch.js';
import styles from './dialog.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './dialog.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Dialogs, sometimes called "modals", appear above the page and require the user's immediate attention.
@@ -53,7 +55,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-dialog')
export default class WaDialog extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);
private originalTrigger: HTMLElement | null;

View File

@@ -1,18 +0,0 @@
:host {
--color: var(--wa-color-surface-border);
--width: var(--wa-border-width-s);
--spacing: var(--wa-space-m);
}
:host(:not([vertical])) {
display: block;
border-top: solid var(--width) var(--color);
margin: var(--spacing) 0;
}
:host([vertical]) {
display: inline-block;
height: 100%;
border-left: solid var(--width) var(--color);
margin: 0 var(--spacing);
}

View File

@@ -0,0 +1,22 @@
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([vertical])) {
display: block;
border-top: solid var(--width) var(--color);
margin: var(--spacing) 0;
}
:host([vertical]) {
display: inline-block;
height: 100%;
border-left: solid var(--width) var(--color);
margin: 0 var(--spacing);
}
`;

View File

@@ -1,7 +1,9 @@
import { customElement, property } from 'lit/decorators.js';
import { watch } from '../../internal/watch.js';
import styles from './divider.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './divider.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Dividers are used to visually separate or group elements.
@@ -15,7 +17,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-divider')
export default class WaDivider extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/** Draws the divider in a vertical orientation. */
@property({ type: Boolean, reflect: true }) vertical = false;

View File

@@ -1,280 +0,0 @@
:host {
--background-color: var(--wa-color-surface-raised);
--box-shadow: var(--wa-shadow-l);
--size: 25rem;
--spacing: var(--wa-space-xl);
--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(--background-color);
border: none;
box-shadow: var(--box-shadow);
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.drawer--top {
animation: show-drawer-from-top var(--show-duration) ease;
}
&.hide.drawer--top {
animation: show-drawer-from-top var(--hide-duration) ease reverse;
}
&.show.drawer--end {
animation: show-drawer-from-end var(--show-duration) ease;
&.drawer--rtl {
animation-name: show-drawer-from-start;
}
}
&.hide.drawer--end {
animation: show-drawer-from-end var(--hide-duration) ease reverse;
&.drawer--rtl {
animation-name: show-drawer-from-start;
}
}
&.show.drawer--bottom {
animation: show-drawer-from-bottom var(--show-duration) ease;
}
&.hide.drawer--bottom {
animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
}
&.show.drawer--start {
animation: show-drawer-from-start var(--show-duration) ease;
&.drawer--rtl {
animation-name: show-drawer-from-end;
}
}
&.hide.drawer--start {
animation: show-drawer-from-start var(--hide-duration) ease reverse;
&.drawer--rtl {
animation-name: show-drawer-from-end;
}
}
&.pulse {
animation: pulse 250ms ease;
}
}
.drawer:focus {
outline: none;
}
.drawer--top {
top: 0;
inset-inline-end: auto;
bottom: auto;
inset-inline-start: 0;
width: 100%;
height: var(--size);
}
.drawer--end {
top: 0;
inset-inline-end: 0;
bottom: auto;
inset-inline-start: auto;
width: var(--size);
height: 100%;
}
.drawer--bottom {
top: auto;
inset-inline-end: auto;
bottom: 0;
inset-inline-start: 0;
width: 100%;
height: var(--size);
}
.drawer--start {
top: 0;
inset-inline-end: auto;
bottom: auto;
inset-inline-start: 0;
width: var(--size);
height: 100%;
}
.drawer__header {
display: flex;
flex-wrap: nowrap;
padding: var(--spacing);
padding-block-end: 0;
}
.drawer__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;
}
.drawer__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);
}
.drawer__header-actions wa-icon-button,
.drawer__header-actions ::slotted(wa-icon-button) {
flex: 0 0 auto;
display: flex;
align-items: center;
font-size: var(--wa-font-size-m);
}
.drawer__body {
flex: 1 1 auto;
display: block;
padding: var(--spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.drawer__footer {
display: flex;
flex-wrap: wrap;
gap: var(--wa-space-xs);
justify-content: end;
padding: var(--spacing);
padding-block-start: 0;
}
.drawer__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;
}
}

View File

@@ -0,0 +1,284 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-color-surface-raised);
--box-shadow: var(--wa-shadow-l);
--size: 25rem;
--spacing: var(--wa-space-xl);
--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(--background-color);
border: none;
box-shadow: var(--box-shadow);
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.drawer--top {
animation: show-drawer-from-top var(--show-duration) ease;
}
&.hide.drawer--top {
animation: show-drawer-from-top var(--hide-duration) ease reverse;
}
&.show.drawer--end {
animation: show-drawer-from-end var(--show-duration) ease;
&.drawer--rtl {
animation-name: show-drawer-from-start;
}
}
&.hide.drawer--end {
animation: show-drawer-from-end var(--hide-duration) ease reverse;
&.drawer--rtl {
animation-name: show-drawer-from-start;
}
}
&.show.drawer--bottom {
animation: show-drawer-from-bottom var(--show-duration) ease;
}
&.hide.drawer--bottom {
animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
}
&.show.drawer--start {
animation: show-drawer-from-start var(--show-duration) ease;
&.drawer--rtl {
animation-name: show-drawer-from-end;
}
}
&.hide.drawer--start {
animation: show-drawer-from-start var(--hide-duration) ease reverse;
&.drawer--rtl {
animation-name: show-drawer-from-end;
}
}
&.pulse {
animation: pulse 250ms ease;
}
}
.drawer:focus {
outline: none;
}
.drawer--top {
top: 0;
inset-inline-end: auto;
bottom: auto;
inset-inline-start: 0;
width: 100%;
height: var(--size);
}
.drawer--end {
top: 0;
inset-inline-end: 0;
bottom: auto;
inset-inline-start: auto;
width: var(--size);
height: 100%;
}
.drawer--bottom {
top: auto;
inset-inline-end: auto;
bottom: 0;
inset-inline-start: 0;
width: 100%;
height: var(--size);
}
.drawer--start {
top: 0;
inset-inline-end: auto;
bottom: auto;
inset-inline-start: 0;
width: var(--size);
height: 100%;
}
.drawer__header {
display: flex;
flex-wrap: nowrap;
padding: var(--spacing);
padding-block-end: 0;
}
.drawer__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;
}
.drawer__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);
}
.drawer__header-actions wa-icon-button,
.drawer__header-actions ::slotted(wa-icon-button) {
flex: 0 0 auto;
display: flex;
align-items: center;
font-size: var(--wa-font-size-m);
}
.drawer__body {
flex: 1 1 auto;
display: block;
padding: var(--spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.drawer__footer {
display: flex;
flex-wrap: wrap;
gap: var(--wa-space-xs);
justify-content: end;
padding: var(--spacing);
padding-block-start: 0;
}
.drawer__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;
}
}
`;

View File

@@ -10,8 +10,10 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
import { WaHideEvent } from '../../events/hide.js';
import { WaShowEvent } from '../../events/show.js';
import { watch } from '../../internal/watch.js';
import styles from './drawer.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './drawer.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Drawers slide in from a container to expose additional options and information.
@@ -58,7 +60,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-drawer')
export default class WaDrawer extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);
private originalTrigger: HTMLElement | null;

View File

@@ -1,47 +0,0 @@
:host {
--box-shadow: var(--wa-shadow-m);
display: inline-block;
}
.dropdown::part(popup) {
z-index: 900;
}
.dropdown[data-current-placement^='top']::part(popup) {
transform-origin: bottom;
}
.dropdown[data-current-placement^='bottom']::part(popup) {
transform-origin: top;
}
.dropdown[data-current-placement^='left']::part(popup) {
transform-origin: right;
}
.dropdown[data-current-placement^='right']::part(popup) {
transform-origin: left;
}
.dropdown__trigger {
display: block;
}
.dropdown__panel {
font: inherit;
box-shadow: var(--box-shadow);
border-radius: var(--wa-border-radius-s);
pointer-events: none;
}
.dropdown--open .dropdown__panel {
display: block;
pointer-events: all;
}
/* When users slot a menu, make sure it conforms to the popup's auto-size */
::slotted(wa-menu) {
max-width: var(--auto-size-available-width) !important;
max-height: var(--auto-size-available-height) !important;
}

View File

@@ -0,0 +1,51 @@
import { css } from 'lit';
export default css`
:host {
--box-shadow: var(--wa-shadow-m);
display: inline-block;
}
.dropdown::part(popup) {
z-index: 900;
}
.dropdown[data-current-placement^='top']::part(popup) {
transform-origin: bottom;
}
.dropdown[data-current-placement^='bottom']::part(popup) {
transform-origin: top;
}
.dropdown[data-current-placement^='left']::part(popup) {
transform-origin: right;
}
.dropdown[data-current-placement^='right']::part(popup) {
transform-origin: left;
}
.dropdown__trigger {
display: block;
}
.dropdown__panel {
font: inherit;
box-shadow: var(--box-shadow);
border-radius: var(--wa-border-radius-s);
pointer-events: none;
}
.dropdown--open .dropdown__panel {
display: block;
pointer-events: all;
}
/* When users slot a menu, make sure it conforms to the popup's auto-size */
::slotted(wa-menu) {
max-width: var(--auto-size-available-width) !important;
max-height: var(--auto-size-available-height) !important;
}
`;

View File

@@ -10,8 +10,10 @@ import { WaHideEvent } from '../../events/hide.js';
import { waitForEvent } from '../../internal/event.js';
import { WaShowEvent } from '../../events/show.js';
import { watch } from '../../internal/watch.js';
import styles from './dropdown.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './dropdown.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
import type { WaSelectEvent } from '../../events/select.js';
import type WaButton from '../button/button.js';
import type WaIconButton from '../icon-button/icon-button.js';
@@ -43,7 +45,7 @@ import type WaPopup from '../popup/popup.js';
*/
@customElement('wa-dropdown')
export default class WaDropdown extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('.dropdown') popup: WaPopup;
@query('.dropdown__trigger') trigger: HTMLSlotElement;

View File

@@ -1,49 +0,0 @@
:host {
--background-color-hover: var(--wa-color-neutral-fill-quiet);
display: inline-block;
color: var(--wa-color-text-quiet);
}
.icon-button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
font-size: inherit;
color: inherit;
padding: var(--wa-space-xs);
cursor: pointer;
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
-webkit-appearance: none;
}
.icon-button:hover:not(.icon-button--disabled),
.icon-button:focus-visible:not(.icon-button--disabled) {
background-color: var(--wa-color-neutral-fill-quiet);
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.icon-button:active:not(.icon-button--disabled) {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.icon-button:focus {
outline: none;
}
.icon-button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.icon-button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.icon-button__icon {
pointer-events: none;
}

View File

@@ -0,0 +1,53 @@
import { css } from 'lit';
export default css`
:host {
--background-color-hover: var(--wa-color-neutral-fill-quiet);
display: inline-block;
color: var(--wa-color-text-quiet);
}
.icon-button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--wa-border-radius-s);
font-size: inherit;
color: inherit;
padding: var(--wa-space-xs);
cursor: pointer;
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
-webkit-appearance: none;
}
.icon-button:hover:not(.icon-button--disabled),
.icon-button:focus-visible:not(.icon-button--disabled) {
background-color: var(--wa-color-neutral-fill-quiet);
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.icon-button:active:not(.icon-button--disabled) {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.icon-button:focus {
outline: none;
}
.icon-button--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.icon-button:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.icon-button__icon {
pointer-events: none;
}
`;

View File

@@ -6,7 +6,9 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { WaBlurEvent } from '../../events/blur.js';
import { WaFocusEvent } from '../../events/focus.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import styles from './icon-button.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './icon-button.styles.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Icons buttons are simple, icon-only buttons that can be used for actions and in toolbars.
@@ -25,7 +27,7 @@ import styles from './icon-button.css';
*/
@customElement('wa-icon-button')
export default class WaIconButton extends WebAwesomeFormAssociatedElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('.icon-button') button: HTMLButtonElement | HTMLLinkElement;

View File

@@ -1,33 +0,0 @@
:host {
--primary-color: currentColor;
--primary-opacity: 1;
--secondary-color: currentColor;
--secondary-opacity: 0.4;
display: inline-flex;
box-sizing: content-box !important;
width: auto;
height: 1em;
}
svg {
display: inline-block;
width: auto;
height: 1em;
fill: currentColor;
.fa-primary {
color: var(--primary-color);
opacity: var(--primary-opacity);
}
.fa-secondary {
color: var(--secondary-color);
opacity: var(--secondary-opacity);
}
}
:host([fixed-width]) {
width: 1em;
justify-content: center;
}

View File

@@ -0,0 +1,37 @@
import { css } from 'lit';
export default css`
:host {
--primary-color: currentColor;
--primary-opacity: 1;
--secondary-color: currentColor;
--secondary-opacity: 0.4;
display: inline-flex;
box-sizing: content-box !important;
width: auto;
height: 1em;
}
svg {
display: inline-block;
width: auto;
height: 1em;
fill: currentColor;
.fa-primary {
color: var(--primary-color);
opacity: var(--primary-opacity);
}
.fa-secondary {
color: var(--secondary-color);
opacity: var(--secondary-opacity);
}
}
:host([fixed-width]) {
width: 1em;
justify-content: center;
}
`;

View File

@@ -5,10 +5,11 @@ import { isTemplateResult } from 'lit/directive-helpers.js';
import { WaErrorEvent } from '../../events/error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import styles from './icon.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './icon.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { HTMLTemplateResult, PropertyValues } from 'lit';
import type { CSSResultGroup, HTMLTemplateResult, PropertyValues } from 'lit';
const CACHEABLE_ERROR = Symbol();
const RETRYABLE_ERROR = Symbol();
@@ -41,7 +42,7 @@ interface IconSource {
*/
@customElement('wa-icon')
export default class WaIcon extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private initialRender = false;

View File

@@ -1,72 +0,0 @@
:host {
--divider-color: var(--wa-color-neutral-fill-quiet);
--divider-width: 0.125rem;
--handle-color: var(--wa-color-neutral-on-quiet);
--handle-size: 2.5rem;
display: inline-block;
position: relative;
}
.image-comparer {
max-width: 100%;
max-height: 100%;
overflow: hidden;
}
.image-comparer__before,
.image-comparer__after {
display: block;
pointer-events: none;
}
.image-comparer__before::slotted(img),
.image-comparer__after::slotted(img),
.image-comparer__before::slotted(svg),
.image-comparer__after::slotted(svg) {
display: block;
max-width: 100% !important;
height: auto;
}
.image-comparer__after {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.image-comparer__divider {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
width: var(--divider-width);
height: 100%;
background-color: var(--divider-color);
translate: calc(var(--divider-width) / -2);
cursor: ew-resize;
}
.image-comparer__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(--divider-color);
border-radius: var(--wa-border-radius-circle);
font-size: calc(var(--handle-size) * 0.4);
color: var(--handle-color);
cursor: inherit;
z-index: 10;
}
.image-comparer__handle:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}

View File

@@ -0,0 +1,76 @@
import { css } from 'lit';
export default css`
:host {
--divider-color: var(--wa-color-neutral-fill-quiet);
--divider-width: 0.125rem;
--handle-color: var(--wa-color-neutral-on-quiet);
--handle-size: 2.5rem;
display: inline-block;
position: relative;
}
.image-comparer {
max-width: 100%;
max-height: 100%;
overflow: hidden;
}
.image-comparer__before,
.image-comparer__after {
display: block;
pointer-events: none;
}
.image-comparer__before::slotted(img),
.image-comparer__after::slotted(img),
.image-comparer__before::slotted(svg),
.image-comparer__after::slotted(svg) {
display: block;
max-width: 100% !important;
height: auto;
}
.image-comparer__after {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.image-comparer__divider {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
width: var(--divider-width);
height: 100%;
background-color: var(--divider-color);
translate: calc(var(--divider-width) / -2);
cursor: ew-resize;
}
.image-comparer__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(--divider-color);
border-radius: var(--wa-border-radius-circle);
font-size: calc(var(--handle-size) * 0.4);
color: var(--handle-color);
cursor: inherit;
z-index: 10;
}
.image-comparer__handle:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
`;

View File

@@ -8,8 +8,10 @@ import { LocalizeController } from '../../utilities/localize.js';
import { styleMap } from 'lit/directives/style-map.js';
import { WaChangeEvent } from '../../events/change.js';
import { watch } from '../../internal/watch.js';
import styles from './image-comparer.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './image-comparer.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Compare visual differences between similar photos with a sliding panel.
@@ -38,7 +40,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-image-comparer')
export default class WaImageComparer extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);

View File

@@ -1,3 +0,0 @@
:host {
display: block;
}

View File

@@ -0,0 +1,7 @@
import { css } from 'lit';
export default css`
:host {
display: block;
}
`;

View File

@@ -4,8 +4,10 @@ import { requestInclude } from './request.js';
import { WaIncludeErrorEvent } from '../../events/include-error.js';
import { WaLoadEvent } from '../../events/load.js';
import { watch } from '../../internal/watch.js';
import styles from './include.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './include.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Includes give you the power to embed external HTML files into the page.
@@ -18,7 +20,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-include')
export default class WaInclude extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
/**
* The location of the HTML file to include. Be sure you trust the content you are including as it will be executed as

View File

@@ -1,262 +0,0 @@
:host {
--background-color: var(--wa-form-control-background-color);
--border-color: var(--wa-form-control-resting-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);
--box-shadow: initial;
display: block;
}
:host([filled]) {
--background-color: var(--wa-color-neutral-fill-quiet);
--border-color: var(--background-color);
}
.input {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
flex: 1 1 auto;
display: inline-flex;
align-items: stretch;
justify-content: start;
position: relative;
width: 100%;
font: inherit;
vertical-align: middle;
overflow: hidden;
cursor: text;
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border var(--wa-transition-normal) var(--wa-transition-easing),
outline var(--wa-transition-fast) var(--wa-transition-easing);
}
/* Standard inputs */
.input--standard.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
border-color: var(--wa-form-control-activated-color);
}
.input--standard.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Filled inputs */
.input--filled.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.input--filled.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.input__control {
flex: 1 1 auto;
min-width: 0;
height: 100%;
font: inherit;
line-height: var(--wa-form-control-value-line-height);
color: var(--wa-form-control-value-color);
border: none;
/* prettier-ignore */
background-color: rgb(118 118 118 / 0); /* ensures proper placeholder styles in webkit's date input */
box-shadow: none;
padding: 0;
margin: 0;
cursor: inherit;
-webkit-appearance: none;
}
.input__control::-webkit-search-decoration,
.input__control::-webkit-search-cancel-button,
.input__control::-webkit-search-results-button,
.input__control::-webkit-search-results-decoration {
-webkit-appearance: none;
}
.input__control:-webkit-autofill,
.input__control:-webkit-autofill:hover,
.input__control:-webkit-autofill:focus,
.input__control:-webkit-autofill:active {
box-shadow: none;
-webkit-text-fill-color: var(--wa-color-brand-on-normal);
caret-color: var(--wa-form-control-value-color);
}
.input--filled .input__control:-webkit-autofill,
.input--filled .input__control:-webkit-autofill:hover,
.input--filled .input__control:-webkit-autofill:focus,
.input--filled .input__control:-webkit-autofill:active {
box-shadow: none;
}
.input__control::placeholder {
color: var(--wa-form-control-placeholder-color);
user-select: none;
-webkit-user-select: none;
}
.input__control:focus {
outline: none;
}
.input__prefix,
.input__suffix {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
cursor: default;
}
.input__prefix ::slotted(wa-icon),
.input__suffix ::slotted(wa-icon) {
color: var(--wa-color-neutral-on-quiet);
}
/*
* Size modifiers
*/
.input--small {
font-size: var(--wa-font-size-s);
height: var(--wa-form-control-height-s);
}
.input--small .input__control {
height: calc(var(--wa-form-control-height-s) - var(--border-width) * 2);
padding: 0 var(--wa-space-s);
}
.input--small .input__clear,
.input--small .input__password-toggle {
width: calc(1em + var(--wa-space-s) * 2);
}
.input--small .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-s);
}
.input--small .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-s);
}
.input--medium {
font-size: var(--wa-font-size-m);
height: var(--wa-form-control-height-m);
}
.input--medium .input__control {
height: calc(var(--wa-form-control-height-m) - var(--border-width) * 2);
padding: 0 var(--wa-space-m);
}
.input--medium .input__clear,
.input--medium .input__password-toggle {
width: calc(1em + var(--wa-space-m) * 2);
}
.input--medium .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-m);
}
.input--medium .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-m);
}
.input--large {
font-size: var(--wa-font-size-l);
height: var(--wa-form-control-height-l);
}
.input--large .input__control {
height: calc(var(--wa-form-control-height-l) - var(--border-width) * 2);
padding: 0 var(--wa-space-l);
}
.input--large .input__clear,
.input--large .input__password-toggle {
width: calc(1em + var(--wa-space-l) * 2);
}
.input--large .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-l);
}
.input--large .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-l);
}
/*
* Pill modifier
*/
.input--pill.input--small {
border-radius: var(--wa-border-radius-pill);
}
.input--pill.input--medium {
border-radius: var(--wa-border-radius-pill);
}
.input--pill.input--large {
border-radius: var(--wa-border-radius-pill);
}
/*
* Clearable + Password Toggle
*/
.input__clear,
.input__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;
}
.input__clear:hover,
.input__password-toggle:hover {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.input__clear:active,
.input__password-toggle:active {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.input__clear:focus,
.input__password-toggle:focus {
outline: none;
}
/* Don't show the browser's password toggle in Edge */
::-ms-reveal {
display: none;
}
/* Hide the built-in number spinner */
.input--no-spin-buttons input[type='number']::-webkit-outer-spin-button,
.input--no-spin-buttons input[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
display: none;
}
.input--no-spin-buttons input[type='number'] {
-moz-appearance: textfield;
}

View File

@@ -0,0 +1,266 @@
import { css } from 'lit';
export default css`
:host {
--background-color: var(--wa-form-control-background-color);
--border-color: var(--wa-form-control-resting-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);
--box-shadow: initial;
display: block;
}
:host([filled]) {
--background-color: var(--wa-color-neutral-fill-quiet);
--border-color: var(--background-color);
}
.input {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
flex: 1 1 auto;
display: inline-flex;
align-items: stretch;
justify-content: start;
position: relative;
width: 100%;
font: inherit;
vertical-align: middle;
overflow: hidden;
cursor: text;
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border var(--wa-transition-normal) var(--wa-transition-easing),
outline var(--wa-transition-fast) var(--wa-transition-easing);
}
/* Standard inputs */
.input--standard.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
border-color: var(--wa-form-control-activated-color);
}
.input--standard.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Filled inputs */
.input--filled.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.input--filled.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.input__control {
flex: 1 1 auto;
min-width: 0;
height: 100%;
font: inherit;
line-height: var(--wa-form-control-value-line-height);
color: var(--wa-form-control-value-color);
border: none;
/* prettier-ignore */
background-color: rgb(118 118 118 / 0); /* ensures proper placeholder styles in webkit's date input */
box-shadow: none;
padding: 0;
margin: 0;
cursor: inherit;
-webkit-appearance: none;
}
.input__control::-webkit-search-decoration,
.input__control::-webkit-search-cancel-button,
.input__control::-webkit-search-results-button,
.input__control::-webkit-search-results-decoration {
-webkit-appearance: none;
}
.input__control:-webkit-autofill,
.input__control:-webkit-autofill:hover,
.input__control:-webkit-autofill:focus,
.input__control:-webkit-autofill:active {
box-shadow: none;
-webkit-text-fill-color: var(--wa-color-brand-on-normal);
caret-color: var(--wa-form-control-value-color);
}
.input--filled .input__control:-webkit-autofill,
.input--filled .input__control:-webkit-autofill:hover,
.input--filled .input__control:-webkit-autofill:focus,
.input--filled .input__control:-webkit-autofill:active {
box-shadow: none;
}
.input__control::placeholder {
color: var(--wa-form-control-placeholder-color);
user-select: none;
-webkit-user-select: none;
}
.input__control:focus {
outline: none;
}
.input__prefix,
.input__suffix {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
cursor: default;
}
.input__prefix ::slotted(wa-icon),
.input__suffix ::slotted(wa-icon) {
color: var(--wa-color-neutral-on-quiet);
}
/*
* Size modifiers
*/
.input--small {
font-size: var(--wa-font-size-s);
height: var(--wa-form-control-height-s);
}
.input--small .input__control {
height: calc(var(--wa-form-control-height-s) - var(--border-width) * 2);
padding: 0 var(--wa-space-s);
}
.input--small .input__clear,
.input--small .input__password-toggle {
width: calc(1em + var(--wa-space-s) * 2);
}
.input--small .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-s);
}
.input--small .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-s);
}
.input--medium {
font-size: var(--wa-font-size-m);
height: var(--wa-form-control-height-m);
}
.input--medium .input__control {
height: calc(var(--wa-form-control-height-m) - var(--border-width) * 2);
padding: 0 var(--wa-space-m);
}
.input--medium .input__clear,
.input--medium .input__password-toggle {
width: calc(1em + var(--wa-space-m) * 2);
}
.input--medium .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-m);
}
.input--medium .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-m);
}
.input--large {
font-size: var(--wa-font-size-l);
height: var(--wa-form-control-height-l);
}
.input--large .input__control {
height: calc(var(--wa-form-control-height-l) - var(--border-width) * 2);
padding: 0 var(--wa-space-l);
}
.input--large .input__clear,
.input--large .input__password-toggle {
width: calc(1em + var(--wa-space-l) * 2);
}
.input--large .input__prefix ::slotted(*) {
margin-inline-start: var(--wa-space-l);
}
.input--large .input__suffix ::slotted(*) {
margin-inline-end: var(--wa-space-l);
}
/*
* Pill modifier
*/
.input--pill.input--small {
border-radius: var(--wa-border-radius-pill);
}
.input--pill.input--medium {
border-radius: var(--wa-border-radius-pill);
}
.input--pill.input--large {
border-radius: var(--wa-border-radius-pill);
}
/*
* Clearable + Password Toggle
*/
.input__clear,
.input__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;
}
.input__clear:hover,
.input__password-toggle:hover {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
}
.input__clear:active,
.input__password-toggle:active {
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
}
.input__clear:focus,
.input__password-toggle:focus {
outline: none;
}
/* Don't show the browser's password toggle in Edge */
::-ms-reveal {
display: none;
}
/* Hide the built-in number spinner */
.input--no-spin-buttons input[type='number']::-webkit-outer-spin-button,
.input--no-spin-buttons input[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
display: none;
}
.input--no-spin-buttons input[type='number'] {
-moz-appearance: textfield;
}
`;

View File

@@ -14,8 +14,10 @@ import { WaFocusEvent } from '../../events/focus.js';
import { WaInputEvent } from '../../events/input.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import componentStyles from '../../styles/component.styles.js';
import formControlStyles from '../../styles/form-control.styles.js';
import styles from './input.css';
import styles from './input.styles.js';
import type { CSSResultGroup } from 'lit';
import type WaButton from '../button/button.js';
/**
@@ -61,7 +63,7 @@ import type WaButton from '../button/button.js';
*/
@customElement('wa-input')
export default class WaInput extends WebAwesomeFormAssociatedElement {
static shadowStyle = [formControlStyles, styles];
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };

View File

@@ -1,152 +0,0 @@
:host {
--background-color-hover: var(--wa-color-neutral-fill-normal);
--label-color-hover: var(--wa-color-neutral-on-normal);
--submenu-offset: -0.125rem;
display: block;
color: var(--wa-color-text-normal);
}
:host([inert]) {
display: none;
}
.menu-item {
position: relative;
display: flex;
align-items: stretch;
font: inherit;
padding: var(--wa-space-xs) var(--wa-space-2xs);
line-height: var(--wa-line-height-condensed);
transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
cursor: pointer;
}
.menu-item.menu-item--disabled {
outline: none;
opacity: 0.5;
cursor: not-allowed;
}
.menu-item.menu-item--loading {
outline: none;
cursor: wait;
}
.menu-item.menu-item--loading *:not(wa-spinner) {
opacity: 0.5;
}
.menu-item--loading wa-spinner {
--indicator-color: currentColor;
--track-width: 0.0625rem;
position: absolute;
font-size: 0.8em;
top: calc(50% - 0.5em);
left: 0.5rem;
opacity: 1;
}
.menu-item .menu-item__label {
flex: 1 1 auto;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
}
.menu-item .menu-item__prefix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.menu-item .menu-item__prefix::slotted(*) {
margin-inline-end: var(--wa-space-xs);
}
.menu-item .menu-item__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.menu-item .menu-item__suffix::slotted(*) {
margin-inline-start: var(--wa-space-xs);
}
/* Safe triangle */
.menu-item--submenu-expanded::after {
content: '';
position: fixed;
z-index: 899;
top: 0;
right: 0;
bottom: 0;
left: 0;
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)
);
}
:host(:focus-visible) {
outline: none;
}
:host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item,
.menu-item--submenu-expanded {
background-color: var(--background-color-hover);
color: var(--label-color-hover);
}
:host(:focus-visible) .menu-item {
outline: var(--wa-focus-ring);
outline-offset: calc(-1 * var(--wa-focus-ring-width));
background: var(--background-color-hover);
color: var(--label-color-hover);
opacity: 1;
}
.menu-item .menu-item__check,
.menu-item .menu-item__chevron {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875em;
width: var(--wa-space-xl);
visibility: hidden;
}
.menu-item--checked .menu-item__check,
.menu-item--has-submenu .menu-item__chevron {
visibility: visible;
}
/* Add elevation and z-index to submenus */
wa-popup::part(popup) {
box-shadow: var(--wa-shadow-m);
z-index: 900;
margin-left: var(--submenu-offset);
}
.menu-item--rtl wa-popup::part(popup) {
margin-left: calc(-1 * var(--submenu-offset));
}
@media (forced-colors: active) {
:host(:hover:not([aria-disabled='true'])) .menu-item,
:host(:focus-visible) .menu-item {
outline: dashed 1px SelectedItem;
outline-offset: -1px;
}
}
::slotted(wa-menu) {
max-width: var(--auto-size-available-width) !important;
max-height: var(--auto-size-available-height) !important;
}

View File

@@ -0,0 +1,156 @@
import { css } from 'lit';
export default css`
:host {
--background-color-hover: var(--wa-color-neutral-fill-normal);
--label-color-hover: var(--wa-color-neutral-on-normal);
--submenu-offset: -0.125rem;
display: block;
color: var(--wa-color-text-normal);
}
:host([inert]) {
display: none;
}
.menu-item {
position: relative;
display: flex;
align-items: stretch;
font: inherit;
padding: var(--wa-space-xs) var(--wa-space-2xs);
line-height: var(--wa-line-height-condensed);
transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
cursor: pointer;
}
.menu-item.menu-item--disabled {
outline: none;
opacity: 0.5;
cursor: not-allowed;
}
.menu-item.menu-item--loading {
outline: none;
cursor: wait;
}
.menu-item.menu-item--loading *:not(wa-spinner) {
opacity: 0.5;
}
.menu-item--loading wa-spinner {
--indicator-color: currentColor;
--track-width: 0.0625rem;
position: absolute;
font-size: 0.8em;
top: calc(50% - 0.5em);
left: 0.5rem;
opacity: 1;
}
.menu-item .menu-item__label {
flex: 1 1 auto;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
}
.menu-item .menu-item__prefix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.menu-item .menu-item__prefix::slotted(*) {
margin-inline-end: var(--wa-space-xs);
}
.menu-item .menu-item__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.menu-item .menu-item__suffix::slotted(*) {
margin-inline-start: var(--wa-space-xs);
}
/* Safe triangle */
.menu-item--submenu-expanded::after {
content: '';
position: fixed;
z-index: 899;
top: 0;
right: 0;
bottom: 0;
left: 0;
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)
);
}
:host(:focus-visible) {
outline: none;
}
:host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item,
.menu-item--submenu-expanded {
background-color: var(--background-color-hover);
color: var(--label-color-hover);
}
:host(:focus-visible) .menu-item {
outline: var(--wa-focus-ring);
outline-offset: calc(-1 * var(--wa-focus-ring-width));
background: var(--background-color-hover);
color: var(--label-color-hover);
opacity: 1;
}
.menu-item .menu-item__check,
.menu-item .menu-item__chevron {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875em;
width: var(--wa-space-xl);
visibility: hidden;
}
.menu-item--checked .menu-item__check,
.menu-item--has-submenu .menu-item__chevron {
visibility: visible;
}
/* Add elevation and z-index to submenus */
wa-popup::part(popup) {
box-shadow: var(--wa-shadow-m);
z-index: 900;
margin-left: var(--submenu-offset);
}
.menu-item--rtl wa-popup::part(popup) {
margin-left: calc(-1 * var(--submenu-offset));
}
@media (forced-colors: active) {
:host(:hover:not([aria-disabled='true'])) .menu-item,
:host(:focus-visible) .menu-item {
outline: dashed 1px SelectedItem;
outline-offset: -1px;
}
}
::slotted(wa-menu) {
max-width: var(--auto-size-available-width) !important;
max-height: var(--auto-size-available-height) !important;
}
`;

View File

@@ -8,9 +8,10 @@ import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import { SubmenuController } from './submenu-controller.js';
import { watch } from '../../internal/watch.js';
import styles from './menu-item.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './menu-item.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { PropertyValues } from 'lit';
import type { CSSResultGroup, PropertyValues } from 'lit';
/**
* @summary Menu items provide options for the user to pick from in a menu.
@@ -41,7 +42,7 @@ import type { PropertyValues } from 'lit';
*/
@customElement('wa-menu-item')
export default class WaMenuItem extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private cachedTextLabel: string;
private readonly localize = new LocalizeController(this);

View File

@@ -1,14 +0,0 @@
:host {
display: block;
color: var(--wa-color-text-quiet);
font-size: var(--wa-font-size-s);
font-weight: var(--wa-font-weight-semibold);
}
.menu-label {
display: inline-block;
font: inherit;
padding: var(--wa-space-2xs) calc(var(--wa-space-2xs) + var(--wa-space-xl));
user-select: none;
-webkit-user-select: none;
}

View File

@@ -0,0 +1,18 @@
import { css } from 'lit';
export default css`
:host {
display: block;
color: var(--wa-color-text-quiet);
font-size: var(--wa-font-size-s);
font-weight: var(--wa-font-weight-semibold);
}
.menu-label {
display: inline-block;
font: inherit;
padding: var(--wa-space-2xs) calc(var(--wa-space-2xs) + var(--wa-space-xl));
user-select: none;
-webkit-user-select: none;
}
`;

View File

@@ -1,7 +1,9 @@
import { customElement } from 'lit/decorators.js';
import { html } from 'lit';
import styles from './menu-label.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './menu-label.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Menu labels are used to describe a group of menu items.
@@ -15,7 +17,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-menu-label')
export default class WaMenuLabel extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
render() {
return html` <slot part="base" class="menu-label"></slot> `;

View File

@@ -1,15 +0,0 @@
:host {
display: block;
position: relative;
text-align: start;
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-s);
padding: var(--wa-space-xs) 0;
overflow: auto;
overscroll-behavior: none;
}
::slotted(wa-divider) {
--spacing: var(--wa-space-xs);
}

View File

@@ -0,0 +1,19 @@
import { css } from 'lit';
export default css`
:host {
display: block;
position: relative;
text-align: start;
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-s);
padding: var(--wa-space-xs) 0;
overflow: auto;
overscroll-behavior: none;
}
::slotted(wa-divider) {
--spacing: var(--wa-space-xs);
}
`;

View File

@@ -2,8 +2,10 @@ import '../menu-item/menu-item.js';
import { customElement, query } from 'lit/decorators.js';
import { html } from 'lit';
import { WaSelectEvent } from '../../events/select.js';
import styles from './menu.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './menu.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
import type WaMenuItem from '../menu-item/menu-item.js';
export interface MenuSelectEventDetail {
@@ -24,7 +26,7 @@ export interface MenuSelectEventDetail {
*/
@customElement('wa-menu')
export default class WaMenu extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
@query('slot') defaultSlot: HTMLSlotElement;

View File

@@ -1,3 +0,0 @@
:host {
display: contents;
}

View File

@@ -0,0 +1,7 @@
import { css } from 'lit';
export default css`
:host {
display: contents;
}
`;

View File

@@ -2,8 +2,10 @@ import { customElement, property } from 'lit/decorators.js';
import { html } from 'lit';
import { WaMutationEvent } from '../../events/mutation.js';
import { watch } from '../../internal/watch.js';
import styles from './mutation-observer.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './mutation-observer.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary The Mutation Observer component offers a thin, declarative interface to the [`MutationObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).
@@ -17,7 +19,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-mutation-observer')
export default class WaMutationObserver extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private mutationObserver: MutationObserver;

View File

@@ -1,85 +0,0 @@
:host {
--background-color-current: var(--wa-color-brand-fill-loud);
--background-color-hover: var(--wa-color-neutral-fill-normal);
--label-color-current: var(--wa-color-brand-on-loud);
--label-color-hover: var(--wa-color-neutral-on-normal);
display: block;
color: var(--wa-color-text-normal);
-webkit-user-select: none;
user-select: none;
}
:host(:focus) {
outline: none;
}
.option {
position: relative;
display: flex;
align-items: center;
font: inherit;
padding: var(--wa-space-xs) var(--wa-space-m) var(--wa-space-xs) var(--wa-space-2xs);
line-height: var(--wa-line-height-condensed);
transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
cursor: pointer;
}
.option--hover:not(.option--current):not(.option--disabled) {
background-color: var(--background-color-hover);
color: var(--label-color-hover);
}
.option--current,
.option--current.option--disabled {
background-color: var(--background-color-current);
color: var(--label-color-current);
opacity: 1;
}
.option--disabled {
outline: none;
opacity: 0.5;
cursor: not-allowed;
}
.option__label {
flex: 1 1 auto;
display: inline-block;
}
.option .option__check {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875em;
visibility: hidden;
width: var(--wa-space-xl);
}
.option--selected .option__check {
visibility: visible;
}
.option__prefix,
.option__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.option__prefix::slotted(*) {
margin-inline-end: var(--wa-space-xs);
}
.option__suffix::slotted(*) {
margin-inline-start: var(--wa-space-xs);
}
@media (forced-colors: active) {
:host(:hover:not([aria-disabled='true'])) .option {
outline: dashed 1px SelectedItem;
outline-offset: -1px;
}
}

View File

@@ -0,0 +1,89 @@
import { css } from 'lit';
export default css`
:host {
--background-color-current: var(--wa-color-brand-fill-loud);
--background-color-hover: var(--wa-color-neutral-fill-normal);
--label-color-current: var(--wa-color-brand-on-loud);
--label-color-hover: var(--wa-color-neutral-on-normal);
display: block;
color: var(--wa-color-text-normal);
-webkit-user-select: none;
user-select: none;
}
:host(:focus) {
outline: none;
}
.option {
position: relative;
display: flex;
align-items: center;
font: inherit;
padding: var(--wa-space-xs) var(--wa-space-m) var(--wa-space-xs) var(--wa-space-2xs);
line-height: var(--wa-line-height-condensed);
transition: fill var(--wa-transition-normal) var(--wa-transition-easing);
cursor: pointer;
}
.option--hover:not(.option--current):not(.option--disabled) {
background-color: var(--background-color-hover);
color: var(--label-color-hover);
}
.option--current,
.option--current.option--disabled {
background-color: var(--background-color-current);
color: var(--label-color-current);
opacity: 1;
}
.option--disabled {
outline: none;
opacity: 0.5;
cursor: not-allowed;
}
.option__label {
flex: 1 1 auto;
display: inline-block;
}
.option .option__check {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.875em;
visibility: hidden;
width: var(--wa-space-xl);
}
.option--selected .option__check {
visibility: visible;
}
.option__prefix,
.option__suffix {
flex: 0 0 auto;
display: flex;
align-items: center;
}
.option__prefix::slotted(*) {
margin-inline-end: var(--wa-space-xs);
}
.option__suffix::slotted(*) {
margin-inline-start: var(--wa-space-xs);
}
@media (forced-colors: active) {
:host(:hover:not([aria-disabled='true'])) .option {
outline: dashed 1px SelectedItem;
outline-offset: -1px;
}
}
`;

View File

@@ -4,8 +4,10 @@ import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import { watch } from '../../internal/watch.js';
import styles from './option.css';
import componentStyles from '../../styles/component.styles.js';
import styles from './option.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Options define the selectable items within various form controls such as [select](/docs/components/select).
@@ -32,7 +34,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
*/
@customElement('wa-option')
export default class WaOption extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
// @ts-expect-error - Controller is currently unused
private readonly localize = new LocalizeController(this);

View File

@@ -1,258 +0,0 @@
:host {
display: block;
background-color: var(--wa-color-surface-default);
box-sizing: border-box;
height: 100%;
--menu-width: auto;
--main-width: 1fr;
--aside-width: auto;
--banner-height: 0px;
--header-height: 0px;
--subheader-height: 0px;
--scroll-margin-top: calc(var(--header-height, 0px) + var(--subheader-height, 0px));
}
slot[name]:not([name='skip-to-content'], [name='navigation-toggle'])::slotted(*) {
display: flex;
background-color: var(--wa-color-surface-default);
}
::slotted([slot='banner']) {
align-items: center;
justify-content: center;
gap: var(--wa-space-m);
padding: var(--wa-space-xs) var(--wa-space-m);
}
::slotted([slot='header']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-m);
flex: auto;
}
::slotted([slot='subheader']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-xs) var(--wa-space-m);
}
::slotted([slot*='navigation']),
::slotted([slot='menu']),
::slotted([slot='aside']) {
flex-direction: column;
gap: var(--wa-space-m);
padding: var(--wa-space-m);
}
::slotted([slot='main-header']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-m) var(--wa-space-3xl);
}
::slotted(:not([slot])) {
padding: var(--wa-space-3xl);
}
::slotted([slot='main-footer']),
::slotted([slot='footer']) {
align-items: start;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-3xl);
}
:host([disable-sticky~='banner']) :is([part~='header'], [part~='subheader']) {
--banner-height: 0px !important;
}
:host([disable-sticky~='header']) [part~='subheader'] {
--header-height: 0px !important;
}
/* Nothing else depends on subheader-height. */
:host([disable-sticky~='subheader']) {
}
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
height: unset;
max-height: unset;
}
:host([disable-sticky~='banner']) [part~='banner'],
:host([disable-sticky~='header']) [part~='header'],
:host([disable-sticky~='subheader']) [part~='subheader'],
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
position: static;
overflow: unset;
}
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
height: auto;
max-height: auto;
}
[part~='base'] {
min-height: 100%;
display: grid;
grid-template-rows: repeat(3, minmax(0, auto)) minmax(0, 1fr) minmax(0, auto);
grid-template-columns: 100%;
width: 100%;
grid-template-areas:
'banner'
'header'
'subheader'
'body'
'footer';
}
/* Grid areas */
[part~='banner'] {
grid-area: banner;
}
[part~='header'] {
grid-area: header;
}
[part~='subheader'] {
grid-area: subheader;
}
[part~='menu'] {
grid-area: menu;
}
[part~='body'] {
grid-area: body;
}
[part~='main'] {
grid-area: main;
}
[part~='aside'] {
grid-area: aside;
}
[part~='footer'] {
grid-area: footer;
}
/* Z-indexes */
[part~='banner'],
[part~='header'],
[part~='subheader'] {
position: sticky;
z-index: 5;
}
[part~='banner'] {
top: 0px;
}
[part~='header'] {
top: var(--banner-height);
/** Make the header flex so that you don't unexpectedly have the default toggle button appearing above a slotted div because block elements are fun. */
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
[part~='subheader'] {
top: calc(var(--header-height) + var(--banner-height));
}
[part~='body'] {
display: grid;
height: 100%;
align-items: flex-start;
grid-template-columns: minmax(0, var(--menu-width)) minmax(0, var(--main-width)) minmax(0, var(--aside-width));
grid-template-rows: minmax(0, 1fr);
grid-template-areas: 'menu main aside';
}
[part~='main'] {
display: grid;
min-height: 100%;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
grid-template-areas:
'main-header'
'main-content'
'main-footer';
}
[part~='main-header'] {
grid-area: main-header;
}
[part~='main-content'] {
grid-area: main-content;
}
[part~='main-footer'] {
grid-area: main-footer;
}
/* Visually hidden */
.skip-to-content:not(:focus-within) {
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;
}
.skip-to-content {
position: absolute;
top: var(--wa-space-m);
left: var(--wa-space-m);
z-index: 6;
border-radius: var(--wa-corners-1x);
background-color: var(--wa-color-surface-default);
color: var(--wa-color-text-link);
text-decoration: none;
padding: var(--wa-space-s) var(--wa-space-m);
box-shadow: var(--wa-shadow-l);
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
[part~='menu'],
[part~='aside'] {
position: sticky;
top: calc(var(--banner-height) + var(--header-height) + var(--subheader-height));
z-index: 4;
height: calc(100dvh - var(--header-height) - var(--banner-height) - var(--subheader-height));
max-height: calc(100dvh - var(--header-height) - var(--banner-height) - var(--subheader-height));
overflow: auto;
}
[part~='navigation'] {
height: 100%;
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
}
[part~='drawer']::part(dialog) {
background-color: var(--wa-color-surface-default);
}
/* Set these on the slot because we don't always control the navigation-toggle since that may be slotted. */
slot[name~='navigation-toggle'],
:host([disable-navigation-toggle]) slot[name~='navigation-toggle'] {
display: none;
}
/* Sometimes the media query in the viewport is stubborn in iframes. This is an extra check to make it behave properly. */
:host(:not([disable-navigation-toggle])[view='mobile']) slot[name~='navigation-toggle'] {
display: contents;
}
[part~='navigation-toggle'] {
/* Use only a margin-inline-start because the slotted header is expected to have default padding
so it looks really awkward if this sets a margin-inline-end and the slotted header has a padding-inline-start. */
margin-inline-start: var(--wa-space-m);
}

Some files were not shown because too many files have changed in this diff Show More