mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-19 07:29:14 +00:00
Compare commits
19 Commits
progress-r
...
konnorroge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
919aa20d40 | ||
|
|
3e36d13c78 | ||
|
|
e7999b0458 | ||
|
|
99a6f37a93 | ||
|
|
bc361c593b | ||
|
|
b5ac468fac | ||
|
|
c7975060b7 | ||
|
|
38288aaefb | ||
|
|
d01291cf9e | ||
|
|
5b9af2190a | ||
|
|
5a12125674 | ||
|
|
6fec10d498 | ||
|
|
984627241f | ||
|
|
9f6c501879 | ||
|
|
8573c32912 | ||
|
|
d9fb3e7353 | ||
|
|
29025a92d9 | ||
|
|
e65a712f70 | ||
|
|
0bfe35b523 |
@@ -15,6 +15,7 @@
|
||||
"autoloading",
|
||||
"autoplay",
|
||||
"bezier",
|
||||
"bluesky",
|
||||
"boxicons",
|
||||
"CACHEABLE",
|
||||
"callout",
|
||||
@@ -83,6 +84,7 @@
|
||||
"jsfiddle",
|
||||
"keydown",
|
||||
"keyframes",
|
||||
"Konnor",
|
||||
"Kool",
|
||||
"labelledby",
|
||||
"Laravel",
|
||||
@@ -120,6 +122,7 @@
|
||||
"peta",
|
||||
"petabit",
|
||||
"Preact",
|
||||
"preconnect",
|
||||
"prismjs",
|
||||
"progressbar",
|
||||
"radiogroup",
|
||||
|
||||
@@ -11,7 +11,7 @@ import { searchPlugin } from './_utils/search.js';
|
||||
import { readFile } from 'fs/promises';
|
||||
import { outlinePlugin } from './_utils/outline.js';
|
||||
import componentList from './_data/componentList.js';
|
||||
import litPlugin from '@lit-labs/eleventy-plugin-lit';
|
||||
import ssrPlugin from '@lit-labs/eleventy-plugin-lit';
|
||||
|
||||
import process from 'process';
|
||||
|
||||
@@ -98,7 +98,14 @@ export default function (eleventyConfig) {
|
||||
])
|
||||
);
|
||||
|
||||
const omittedModules = [];
|
||||
const omittedModules = [
|
||||
//
|
||||
// TODO - dropdown and tooltip fail to open properly after hydration, they show briefly and then hide. It looks like
|
||||
// the body part (of tooltip) has the hidden attribute reapplied to it.
|
||||
//
|
||||
'dropdown',
|
||||
'tooltip'
|
||||
];
|
||||
|
||||
// problematic components:
|
||||
// animation (breaks on navigation + ssr with Turbo)
|
||||
@@ -106,13 +113,13 @@ export default function (eleventyConfig) {
|
||||
// resize-observer (why SSR this?)
|
||||
// tooltip (why SSR this?)
|
||||
const componentModules = componentList
|
||||
// .filter(component => !omittedModules.includes(component.tagName.split(/wa-/)[1]))
|
||||
.filter(component => !omittedModules.includes(component.tagName.split(/wa-/)[1]))
|
||||
.map(component => {
|
||||
const name = component.tagName.split(/wa-/)[1];
|
||||
return `./dist/components/${name}/${name}.js`;
|
||||
});
|
||||
|
||||
eleventyConfig.addPlugin(litPlugin, {
|
||||
eleventyConfig.addPlugin(ssrPlugin, {
|
||||
mode: 'worker',
|
||||
componentModules
|
||||
});
|
||||
@@ -127,10 +134,13 @@ export default function (eleventyConfig) {
|
||||
);
|
||||
|
||||
// Production-only plugins
|
||||
if (!isDeveloping) {
|
||||
// Run Prettier on each file (prod only because it can be slow)
|
||||
eleventyConfig.addPlugin(formatCodePlugin());
|
||||
}
|
||||
//
|
||||
// TODO - disabled because it takes about a minute to run now
|
||||
//
|
||||
// if (!isDeveloping) {
|
||||
// // Run Prettier on each file (prod only because it can be slow)
|
||||
// eleventyConfig.addPlugin(formatCodePlugin());
|
||||
// }
|
||||
|
||||
return {
|
||||
dir: {
|
||||
|
||||
@@ -38,16 +38,16 @@ Use the `--spacing` custom property to change the amount of space between the di
|
||||
</div>
|
||||
```
|
||||
|
||||
### Vertical
|
||||
### Orientation
|
||||
|
||||
Add the `vertical` attribute to draw the divider in a vertical orientation. The divider will span the full height of its container. Vertical dividers work especially well inside of a flex container.
|
||||
Set the `orientation` attribute to `vertical` to render the divider in a vertical orientation. The divider will span the full height of its container. Vertical dividers work especially well inside of a flex container.
|
||||
|
||||
```html {.example}
|
||||
<div style="display: flex; align-items: center; height: 2rem;">
|
||||
First
|
||||
<wa-divider vertical></wa-divider>
|
||||
<wa-divider orientation="vertical"></wa-divider>
|
||||
Middle
|
||||
<wa-divider vertical></wa-divider>
|
||||
<wa-divider orientation="vertical"></wa-divider>
|
||||
Last
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -79,12 +79,12 @@ To set the initial position in pixels instead of a percentage, use the `position
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
### Vertical
|
||||
### Orientation
|
||||
|
||||
Add the `vertical` attribute to render the split panel in a vertical orientation where the start and end panels are stacked. You also need to set a height when using the vertical orientation.
|
||||
Set the `orientation` attribute to `vertical` to render the split panel in a vertical orientation where the start and end panels are stacked. You also need to set a height when using the vertical orientation.
|
||||
|
||||
```html {.example}
|
||||
<wa-split-panel vertical style="height: 400px;">
|
||||
<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div
|
||||
slot="start"
|
||||
style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden;"
|
||||
@@ -247,7 +247,7 @@ Create complex layouts that can be repositioned independently by nesting split p
|
||||
Start
|
||||
</div>
|
||||
<div slot="end">
|
||||
<wa-split-panel vertical style="height: 400px;">
|
||||
<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div
|
||||
slot="start"
|
||||
style="height: 100%; background: var(--wa-color-surface-lowered); display: flex; align-items: center; justify-content: center; overflow: hidden"
|
||||
|
||||
@@ -35,24 +35,19 @@ TODO Page Description
|
||||
<div style="border-bottom: 1px solid var(--wa-color-surface-border);margin-bottom: 1rem; padding-bottom: 1rem;">
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/article-flower.jpg" alt="">
|
||||
<h2 style="margin-bottom: var(--wa-space-s);">Title</h2>
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Fusce lectus lorem, tincidunt non semper sit amet, laoreet vitae nunc. Morbi egestas, libero vitae elementum pretium, nibh ipsum faucibus lacus, id pretium urna ligula eu mauris. Aliquam erat volutpat. Mauris pharetra lacus rhoncus ligula bibendum, at consectetur erat auctor.</p>
|
||||
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Well, the way they make shows is, they make one show. That show's called a pilot.</p>
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
|
||||
<div>
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/article-flower.jpg" alt="">
|
||||
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Etiam et tincidunt est, sollicitudin fermentum ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut suscipit libero at velit fringilla, ac pretium lorem rutrum. Cras luctus blandit semper.</p>
|
||||
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/article-flower.jpg" alt="">
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Normally, both your asses would be dead as fucking fried chicken.</p>
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
</div>
|
||||
<div>
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/article-flower.jpg" alt="">
|
||||
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris in fringilla ante. In mattis sapien ac aliquet mattis.</p>
|
||||
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/article-flower.jpg" alt="">
|
||||
<p style="margin-bottom: var(--wa-space-3xs);">Besides, I've already been through too much shit this morning over this case to hand it over to your dumb ass.</p>
|
||||
<span style="font-size: small;font-weight: 600;font-style: italic;">sub-title</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,36 +59,36 @@ TODO Page Description
|
||||
```html{.example}
|
||||
<div class="news-footer">
|
||||
<div class="container">
|
||||
<!-- <div class="logo"> <wa-icon name="user-secret"></wa-icon> <h1 style="--wa-space-xl: 0;">Daily Snoop</h1></div> -->
|
||||
<!-- <div class="logo"> <wa-icon name="user-secret"></wa-icon><h1 style="--wa-space-xl: 0;">Daily Snoop</h1></div> -->
|
||||
<div class="nav">
|
||||
<section>
|
||||
<h4 style="--wa-space-xl: 0;">News</h4>
|
||||
<ul>
|
||||
<li><a href="#">U.S.</a></li>
|
||||
<li><a href="#">World</a></li>
|
||||
<li><a href="#">Politics</a></li>
|
||||
<li><a href="#">Education</a></li>
|
||||
<li><a href="#">Sports</a></li>
|
||||
<li><a href="#">Business</a></li>
|
||||
<li><a href="#">Tech</a></li>
|
||||
<li><a href="#">Science</a></li>
|
||||
</ul>
|
||||
<li><a href="#">U.S.</a></li>
|
||||
<li><a href="#">World</a></li>
|
||||
<li><a href="#">Politics</a></li>
|
||||
<li><a href="#">Education</a></li>
|
||||
<li><a href="#">Sports</a></li>
|
||||
<li><a href="#">Business</a></li>
|
||||
<li><a href="#">Tech</a></li>
|
||||
<li><a href="#">Science</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h4 style="--wa-space-xl: 0;">Arts</h4>
|
||||
<ul>
|
||||
<li><a href="#">Book Review</a></li>
|
||||
<li><a href="#">Dance</a></li>
|
||||
<li><a href="#">Movies</a></li>
|
||||
<li><a href="#">Pop Culture</a></li>
|
||||
</ul>
|
||||
<li><a href="#">Book Review</a></li>
|
||||
<li><a href="#">Dance</a></li>
|
||||
<li><a href="#">Movies</a></li>
|
||||
<li><a href="#">Pop Culture</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h4 style="--wa-space-xl: 0;">Subscriptions</h4>
|
||||
<ul class="list">
|
||||
<li><a href="#"><wa-icon fixed-width name="game-board-simple"></wa-icon> Crossword</a></li>
|
||||
<li><a href="#"><wa-icon fixed-width name="paper-plane"></wa-icon> Newsletters</a></li>
|
||||
<li><a href="#"><wa-icon fixed-width name="microphone-lines"></wa-icon> Podcast</a></li>
|
||||
<li><a href="#"><wa-icon fixed-width name="game-board-simple"></wa-icon>Crossword</a></li>
|
||||
<li><a href="#"><wa-icon fixed-width name="paper-plane"></wa-icon>Newsletters</a></li>
|
||||
<li><a href="#"><wa-icon fixed-width name="microphone-lines"></wa-icon>Podcast</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
@@ -115,12 +110,11 @@ TODO Page Description
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/app_store.svg" alt="">
|
||||
<img src="https://img.fortawesome.com/cfa83f3c/google_play.svg" alt="">
|
||||
</div>
|
||||
<div class="legal">© 2024 All rights reserved.</div>
|
||||
<div class="legal">© 2024 All rights reserved.</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.news-footer {
|
||||
|
||||
.container {
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
|
||||
@@ -188,9 +188,8 @@ When authoring components, please try to follow the same structure and conventio
|
||||
- `@query` decorators
|
||||
- `@state` decorators
|
||||
- `@property` decorators
|
||||
- Lifecycle methods (`connectedCallback()`, `disconnectedCallback()`, `firstUpdated()`, etc.)
|
||||
- Lifecycle methods (`connectedCallback()`, `disconnectedCallback()`, `firstUpdated()`, `updated()`, etc.)
|
||||
- Private methods
|
||||
- `@watch` decorators
|
||||
- Public methods
|
||||
- The `render()` method
|
||||
|
||||
|
||||
284
package-lock.json
generated
284
package-lock.json
generated
@@ -9,23 +9,23 @@
|
||||
"version": "3.0.0-alpha.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.0.2",
|
||||
"@floating-ui/dom": "^1.5.3",
|
||||
"@shoelace-style/animations": "^1.1.0",
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@floating-ui/dom": "^1.6.12",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.4",
|
||||
"lit": "^3.0.0",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0-alpha.5",
|
||||
"@custom-elements-manifest/analyzer": "^0.9.4",
|
||||
"@custom-elements-manifest/analyzer": "^0.10.3",
|
||||
"@lit-labs/eleventy-plugin-lit": "^1.0.3",
|
||||
"@lit-labs/testing": "^0.2.4",
|
||||
"@lit/react": "^1.0.0",
|
||||
"@lit-labs/testing": "^0.2.5",
|
||||
"@lit/react": "^1.0.6",
|
||||
"@open-wc/testing": "^3.2.0",
|
||||
"@types/mocha": "^10.0.2",
|
||||
"@types/react": "^18.2.28",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/react": "^18.3.12",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
||||
"@typescript-eslint/parser": "^6.7.5",
|
||||
"@web/dev-server-esbuild": "^0.3.6",
|
||||
@@ -37,7 +37,7 @@
|
||||
"change-case": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.0",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
"custom-element-jet-brains-integration": "^1.4.0",
|
||||
"custom-element-vs-code-integration": "^1.2.1",
|
||||
@@ -56,31 +56,32 @@
|
||||
"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",
|
||||
"get-port": "^7.1.0",
|
||||
"globby": "^13.2.2",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^14.0.1",
|
||||
"lunr": "^2.3.9",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-attrs": "^4.1.6",
|
||||
"markdown-it-attrs": "^4.2.0",
|
||||
"markdown-it-container": "^3.0.0",
|
||||
"markdown-it-ins": "^3.0.1",
|
||||
"markdown-it-kbd": "^2.2.2",
|
||||
"markdown-it-mark": "^3.0.1",
|
||||
"marked": "^11.1.0",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"ora": "^8.0.1",
|
||||
"npm-check-updates": "^17.1.11",
|
||||
"ora": "^8.1.1",
|
||||
"pascal-case": "^3.1.2",
|
||||
"playwright": "^1.46.1",
|
||||
"plop": "^4.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"playwright": "^1.49.0",
|
||||
"plop": "^4.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"recursive-copy": "^2.0.14",
|
||||
"sinon": "^16.1.0",
|
||||
"source-map": "^0.7.4",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.2.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.7.2",
|
||||
"user-agent-data-types": "^0.3.1",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
@@ -856,17 +857,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.0.3.tgz",
|
||||
"integrity": "sha512-e9nEVehVJwkymQpkGhdSNzLT2Lr9UTTby+JePq4Z2SxBbOQjY7pLgSouAaXvfaGQVSAaY0U4eJdwfSDmCbItcw==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.1.0.tgz",
|
||||
"integrity": "sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/analyzer": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.9.4.tgz",
|
||||
"integrity": "sha512-XPjEbfkq71oQl6tIfDy1ashdvOf42p3BtqebEaUohqTEPAyBuShGwQiB2B7xjsUwi3VfSQCnPlGwmigIDPjtWg==",
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.10.3.tgz",
|
||||
"integrity": "sha512-e2Ax59vK9sNedmDlPqZS11L54iAlKSjOJuv5etpTy5SygLBW3GcUtocHZm8wO013L0griTPpgWB0tuV7/JXy5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@custom-elements-manifest/find-dependencies": "^0.0.5",
|
||||
@@ -968,6 +969,19 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/analyzer/node_modules/typescript": {
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/find-dependencies": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/find-dependencies/-/find-dependencies-0.0.5.tgz",
|
||||
@@ -1466,26 +1480,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.3.tgz",
|
||||
"integrity": "sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==",
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
|
||||
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.0"
|
||||
"@floating-ui/utils": "^0.2.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.4.tgz",
|
||||
"integrity": "sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==",
|
||||
"version": "1.6.12",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
|
||||
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.5.3",
|
||||
"@floating-ui/utils": "^0.2.0"
|
||||
"@floating-ui/core": "^1.6.0",
|
||||
"@floating-ui/utils": "^0.2.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
|
||||
"integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
|
||||
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
|
||||
},
|
||||
"node_modules/@github/catalyst": {
|
||||
"version": "1.6.0",
|
||||
@@ -1682,9 +1696,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lit-labs/testing": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/testing/-/testing-0.2.4.tgz",
|
||||
"integrity": "sha512-NasNKbELasyfA1vIcfMwM0H/2mE98uFsyf/yDWtcl9fAEsTpRRWrmPdQDrHDyim5LKnsQutCzBP3Fof83hSCIA==",
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/testing/-/testing-0.2.5.tgz",
|
||||
"integrity": "sha512-VVYPhnpYhTgmZ3pWGQV8ZN/c81/aUlxSya+G94pNhlAiKUqsAwJZAkQCEZLncF8WHWg9jhas3eswxe9G3oQr1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@lit-labs/ssr": "^3.1.8",
|
||||
@@ -1792,9 +1806,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lit/react": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.2.tgz",
|
||||
"integrity": "sha512-UJ5TQ46DPcJDIzyjbwbj6Iye0XcpCxL2yb03zcWq1BpWchpXS3Z0BPVhg7zDfZLF6JemPml8u/gt/+KwJ/23sg==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.6.tgz",
|
||||
"integrity": "sha512-QIss8MPh6qUoFJmuaF4dSHts3qCsA36S3HcOLiNPShxhgYPr4XJRnCBKPipk85sR9xr6TQrOcDMfexwbNdJHYA==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "17 || 18"
|
||||
@@ -2215,9 +2229,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@shoelace-style/animations": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@shoelace-style/animations/-/animations-1.1.0.tgz",
|
||||
"integrity": "sha512-Be+cahtZyI2dPKRm8EZSx3YJQ+jLvEcn3xzRP7tM4tqBnvd/eW/64Xh0iOf0t2w5P8iJKfdBbpVNE9naCaOf2g==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shoelace-style/animations/-/animations-1.2.0.tgz",
|
||||
"integrity": "sha512-avvo1xxkLbv2dgtabdewBbqcJfV0e0zCwFqkPMnHFGbJbBHorRFfMAHh1NG9ymmXn0jW95ibUVH03E1NYXD6Gw==",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/claviska"
|
||||
@@ -2600,9 +2614,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mocha": {
|
||||
"version": "10.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz",
|
||||
"integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==",
|
||||
"version": "10.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
|
||||
"integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
@@ -2639,13 +2653,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz",
|
||||
"integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==",
|
||||
"version": "18.3.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz",
|
||||
"integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
@@ -2655,12 +2668,6 @@
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
|
||||
@@ -8337,9 +8344,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
|
||||
"integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
|
||||
"integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -8368,9 +8375,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-port": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz",
|
||||
"integrity": "sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==",
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz",
|
||||
"integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
@@ -10586,9 +10593,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lit": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-3.2.0.tgz",
|
||||
"integrity": "sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz",
|
||||
"integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==",
|
||||
"dependencies": {
|
||||
"@lit/reactive-element": "^2.0.4",
|
||||
"lit-element": "^4.1.0",
|
||||
@@ -11069,9 +11076,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-attrs": {
|
||||
"version": "4.1.6",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.1.6.tgz",
|
||||
"integrity": "sha512-O7PDKZlN8RFMyDX13JnctQompwrrILuz2y43pW2GagcwpIIElkAdfeek+erHfxUOlXWPsjFeWmZ8ch1xtRLWpA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-4.2.0.tgz",
|
||||
"integrity": "sha512-m7svtUBythvcGFFZAv9VjMEvs8UbHri2sojJ3juJumoOzv8sdkx9a7W3KxiHbXxAbvL3Xauak8TMwCnvigVPKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -11551,6 +11558,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-function": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
|
||||
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
@@ -11888,6 +11907,20 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-check-updates": {
|
||||
"version": "17.1.11",
|
||||
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.11.tgz",
|
||||
"integrity": "sha512-TR2RuGIH7P3Qrb0jfdC/nT7JWqXPKjDlxuNQt3kx4oNVf1Pn5SBRB7KLypgYZhruivJthgTtfkkyK4mz342VjA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"ncu": "build/cli.js",
|
||||
"npm-check-updates": "build/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0",
|
||||
"npm": ">=8.12.1"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
|
||||
@@ -12237,19 +12270,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ora": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-8.0.1.tgz",
|
||||
"integrity": "sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==",
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ora/-/ora-8.1.1.tgz",
|
||||
"integrity": "sha512-YWielGi1XzG1UTvOaCFaNgEnuhZVMSHYkW/FQ7UX8O26PtlpdM84c0f7wLPlkvx2RfiQmnzd61d/MGxmpQeJPw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^5.3.0",
|
||||
"cli-cursor": "^4.0.0",
|
||||
"cli-cursor": "^5.0.0",
|
||||
"cli-spinners": "^2.9.2",
|
||||
"is-interactive": "^2.0.0",
|
||||
"is-unicode-supported": "^2.0.0",
|
||||
"log-symbols": "^6.0.0",
|
||||
"stdin-discarder": "^0.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"stdin-discarder": "^0.2.2",
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -12260,15 +12293,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ora/node_modules/cli-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
|
||||
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"restore-cursor": "^4.0.0"
|
||||
"restore-cursor": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
@@ -12286,46 +12319,49 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ora/node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/ora/node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
|
||||
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
"mimic-function": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ora/node_modules/restore-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
|
||||
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
|
||||
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
"onetime": "^7.0.0",
|
||||
"signal-exit": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ora/node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
@@ -12770,12 +12806,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz",
|
||||
"integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==",
|
||||
"version": "1.49.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz",
|
||||
"integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright-core": "1.46.1"
|
||||
"playwright-core": "1.49.0"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -12788,9 +12824,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz",
|
||||
"integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==",
|
||||
"version": "1.49.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz",
|
||||
"integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@@ -12967,9 +13003,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
|
||||
"integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
|
||||
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
@@ -13264,9 +13300,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
||||
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
@@ -14590,9 +14626,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz",
|
||||
"integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^10.3.0",
|
||||
@@ -14977,9 +15013,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tsscmp": {
|
||||
@@ -15100,9 +15136,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
44
package.json
44
package.json
@@ -56,29 +56,30 @@
|
||||
"prettier:fix": "prettier --write --log-level=warn .",
|
||||
"spellcheck": "cspell \"**/*.{js,ts,json,html,css,md}\" --no-progress",
|
||||
"verify": "npm run prettier && npm run lint && npm run build && npm run test",
|
||||
"prepublishOnly": "npm run verify"
|
||||
"prepublishOnly": "npm run verify",
|
||||
"check-updates": "npx npm-check-updates -i"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^4.0.2",
|
||||
"@floating-ui/dom": "^1.5.3",
|
||||
"@shoelace-style/animations": "^1.1.0",
|
||||
"@ctrl/tinycolor": "^4.1.0",
|
||||
"@floating-ui/dom": "^1.6.12",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.4",
|
||||
"lit": "^3.0.0",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0-alpha.5",
|
||||
"@custom-elements-manifest/analyzer": "^0.9.4",
|
||||
"@custom-elements-manifest/analyzer": "^0.10.3",
|
||||
"@lit-labs/eleventy-plugin-lit": "^1.0.3",
|
||||
"@lit-labs/testing": "^0.2.4",
|
||||
"@lit/react": "^1.0.0",
|
||||
"@lit-labs/testing": "^0.2.5",
|
||||
"@lit/react": "^1.0.6",
|
||||
"@open-wc/testing": "^3.2.0",
|
||||
"@types/mocha": "^10.0.2",
|
||||
"@types/react": "^18.2.28",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/react": "^18.3.12",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
||||
"@typescript-eslint/parser": "^6.7.5",
|
||||
"@web/dev-server-esbuild": "^0.3.6",
|
||||
@@ -90,7 +91,7 @@
|
||||
"change-case": "^4.1.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.0",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
"custom-element-jet-brains-integration": "^1.4.0",
|
||||
"custom-element-vs-code-integration": "^1.2.1",
|
||||
@@ -109,36 +110,37 @@
|
||||
"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",
|
||||
"get-port": "^7.1.0",
|
||||
"globby": "^13.2.2",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^14.0.1",
|
||||
"lunr": "^2.3.9",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-attrs": "^4.1.6",
|
||||
"markdown-it-attrs": "^4.2.0",
|
||||
"markdown-it-container": "^3.0.0",
|
||||
"markdown-it-ins": "^3.0.1",
|
||||
"markdown-it-kbd": "^2.2.2",
|
||||
"markdown-it-mark": "^3.0.1",
|
||||
"marked": "^11.1.0",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"ora": "^8.0.1",
|
||||
"npm-check-updates": "^17.1.11",
|
||||
"ora": "^8.1.1",
|
||||
"pascal-case": "^3.1.2",
|
||||
"playwright": "^1.46.1",
|
||||
"plop": "^4.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"playwright": "^1.49.0",
|
||||
"plop": "^4.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"recursive-copy": "^2.0.14",
|
||||
"sinon": "^16.1.0",
|
||||
"source-map": "^0.7.4",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.2.2",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.7.2",
|
||||
"user-agent-data-types": "^0.3.1",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"overrides": {
|
||||
"playwright": "^1.46.1"
|
||||
"playwright": "^1.49.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,js}": [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './test-element.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
@@ -33,11 +32,6 @@ export default class {{ properCase tag }} extends WebAwesomeElement {
|
||||
/** An example attribute. */
|
||||
@property() attr = 'example';
|
||||
|
||||
@watch('example')
|
||||
handleExampleChange() {
|
||||
// do something
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <slot></slot> `;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { WaErrorEvent } from '../../events/error.js';
|
||||
import { WaLoadEvent } from '../../events/load.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
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';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
|
||||
@@ -46,6 +45,21 @@ export default class WaAnimatedImage extends WebAwesomeElement {
|
||||
/** Plays the animation. When this attribute is remove, the animation will pause. */
|
||||
@property({ type: Boolean, reflect: true }) play: boolean;
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('play') && this.hasUpdated) {
|
||||
// When the animation starts playing, reset the src so it plays from the beginning. Since the src is cached, this
|
||||
// won't trigger another request.
|
||||
if (this.play) {
|
||||
this.animatedImage.src = '';
|
||||
this.animatedImage.src = this.src;
|
||||
}
|
||||
}
|
||||
|
||||
if (changedProperties.has('src')) {
|
||||
this.isLoaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
private handleClick() {
|
||||
this.play = !this.play;
|
||||
}
|
||||
@@ -68,21 +82,6 @@ export default class WaAnimatedImage extends WebAwesomeElement {
|
||||
this.dispatchEvent(new WaErrorEvent());
|
||||
}
|
||||
|
||||
@watch('play', { waitUntilFirstUpdate: true })
|
||||
handlePlayChange() {
|
||||
// When the animation starts playing, reset the src so it plays from the beginning. Since the src is cached, this
|
||||
// won't trigger another request.
|
||||
if (this.play) {
|
||||
this.animatedImage.src = '';
|
||||
this.animatedImage.src = this.src;
|
||||
}
|
||||
}
|
||||
|
||||
@watch('src')
|
||||
handleSrcChange() {
|
||||
this.isLoaded = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="animated-image">
|
||||
|
||||
@@ -4,11 +4,10 @@ import { html } from 'lit';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './animation.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } 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).
|
||||
@@ -102,6 +101,51 @@ export default class WaAnimation extends WebAwesomeElement {
|
||||
this.destroyAnimation();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle animation changes
|
||||
if (
|
||||
changedProperties.has('name') ||
|
||||
changedProperties.has('delay') ||
|
||||
changedProperties.has('direction') ||
|
||||
changedProperties.has('duration') ||
|
||||
changedProperties.has('easing') ||
|
||||
changedProperties.has('endDelay') ||
|
||||
changedProperties.has('fill') ||
|
||||
changedProperties.has('iterations') ||
|
||||
changedProperties.has('iterationStart') ||
|
||||
changedProperties.has('keyframes')
|
||||
) {
|
||||
if (!this.hasUpdated) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.createAnimation();
|
||||
}
|
||||
|
||||
// Handle play change
|
||||
if (changedProperties.has('play')) {
|
||||
if (this.animation) {
|
||||
if (this.play && !this.hasStarted) {
|
||||
this.hasStarted = true;
|
||||
this.dispatchEvent(new WaStartEvent());
|
||||
}
|
||||
|
||||
if (this.play) {
|
||||
this.animation.play();
|
||||
} else {
|
||||
this.animation.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle playback rate change
|
||||
if (changedProperties.has('playbackRate')) {
|
||||
if (this.animation) {
|
||||
this.animation.playbackRate = this.playbackRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleAnimationFinish = () => {
|
||||
this.play = false;
|
||||
this.hasStarted = false;
|
||||
@@ -163,52 +207,6 @@ export default class WaAnimation extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch([
|
||||
'name',
|
||||
'delay',
|
||||
'direction',
|
||||
'duration',
|
||||
'easing',
|
||||
'endDelay',
|
||||
'fill',
|
||||
'iterations',
|
||||
'iterationsStart',
|
||||
'keyframes'
|
||||
])
|
||||
handleAnimationChange() {
|
||||
if (!this.hasUpdated) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.createAnimation();
|
||||
}
|
||||
|
||||
@watch('play')
|
||||
handlePlayChange() {
|
||||
if (this.animation) {
|
||||
if (this.play && !this.hasStarted) {
|
||||
this.hasStarted = true;
|
||||
this.dispatchEvent(new WaStartEvent());
|
||||
}
|
||||
|
||||
if (this.play) {
|
||||
this.animation.play();
|
||||
} else {
|
||||
this.animation.pause();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@watch('playbackRate')
|
||||
handlePlaybackRateChange() {
|
||||
if (this.animation) {
|
||||
this.animation.playbackRate = this.playbackRate;
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears all keyframe effects caused by this animation and aborts its playback. */
|
||||
cancel() {
|
||||
this.animation?.cancel();
|
||||
|
||||
@@ -3,11 +3,10 @@ import { classMap } from 'lit/directives/class-map.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './avatar.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Avatars are used to represent a person or object.
|
||||
@@ -35,7 +34,7 @@ import type { CSSResultGroup } from 'lit';
|
||||
export default class WaAvatar extends WebAwesomeElement {
|
||||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
|
||||
@state() private hasError = false;
|
||||
@state() hasError = false;
|
||||
|
||||
/** The image source to use for the avatar. */
|
||||
@property() image = '';
|
||||
@@ -52,10 +51,10 @@ export default class WaAvatar extends WebAwesomeElement {
|
||||
/** The shape of the avatar. */
|
||||
@property({ reflect: true }) shape: 'circle' | 'square' | 'rounded' = 'circle';
|
||||
|
||||
@watch('image')
|
||||
handleImageChange() {
|
||||
// Reset the error when a new image is provided
|
||||
this.hasError = false;
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('image')) {
|
||||
this.hasError = false;
|
||||
}
|
||||
}
|
||||
|
||||
private handleImageLoadError() {
|
||||
|
||||
@@ -1,11 +1,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 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';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Breadcrumb Items are used inside [breadcrumbs](/docs/components/breadcrumb) to represent different links.
|
||||
@@ -31,7 +30,7 @@ export default class WaBreadcrumbItem extends WebAwesomeElement {
|
||||
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
|
||||
@state() private renderType: 'button' | 'link' | 'dropdown' = 'button';
|
||||
@state() renderType: 'button' | 'link' | 'dropdown' = 'button';
|
||||
|
||||
/**
|
||||
* Optional URL to direct the user to when the breadcrumb item is activated. When set, a link will be rendered
|
||||
@@ -63,9 +62,10 @@ export default class WaBreadcrumbItem extends WebAwesomeElement {
|
||||
this.renderType = 'button';
|
||||
}
|
||||
|
||||
@watch('href', { waitUntilFirstUpdate: true })
|
||||
hrefChanged() {
|
||||
this.setRenderType();
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('href') && this.hasUpdated) {
|
||||
this.setRenderType();
|
||||
}
|
||||
}
|
||||
|
||||
handleSlotChange() {
|
||||
|
||||
@@ -8,7 +8,7 @@ export default css`
|
||||
.button-group {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: none;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { html } from 'lit';
|
||||
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';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Button groups can be used to group related buttons into sections.
|
||||
@@ -33,8 +33,8 @@ export default class WaButtonGroup extends WebAwesomeElement {
|
||||
/** The button group's orientation. */
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
||||
updated(changedProps: Map<string, unknown>) {
|
||||
if (changedProps.has('orientation')) {
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('orientation')) {
|
||||
this.setAttribute('aria-orientation', this.orientation);
|
||||
this.updateClassNames();
|
||||
}
|
||||
|
||||
@@ -9,11 +9,10 @@ import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
|
||||
import { WaBlurEvent } from '../../events/blur.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './button.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Buttons represent actions that are available to the user.
|
||||
@@ -66,7 +65,7 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('.button') button: HTMLButtonElement | HTMLLinkElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
@state() visuallyHiddenLabel = false;
|
||||
@state() invalid = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
@@ -211,9 +210,10 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
return this.href ? true : false;
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
this.updateValidity();
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
this.updateValidity();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
|
||||
@@ -12,11 +12,10 @@ import { prefersReducedMotion } from '../../internal/animate.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './carousel.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup, PropertyValueMap } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
import type WaCarouselItem from '../carousel-item/carousel-item.js';
|
||||
|
||||
/**
|
||||
@@ -83,7 +82,7 @@ export default class WaCarousel extends WebAwesomeElement {
|
||||
@property({ type: Number, attribute: 'slides-per-move' }) slidesPerMove = 1;
|
||||
|
||||
/** Specifies the orientation in which the carousel will lay out. */
|
||||
@property() orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
||||
/** When set, it is possible to scroll through the slides by dragging them with the mouse. */
|
||||
@property({ type: Boolean, reflect: true, attribute: 'mouse-dragging' }) mouseDragging = false;
|
||||
@@ -123,7 +122,47 @@ export default class WaCarousel extends WebAwesomeElement {
|
||||
});
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValueMap<WaCarousel> | Map<PropertyKey, unknown>): void {
|
||||
protected updated(changedProperties: PropertyValues<this>) {
|
||||
// Reinitialize when looping or slides per page change
|
||||
if (changedProperties.has('loop') || changedProperties.has('slidesPerPage')) {
|
||||
if (this.hasUpdated) {
|
||||
this.initializeSlides();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle slide changes
|
||||
if (changedProperties.has('activeSlide')) {
|
||||
const slides = this.getSlides();
|
||||
slides.forEach((slide, i) => {
|
||||
slide.classList.toggle('--is-active', i === this.activeSlide);
|
||||
});
|
||||
|
||||
// Do not emit an event on first render
|
||||
if (this.hasUpdated) {
|
||||
this.dispatchEvent(
|
||||
new WaSlideChangeEvent({
|
||||
index: this.activeSlide,
|
||||
slide: slides[this.activeSlide]
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle slides per move changes
|
||||
if (changedProperties.has('slidesPerMove')) {
|
||||
this.updateSlidesSnap();
|
||||
}
|
||||
|
||||
// Handle autoplay changes
|
||||
if (changedProperties.has('autoplay')) {
|
||||
this.autoplayController.stop();
|
||||
if (this.autoplay) {
|
||||
this.autoplayController.start(this.autoplayInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
// Ensure the slidesPerMove is never higher than the slidesPerPage
|
||||
if (changedProperties.has('slidesPerMove') || changedProperties.has('slidesPerPage')) {
|
||||
this.slidesPerMove = Math.min(this.slidesPerMove, this.slidesPerPage);
|
||||
@@ -355,8 +394,6 @@ export default class WaCarousel extends WebAwesomeElement {
|
||||
this.requestUpdate();
|
||||
};
|
||||
|
||||
@watch('loop', { waitUntilFirstUpdate: true })
|
||||
@watch('slidesPerPage', { waitUntilFirstUpdate: true })
|
||||
initializeSlides() {
|
||||
// Removes all the cloned elements from the carousel
|
||||
this.getSlides({ excludeClones: false }).forEach((slide, index) => {
|
||||
@@ -402,26 +439,7 @@ export default class WaCarousel extends WebAwesomeElement {
|
||||
});
|
||||
}
|
||||
|
||||
@watch('activeSlide')
|
||||
handelSlideChange() {
|
||||
const slides = this.getSlides();
|
||||
slides.forEach((slide, i) => {
|
||||
slide.classList.toggle('--is-active', i === this.activeSlide);
|
||||
});
|
||||
|
||||
// Do not emit an event on first render
|
||||
if (this.hasUpdated) {
|
||||
this.dispatchEvent(
|
||||
new WaSlideChangeEvent({
|
||||
index: this.activeSlide,
|
||||
slide: slides[this.activeSlide]
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@watch('slidesPerMove')
|
||||
updateSlidesSnap() {
|
||||
private updateSlidesSnap() {
|
||||
const slides = this.getSlides();
|
||||
|
||||
const slidesPerMove = this.slidesPerMove;
|
||||
@@ -435,14 +453,6 @@ export default class WaCarousel extends WebAwesomeElement {
|
||||
});
|
||||
}
|
||||
|
||||
@watch('autoplay')
|
||||
handleAutoplayChange() {
|
||||
this.autoplayController.stop();
|
||||
if (this.autoplay) {
|
||||
this.autoplayController.start(this.autoplayInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the carousel backward by `slides-per-move` slides.
|
||||
*
|
||||
|
||||
@@ -10,7 +10,6 @@ import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
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';
|
||||
@@ -79,7 +78,7 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('input[type="checkbox"]') input: HTMLInputElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
@@ -129,6 +128,25 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
/** The checkbox's help text. If you need to display HTML, use the `help-text` slot instead. */
|
||||
@property({ attribute: 'help-text' }) helpText = '';
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle checked/indeterminate changes
|
||||
if (changedProperties.has('checked') || changedProperties.has('indeterminate')) {
|
||||
if (this.hasUpdated) {
|
||||
this.input.checked = this.checked; // force a sync update
|
||||
this.input.indeterminate = this.indeterminate; // force a sync update
|
||||
this.updateValidity();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle defaultChecked changes
|
||||
if (changedProperties.has('defaultChecked')) {
|
||||
if (!this.hasInteracted && this.checked !== this.defaultChecked) {
|
||||
this.checked = this.defaultChecked;
|
||||
this.handleValueOrCheckedChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleClick() {
|
||||
this.hasInteracted = true;
|
||||
this.checked = !this.checked;
|
||||
@@ -150,29 +168,12 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
this.dispatchEvent(new WaFocusEvent());
|
||||
}
|
||||
|
||||
@watch('defaultChecked')
|
||||
handleDefaultCheckedChange() {
|
||||
if (!this.hasInteracted && this.checked !== this.defaultChecked) {
|
||||
this.checked = this.defaultChecked;
|
||||
this.handleValueOrCheckedChange();
|
||||
}
|
||||
}
|
||||
|
||||
handleValueOrCheckedChange() {
|
||||
this.toggleCustomState('checked', this.checked);
|
||||
|
||||
// These @watch() commands seem to override the base element checks for changes, so we need to setValue for the form and and updateValidity()
|
||||
this.setValue(this.checked ? this.value : null, this._value);
|
||||
this.updateValidity();
|
||||
}
|
||||
|
||||
@watch(['checked', 'indeterminate'], { waitUntilFirstUpdate: true })
|
||||
handleStateChange() {
|
||||
this.input.checked = this.checked; // force a sync update
|
||||
this.input.indeterminate = this.indeterminate; // force a sync update
|
||||
this.updateValidity();
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import { WaChangeEvent } from '../../events/change.js';
|
||||
import { WaFocusEvent } from '../../events/focus.js';
|
||||
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';
|
||||
@@ -142,14 +141,14 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
@query('[part~="preview"]') previewButton: HTMLButtonElement;
|
||||
@query('[part~="trigger"]') trigger: HTMLButtonElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() private isDraggingGridHandle = false;
|
||||
@state() private isEmpty = true;
|
||||
@state() private inputValue = '';
|
||||
@state() private hue = 0;
|
||||
@state() private saturation = 100;
|
||||
@state() private brightness = 100;
|
||||
@state() private alpha = 100;
|
||||
@state() hasFocus = false;
|
||||
@state() isDraggingGridHandle = false;
|
||||
@state() isEmpty = true;
|
||||
@state() inputValue = '';
|
||||
@state() hue = 0;
|
||||
@state() saturation = 100;
|
||||
@state() brightness = 100;
|
||||
@state() alpha = 100;
|
||||
|
||||
private _value: string | null = null;
|
||||
|
||||
@@ -183,7 +182,7 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
@property({ attribute: 'with-label', reflect: true, type: Boolean }) withLabel = false;
|
||||
@property({ attribute: 'with-help-text', reflect: true, type: Boolean }) withHelpText = false;
|
||||
|
||||
@state() private hasEyeDropper: boolean = false;
|
||||
@state() hasEyeDropper: boolean = false;
|
||||
|
||||
/**
|
||||
* The color picker's label. This will not be displayed, but it will be announced by assistive devices. If you need to
|
||||
@@ -252,6 +251,23 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle format changes
|
||||
if (changedProperties.has('format') && this.hasUpdated) {
|
||||
this.syncValues();
|
||||
}
|
||||
|
||||
// Handle opacity changes
|
||||
if (changedProperties.has('opacity')) {
|
||||
this.alpha = 100;
|
||||
}
|
||||
|
||||
// Handle value changes
|
||||
if (changedProperties.has('value')) {
|
||||
this.handleValueChange(changedProperties.get('value') as string, this.value + '');
|
||||
}
|
||||
}
|
||||
|
||||
private handleCopy() {
|
||||
this.input.select();
|
||||
document.execCommand('copy');
|
||||
@@ -728,16 +744,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
||||
@watch('format', { waitUntilFirstUpdate: true })
|
||||
handleFormatChange() {
|
||||
this.syncValues();
|
||||
}
|
||||
|
||||
@watch('opacity')
|
||||
handleOpacityChange() {
|
||||
this.alpha = 100;
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValues<this>): void {
|
||||
super.willUpdate(changedProperties);
|
||||
|
||||
@@ -747,7 +753,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('value')
|
||||
handleValueChange(oldValue: string | undefined, newValue: string) {
|
||||
this.isEmpty = !newValue;
|
||||
|
||||
|
||||
@@ -8,11 +8,10 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './details.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Details show a brief summary and expand to show additional content.
|
||||
@@ -91,6 +90,63 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
this.detailsObserver.observe(this.details, { attributes: true });
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('open') && this.hasUpdated) {
|
||||
if (this.open) {
|
||||
this.details.open = true;
|
||||
// Show
|
||||
const waShow = new WaShowEvent();
|
||||
this.dispatchEvent(waShow);
|
||||
if (waShow.defaultPrevented) {
|
||||
this.open = false;
|
||||
this.details.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--show-duration'));
|
||||
// We can't animate to 'auto', so use the scroll height for now
|
||||
animate(
|
||||
this.body,
|
||||
[
|
||||
{ height: '0', opacity: '0' },
|
||||
{ height: `${this.body.scrollHeight}px`, opacity: '1' }
|
||||
],
|
||||
{
|
||||
duration,
|
||||
easing: 'linear'
|
||||
}
|
||||
).then(() => {
|
||||
this.body.style.height = 'auto';
|
||||
this.dispatchEvent(new WaAfterShowEvent());
|
||||
});
|
||||
} else {
|
||||
// Hide
|
||||
const waHide = new WaHideEvent();
|
||||
this.dispatchEvent(waHide);
|
||||
if (waHide.defaultPrevented) {
|
||||
this.details.open = true;
|
||||
this.open = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--hide-duration'));
|
||||
// We can't animate from 'auto', so use the scroll height for now
|
||||
animate(
|
||||
this.body,
|
||||
[
|
||||
{ height: `${this.body.scrollHeight}px`, opacity: '1' },
|
||||
{ height: '0', opacity: '0' }
|
||||
],
|
||||
{ duration, easing: 'linear' }
|
||||
).then(() => {
|
||||
this.body.style.height = 'auto';
|
||||
this.details.open = false;
|
||||
this.dispatchEvent(new WaAfterHideEvent());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.detailsObserver?.disconnect();
|
||||
@@ -131,62 +187,6 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
if (this.open) {
|
||||
this.details.open = true;
|
||||
// Show
|
||||
const waShow = new WaShowEvent();
|
||||
this.dispatchEvent(waShow);
|
||||
if (waShow.defaultPrevented) {
|
||||
this.open = false;
|
||||
this.details.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--show-duration'));
|
||||
// We can't animate to 'auto', so use the scroll height for now
|
||||
await animate(
|
||||
this.body,
|
||||
[
|
||||
{ height: '0', opacity: '0' },
|
||||
{ height: `${this.body.scrollHeight}px`, opacity: '1' }
|
||||
],
|
||||
{
|
||||
duration,
|
||||
easing: 'linear'
|
||||
}
|
||||
);
|
||||
this.body.style.height = 'auto';
|
||||
|
||||
this.dispatchEvent(new WaAfterShowEvent());
|
||||
} else {
|
||||
// Hide
|
||||
const waHide = new WaHideEvent();
|
||||
this.dispatchEvent(waHide);
|
||||
if (waHide.defaultPrevented) {
|
||||
this.details.open = true;
|
||||
this.open = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--hide-duration'));
|
||||
// We can't animate from 'auto', so use the scroll height for now
|
||||
await animate(
|
||||
this.body,
|
||||
[
|
||||
{ height: `${this.body.scrollHeight}px`, opacity: '1' },
|
||||
{ height: '0', opacity: '0' }
|
||||
],
|
||||
{ duration, easing: 'linear' }
|
||||
);
|
||||
this.body.style.height = 'auto';
|
||||
|
||||
this.details.open = false;
|
||||
this.dispatchEvent(new WaAfterHideEvent());
|
||||
}
|
||||
}
|
||||
|
||||
/** Shows the details. */
|
||||
async show() {
|
||||
if (this.open || this.disabled) {
|
||||
|
||||
@@ -9,11 +9,10 @@ import { WaAfterHideEvent } from '../../events/after-hide.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './dialog.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Dialogs, sometimes called "modals", appear above the page and require the user's immediate attention.
|
||||
@@ -92,6 +91,18 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('open') && this.hasUpdated) {
|
||||
// Open or close the dialog
|
||||
if (this.open && !this.dialog.open) {
|
||||
this.show();
|
||||
} else if (this.dialog.open) {
|
||||
this.open = true;
|
||||
this.requestClose(this.dialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unlockBodyScrolling(this);
|
||||
@@ -181,17 +192,6 @@ export default class WaDialog extends WebAwesomeElement {
|
||||
}
|
||||
};
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
handleOpenChange() {
|
||||
// Open or close the dialog
|
||||
if (this.open && !this.dialog.open) {
|
||||
this.show();
|
||||
} else if (this.dialog.open) {
|
||||
this.open = true;
|
||||
this.requestClose(this.dialog);
|
||||
}
|
||||
}
|
||||
|
||||
/** Shows the dialog. */
|
||||
private async show() {
|
||||
// Show
|
||||
|
||||
@@ -7,13 +7,13 @@ export default css`
|
||||
--spacing: var(--wa-space-m);
|
||||
}
|
||||
|
||||
:host(:not([vertical])) {
|
||||
:host(:not([orientation='vertical'])) {
|
||||
display: block;
|
||||
border-top: solid var(--width) var(--color);
|
||||
margin: var(--spacing) 0;
|
||||
}
|
||||
|
||||
:host([vertical]) {
|
||||
:host([orientation='vertical']) {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
border-left: solid var(--width) var(--color);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
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';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Dividers are used to visually separate or group elements.
|
||||
@@ -20,16 +19,17 @@ export default class WaDivider extends WebAwesomeElement {
|
||||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
|
||||
/** Draws the divider in a vertical orientation. */
|
||||
@property({ type: Boolean, reflect: true }) vertical = false;
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.setAttribute('role', 'separator');
|
||||
}
|
||||
|
||||
@watch('vertical')
|
||||
handleVerticalChange() {
|
||||
this.setAttribute('aria-orientation', this.vertical ? 'vertical' : 'horizontal');
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('orientation')) {
|
||||
this.setAttribute('aria-orientation', this.orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,11 +9,10 @@ import { WaAfterHideEvent } from '../../events/after-hide.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './drawer.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Drawers slide in from a container to expose additional options and information.
|
||||
@@ -92,6 +91,12 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
/** When enabled, the drawer will be closed when the user clicks outside of it. */
|
||||
@property({ attribute: 'light-dismiss', type: Boolean }) lightDismiss = false;
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unlockBodyScrolling(this);
|
||||
this.removeOpenListeners();
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (isServer) {
|
||||
return;
|
||||
@@ -103,10 +108,16 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unlockBodyScrolling(this);
|
||||
this.removeOpenListeners();
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('open') && this.hasUpdated) {
|
||||
// Open or close the dialog
|
||||
if (this.open && !this.drawer.open) {
|
||||
this.show();
|
||||
} else if (this.drawer.open) {
|
||||
this.open = true;
|
||||
this.requestClose(this.drawer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async requestClose(source: Element) {
|
||||
@@ -192,17 +203,6 @@ export default class WaDrawer extends WebAwesomeElement {
|
||||
}
|
||||
};
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
handleOpenChange() {
|
||||
// Open or close the drawer
|
||||
if (this.open && !this.drawer.open) {
|
||||
this.show();
|
||||
} else if (this.drawer.open) {
|
||||
this.open = true;
|
||||
this.requestClose(this.drawer);
|
||||
}
|
||||
}
|
||||
|
||||
/** Shows the drawer. */
|
||||
private async show() {
|
||||
// Show
|
||||
|
||||
@@ -9,11 +9,10 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
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 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 { CSSResultGroup, PropertyValues } 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';
|
||||
@@ -117,20 +116,72 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
firstUpdated (changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties)
|
||||
this.panel.hidden = !this.open;
|
||||
const initiallyOpen = this.open
|
||||
this.open = false
|
||||
|
||||
// If the dropdown is visible on init, update its position
|
||||
if (this.open) {
|
||||
this.addOpenListeners();
|
||||
this.popup.active = true;
|
||||
// With SSR timings, sometimes the popup animations never get a chance to end / cancel.
|
||||
// This is a hacky workaround to "fix" those animation issues.
|
||||
setTimeout(() => {
|
||||
this.popup.popup.dispatchEvent(new Event("animationend"))
|
||||
|
||||
// If the dropdown is visible on init, update its position
|
||||
if (initiallyOpen) {
|
||||
setTimeout(() => {
|
||||
this.open = true
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async updated(changeProperties: PropertyValues<this>) {
|
||||
// Handle open changes
|
||||
if (changeProperties.has('open') && this.hasUpdated) {
|
||||
if (this.disabled) {
|
||||
this.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateAccessibleTrigger();
|
||||
|
||||
if (this.open) {
|
||||
// Show
|
||||
const waShowEvent = new WaShowEvent();
|
||||
this.dispatchEvent(waShowEvent);
|
||||
if (waShowEvent.defaultPrevented) {
|
||||
this.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.addOpenListeners();
|
||||
this.panel.hidden = false;
|
||||
this.popup.active = true;
|
||||
await animateWithClass(this.popup.popup, 'show-with-scale');
|
||||
this.dispatchEvent(new WaAfterShowEvent());
|
||||
} else {
|
||||
// Hide
|
||||
const waHideEvent = new WaHideEvent();
|
||||
this.dispatchEvent(waHideEvent);
|
||||
if (waHideEvent.defaultPrevented) {
|
||||
this.open = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeOpenListeners();
|
||||
await animateWithClass(this.popup.popup, 'hide-with-scale');
|
||||
this.panel.hidden = true;
|
||||
this.popup.active = false;
|
||||
this.dispatchEvent(new WaAfterHideEvent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeOpenListeners();
|
||||
this.hide();
|
||||
this.open = false;
|
||||
}
|
||||
|
||||
focusOnTrigger() {
|
||||
@@ -151,7 +202,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
// in case any ancestors are also listening for this key.
|
||||
if (this.open && event.key === 'Escape' && !this.closeWatcher) {
|
||||
event.stopPropagation();
|
||||
this.hide();
|
||||
this.open = false;
|
||||
this.focusOnTrigger();
|
||||
}
|
||||
};
|
||||
@@ -161,7 +212,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
if (event.key === 'Escape' && this.open) {
|
||||
event.stopPropagation();
|
||||
this.focusOnTrigger();
|
||||
this.hide();
|
||||
this.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -170,7 +221,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
// Tabbing within an open menu should close the dropdown and refocus the trigger
|
||||
if (this.open && document.activeElement?.tagName.toLowerCase() === 'wa-menu-item') {
|
||||
event.preventDefault();
|
||||
this.hide();
|
||||
this.open = false;
|
||||
this.focusOnTrigger();
|
||||
return;
|
||||
}
|
||||
@@ -189,7 +240,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
!this.containingElement ||
|
||||
activeElement?.closest(this.containingElement.tagName.toLowerCase()) !== this.containingElement
|
||||
) {
|
||||
this.hide();
|
||||
this.open = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -199,7 +250,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
// Close when clicking outside of the containing element
|
||||
const path = event.composedPath();
|
||||
if (this.containingElement && !path.includes(this.containingElement)) {
|
||||
this.hide();
|
||||
this.open = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -208,16 +259,16 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
|
||||
// Hide the dropdown when a menu item is selected
|
||||
if (!this.stayOpenOnSelect && target.tagName.toLowerCase() === 'wa-menu') {
|
||||
this.hide();
|
||||
this.open = false;
|
||||
this.focusOnTrigger();
|
||||
}
|
||||
};
|
||||
|
||||
handleTriggerClick() {
|
||||
if (this.open) {
|
||||
this.hide();
|
||||
this.open = false;
|
||||
} else {
|
||||
this.show();
|
||||
this.open = true;
|
||||
this.focusOnTrigger();
|
||||
}
|
||||
}
|
||||
@@ -246,7 +297,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
|
||||
// Show the menu if it's not already open
|
||||
if (!this.open) {
|
||||
this.show();
|
||||
this.open = true;
|
||||
|
||||
// Wait for the dropdown to open before focusing, but not the animation
|
||||
await this.updateComplete;
|
||||
@@ -349,7 +400,7 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
this.closeWatcher?.destroy();
|
||||
this.closeWatcher = new CloseWatcher();
|
||||
this.closeWatcher.onclose = () => {
|
||||
this.hide();
|
||||
this.open = false;
|
||||
this.focusOnTrigger();
|
||||
};
|
||||
} else {
|
||||
@@ -369,46 +420,6 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
this.closeWatcher?.destroy();
|
||||
}
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
if (this.disabled) {
|
||||
this.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateAccessibleTrigger();
|
||||
|
||||
if (this.open) {
|
||||
// Show
|
||||
const waShowEvent = new WaShowEvent();
|
||||
this.dispatchEvent(waShowEvent);
|
||||
if (waShowEvent.defaultPrevented) {
|
||||
this.open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.addOpenListeners();
|
||||
this.panel.hidden = false;
|
||||
this.popup.active = true;
|
||||
await animateWithClass(this.popup.popup, 'show-with-scale');
|
||||
this.dispatchEvent(new WaAfterShowEvent());
|
||||
} else {
|
||||
// Hide
|
||||
const waHideEvent = new WaHideEvent();
|
||||
this.dispatchEvent(waHideEvent);
|
||||
if (waHideEvent.defaultPrevented) {
|
||||
this.open = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.removeOpenListeners();
|
||||
await animateWithClass(this.popup.popup, 'hide-with-scale');
|
||||
this.panel.hidden = true;
|
||||
this.popup.active = false;
|
||||
this.dispatchEvent(new WaAfterHideEvent());
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<wa-popup
|
||||
|
||||
@@ -31,7 +31,7 @@ export default class WaIconButton extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('.icon-button') button: HTMLButtonElement | HTMLLinkElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
|
||||
/** The name of the icon to draw. Available names depend on the icon library being used. */
|
||||
@property({ reflect: true }) name: string | null = null;
|
||||
|
||||
@@ -4,7 +4,6 @@ import { html } from 'lit';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './icon.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
@@ -46,7 +45,7 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
|
||||
private initialRender = false;
|
||||
|
||||
@state() private svg: SVGElement | HTMLTemplateResult | null = null;
|
||||
@state() svg: SVGElement | HTMLTemplateResult | null = null;
|
||||
|
||||
/** The name of the icon to draw. Available names depend on the icon library being used. */
|
||||
@property({ reflect: true }) name?: string;
|
||||
@@ -93,6 +92,43 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Sometimes (like with SSR -> hydration) mutators don't get applied due to race conditions. This ensures mutators
|
||||
// get re-applied.
|
||||
const library = getIconLibrary(this.library);
|
||||
|
||||
const svg = this.shadowRoot?.querySelector('svg');
|
||||
if (svg) {
|
||||
library?.mutator?.(svg);
|
||||
}
|
||||
|
||||
// Handle label changes
|
||||
if (changedProperties.has('label')) {
|
||||
const hasLabel = typeof this.label === 'string' && this.label.length > 0;
|
||||
|
||||
if (hasLabel) {
|
||||
this.setAttribute('role', 'img');
|
||||
this.setAttribute('aria-label', this.label);
|
||||
this.removeAttribute('aria-hidden');
|
||||
} else {
|
||||
this.removeAttribute('role');
|
||||
this.removeAttribute('aria-label');
|
||||
this.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle icon changes
|
||||
if (
|
||||
changedProperties.has('family') ||
|
||||
changedProperties.has('name') ||
|
||||
changedProperties.has('library') ||
|
||||
changedProperties.has('variant') ||
|
||||
changedProperties.has('src')
|
||||
) {
|
||||
this.setIcon();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unwatchIcon(this);
|
||||
@@ -162,22 +198,6 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('label')
|
||||
handleLabelChange() {
|
||||
const hasLabel = typeof this.label === 'string' && this.label.length > 0;
|
||||
|
||||
if (hasLabel) {
|
||||
this.setAttribute('role', 'img');
|
||||
this.setAttribute('aria-label', this.label);
|
||||
this.removeAttribute('aria-hidden');
|
||||
} else {
|
||||
this.removeAttribute('role');
|
||||
this.removeAttribute('aria-label');
|
||||
this.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
@watch(['family', 'name', 'library', 'variant', 'src'])
|
||||
async setIcon() {
|
||||
const { url, fromLibrary } = this.getIconSource();
|
||||
const library = fromLibrary ? getIconLibrary(this.library) : undefined;
|
||||
@@ -227,24 +247,15 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
// Sometimes (like with SSR -> hydration) mutators dont get applied due to race conditions. This ensures mutators get re-applied.
|
||||
const library = getIconLibrary(this.library);
|
||||
|
||||
const svg = this.shadowRoot?.querySelector('svg');
|
||||
if (svg) {
|
||||
library?.mutator?.(svg);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.hasUpdated) {
|
||||
return this.svg;
|
||||
}
|
||||
|
||||
// @TODO: 16x16 is generally a safe bet. Perhaps be user setable?? `size="16x16"`, size="20x16". We just want to avoid "blowouts" with SSR.
|
||||
//
|
||||
// TODO: 16x16 is generally a safe bet. Perhaps this should be user settable, e.g. `size="16x16"`. We just want to
|
||||
// avoid SSR "blowouts."
|
||||
//
|
||||
return html`<svg part="svg" fill="currentColor" width="16" height="16"></svg>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,10 @@ import { drag } from '../../internal/drag.js';
|
||||
import { html } from 'lit';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
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';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Compare visual differences between similar photos with a sliding panel.
|
||||
@@ -47,6 +46,13 @@ export default class WaImageComparer extends WebAwesomeElement {
|
||||
/** The position of the divider as a percentage. */
|
||||
@property({ type: Number, reflect: true }) position = 50;
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle position changes
|
||||
if (changedProperties.has('position') && this.hasUpdated) {
|
||||
this.dispatchEvent(new WaChangeEvent());
|
||||
}
|
||||
}
|
||||
|
||||
private handleDrag(event: PointerEvent) {
|
||||
const { width } = this.base.getBoundingClientRect();
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
@@ -90,11 +96,6 @@ export default class WaImageComparer extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('position', { waitUntilFirstUpdate: true })
|
||||
handlePositionChange() {
|
||||
this.dispatchEvent(new WaChangeEvent());
|
||||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.hasUpdated ? this.matches(':dir(rtl)') : this.dir === 'rtl';
|
||||
|
||||
|
||||
@@ -3,11 +3,10 @@ import { html } from 'lit';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './include.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Includes give you the power to embed external HTML files into the page.
|
||||
@@ -37,6 +36,36 @@ export default class WaInclude extends WebAwesomeElement {
|
||||
*/
|
||||
@property({ attribute: 'allow-scripts', type: Boolean }) allowScripts = false;
|
||||
|
||||
async updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle src changes
|
||||
if (changedProperties.has('src')) {
|
||||
try {
|
||||
const src = this.src;
|
||||
const file = await requestInclude(src, this.mode);
|
||||
|
||||
// If the src changed since the request started do nothing, otherwise we risk overwriting a subsequent response
|
||||
if (src !== this.src) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file.ok) {
|
||||
this.dispatchEvent(new WaIncludeErrorEvent({ status: file.status }));
|
||||
return;
|
||||
}
|
||||
|
||||
this.innerHTML = file.html;
|
||||
|
||||
if (this.allowScripts) {
|
||||
[...this.querySelectorAll('script')].forEach(script => this.executeScript(script));
|
||||
}
|
||||
|
||||
this.dispatchEvent(new WaLoadEvent());
|
||||
} catch {
|
||||
this.dispatchEvent(new WaIncludeErrorEvent({ status: -1 }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private executeScript(script: HTMLScriptElement) {
|
||||
// Create a copy of the script and swap it out so the browser executes it
|
||||
const newScript = document.createElement('script');
|
||||
@@ -45,34 +74,6 @@ export default class WaInclude extends WebAwesomeElement {
|
||||
script.parentNode!.replaceChild(newScript, script);
|
||||
}
|
||||
|
||||
@watch('src')
|
||||
async handleSrcChange() {
|
||||
try {
|
||||
const src = this.src;
|
||||
const file = await requestInclude(src, this.mode);
|
||||
|
||||
// If the src changed since the request started do nothing, otherwise we risk overwriting a subsequent response
|
||||
if (src !== this.src) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!file.ok) {
|
||||
this.dispatchEvent(new WaIncludeErrorEvent({ status: file.status }));
|
||||
return;
|
||||
}
|
||||
|
||||
this.innerHTML = file.html;
|
||||
|
||||
if (this.allowScripts) {
|
||||
[...this.querySelectorAll('script')].forEach(script => this.executeScript(script));
|
||||
}
|
||||
|
||||
this.dispatchEvent(new WaLoadEvent());
|
||||
} catch {
|
||||
this.dispatchEvent(new WaIncludeErrorEvent({ status: -1 }));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<slot></slot>`;
|
||||
}
|
||||
|
||||
@@ -12,12 +12,11 @@ import { WaChangeEvent } from '../../events/change.js';
|
||||
import { WaClearEvent } from '../../events/clear.js';
|
||||
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.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
import type WaButton from '../button/button.js';
|
||||
|
||||
/**
|
||||
@@ -77,7 +76,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('.input__control') input: HTMLInputElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
/**
|
||||
@@ -229,6 +228,16 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
*/
|
||||
@property({ attribute: 'with-help-text', type: Boolean }) withHelpText = false;
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle step changes
|
||||
if (changedProperties.has('step') && this.hasUpdated) {
|
||||
// If step changes, the value may become invalid so we need to recheck after the update. We set the new step
|
||||
// imperatively so we don't have to wait for the next render to report the updated validity.
|
||||
this.input.step = String(this.step);
|
||||
this.updateValidity();
|
||||
}
|
||||
}
|
||||
|
||||
private handleBlur() {
|
||||
this.hasFocus = false;
|
||||
this.dispatchEvent(new WaBlurEvent());
|
||||
@@ -314,14 +323,6 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
|
||||
this.passwordVisible = !this.passwordVisible;
|
||||
}
|
||||
|
||||
@watch('step', { waitUntilFirstUpdate: true })
|
||||
handleStepChange() {
|
||||
// If step changes, the value may become invalid so we need to recheck after the update. We set the new step
|
||||
// imperatively so we don't have to wait for the next render to report the updated validity.
|
||||
this.input.step = String(this.step);
|
||||
this.updateValidity();
|
||||
}
|
||||
|
||||
/** Sets focus on the input. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.input.focus(options);
|
||||
|
||||
@@ -6,7 +6,6 @@ import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { getTextContent } from '../../internal/slot.js';
|
||||
import { html } from 'lit';
|
||||
import { SubmenuController } from './submenu-controller.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './menu-item.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
@@ -82,7 +81,7 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
this.removeEventListener('mouseover', this.handleMouseOver);
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProperties: PropertyValues<this>): void {
|
||||
firstUpdated(changedProperties: PropertyValues<this>): void {
|
||||
// Kick it so that it renders the "submenu" properly.
|
||||
if (this.isSubmenu()) {
|
||||
this.requestUpdate();
|
||||
@@ -91,6 +90,40 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
super.firstUpdated(changedProperties);
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle checked change
|
||||
if (changedProperties.has('checked')) {
|
||||
// For proper accessibility, users have to use type="checkbox" to use the checked attribute
|
||||
if (this.checked && this.type !== 'checkbox') {
|
||||
this.checked = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only checkbox types can receive the aria-checked attribute
|
||||
if (this.type === 'checkbox') {
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
} else {
|
||||
this.removeAttribute('aria-checked');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle disabled change
|
||||
if (changedProperties.has('disabled')) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
// Handle type change
|
||||
if (changedProperties.has('type')) {
|
||||
if (this.type === 'checkbox') {
|
||||
this.setAttribute('role', 'menuitemcheckbox');
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
} else {
|
||||
this.setAttribute('role', 'menuitem');
|
||||
this.removeAttribute('aria-checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleDefaultSlotChange() {
|
||||
const textLabel = this.getTextLabel();
|
||||
|
||||
@@ -121,38 +154,6 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
@watch('checked')
|
||||
handleCheckedChange() {
|
||||
// For proper accessibility, users have to use type="checkbox" to use the checked attribute
|
||||
if (this.checked && this.type !== 'checkbox') {
|
||||
this.checked = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only checkbox types can receive the aria-checked attribute
|
||||
if (this.type === 'checkbox') {
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
} else {
|
||||
this.removeAttribute('aria-checked');
|
||||
}
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('type')
|
||||
handleTypeChange() {
|
||||
if (this.type === 'checkbox') {
|
||||
this.setAttribute('role', 'menuitemcheckbox');
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
} else {
|
||||
this.setAttribute('role', 'menuitem');
|
||||
this.removeAttribute('aria-checked');
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a text label based on the contents of the menu item's default slot. */
|
||||
getTextLabel() {
|
||||
return getTextContent(this.defaultSlot);
|
||||
|
||||
@@ -1,11 +1,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 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';
|
||||
import type { CSSResultGroup, PropertyValues } 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).
|
||||
@@ -56,6 +55,29 @@ export default class WaMutationObserver extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled')) {
|
||||
if (this.disabled) {
|
||||
this.stopObserver();
|
||||
} else {
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle other changes
|
||||
if (
|
||||
changedProperties.has('attr') ||
|
||||
changedProperties.has('attrOldValue') ||
|
||||
changedProperties.has('charData') ||
|
||||
changedProperties.has('charDataOldValue') ||
|
||||
changedProperties.has('childList')
|
||||
) {
|
||||
this.stopObserver();
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.stopObserver();
|
||||
@@ -92,25 +114,6 @@ export default class WaMutationObserver extends WebAwesomeElement {
|
||||
this.mutationObserver.disconnect();
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
if (this.disabled) {
|
||||
this.stopObserver();
|
||||
} else {
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
|
||||
@watch('attr', { waitUntilFirstUpdate: true })
|
||||
@watch('attr-old-value', { waitUntilFirstUpdate: true })
|
||||
@watch('char-data', { waitUntilFirstUpdate: true })
|
||||
@watch('char-data-old-value', { waitUntilFirstUpdate: true })
|
||||
@watch('childList', { waitUntilFirstUpdate: true })
|
||||
handleChange() {
|
||||
this.stopObserver();
|
||||
this.startObserver();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <slot></slot> `;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,10 @@ import { classMap } from 'lit/directives/class-map.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './option.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Options define the selectable items within various form controls such as [select](/docs/components/select).
|
||||
@@ -61,6 +60,33 @@ export default class WaOption extends WebAwesomeElement {
|
||||
this.setAttribute('aria-selected', 'false');
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle disabled changes\
|
||||
if (changedProperties.has('disabled')) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
// Handle selected changes\
|
||||
if (changedProperties.has('selected')) {
|
||||
this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
|
||||
}
|
||||
|
||||
// Handle value changes\
|
||||
if (changedProperties.has('value')) {
|
||||
// Ensure the value is a string. This ensures the next line doesn't error and allows framework users to pass numbers
|
||||
// instead of requiring them to cast the value to a string.
|
||||
if (typeof this.value !== 'string') {
|
||||
this.value = String(this.value);
|
||||
}
|
||||
|
||||
if (this.value.includes(' ')) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Option values cannot include a space. All spaces have been replaced with underscores.`, this);
|
||||
this.value = this.value.replace(/ /g, '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleDefaultSlotChange() {
|
||||
// When the label changes, tell the controller to update
|
||||
customElements.whenDefined('wa-select').then(() => {
|
||||
@@ -79,31 +105,6 @@ export default class WaOption extends WebAwesomeElement {
|
||||
this.hasHover = false;
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('selected')
|
||||
handleSelectedChange() {
|
||||
this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('value')
|
||||
handleValueChange() {
|
||||
// Ensure the value is a string. This ensures the next line doesn't error and allows framework users to pass numbers
|
||||
// instead of requiring them to cast the value to a string.
|
||||
if (typeof this.value !== 'string') {
|
||||
this.value = String(this.value);
|
||||
}
|
||||
|
||||
if (this.value.includes(' ')) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Option values cannot include a space. All spaces have been replaced with underscores.`, this);
|
||||
this.value = this.value.replace(/ /g, '_');
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a plain text label based on the option's content. */
|
||||
getTextLabel() {
|
||||
const nodes = this.childNodes;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { WaRepositionEvent } from '../../events/reposition.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './popup.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
export interface VirtualElement {
|
||||
getBoundingClientRect: () => DOMRect;
|
||||
@@ -222,11 +222,11 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
this.stop();
|
||||
}
|
||||
|
||||
async updated(changedProps: Map<string, unknown>) {
|
||||
super.updated(changedProps);
|
||||
async updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
// Start or stop the positioner when active changes
|
||||
if (changedProps.has('active')) {
|
||||
if (changedProperties.has('active')) {
|
||||
if (this.active) {
|
||||
this.start();
|
||||
} else {
|
||||
@@ -235,7 +235,7 @@ export default class WaPopup extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
// Update the anchor when anchor changes
|
||||
if (changedProps.has('anchor')) {
|
||||
if (changedProperties.has('anchor')) {
|
||||
this.handleAnchorChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { LocalizeController } from '../../utilities/localize.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './progress-ring.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Progress rings are used to show the progress of a determinate operation in a circular fashion.
|
||||
@@ -40,15 +40,15 @@ export default class WaProgressRing extends WebAwesomeElement {
|
||||
/** A custom label for assistive devices. */
|
||||
@property() label = '';
|
||||
|
||||
updated(changedProps: Map<string, unknown>) {
|
||||
super.updated(changedProps);
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
//
|
||||
// This block is only required for Safari because it doesn't transition the circle when the custom properties
|
||||
// change, possibly because of a mix of pixel + unit-less values in the calc() function. It seems like a Safari bug,
|
||||
// but I couldn't pinpoint it so this works around the problem.
|
||||
//
|
||||
if (changedProps.has('value')) {
|
||||
if (changedProperties.has('value')) {
|
||||
const radius = parseFloat(getComputedStyle(this.indicator).getPropertyValue('r'));
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
const offset = circumference - (this.value / 100) * circumference;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './qr-code.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
@@ -44,11 +43,8 @@ export default class WaQrCode extends WebAwesomeElement {
|
||||
/** The level of error correction to use. [Learn more](https://www.qrcode.com/en/about/error_correction.html) */
|
||||
@property({ attribute: 'error-correction' }) errorCorrection: 'L' | 'M' | 'Q' | 'H' = 'H';
|
||||
|
||||
/**
|
||||
* Whether or not the qr-code generated.
|
||||
*/
|
||||
// @ts-expect-error Don't know why it marks it as unused.
|
||||
@state() private generated = false;
|
||||
/** Whether or not the qr-code generated. */
|
||||
@state() generated = false;
|
||||
|
||||
firstUpdated(changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties);
|
||||
@@ -58,8 +54,21 @@ export default class WaQrCode extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch(['background', 'errorCorrection', 'fill', 'radius', 'size', 'value'])
|
||||
generate() {
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Regenerate the code when these properties change
|
||||
if (
|
||||
changedProperties.has('background') ||
|
||||
changedProperties.has('errorCorrection') ||
|
||||
changedProperties.has('fill') ||
|
||||
changedProperties.has('radius') ||
|
||||
changedProperties.has('size') ||
|
||||
changedProperties.has('value')
|
||||
) {
|
||||
this.generate();
|
||||
}
|
||||
}
|
||||
|
||||
private generate() {
|
||||
this.style.setProperty('--size', `${this.size}px`);
|
||||
|
||||
if (!this.hasUpdated) {
|
||||
|
||||
@@ -5,11 +5,10 @@ import { html } from 'lit/static-html.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaFocusEvent } from '../../events/focus.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './radio-button.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Radios buttons allow the user to select a single option from a group using a button-like control.
|
||||
@@ -107,6 +106,13 @@ export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
|
||||
this.setAttribute('role', 'presentation');
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
|
||||
private handleBlur() {
|
||||
this.hasFocus = false;
|
||||
this.dispatchEvent(new WaBlurEvent());
|
||||
@@ -127,11 +133,6 @@ export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
|
||||
this.dispatchEvent(new WaFocusEvent());
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/** Sets focus on the radio button. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.input.focus(options);
|
||||
|
||||
@@ -8,12 +8,11 @@ import { RequiredValidator } from '../../internal/validators/required-validator.
|
||||
import { uniqueId } from '../../internal/math.js';
|
||||
import { WaChangeEvent } from '../../events/change.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 './radio-group.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
import type WaRadio from '../radio/radio.js';
|
||||
import type WaRadioButton from '../radio-button/radio-button.js';
|
||||
|
||||
@@ -65,7 +64,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
|
||||
@state() private hasButtonGroup = false;
|
||||
@state() hasButtonGroup = false;
|
||||
|
||||
/**
|
||||
* The radio group's label. Required for proper accessibility. If you need to display HTML, use the `label` slot
|
||||
@@ -134,6 +133,13 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues) {
|
||||
// Handle value/size changes
|
||||
if (changedProperties.has('value') || changedProperties.has('size')) {
|
||||
this.syncRadioElements();
|
||||
}
|
||||
}
|
||||
|
||||
private handleRadioClick = (e: Event) => {
|
||||
const clickedRadio = (e.target as HTMLElement).closest<WaRadio | WaRadioButton>('wa-radio, wa-radio-button');
|
||||
|
||||
@@ -230,16 +236,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
: this.querySelector<WaRadio | WaRadioButton>(':is(wa-radio, wa-radio-button):not([disabled])') || undefined;
|
||||
}
|
||||
|
||||
@watch('value')
|
||||
handleValueChange() {
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
@watch('size', { waitUntilFirstUpdate: true })
|
||||
handleSizeChange() {
|
||||
this.syncRadioElements();
|
||||
}
|
||||
|
||||
formResetCallback(...args: Parameters<WebAwesomeFormAssociatedElement['formResetCallback']>) {
|
||||
this.value = this.defaultValue;
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@ import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { html, isServer } from 'lit';
|
||||
import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaFocusEvent } from '../../events/focus.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './radio.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Radios allow the user to select a single option from a group.
|
||||
@@ -78,6 +77,19 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
|
||||
this.setInitialAttributes();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues) {
|
||||
// Handle checked change
|
||||
if (changedProperties.has('checked')) {
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
this.tabIndex = this.checked ? 0 : -1;
|
||||
}
|
||||
|
||||
// Handle disabled change
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
|
||||
private handleBlur = () => {
|
||||
this.hasFocus = false;
|
||||
this.dispatchEvent(new WaBlurEvent());
|
||||
@@ -94,12 +106,6 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('checked')
|
||||
handleCheckedChange() {
|
||||
this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
|
||||
this.tabIndex = this.checked ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -107,11 +113,6 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
|
||||
// We override `setValue` because we don't want to set form values from here. We want to do that in "RadioGroup" itself.
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
private handleClick = () => {
|
||||
if (!this.disabled) {
|
||||
this.checked = true;
|
||||
|
||||
@@ -10,12 +10,11 @@ import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
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 './range.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Ranges allow the user to select a single value within a given range using a slider.
|
||||
@@ -65,8 +64,8 @@ export default class WaRange extends WebAwesomeFormAssociatedElement {
|
||||
@query('.range__control') input: HTMLInputElement;
|
||||
@query('.range__tooltip') output: HTMLOutputElement | null;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() private hasTooltip = false;
|
||||
@state() hasFocus = false;
|
||||
@state() hasTooltip = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
/** The name of the range, submitted as a name/value pair with form data. */
|
||||
@@ -157,6 +156,22 @@ export default class WaRange extends WebAwesomeFormAssociatedElement {
|
||||
});
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('value') && this.hasUpdated) {
|
||||
// The value may have constraints, so we set the native control's value and sync it back to ensure it adhere's to
|
||||
// min, max, and step properly
|
||||
this.input.value = this.value.toString();
|
||||
this.value = parseFloat(this.input.value);
|
||||
this.updateValidity();
|
||||
|
||||
this.syncRange();
|
||||
}
|
||||
|
||||
if (changedProperties.has('hasTooltip') && this.hasUpdated) {
|
||||
this.syncRange();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.resizeObserver?.unobserve(this.input);
|
||||
@@ -218,19 +233,7 @@ export default class WaRange extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('value', { waitUntilFirstUpdate: true })
|
||||
handleValueChange() {
|
||||
// The value may have constraints, so we set the native control's value and sync it back to ensure it adhere's to
|
||||
// min, max, and step properly
|
||||
this.input.value = this.value.toString();
|
||||
this.value = parseFloat(this.input.value);
|
||||
this.updateValidity();
|
||||
|
||||
this.syncRange();
|
||||
}
|
||||
|
||||
@watch('hasTooltip', { waitUntilFirstUpdate: true })
|
||||
syncRange() {
|
||||
private syncRange() {
|
||||
const percent = Math.max(0, (this.value - this.min) / (this.max - this.min));
|
||||
|
||||
this.syncProgress(percent);
|
||||
|
||||
@@ -7,11 +7,10 @@ import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
import { WaHoverEvent } from '../../events/hover.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './rating.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Ratings give users a way to quickly view and provide feedback.
|
||||
@@ -39,8 +38,8 @@ export default class WaRating extends WebAwesomeElement {
|
||||
|
||||
@query('.rating') rating: HTMLElement;
|
||||
|
||||
@state() private hoverValue = 0;
|
||||
@state() private isHovering = false;
|
||||
@state() hoverValue = 0;
|
||||
@state() isHovering = false;
|
||||
|
||||
/** A label that describes the rating to assistive devices. */
|
||||
@property() label = '';
|
||||
@@ -71,6 +70,28 @@ export default class WaRating extends WebAwesomeElement {
|
||||
@property() getSymbol: (value: number) => string = () =>
|
||||
'<wa-icon name="star" library="system" variant="solid"></wa-icon>';
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle hoverValue changes
|
||||
if (changedProperties.has('hoverValue')) {
|
||||
this.dispatchEvent(
|
||||
new WaHoverEvent({
|
||||
phase: 'move',
|
||||
value: this.hoverValue
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Handle isHovering changes
|
||||
if (changedProperties.has('isHovering')) {
|
||||
this.dispatchEvent(
|
||||
new WaHoverEvent({
|
||||
phase: this.isHovering ? 'start' : 'end',
|
||||
value: this.hoverValue
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private getValueFromMousePosition(event: MouseEvent) {
|
||||
return this.getValueFromXCoordinate(event.clientX);
|
||||
}
|
||||
@@ -183,26 +204,6 @@ export default class WaRating extends WebAwesomeElement {
|
||||
return Math.ceil(numberToRound * multiplier) / multiplier;
|
||||
}
|
||||
|
||||
@watch('hoverValue')
|
||||
handleHoverValueChange() {
|
||||
this.dispatchEvent(
|
||||
new WaHoverEvent({
|
||||
phase: 'move',
|
||||
value: this.hoverValue
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@watch('isHovering')
|
||||
handleIsHoveringChange() {
|
||||
this.dispatchEvent(
|
||||
new WaHoverEvent({
|
||||
phase: this.isHovering ? 'start' : 'end',
|
||||
value: this.hoverValue
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/** Sets focus on the rating. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.rating.focus(options);
|
||||
|
||||
@@ -29,8 +29,8 @@ export default class WaRelativeTime extends WebAwesomeElement {
|
||||
private readonly localize = new LocalizeController(this);
|
||||
private updateTimeout: number | ReturnType<typeof setTimeout>;
|
||||
|
||||
@state() private isoTime = '';
|
||||
@state() private relativeTime = '';
|
||||
@state() isoTime = '';
|
||||
@state() relativeTime = '';
|
||||
|
||||
/**
|
||||
* The date from which to calculate time from. If not set, the current date and time will be used. When passing a
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { WaResizeEvent } from '../../events/resize.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './resize-observer.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary The Resize Observer component offers a thin, declarative interface to the [`ResizeObserver API`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).
|
||||
@@ -40,6 +39,17 @@ export default class WaResizeObserver extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
if (this.disabled) {
|
||||
this.stopObserver();
|
||||
} else {
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.stopObserver();
|
||||
@@ -73,15 +83,6 @@ export default class WaResizeObserver extends WebAwesomeElement {
|
||||
this.resizeObserver.disconnect();
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
if (this.disabled) {
|
||||
this.stopObserver();
|
||||
} else {
|
||||
this.startObserver();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <slot @slotchange=${this.handleSlotChange}></slot> `;
|
||||
}
|
||||
|
||||
@@ -20,12 +20,11 @@ import { WaHideEvent } from '../../events/hide.js';
|
||||
import { WaInputEvent } from '../../events/input.js';
|
||||
import { waitForEvent } from '../../internal/event.js';
|
||||
import { WaShowEvent } from '../../events/show.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 './select.styles.js';
|
||||
import type { CSSResultGroup, TemplateResult } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
||||
import type { WaRemoveEvent } from '../../events/remove.js';
|
||||
import type WaOption from '../option/option.js';
|
||||
import type WaPopup from '../popup/popup.js';
|
||||
@@ -269,6 +268,29 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
this.open = false;
|
||||
}
|
||||
|
||||
firstUpdated (changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties)
|
||||
// With SSR timings, sometimes the popup animations never get a chance to end / cancel.
|
||||
// This is a hacky workaround to "fix" those animation issues.
|
||||
setTimeout(() => {
|
||||
this.popup.popup.dispatchEvent(new Event("animationend"))
|
||||
})
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
// Close the listbox when the control is disabled
|
||||
if (this.disabled) {
|
||||
this.open = false;
|
||||
this.handleOpenChange();
|
||||
}
|
||||
}
|
||||
|
||||
if (changedProperties.has('open') && this.hasUpdated) {
|
||||
this.handleOpenChange();
|
||||
}
|
||||
}
|
||||
|
||||
private addOpenListeners() {
|
||||
//
|
||||
// Listen on the root node instead of the document in case the elements are inside a shadow root
|
||||
@@ -676,17 +698,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
});
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
// Close the listbox when the control is disabled
|
||||
if (this.disabled) {
|
||||
this.open = false;
|
||||
this.handleOpenChange();
|
||||
}
|
||||
}
|
||||
|
||||
@watch('value', { waitUntilFirstUpdate: true })
|
||||
handleValueChange() {
|
||||
private handleValueChange() {
|
||||
const allOptions = this.getAllOptions();
|
||||
const value = Array.isArray(this.value) ? this.value : [this.value];
|
||||
|
||||
@@ -695,7 +707,6 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
|
||||
this.updateValidity();
|
||||
}
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
if (this.open && !this.disabled) {
|
||||
// Reset the current option
|
||||
|
||||
@@ -40,11 +40,11 @@ export default css`
|
||||
}
|
||||
|
||||
/* Horizontal */
|
||||
:host(:not([vertical], [disabled])) .divider {
|
||||
:host(:not([orientation='vertical'], [disabled])) .divider {
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
:host(:not([vertical])) .divider::after {
|
||||
:host(:not([orientation='vertical'])) .divider::after {
|
||||
display: flex;
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -54,15 +54,15 @@ export default css`
|
||||
}
|
||||
|
||||
/* Vertical */
|
||||
:host([vertical]) {
|
||||
:host([orientation='vertical']) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:host([vertical]:not([disabled])) .divider {
|
||||
:host([orientation='vertical']:not([disabled])) .divider {
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
:host([vertical]) .divider::after {
|
||||
:host([orientation='vertical']) .divider::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
@@ -185,7 +185,7 @@ describe('<wa-split-panel>', () => {
|
||||
describe('panel sizing vertical', () => {
|
||||
it('has two evenly sized panels by default', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel vertical style="height: 400px;">
|
||||
html`<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div slot="start" data-testid="start-panel">Start</div>
|
||||
<div slot="end" data-testid="end-panel">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -199,7 +199,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('changes the sizing of the panels based on the position attribute', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel position="25" vertical style="height: 400px;">
|
||||
html`<wa-split-panel position="25" orientation="vertical" style="height: 400px;">
|
||||
<div slot="start" data-testid="start-panel">Start</div>
|
||||
<div slot="end" data-testid="end-panel">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -213,7 +213,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('updates the position in pixels to the correct result', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel position="25" vertical style="height: 400px;">
|
||||
html`<wa-split-panel position="25" orientation="vertical" style="height: 400px;">
|
||||
<div slot="start" data-testid="start-panel">Start</div>
|
||||
<div slot="end" data-testid="end-panel">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -228,7 +228,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('emits the wa-reposition event on position change ', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel vertical style="height: 400px;">
|
||||
html`<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div slot="start">Start</div>
|
||||
<div slot="end">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -241,7 +241,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('can be resized using the mouse ', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel vertical style="height: 400px;">
|
||||
html`<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div slot="start">Start</div>
|
||||
<div slot="end">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -259,7 +259,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('cannot be resized if disabled', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel disabled vertical style="height: 400px;">
|
||||
html`<wa-split-panel disabled orientation="vertical" style="height: 400px;">
|
||||
<div slot="start">Start</div>
|
||||
<div slot="end">End</div>
|
||||
</wa-split-panel>`
|
||||
@@ -277,7 +277,7 @@ describe('<wa-split-panel>', () => {
|
||||
|
||||
it('snaps to predefined positions', async () => {
|
||||
const splitPanel = await fixture<WaSplitPanel>(
|
||||
html`<wa-split-panel vertical style="height: 400px;">
|
||||
html`<wa-split-panel orientation="vertical" style="height: 400px;">
|
||||
<div slot="start">Start</div>
|
||||
<div slot="end">End</div>
|
||||
</wa-split-panel>`
|
||||
|
||||
@@ -5,11 +5,10 @@ import { html } from 'lit';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { WaRepositionEvent } from '../../events/reposition.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './split-panel.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Split panels display two adjacent panels, allowing the user to reposition them.
|
||||
@@ -58,7 +57,7 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
@property({ attribute: 'position-in-pixels', type: Number }) positionInPixels: number;
|
||||
|
||||
/** Draws the split panel in a vertical orientation with the start and end panels stacked. */
|
||||
@property({ type: Boolean, reflect: true }) vertical = false;
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
||||
/** Disables resizing. Note that the position may still change as a result of resizing the host element. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
@@ -88,6 +87,27 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
this.cachedPositionInPixels = this.percentageToPixels(this.position);
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle position change
|
||||
if (changedProperties.has('position')) {
|
||||
this.cachedPositionInPixels = this.percentageToPixels(this.position);
|
||||
this.positionInPixels = this.percentageToPixels(this.position);
|
||||
this.isCollapsed = false;
|
||||
this.positionBeforeCollapsing = 0;
|
||||
this.dispatchEvent(new WaRepositionEvent());
|
||||
}
|
||||
|
||||
// Handle positionInPixels change
|
||||
if (changedProperties.has('positionInPixels')) {
|
||||
this.position = this.pixelsToPercentage(this.positionInPixels);
|
||||
}
|
||||
|
||||
// Handle orientation change
|
||||
if (changedProperties.has('orientation')) {
|
||||
this.detectSize();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.resizeObserver?.unobserve(this);
|
||||
@@ -95,7 +115,7 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
|
||||
private detectSize() {
|
||||
const { width, height } = this.getBoundingClientRect();
|
||||
this.size = this.vertical ? height : width;
|
||||
this.size = this.orientation === 'vertical' ? height : width;
|
||||
}
|
||||
|
||||
private percentageToPixels(value: number) {
|
||||
@@ -120,7 +140,7 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
|
||||
drag(this, {
|
||||
onMove: (x, y) => {
|
||||
let newPositionInPixels = this.vertical ? y : x;
|
||||
let newPositionInPixels = this.orientation === 'vertical' ? y : x;
|
||||
|
||||
// Flip for end panels
|
||||
if (this.primary === 'end') {
|
||||
@@ -140,7 +160,7 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
snapPoint = parseFloat(value);
|
||||
}
|
||||
|
||||
if (isRtl && !this.vertical) {
|
||||
if (isRtl && this.orientation !== 'vertical') {
|
||||
snapPoint = this.size - snapPoint;
|
||||
}
|
||||
|
||||
@@ -170,11 +190,17 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if ((event.key === 'ArrowLeft' && !this.vertical) || (event.key === 'ArrowUp' && this.vertical)) {
|
||||
if (
|
||||
(event.key === 'ArrowLeft' && this.orientation !== 'vertical') ||
|
||||
(event.key === 'ArrowUp' && this.orientation === 'vertical')
|
||||
) {
|
||||
newPosition -= incr;
|
||||
}
|
||||
|
||||
if ((event.key === 'ArrowRight' && !this.vertical) || (event.key === 'ArrowDown' && this.vertical)) {
|
||||
if (
|
||||
(event.key === 'ArrowRight' && this.orientation !== 'vertical') ||
|
||||
(event.key === 'ArrowDown' && this.orientation === 'vertical')
|
||||
) {
|
||||
newPosition += incr;
|
||||
}
|
||||
|
||||
@@ -210,7 +236,7 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
|
||||
private handleResize(entries: ResizeObserverEntry[]) {
|
||||
const { width, height } = entries[0].contentRect;
|
||||
this.size = this.vertical ? height : width;
|
||||
this.size = this.orientation === 'vertical' ? height : width;
|
||||
|
||||
// There's some weird logic that gets `this.cachedPositionInPixels = NaN` or `this.position === Infinity` when
|
||||
// a split-panel goes from `display: none;` to showing.
|
||||
@@ -226,28 +252,9 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('position')
|
||||
handlePositionChange() {
|
||||
this.cachedPositionInPixels = this.percentageToPixels(this.position);
|
||||
this.positionInPixels = this.percentageToPixels(this.position);
|
||||
this.isCollapsed = false;
|
||||
this.positionBeforeCollapsing = 0;
|
||||
this.dispatchEvent(new WaRepositionEvent());
|
||||
}
|
||||
|
||||
@watch('positionInPixels')
|
||||
handlePositionInPixelsChange() {
|
||||
this.position = this.pixelsToPercentage(this.positionInPixels);
|
||||
}
|
||||
|
||||
@watch('vertical')
|
||||
handleVerticalChange() {
|
||||
this.detectSize();
|
||||
}
|
||||
|
||||
render() {
|
||||
const gridTemplate = this.vertical ? 'gridTemplateRows' : 'gridTemplateColumns';
|
||||
const gridTemplateAlt = this.vertical ? 'gridTemplateColumns' : 'gridTemplateRows';
|
||||
const gridTemplate = this.orientation === 'vertical' ? 'gridTemplateRows' : 'gridTemplateColumns';
|
||||
const gridTemplateAlt = this.orientation === 'vertical' ? 'gridTemplateColumns' : 'gridTemplateRows';
|
||||
const isRtl = this.hasUpdated ? this.matches(':dir(rtl)') : this.dir === 'rtl';
|
||||
const primary = `
|
||||
clamp(
|
||||
@@ -269,13 +276,13 @@ export default class WaSplitPanel extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
if (this.primary === 'end') {
|
||||
if (isRtl && !this.vertical) {
|
||||
if (isRtl && this.orientation !== 'vertical') {
|
||||
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||||
} else {
|
||||
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||||
}
|
||||
} else {
|
||||
if (isRtl && !this.vertical) {
|
||||
if (isRtl && this.orientation !== 'vertical') {
|
||||
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||||
} else {
|
||||
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||||
|
||||
@@ -9,7 +9,6 @@ import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
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';
|
||||
@@ -63,7 +62,7 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('input[type="checkbox"]') input: HTMLInputElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
/** The name of the switch, submitted as a name/value pair with form data. */
|
||||
@@ -129,6 +128,13 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
|
||||
this.handleValueOrCheckedChange();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('disabled') && this.hasUpdated) {
|
||||
// Disabled form controls are always valid
|
||||
this.updateValidity();
|
||||
}
|
||||
}
|
||||
|
||||
private handleBlur() {
|
||||
this.hasFocus = false;
|
||||
this.dispatchEvent(new WaBlurEvent());
|
||||
@@ -192,12 +198,6 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('disabled', { waitUntilFirstUpdate: true })
|
||||
handleDisabledChange() {
|
||||
// Disabled form controls are always valid
|
||||
this.updateValidity();
|
||||
}
|
||||
|
||||
/** Simulates a click on the switch. */
|
||||
click() {
|
||||
this.input.click();
|
||||
|
||||
@@ -8,11 +8,10 @@ import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { scrollIntoView } from '../../internal/scroll.js';
|
||||
import { WaTabHideEvent } from '../../events/tab-hide.js';
|
||||
import { WaTabShowEvent } from '../../events/tab-show.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tab-group.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
import type WaTab from '../tab/tab.js';
|
||||
import type WaTabPanel from '../tab-panel/tab-panel.js';
|
||||
|
||||
@@ -63,7 +62,7 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
@query('.tab-group__body') body: HTMLSlotElement;
|
||||
@query('.tab-group__nav') nav: HTMLElement;
|
||||
|
||||
@state() private hasScrollControls = false;
|
||||
@state() hasScrollControls = false;
|
||||
|
||||
/** Sets the active tab. */
|
||||
@property({ reflect: true }) active = '';
|
||||
@@ -127,6 +126,19 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
});
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('active')) {
|
||||
const tab = this.tabs.find(el => el.panel === this.active);
|
||||
if (tab) {
|
||||
this.setActiveTab(tab, { scrollBehavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
|
||||
if (changedProperties.has('noScrollControls') && this.hasUpdated) {
|
||||
this.updateScrollControls();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.mutationObserver?.disconnect();
|
||||
@@ -336,17 +348,7 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
this.updateComplete.then(() => this.updateScrollControls());
|
||||
}
|
||||
|
||||
@watch('active')
|
||||
updateActiveTab() {
|
||||
const tab = this.tabs.find(el => el.panel === this.active);
|
||||
|
||||
if (tab) {
|
||||
this.setActiveTab(tab, { scrollBehavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
|
||||
@watch('noScrollControls', { waitUntilFirstUpdate: true })
|
||||
updateScrollControls() {
|
||||
private updateScrollControls() {
|
||||
if (this.noScrollControls) {
|
||||
this.hasScrollControls = false;
|
||||
} else {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tab-panel.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
let id = 0;
|
||||
|
||||
@@ -40,9 +39,10 @@ export default class WaTabPanel extends WebAwesomeElement {
|
||||
this.setAttribute('role', 'tabpanel');
|
||||
}
|
||||
|
||||
@watch('active')
|
||||
handleActiveChange() {
|
||||
this.setAttribute('aria-hidden', this.active ? 'false' : 'true');
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('active')) {
|
||||
this.setAttribute('aria-hidden', this.active ? 'false' : 'true');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tab.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
let id = 0;
|
||||
|
||||
@@ -53,19 +52,21 @@ export default class WaTab extends WebAwesomeElement {
|
||||
this.setAttribute('role', 'tab');
|
||||
}
|
||||
|
||||
@watch('active')
|
||||
handleActiveChange() {
|
||||
this.setAttribute('aria-selected', this.active ? 'true' : 'false');
|
||||
}
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle active changes
|
||||
if (changedProperties.has('active')) {
|
||||
this.setAttribute('aria-selected', this.active ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled')) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
|
||||
if (this.disabled && !this.active) {
|
||||
this.tabIndex = -1;
|
||||
} else {
|
||||
this.tabIndex = 0;
|
||||
if (this.disabled && !this.active) {
|
||||
this.tabIndex = -1;
|
||||
} else {
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,11 @@ import { WaBlurEvent } from '../../events/blur.js';
|
||||
import { WaChangeEvent } from '../../events/change.js';
|
||||
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 './textarea.styles.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Textareas collect data from the user and allow multiple lines of text.
|
||||
@@ -58,7 +57,7 @@ export default class WaTextarea extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
@query('.textarea__control') input: HTMLTextAreaElement;
|
||||
|
||||
@state() private hasFocus = false;
|
||||
@state() hasFocus = false;
|
||||
@property() title = ''; // make reactive to pass through
|
||||
|
||||
/** The name of the textarea, submitted as a name/value pair with form data. */
|
||||
@@ -193,6 +192,18 @@ export default class WaTextarea extends WebAwesomeFormAssociatedElement {
|
||||
});
|
||||
}
|
||||
|
||||
async updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('rows') && this.hasUpdated) {
|
||||
this.setTextareaHeight();
|
||||
}
|
||||
|
||||
if (changedProperties.has('value') && this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
this.checkValidity();
|
||||
this.setTextareaHeight();
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (this.input) {
|
||||
@@ -232,18 +243,6 @@ export default class WaTextarea extends WebAwesomeFormAssociatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('rows', { waitUntilFirstUpdate: true })
|
||||
handleRowsChange() {
|
||||
this.setTextareaHeight();
|
||||
}
|
||||
|
||||
@watch('value', { waitUntilFirstUpdate: true })
|
||||
async handleValueChange() {
|
||||
await this.updateComplete;
|
||||
this.checkValidity();
|
||||
this.setTextareaHeight();
|
||||
}
|
||||
|
||||
/** Sets focus on the textarea. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.input.focus(options);
|
||||
|
||||
@@ -8,12 +8,11 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
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 componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tooltip.styles.js';
|
||||
import WaPopup from '../popup/popup.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary Tooltips display additional information based on a specific action.
|
||||
@@ -142,13 +141,57 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
firstUpdated (changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties)
|
||||
this.body.hidden = !this.open;
|
||||
|
||||
// With SSR timings, sometimes the popup animations never get a chance to end / cancel.
|
||||
// This is a hacky workaround to "fix" those animation issues.
|
||||
setTimeout(() => {
|
||||
this.popup.popup.dispatchEvent(new Event("animationend"))
|
||||
|
||||
if (this.open) {
|
||||
// This makes sure the "animationend" event has finished then it will show the tooltip in the "open" state.
|
||||
setTimeout(() => {
|
||||
this.body.hidden = false
|
||||
this.popup.active = true;
|
||||
this.popup.reposition();
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// If the tooltip is visible on init, update its position
|
||||
if (this.open) {
|
||||
this.popup.active = true;
|
||||
this.popup.reposition();
|
||||
}
|
||||
|
||||
async updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle open changes
|
||||
if (changedProperties.has('open')) {
|
||||
this.handleOpenChange();
|
||||
}
|
||||
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled')) {
|
||||
if (this.disabled && this.open) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle for changes
|
||||
if (changedProperties.has('for')) {
|
||||
this.handleForChange();
|
||||
}
|
||||
|
||||
// Handle other changes
|
||||
if (
|
||||
changedProperties.has('distance') ||
|
||||
changedProperties.has('hoist') ||
|
||||
changedProperties.has('placement') ||
|
||||
changedProperties.has('hoist')
|
||||
) {
|
||||
if (this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
this.popup.reposition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,8 +245,7 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
return triggers.includes(triggerType);
|
||||
}
|
||||
|
||||
@watch('open', { waitUntilFirstUpdate: true })
|
||||
async handleOpenChange() {
|
||||
private async handleOpenChange() {
|
||||
if (this.open) {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
@@ -231,7 +273,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.popup.active = true;
|
||||
await animateWithClass(this.popup.popup, 'show-with-scale');
|
||||
this.popup.reposition();
|
||||
|
||||
this.dispatchEvent(new WaAfterShowEvent());
|
||||
} else {
|
||||
// Hide
|
||||
@@ -245,16 +286,17 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.closeWatcher?.destroy();
|
||||
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
||||
|
||||
await animateWithClass(this.popup.popup, 'hide-with-scale');
|
||||
if (this.hasUpdated) {
|
||||
await animateWithClass(this.popup.popup, 'hide-with-scale');
|
||||
}
|
||||
|
||||
this.popup.active = false;
|
||||
this.body.hidden = true;
|
||||
|
||||
this.dispatchEvent(new WaAfterHideEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@watch('for')
|
||||
handleForChange() {
|
||||
private handleForChange() {
|
||||
const rootNode = this.getRootNode() as Document | ShadowRoot | null;
|
||||
|
||||
if (!rootNode) {
|
||||
@@ -270,16 +312,16 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
|
||||
const { signal } = this.eventController;
|
||||
|
||||
// "\\b" is a space boundary, used for making sure we dont add the tooltip to aria-labelledby twice.
|
||||
// "\\b" is a space boundary, used for making sure we don't add the tooltip to aria-labelledby twice.
|
||||
const labelRegex = new RegExp(`\\b${this.id}\\b`);
|
||||
|
||||
if (newAnchor) {
|
||||
/**
|
||||
* We use `aria-labelledby` because it seems to have the most consistent screenreader experience.
|
||||
* We use `aria-labelledby` because it seems to have the most consistent screen reader experience.
|
||||
* Particularly for our "special" focusable elements like `<wa-button>`, `<wa-input>` etc.
|
||||
* aria-describedby usually in some screenreaders is required to be on the actually focusable element,
|
||||
* whereas with `aria-labelledby` it'll still read on first focus. The APG does and WAI-ARIA does recommend aria-describedby
|
||||
* so perhaps once we have cross-root aria, we can revisit this decision.
|
||||
* aria-describedby usually in some screen readers is required to be on the actually focusable element,
|
||||
* whereas with `aria-labelledby` it'll still read on first focus. The APG does and WAI-ARIA does recommend
|
||||
* aria-describedby so perhaps once we have cross-root aria, we can revisit this decision.
|
||||
*/
|
||||
const currentLabel = newAnchor.getAttribute('aria-labelledby') || '';
|
||||
if (!currentLabel.match(labelRegex)) {
|
||||
@@ -306,21 +348,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.anchor = newAnchor;
|
||||
}
|
||||
|
||||
@watch(['distance', 'hoist', 'placement', 'skidding'])
|
||||
async handleOptionsChange() {
|
||||
if (this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
this.popup.reposition();
|
||||
}
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
if (this.disabled && this.open) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
|
||||
/** Shows the tooltip. */
|
||||
async show() {
|
||||
if (this.open) {
|
||||
|
||||
@@ -13,12 +13,11 @@ import { WaCollapseEvent } from '../../events/collapse.js';
|
||||
import { WaExpandEvent } from '../../events/expand.js';
|
||||
import { WaLazyChangeEvent } from '../../events/lazy-change.js';
|
||||
import { WaLazyLoadEvent } from '../../events/lazy-load.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { when } from 'lit/directives/when.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tree-item.styles.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup, PropertyValueMap } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
/**
|
||||
* @summary A tree item serves as a hierarchical node that lives inside a [tree](/docs/components/tree).
|
||||
@@ -122,6 +121,55 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
this.handleExpandedChange();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
// Handle loading changes
|
||||
if (changedProperties.has('loading') && this.hasUpdated) {
|
||||
this.setAttribute('aria-busy', this.loading ? 'true' : 'false');
|
||||
|
||||
if (!this.loading) {
|
||||
this.animateExpand();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle disabled changes
|
||||
if (changedProperties.has('disabled')) {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
// Handle selected changes
|
||||
if (changedProperties.has('selected')) {
|
||||
this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
|
||||
}
|
||||
|
||||
// Handle expanded changes
|
||||
if (changedProperties.has('expanded') && this.hasUpdated) {
|
||||
if (!this.isLeaf) {
|
||||
this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');
|
||||
} else {
|
||||
this.removeAttribute('aria-expanded');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle expanded changes
|
||||
if (changedProperties.has('expanded') && this.hasUpdated) {
|
||||
if (this.expanded) {
|
||||
if (this.lazy) {
|
||||
this.loading = true;
|
||||
this.dispatchEvent(new WaLazyLoadEvent());
|
||||
} else {
|
||||
this.animateExpand();
|
||||
}
|
||||
} else {
|
||||
this.animateCollapse();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle lazy changes
|
||||
if (changedProperties.has('lazy') && this.hasUpdated) {
|
||||
this.dispatchEvent(new WaLazyChangeEvent());
|
||||
}
|
||||
}
|
||||
|
||||
private async animateCollapse() {
|
||||
this.dispatchEvent(new WaCollapseEvent());
|
||||
|
||||
@@ -151,7 +199,7 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
this.isLeaf = !this.lazy && this.getChildrenItems().length === 0;
|
||||
}
|
||||
|
||||
protected willUpdate(changedProperties: PropertyValueMap<WaTreeItem> | Map<PropertyKey, unknown>) {
|
||||
protected willUpdate(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('selected') && !changedProperties.has('indeterminate')) {
|
||||
this.indeterminate = false;
|
||||
}
|
||||
@@ -179,7 +227,6 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
this.dispatchEvent(new WaAfterExpandEvent());
|
||||
}
|
||||
|
||||
@watch('loading', { waitUntilFirstUpdate: true })
|
||||
handleLoadingChange() {
|
||||
this.setAttribute('aria-busy', this.loading ? 'true' : 'false');
|
||||
|
||||
@@ -188,17 +235,14 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('selected')
|
||||
handleSelectedChange() {
|
||||
this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('expanded', { waitUntilFirstUpdate: true })
|
||||
handleExpandedChange() {
|
||||
if (!this.isLeaf) {
|
||||
this.setAttribute('aria-expanded', this.expanded ? 'true' : 'false');
|
||||
@@ -207,7 +251,6 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('expanded', { waitUntilFirstUpdate: true })
|
||||
handleExpandAnimation() {
|
||||
if (this.expanded) {
|
||||
if (this.lazy) {
|
||||
@@ -221,7 +264,6 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch('lazy', { waitUntilFirstUpdate: true })
|
||||
handleLazyChange() {
|
||||
this.dispatchEvent(new WaLazyChangeEvent());
|
||||
}
|
||||
|
||||
@@ -2,12 +2,11 @@ import { clamp } from '../../internal/math.js';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { html, isServer } from 'lit';
|
||||
import { WaSelectionChangeEvent } from '../../events/selection-change.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
import styles from './tree.styles.js';
|
||||
import WaTreeItem from '../tree-item/tree-item.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
import type { CSSResultGroup, PropertyValues } from 'lit';
|
||||
|
||||
function syncCheckboxes(changedTreeItem: WaTreeItem, initialSync = false) {
|
||||
function syncParentItem(treeItem: WaTreeItem) {
|
||||
@@ -121,6 +120,12 @@ export default class WaTree extends WebAwesomeElement {
|
||||
this.mutationObserver?.disconnect();
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has('selection')) {
|
||||
this.handleSelectionChange();
|
||||
}
|
||||
}
|
||||
|
||||
// Generates a clone of the expand icon element to use for each tree item
|
||||
private getExpandButtonIcon(status: 'expand' | 'collapse') {
|
||||
const slot = status === 'expand' ? this.expandedIconSlot : this.collapsedIconSlot;
|
||||
@@ -353,7 +358,6 @@ export default class WaTree extends WebAwesomeElement {
|
||||
items.forEach(this.initTreeItem);
|
||||
}
|
||||
|
||||
@watch('selection')
|
||||
async handleSelectionChange() {
|
||||
const isSelectionMultiple = this.selection === 'multiple';
|
||||
const items = this.getAllTreeItems();
|
||||
|
||||
@@ -11,7 +11,13 @@ export async function animate(el: Element, keyframes: Keyframe[], options?: Keyf
|
||||
*/
|
||||
export function animateWithClass(el: Element, className: string) {
|
||||
return new Promise<void>(resolve => {
|
||||
if (!el) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
el.classList.remove(className);
|
||||
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import type { LitElement } from 'lit';
|
||||
|
||||
type UpdateHandler = (prev?: unknown, next?: unknown) => void;
|
||||
|
||||
type NonUndefined<A> = A extends undefined ? never : A;
|
||||
|
||||
type UpdateHandlerFunctionKeys<T extends object> = {
|
||||
[K in keyof T]-?: NonUndefined<T[K]> extends UpdateHandler ? K : never;
|
||||
}[keyof T];
|
||||
|
||||
interface WatchOptions {
|
||||
/**
|
||||
* If true, will only start watching after the initial update/render
|
||||
*/
|
||||
waitUntilFirstUpdate?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs when observed properties change, e.g. @property or @state, but before the component updates. To wait for an
|
||||
* update to complete after a change occurs, use `await this.updateComplete` in the handler. To start watching after the
|
||||
* initial update/render, use `{ waitUntilFirstUpdate: true }` or `this.hasUpdated` in the handler.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* @watch('propName')
|
||||
* handlePropChange(oldValue, newValue) {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
export function watch(propertyName: string | string[], options?: WatchOptions) {
|
||||
const resolvedOptions: Required<WatchOptions> = {
|
||||
waitUntilFirstUpdate: false,
|
||||
...options
|
||||
};
|
||||
return <ElemClass extends LitElement>(proto: ElemClass, decoratedFnName: UpdateHandlerFunctionKeys<ElemClass>) => {
|
||||
// @ts-expect-error - update is a protected property
|
||||
const { update } = proto;
|
||||
const watchedProperties = Array.isArray(propertyName) ? propertyName : [propertyName];
|
||||
|
||||
// @ts-expect-error - update is a protected property
|
||||
proto.update = function (this: ElemClass, changedProps: Map<keyof ElemClass, ElemClass[keyof ElemClass]>) {
|
||||
watchedProperties.forEach(property => {
|
||||
const key = property as keyof ElemClass;
|
||||
if (changedProps.has(key)) {
|
||||
const oldValue = changedProps.get(key);
|
||||
const newValue = this[key];
|
||||
|
||||
if (oldValue !== newValue) {
|
||||
if (!resolvedOptions.waitUntilFirstUpdate || this.hasUpdated) {
|
||||
(this[decoratedFnName] as unknown as UpdateHandler)(oldValue, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
update.call(this, changedProps);
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -201,6 +201,7 @@ export class WebAwesomeFormAssociatedElement
|
||||
this.addEventListener('invalid', this.emitInvalid);
|
||||
}
|
||||
}
|
||||
states: CustomStateSet;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
@@ -468,7 +469,6 @@ export class WebAwesomeFormAssociatedElement
|
||||
// Custom states
|
||||
addCustomState(state: string) {
|
||||
try {
|
||||
// @ts-expect-error CustomStateSet doesn't exist in TS yet.
|
||||
(this.internals.states as Set<string>).add(state);
|
||||
} catch (_) {
|
||||
// Without this, test suite errors.
|
||||
@@ -479,7 +479,6 @@ export class WebAwesomeFormAssociatedElement
|
||||
|
||||
deleteCustomState(state: string) {
|
||||
try {
|
||||
// @ts-expect-error CustomStateSet doesn't exist in TS yet.
|
||||
(this.internals.states as Set<string>).delete(state);
|
||||
} catch (_) {
|
||||
// Without this, test suite errors.
|
||||
@@ -506,7 +505,6 @@ export class WebAwesomeFormAssociatedElement
|
||||
let bool = false;
|
||||
|
||||
try {
|
||||
// @ts-expect-error CustomStateSet doesn't exist in TS yet.
|
||||
bool = (this.internals.states as Set<string>).has(state);
|
||||
} catch (_) {
|
||||
// Without this, test suite errors.
|
||||
|
||||
Reference in New Issue
Block a user