mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-19 15:34:15 +00:00
Compare commits
50 Commits
dropdown-i
...
llms-txt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfa07b7d01 | ||
|
|
6a03c17b34 | ||
|
|
71fce016cf | ||
|
|
c8ddc2c1c0 | ||
|
|
64a9374aa9 | ||
|
|
67785f64cb | ||
|
|
39ab883802 | ||
|
|
08ef969db3 | ||
|
|
72c4fb7af7 | ||
|
|
827d70b2f5 | ||
|
|
0cfd4711f0 | ||
|
|
46aa1429a7 | ||
|
|
4b68a741bd | ||
|
|
bd58f7f0a1 | ||
|
|
e8f366835c | ||
|
|
70df6fea1f | ||
|
|
b98238f8c3 | ||
|
|
c67bc302ea | ||
|
|
d76bef5dbb | ||
|
|
f8f54d543a | ||
|
|
5b0e3ed1e8 | ||
|
|
09ace44c17 | ||
|
|
f3de45803f | ||
|
|
ede1f0725d | ||
|
|
50472f6461 | ||
|
|
56b1196265 | ||
|
|
7e5f18ea97 | ||
|
|
c748721f12 | ||
|
|
6e5a720f51 | ||
|
|
f739121aaf | ||
|
|
5fb3625ee5 | ||
|
|
da206a8787 | ||
|
|
2b69fa74a5 | ||
|
|
d1b6628d59 | ||
|
|
4dca4185e7 | ||
|
|
1e6d468959 | ||
|
|
00b8150f3e | ||
|
|
3d395653fc | ||
|
|
b3844ef77f | ||
|
|
a50648c6e8 | ||
|
|
b6b82fb0ac | ||
|
|
fa073e8d21 | ||
|
|
e0f6ff11ec | ||
|
|
895fb304e0 | ||
|
|
079c09b9a3 | ||
|
|
fa6ccc1ee2 | ||
|
|
579e86fc49 | ||
|
|
2baebca230 | ||
|
|
c0ced13f06 | ||
|
|
8ae90ef2b2 |
@@ -20,4 +20,5 @@ packages/**/*/src/react/index.ts
|
||||
node_modules
|
||||
|
||||
packages/**/*/_site
|
||||
packages/**/*/_bundle_
|
||||
packages/webawesome/docs/assets/scripts/prism-downloaded.js
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
3.0.0
|
||||
3.1.0
|
||||
|
||||
15
cspell.json
15
cspell.json
@@ -70,6 +70,7 @@
|
||||
"exportparts",
|
||||
"fetchpriority",
|
||||
"fieldsets",
|
||||
"flexbox",
|
||||
"focusin",
|
||||
"focusout",
|
||||
"fontawesome",
|
||||
@@ -105,6 +106,7 @@
|
||||
"keydown",
|
||||
"keyframes",
|
||||
"keymaker",
|
||||
"Kickstarter",
|
||||
"Konnor",
|
||||
"Kool",
|
||||
"labelledby",
|
||||
@@ -113,10 +115,14 @@
|
||||
"listbox",
|
||||
"listitem",
|
||||
"litelement",
|
||||
"llm",
|
||||
"llms",
|
||||
"llmstxt",
|
||||
"longform",
|
||||
"lowercasing",
|
||||
"Lucide",
|
||||
"maxlength",
|
||||
"mdash",
|
||||
"Menlo",
|
||||
"menuitemcheckbox",
|
||||
"menuitemradio",
|
||||
@@ -130,6 +136,7 @@
|
||||
"mouseout",
|
||||
"mouseup",
|
||||
"multiselectable",
|
||||
"nbsp",
|
||||
"nextjs",
|
||||
"nocheck",
|
||||
"noindex",
|
||||
@@ -148,6 +155,7 @@
|
||||
"ParamagicDev",
|
||||
"peta",
|
||||
"petabit",
|
||||
"pointercancel",
|
||||
"Preact",
|
||||
"preconnect",
|
||||
"prerendered",
|
||||
@@ -179,6 +187,7 @@
|
||||
"shadowrootmode",
|
||||
"Shortcode",
|
||||
"Shortcodes",
|
||||
"signup",
|
||||
"sitedir",
|
||||
"slotchange",
|
||||
"smartquotes",
|
||||
@@ -200,6 +209,8 @@
|
||||
"thead",
|
||||
"Themer",
|
||||
"tinycolor",
|
||||
"touchcancel",
|
||||
"touchend",
|
||||
"transitionend",
|
||||
"treeitem",
|
||||
"treeshaking",
|
||||
@@ -233,8 +244,6 @@
|
||||
"src/translations/!(en).ts",
|
||||
"**/*.min.js"
|
||||
],
|
||||
"ignoreRegExpList": [
|
||||
"(^|[^a-z])sl[a-z]*(^|[^a-z])"
|
||||
],
|
||||
"ignoreRegExpList": ["(^|[^a-z])sl[a-z]*(^|[^a-z])"],
|
||||
"useGitignore": true
|
||||
}
|
||||
|
||||
200
package-lock.json
generated
200
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@webawesome/monorepo",
|
||||
"version": "3.0.0-alpha.13",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@webawesome/monorepo",
|
||||
"version": "3.0.0-alpha.13",
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@@ -593,6 +593,10 @@
|
||||
"resolved": "packages/webawesome",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@awesome.me/webawesome-pro": {
|
||||
"resolved": "packages/webawesome-pro",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.23.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
|
||||
@@ -2519,10 +2523,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.2.1.tgz",
|
||||
"integrity": "sha512-r4C9C/5kSfMBIr0D9imvpRdCNXtUNgyYThc4YlS6K5Hchv1UyxNQ9mxwj+BTRH2i1Neits260sR3OjKMnplsFA=="
|
||||
},
|
||||
"node_modules/@shoelace-style/webawesome-pro": {
|
||||
"resolved": "packages/webawesome-pro",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
|
||||
@@ -12139,6 +12139,16 @@
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-typescript-paths": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-typescript-paths/-/rollup-plugin-typescript-paths-1.5.0.tgz",
|
||||
"integrity": "sha512-zly2aiGNjYJNq5YUi6eyGrQnCYUQ8b5czOtHZIGriwG9U3Ba2F9hlSklafXCdsNulK/IlNmE0Kzj0h+fVV32pA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"typescript": ">=3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/run-async": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
|
||||
@@ -14013,7 +14023,7 @@
|
||||
},
|
||||
"packages/webawesome": {
|
||||
"name": "@awesome.me/webawesome",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "4.1.0",
|
||||
@@ -14030,6 +14040,7 @@
|
||||
"@wc-toolkit/jsx-types": "^1.3.0",
|
||||
"eleventy-plugin-git-commit-date": "^0.1.3",
|
||||
"esbuild": "^0.25.11",
|
||||
"gray-matter": "^4.0.3",
|
||||
"npm-check-updates": "^19.1.2"
|
||||
},
|
||||
"engines": {
|
||||
@@ -14037,8 +14048,8 @@
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro": {
|
||||
"name": "@shoelace-style/webawesome-pro",
|
||||
"version": "3.0.0",
|
||||
"name": "@awesome.me/webawesome-pro",
|
||||
"version": "3.1.0",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "4.1.0",
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
@@ -14052,8 +14063,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wc-toolkit/jsx-types": "^1.3.0",
|
||||
"@web/dev-server-rollup": "^0.6.4",
|
||||
"eleventy-plugin-git-commit-date": "^0.1.3",
|
||||
"esbuild": "^0.25.11"
|
||||
"esbuild": "^0.25.11",
|
||||
"npm-check-updates": "^19.1.2",
|
||||
"rollup-plugin-typescript-paths": "^1.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17.0"
|
||||
@@ -14467,6 +14481,84 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/@web/dev-server-core": {
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.7.5.tgz",
|
||||
"integrity": "sha512-Da65zsiN6iZPMRuj4Oa6YPwvsmZmo5gtPWhW2lx3GTUf5CAEapjVpZVlUXnKPL7M7zRuk72jSsIl8lo+XpTCtw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/koa": "^2.11.6",
|
||||
"@types/ws": "^7.4.0",
|
||||
"@web/parse5-utils": "^2.1.0",
|
||||
"chokidar": "^4.0.1",
|
||||
"clone": "^2.1.2",
|
||||
"es-module-lexer": "^1.0.0",
|
||||
"get-stream": "^6.0.0",
|
||||
"is-stream": "^2.0.0",
|
||||
"isbinaryfile": "^5.0.0",
|
||||
"koa": "^2.13.0",
|
||||
"koa-etag": "^4.0.0",
|
||||
"koa-send": "^5.0.1",
|
||||
"koa-static": "^5.0.0",
|
||||
"lru-cache": "^8.0.4",
|
||||
"mime-types": "^2.1.27",
|
||||
"parse5": "^6.0.1",
|
||||
"picomatch": "^2.2.2",
|
||||
"ws": "^7.5.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/@web/dev-server-rollup": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.6.4.tgz",
|
||||
"integrity": "sha512-sJZfTGCCrdku5xYnQQG51odGI092hKY9YFM0X3Z0tRY3iXKXcYRaLZrErw5KfCxr6g0JRuhe4BBhqXTA5Q2I3Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@web/dev-server-core": "^0.7.2",
|
||||
"nanocolors": "^0.2.1",
|
||||
"parse5": "^6.0.1",
|
||||
"rollup": "^4.4.0",
|
||||
"whatwg-url": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/@web/parse5-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@web/parse5-utils/-/parse5-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-GzfK5disEJ6wEjoPwx8AVNwUe9gYIiwc+x//QYxYDAFKUp4Xb1OJAGLc2l2gVrSQmtPGLKrTRcW90Hv4pEq1qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/parse5": "^6.0.1",
|
||||
"parse5": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/esbuild": {
|
||||
"version": "0.25.11",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz",
|
||||
@@ -14509,6 +14601,16 @@
|
||||
"@esbuild/win32-x64": "0.25.11"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/lru-cache": {
|
||||
"version": "8.0.5",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz",
|
||||
"integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/nanoid": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz",
|
||||
@@ -14526,6 +14628,84 @@
|
||||
"node": "^18 || >=20"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/npm-check-updates": {
|
||||
"version": "19.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-19.1.2.tgz",
|
||||
"integrity": "sha512-FNeFCVgPOj0fz89hOpGtxP2rnnRHR7hD2E8qNU8SMWfkyDZXA/xpgjsL3UMLSo3F/K13QvJDnbxPngulNDDo/g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"ncu": "build/cli.js",
|
||||
"npm-check-updates": "build/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0",
|
||||
"npm": ">=8.12.1"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/tr46": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
|
||||
"integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"punycode": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/whatwg-url": {
|
||||
"version": "14.2.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
|
||||
"integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "^5.1.0",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"packages/webawesome-pro/node_modules/ws": {
|
||||
"version": "7.5.10",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
|
||||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages/webawesome/node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@webawesome/monorepo",
|
||||
"private": true,
|
||||
"description": "A forward-thinking library of web components.",
|
||||
"version": "3.0.0-alpha.13",
|
||||
"version": "3.1.0",
|
||||
"homepage": "https://webawesome.com/",
|
||||
"author": "Web Awesome",
|
||||
"license": "MIT",
|
||||
@@ -85,4 +85,4 @@
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import fs from 'fs';
|
||||
import * as path from 'node:path';
|
||||
import { pascalCase } from 'pascal-case';
|
||||
import * as url from 'url';
|
||||
import { llmsTxtPlugin } from './scripts/llms.js';
|
||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
const packageData = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
|
||||
@@ -188,6 +189,13 @@ export default {
|
||||
},
|
||||
}),
|
||||
|
||||
// Generate llms.txt
|
||||
llmsTxtPlugin({
|
||||
outdir,
|
||||
docsDir: path.join(__dirname, 'docs'),
|
||||
baseUrl: 'https://webawesome.com',
|
||||
}),
|
||||
|
||||
//
|
||||
// TODO - figure out why this broke when events were updated
|
||||
//
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
<p>Celebrate our official launch with a 20% discount on a Web Awesome Pro plan…<span class="appearance-underlined variant-drawn" style="--underline-color: var(--wa-color-brand);">for life</span>! But hurry, this lifetime discount is only available for a limited time.</p>
|
||||
|
||||
<div class="wa-split">
|
||||
<wa-button type="button" appearance="plain" data-dialog="close" class="plausible-event-name=launch_dialog:close_button_click">Maybe Later</wa-button>
|
||||
<wa-button variant="neutral" appearance="accent" href="/purchase" class="brand-font plausible-event-name=launch_dialog:pro_purchase_button_click">
|
||||
<wa-button type="button" appearance="plain" data-dialog="close">Maybe Later</wa-button>
|
||||
<wa-button variant="neutral" appearance="accent" href="/purchase" class="brand-font">
|
||||
<wa-icon slot="start" variant="regular" name="rocket-launch"></wa-icon>
|
||||
Get Pro + Save 20%
|
||||
</wa-button>
|
||||
@@ -43,13 +43,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper function to safely track Plausible events
|
||||
const trackEvent = (eventName) => {
|
||||
if (typeof plausible !== 'undefined') {
|
||||
plausible(eventName);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize dialog functionality
|
||||
let initCalled = false;
|
||||
const initDialog = () => {
|
||||
@@ -59,19 +52,8 @@
|
||||
}
|
||||
initCalled = true;
|
||||
|
||||
// Track when dialog is shown
|
||||
dialog.addEventListener('wa-show', () => {
|
||||
trackEvent('launch_dialog:view');
|
||||
}, { once: true });
|
||||
|
||||
// Track when dialog is dismissed
|
||||
// Save dismissal state when dialog is hidden
|
||||
dialog.addEventListener('wa-hide', (event) => {
|
||||
// Track overlay click or Escape key dismissal
|
||||
// Button clicks are tracked via CSS classes, so we only track non-button dismissals
|
||||
if (event.detail?.source === dialog) {
|
||||
trackEvent('launch_dialog:overlay_click');
|
||||
}
|
||||
|
||||
// Save dismissal state to localStorage
|
||||
try {
|
||||
localStorage.setItem(SITE_DIALOG_DISMISSED_KEY, 'true');
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
<script type="module" src="/assets/scripts/color-scheme.js"></script>
|
||||
<script type="module" src="/assets/scripts/theme.js"></script>
|
||||
{% if hasSidebar %}<script type="module" src="/assets/scripts/sidebar.js"></script>{% endif %}
|
||||
<script defer data-domain="webawesome.com" src="https://plausible.io/js/script.js"></script>
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/assets/styles/docs.css" />
|
||||
@@ -142,6 +141,9 @@
|
||||
{% include "_dialog-wa-launch.njk" ignore missing %}
|
||||
{% endif %}
|
||||
|
||||
{#- Cookie Consent Dialog -#}
|
||||
{% include "cookie-consent.njk" ignore missing %}
|
||||
|
||||
{# Footer #}
|
||||
{% block pageFooter %}{% endblock %}
|
||||
</wa-page>
|
||||
|
||||
@@ -29,8 +29,12 @@
|
||||
<li><a href="/docs/resources/contributing">Contributing</a></li>
|
||||
<li><a href="/docs/resources/changelog">Changelog</a></li>
|
||||
<li><a href="/docs/resources/visual-tests">Visual Tests</a></li>
|
||||
|
||||
|
||||
<li>
|
||||
<a class="wa-cluster wa-gap-xs" href="/docs/resources/llms">
|
||||
LLMs
|
||||
<wa-icon name="flask" aria-hidden="true" class="icon-shrink"></wa-icon>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Components -->
|
||||
@@ -81,7 +85,15 @@
|
||||
<li><span class="is-planned wa-split">Charts <span><a href="https://github.com/shoelace-style/webawesome/issues/1073" target="_blank">{{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}</a>{{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}</span></span></li>
|
||||
<li><a href="/docs/components/checkbox/">Checkbox</a></li>
|
||||
<li><a href="/docs/components/color-picker/">Color Picker</a></li>
|
||||
<li><span class="is-planned wa-split">Combobox <span><a href="https://github.com/shoelace-style/webawesome/issues/1074" target="_blank">{{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}</a>{{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}</span></span></li>
|
||||
<li>
|
||||
<span class="wa-split">
|
||||
<span>
|
||||
<a href="/docs/components/combobox">Combobox</a>
|
||||
<wa-icon name="flask" aria-hidden="true" class="icon-shrink"></wa-icon>
|
||||
</span>
|
||||
{{ proBadge() }}
|
||||
</span>
|
||||
</li>
|
||||
<li><a href="/docs/components/comparison/">Comparison</a></li>
|
||||
<li>
|
||||
<a class="wa-cluster wa-gap-xs" href="/docs/components/copy-button/">
|
||||
@@ -90,7 +102,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li><span class="is-planned wa-split">Data Grid <span><a href="https://github.com/shoelace-style/webawesome/issues/1072" target="_blank">{{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}</a>{{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}</span></span></li>
|
||||
<li><span class="is-planned wa-split">Datepicker <span><a href="https://github.com/shoelace-style/webawesome/issues/1075" target="_blank">{{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}</a>{{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}</span></span></li>
|
||||
<li><span class="is-planned wa-split">Date Picker <span><a href="https://github.com/shoelace-style/webawesome/issues/1075" target="_blank">{{ plannedBadge("A Web Awesome Kickstarter stretch goal!") }}</a>{{ proBadge({ description: "This will require access to Web Awesome Pro" }) }}</span></span></li>
|
||||
<li><a href="/docs/components/details/">Details</a></li>
|
||||
<li><a href="/docs/components/dialog/">Dialog</a></li>
|
||||
<li><a href="/docs/components/divider/">Divider</a></li>
|
||||
@@ -188,6 +200,8 @@
|
||||
</h2>
|
||||
<ul>
|
||||
<li><a href="/docs/utilities/align-items/">Align Items</a></li>
|
||||
<!-- Pending 3.2.0 release -->
|
||||
<!-- <li><a href="/docs/utilities/justify-content/">Justify Content</a></li> -->
|
||||
<li><a href="/docs/utilities/gap/">Gap</a></li>
|
||||
<li><a href="/docs/utilities/cluster/">Cluster</a></li>
|
||||
<li><a href="/docs/utilities/flank/">Flank</a></li>
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
<wa-badge variant="neutral">Since {{ component.since }}</wa-badge>
|
||||
<wa-badge
|
||||
{% if component.status == 'stable' %}variant="brand"{% endif %}
|
||||
{% if component.status == 'experimental' %}variant="warning"{% endif %}
|
||||
{% if component.status == 'experimental' %}variant="warning" appearance="filled"{% endif %}
|
||||
>
|
||||
{{ component.status }}
|
||||
</wa-badge>
|
||||
{% if isProComponent %}
|
||||
<wa-badge class="pro">Pro</wa-badge>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="component-summary">
|
||||
{{ component.summary | inlineMarkdown | safe }}
|
||||
@@ -20,6 +23,37 @@
|
||||
|
||||
{# Component API #}
|
||||
{% block afterContent %}
|
||||
{# Importing #}
|
||||
<h2>Importing</h2>
|
||||
<p>
|
||||
Autoloading components via <a href="/docs/#using-a-project">projects</a> is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
|
||||
</p>
|
||||
|
||||
{% set componentName = component.tagName | stripPrefix %}
|
||||
{% set componentPath = ["components/", componentName, "/", componentName, ".js"] | join("") %}
|
||||
<wa-tab-group label="How would you like to import this component?">
|
||||
<wa-tab panel="cdn">CDN</wa-tab>
|
||||
<wa-tab panel="npm">npm</wa-tab>
|
||||
<wa-tab panel="react">React</wa-tab>
|
||||
<wa-tab-panel name="cdn">
|
||||
<p>
|
||||
Let your project code do the work! <a href="/signup">Sign up for free</a> to use a project with your very own CDN — it's the fastest and easiest way to use Web Awesome.
|
||||
</p>
|
||||
</wa-tab-panel>
|
||||
<wa-tab-panel name="npm">
|
||||
<p>
|
||||
To manually import this component from NPM, use the following code.
|
||||
</p>
|
||||
<pre><code class="language-js">import '@awesome.me/webawesome/dist/{{ componentPath }}';</code></pre>
|
||||
</wa-tab-panel>
|
||||
<wa-tab-panel name="react">
|
||||
<p>
|
||||
To manually import this component from React, use the following code.
|
||||
</p>
|
||||
<pre><code class="language-js">import {{ component.name }} from '@awesome.me/webawesome/dist/react/{{ componentName }}';</code></pre>
|
||||
</wa-tab-panel>
|
||||
</wa-tab-group>
|
||||
|
||||
{# Slots #}
|
||||
{% if component.slots.length %}
|
||||
<h2>Slots</h2>
|
||||
@@ -270,38 +304,6 @@
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{# Importing #}
|
||||
<h2>Importing</h2>
|
||||
<p>
|
||||
Autoloading components via <a href="/docs/#using-a-project">projects</a> is the recommended way to import components. If you prefer to do it manually, use one of the following code snippets.
|
||||
</p>
|
||||
|
||||
|
||||
{% set componentName = component.tagName | stripPrefix %}
|
||||
{% set componentPath = ["components/", componentName, "/", componentName, ".js"] | join("") %}
|
||||
<wa-tab-group label="How would you like to import this component?">
|
||||
<wa-tab panel="cdn">CDN</wa-tab>
|
||||
<wa-tab panel="npm">npm</wa-tab>
|
||||
<wa-tab panel="react">React</wa-tab>
|
||||
<wa-tab-panel name="cdn">
|
||||
<p>
|
||||
Let your project code do the work! <a href="/signup">Sign up for free</a> to use a project with your very own CDN — it's the fastest and easiest way to use Web Awesome.
|
||||
</p>
|
||||
</wa-tab-panel>
|
||||
<wa-tab-panel name="npm">
|
||||
<p>
|
||||
To manually import this component from NPM, use the following code.
|
||||
</p>
|
||||
<pre><code class="language-js">import '@awesome.me/webawesome/dist/{{ componentPath }}';</code></pre>
|
||||
</wa-tab-panel>
|
||||
<wa-tab-panel name="react">
|
||||
<p>
|
||||
To manually import this component from React, use the following code.
|
||||
</p>
|
||||
<pre><code class="language-js">import {{ component.name }} from '@awesome.me/webawesome/dist/react/{{ componentName }}';</code></pre>
|
||||
</wa-tab-panel>
|
||||
</wa-tab-group>
|
||||
|
||||
<wa-divider></wa-divider>
|
||||
|
||||
<div class="component-help">
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
// Search data
|
||||
const version = document.documentElement.getAttribute('data-version') || '';
|
||||
const res = await Promise.all([import('https://cdn.jsdelivr.net/npm/lunr/+esm'), fetch(`/search.json?v=${version}`)]);
|
||||
const res = await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/lunr/+esm'),
|
||||
fetch(`/search.json?v=${version}`),
|
||||
import('/assets/scripts/track.js').catch(() => null),
|
||||
]);
|
||||
const lunr = res[0].default;
|
||||
const searchData = await res[1].json();
|
||||
const searchIndex = lunr.Index.load(searchData.searchIndex);
|
||||
const map = searchData.map;
|
||||
const searchDebounce = 200;
|
||||
const queryTrackDelay = 1000;
|
||||
let searchTimeout;
|
||||
let queryTrackTimeout;
|
||||
let lastTrackedQuery = '';
|
||||
let resultSelected = false;
|
||||
|
||||
// Optional event tracking - works standalone if track.js isn't available
|
||||
const trackModule = res[2];
|
||||
const trackEvent = trackModule?.trackEvent || window.trackEvent || (() => {});
|
||||
|
||||
// We're using Turbo, so references to these elements aren't guaranteed to remain intact
|
||||
function getElements() {
|
||||
@@ -17,6 +29,24 @@ function getElements() {
|
||||
};
|
||||
}
|
||||
|
||||
function trackQuerySubmit(query, resultSelectedValue) {
|
||||
if (!query || query.length === 0) return;
|
||||
|
||||
const { results } = getElements();
|
||||
if (!results) return;
|
||||
|
||||
const matches = results.querySelectorAll('li').length;
|
||||
const truncatedQuery = query.length > 500 ? query.substring(0, 500) : query;
|
||||
|
||||
trackEvent('navigation:search_query_submit', {
|
||||
query: truncatedQuery,
|
||||
query_length: query.length,
|
||||
result_count: matches,
|
||||
has_results: matches > 0,
|
||||
result_selected: resultSelectedValue,
|
||||
});
|
||||
}
|
||||
|
||||
// Show the search dialog when slash (or CMD+K) is pressed and focus is not inside a form element
|
||||
document.addEventListener('keydown', event => {
|
||||
if (
|
||||
@@ -42,40 +72,98 @@ document.addEventListener('click', event => {
|
||||
|
||||
function show() {
|
||||
const { dialog, input, results } = getElements();
|
||||
if (!dialog || !input || !results) return;
|
||||
|
||||
const wasAlreadyOpen = dialog.open;
|
||||
|
||||
// Remove existing listeners before adding to prevent duplicates
|
||||
input.removeEventListener('input', handleInput);
|
||||
results.removeEventListener('click', handleSelection);
|
||||
dialog.removeEventListener('keydown', handleKeyDown);
|
||||
dialog.removeEventListener('wa-hide', handleClose);
|
||||
resultSelected = false;
|
||||
lastTrackedQuery = '';
|
||||
input.addEventListener('input', handleInput);
|
||||
results.addEventListener('click', handleSelection);
|
||||
dialog.addEventListener('keydown', handleKeyDown);
|
||||
dialog.addEventListener('wa-hide', handleClose);
|
||||
dialog.open = true;
|
||||
if (!wasAlreadyOpen) {
|
||||
trackEvent('navigation:search_dialog_open');
|
||||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
function cleanup() {
|
||||
const { dialog, input, results } = getElements();
|
||||
|
||||
if (!dialog || !input || !results) return;
|
||||
clearTimeout(searchTimeout);
|
||||
clearTimeout(queryTrackTimeout);
|
||||
input.removeEventListener('input', handleInput);
|
||||
results.removeEventListener('click', handleSelection);
|
||||
dialog.removeEventListener('keydown', handleKeyDown);
|
||||
dialog.removeEventListener('wa-hide', handleClose);
|
||||
dialog.open = false;
|
||||
|
||||
// Reset state to prevent leakage between dialog sessions
|
||||
resultSelected = false;
|
||||
lastTrackedQuery = '';
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
const { input } = getElements();
|
||||
async function handleClose() {
|
||||
const { dialog, input } = getElements();
|
||||
if (!dialog || !input) return;
|
||||
clearTimeout(queryTrackTimeout);
|
||||
queryTrackTimeout = null;
|
||||
dialog.removeEventListener('wa-hide', handleClose);
|
||||
if (!resultSelected) {
|
||||
const query = input.value.trim();
|
||||
if (query.length > 0 && query !== lastTrackedQuery) {
|
||||
trackQuerySubmit(query, false);
|
||||
lastTrackedQuery = query;
|
||||
}
|
||||
}
|
||||
|
||||
input.value = '';
|
||||
updateResults();
|
||||
try {
|
||||
await updateResults();
|
||||
} catch (error) {
|
||||
// Silently handle errors - UI cleanup should continue
|
||||
}
|
||||
cleanup();
|
||||
trackEvent('navigation:search_dialog_close');
|
||||
}
|
||||
|
||||
function handleInput() {
|
||||
const { input } = getElements();
|
||||
|
||||
if (!input) return;
|
||||
clearTimeout(searchTimeout);
|
||||
searchTimeout = setTimeout(() => updateResults(input.value), searchDebounce);
|
||||
clearTimeout(queryTrackTimeout);
|
||||
|
||||
const query = input.value.trim();
|
||||
|
||||
if (query.length === 0) {
|
||||
lastTrackedQuery = '';
|
||||
}
|
||||
|
||||
searchTimeout = setTimeout(async () => {
|
||||
await updateResults(query);
|
||||
if (query.length > 0 && query !== lastTrackedQuery) {
|
||||
queryTrackTimeout = setTimeout(() => {
|
||||
const { input: currentInput, results } = getElements();
|
||||
if (!currentInput || resultSelected) return;
|
||||
|
||||
const currentQuery = currentInput.value.trim();
|
||||
if (currentQuery === query && currentQuery !== lastTrackedQuery) {
|
||||
trackQuerySubmit(currentQuery, false);
|
||||
lastTrackedQuery = currentQuery;
|
||||
}
|
||||
}, queryTrackDelay);
|
||||
}
|
||||
}, searchDebounce);
|
||||
}
|
||||
|
||||
function handleKeyDown(event) {
|
||||
const { input, results } = getElements();
|
||||
if (!input || !results) return;
|
||||
|
||||
// Handle keyboard selections
|
||||
if (['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter'].includes(event.key)) {
|
||||
@@ -104,7 +192,12 @@ function handleKeyDown(event) {
|
||||
nextEl = items[items.length - 1];
|
||||
break;
|
||||
case 'Enter':
|
||||
currentEl?.querySelector('a')?.click();
|
||||
if (currentEl) {
|
||||
const link = currentEl.querySelector('a');
|
||||
if (link) {
|
||||
selectResult(link, 'keyboard_enter');
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -121,27 +214,62 @@ function handleKeyDown(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function selectResult(link, selectionMethod) {
|
||||
const { input, results } = getElements();
|
||||
if (!input || !link) return;
|
||||
|
||||
// Clear pending query tracking timeout to prevent duplicate events
|
||||
clearTimeout(queryTrackTimeout);
|
||||
queryTrackTimeout = null;
|
||||
resultSelected = true; // Set immediately so timeout callback (if executing) sees it
|
||||
|
||||
const query = input.value.trim();
|
||||
if (!link.dataset.searchResultIndex) return;
|
||||
const resultIndex = parseInt(link.dataset.searchResultIndex, 10);
|
||||
if (isNaN(resultIndex) || resultIndex < 1) return;
|
||||
|
||||
const resultUrl = link.dataset.searchResultUrl || link.getAttribute('href');
|
||||
if (!resultUrl) return;
|
||||
lastTrackedQuery = query;
|
||||
trackQuerySubmit(query, true);
|
||||
trackEvent('navigation:search_result_click', {
|
||||
query,
|
||||
result_index: resultIndex,
|
||||
result_url: resultUrl,
|
||||
selection_method: selectionMethod,
|
||||
});
|
||||
|
||||
const { dialog } = getElements();
|
||||
if (dialog) {
|
||||
dialog.removeEventListener('wa-hide', handleClose);
|
||||
cleanup();
|
||||
trackEvent('navigation:search_dialog_close');
|
||||
dialog.open = false;
|
||||
}
|
||||
|
||||
if (window.Turbo) {
|
||||
Turbo.visit(resultUrl);
|
||||
} else {
|
||||
location.href = resultUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelection(event) {
|
||||
const link = event.target.closest('a');
|
||||
|
||||
if (link) {
|
||||
event.preventDefault();
|
||||
hide();
|
||||
|
||||
if (window.Turbo) {
|
||||
Turbo.visit(link.href);
|
||||
} else {
|
||||
location.href = link.href;
|
||||
}
|
||||
selectResult(link, 'mouse_click');
|
||||
}
|
||||
}
|
||||
|
||||
// Queries the search index and updates the results
|
||||
async function updateResults(query = '') {
|
||||
const { dialog, input, results } = getElements();
|
||||
|
||||
if (!dialog || !input || !results) return;
|
||||
try {
|
||||
const hasQuery = query.length > 0;
|
||||
const trimmedQuery = query.trim();
|
||||
const hasQuery = trimmedQuery.length > 0;
|
||||
let matches = [];
|
||||
|
||||
if (hasQuery) {
|
||||
@@ -149,13 +277,13 @@ async function updateResults(query = '') {
|
||||
const seenRefs = new Set();
|
||||
|
||||
// Start with a standard search to get the best "exact match" result
|
||||
searchIndex.search(`${query}`).forEach(match => {
|
||||
searchIndex.search(`${trimmedQuery}`).forEach(match => {
|
||||
matches.push(match);
|
||||
seenRefs.add(match.ref);
|
||||
});
|
||||
|
||||
// Add wildcard matches if not already included
|
||||
searchIndex.search(`${query}*`).forEach(match => {
|
||||
searchIndex.search(`${trimmedQuery}*`).forEach(match => {
|
||||
if (!seenRefs.has(match.ref)) {
|
||||
matches.push(match);
|
||||
seenRefs.add(match.ref);
|
||||
@@ -163,11 +291,10 @@ async function updateResults(query = '') {
|
||||
});
|
||||
|
||||
// Add fuzzy search matches last
|
||||
const fuzzyTokens = query
|
||||
const fuzzyTokens = trimmedQuery
|
||||
.split(' ')
|
||||
.map(term => `${term}~1`)
|
||||
.join(' ');
|
||||
|
||||
searchIndex.search(fuzzyTokens).forEach(match => {
|
||||
if (!seenRefs.has(match.ref)) {
|
||||
matches.push(match);
|
||||
@@ -180,12 +307,12 @@ async function updateResults(query = '') {
|
||||
|
||||
dialog.classList.toggle('has-results', hasQuery && hasResults);
|
||||
dialog.classList.toggle('no-results', hasQuery && !hasResults);
|
||||
|
||||
input.setAttribute('aria-activedescendant', '');
|
||||
results.innerHTML = '';
|
||||
|
||||
matches.forEach((match, index) => {
|
||||
const page = map[match.ref];
|
||||
if (!page || !page.url) return;
|
||||
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
const displayTitle = page.title ?? '';
|
||||
@@ -197,12 +324,10 @@ async function updateResults(query = '') {
|
||||
li.setAttribute('role', 'option');
|
||||
li.setAttribute('id', `search-result-item-${match.ref}`);
|
||||
li.setAttribute('data-selected', index === 0 ? 'true' : 'false');
|
||||
|
||||
if (page.url === '/') icon = 'home';
|
||||
if (page.url.startsWith('/docs/utilities/native')) icon = 'code';
|
||||
if (page.url.startsWith('/docs/components')) icon = 'puzzle-piece';
|
||||
if (page.url.startsWith('/docs/theme') || page.url.startsWith('/docs/restyle')) icon = 'palette';
|
||||
|
||||
a.href = page.url;
|
||||
a.innerHTML = `
|
||||
<div class="site-search-result-icon" aria-hidden="true">
|
||||
@@ -218,6 +343,9 @@ async function updateResults(query = '') {
|
||||
a.querySelector('.site-search-result-description').textContent = displayDescription;
|
||||
a.querySelector('.site-search-result-url').textContent = displayUrl;
|
||||
|
||||
// Use 1-based indexing for analytics
|
||||
a.dataset.searchResultIndex = (index + 1).toString();
|
||||
a.dataset.searchResultUrl = page.url;
|
||||
li.appendChild(a);
|
||||
results.appendChild(li);
|
||||
});
|
||||
|
||||
@@ -10,6 +10,13 @@
|
||||
:root {
|
||||
--wa-brand-orange: #f36944;
|
||||
--wa-brand-grey: #30323b;
|
||||
|
||||
/* layout-based example style aspects */
|
||||
--layout-example-border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
--layout-example-border-radius: var(--wa-border-radius-l);
|
||||
--layout-example-padding: var(--wa-space-s);
|
||||
--layout-example-element-background: var(--wa-color-indigo-60);
|
||||
--layout-example-element-border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
.wa-dark .only-light,
|
||||
|
||||
@@ -130,6 +130,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* dialogs */
|
||||
wa-dialog:has([slot='footer']) [slot='footer'] {
|
||||
border-block-start: var(--wa-border-width-s) solid var(--wa-color-surface-border);
|
||||
flex-grow: 1; /* make footer contents span entire width of dialog */
|
||||
padding-block-start: var(--wa-space-l);
|
||||
}
|
||||
|
||||
/* anchor headings */
|
||||
.anchor-heading a {
|
||||
opacity: 0;
|
||||
@@ -250,7 +257,6 @@
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* buttons with icon toggle on hover */
|
||||
wa-button .icon-hover {
|
||||
@@ -262,6 +268,13 @@
|
||||
wa-button:hover .icon-hover {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
/* buttons that are "shushed" (visually muted) by default, but have their full presentation otherwise */
|
||||
wa-button.shush {
|
||||
&:not(:hover):not(active)::part(base) {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
/* #region resets */
|
||||
|
||||
@@ -40,60 +40,6 @@ Set the `orientation` attribute to `vertical` to make a vertical button group.
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
### Theme Buttons
|
||||
|
||||
Theme buttons are supported through the button group's `variant` attribute.
|
||||
|
||||
```html {.example}
|
||||
<wa-button-group label="Alignment" variant="brand">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<wa-button-group label="Alignment" variant="success">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<wa-button-group label="Alignment">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<wa-button-group label="Alignment" variant="warning">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<wa-button-group label="Alignment" variant="danger">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
You can still use the buttons’ own `variant` attribute to override the inherited variant.
|
||||
|
||||
```html {.example}
|
||||
<wa-button-group label="Alignment" variant="brand">
|
||||
<wa-button>Left</wa-button>
|
||||
<wa-button>Center</wa-button>
|
||||
<wa-button variant="neutral">Right</wa-button>
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Pill buttons are supported through the button's `pill` attribute.
|
||||
|
||||
@@ -178,11 +178,11 @@ If you want the dialog to close when the user clicks on the overlay, add the `li
|
||||
|
||||
### Preventing the Dialog from Closing
|
||||
|
||||
By default, dialogs will close when the user clicks the close button, clicks the overlay, or presses the [[Escape]] key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
|
||||
By default, dialogs will close when the user clicks the close button or presses the [[Escape]] key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
|
||||
|
||||
To keep the dialog open in such cases, you can cancel the `wa-hide` event. When canceled, the dialog will remain open and pulse briefly to draw the user's attention to it.
|
||||
|
||||
You can use `event.detail.source` to determine which element triggered the request to close. This example prevents the dialog from closing when the overlay is clicked, but allows the close button or [[Escape]] to dismiss it.
|
||||
You can use `event.detail.source` to determine which element triggered the request to close. This example prevents the dialog from closing unless a specific button is clicked.
|
||||
|
||||
```html {.example}
|
||||
<wa-dialog label="Dialog" class="dialog-deny-close">
|
||||
|
||||
@@ -41,7 +41,7 @@ Use the `--spacing` custom property to change the amount of space between the di
|
||||
|
||||
### Orientation
|
||||
|
||||
The default orientation for dividers is `horizontal`. Set `orientation` attribute to `vertical` to draw a vertical divider. The divider will span the full height of its container.
|
||||
The default orientation for dividers is `horizontal`. Set `orientation` attribute to `vertical` to draw a vertical divider. The divider will span the full height of its [Flexbox](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/CSS_layout/Flexbox) or [CSS Grid](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/grid) container.
|
||||
|
||||
```html {.example}
|
||||
<div style="display: flex; align-items: center;">
|
||||
@@ -53,6 +53,10 @@ The default orientation for dividers is `horizontal`. Set `orientation` attribut
|
||||
</div>
|
||||
```
|
||||
|
||||
:::info
|
||||
If your container isn't Flexbox or CSS Grid, you may need to set an explicit height for the divider.
|
||||
:::
|
||||
|
||||
### Dropdown Dividers
|
||||
|
||||
Use dividers in [dropdowns](/docs/components/dropdown) to visually group dropdown items.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
title: Intersection Observer
|
||||
description: Tracks immediate child elements and fires events as they move in and out of view.
|
||||
layout: component
|
||||
category: Utilities
|
||||
---
|
||||
|
||||
This component leverages the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) to track when its direct children enter or leave a designated root element. The `wa-intersect` event fires whenever elements cross the visibility threshold.
|
||||
|
||||
@@ -285,9 +285,10 @@ Remember that custom tags are rendered in a shadow root. To style them, you can
|
||||
const name = option.querySelector('wa-icon[slot="start"]').name;
|
||||
|
||||
// You can return a string, a Lit Template, or an HTMLElement here
|
||||
// Important: include data-value so the tag can be removed properly!
|
||||
return `
|
||||
<wa-tag with-remove>
|
||||
<wa-icon name="${name}" style="padding-inline-end: .5rem;"></wa-icon>
|
||||
<wa-tag with-remove data-value="${option.value}">
|
||||
<wa-icon name="${name}"></wa-icon>
|
||||
${option.label}
|
||||
</wa-tag>
|
||||
`;
|
||||
@@ -299,6 +300,10 @@ Remember that custom tags are rendered in a shadow root. To style them, you can
|
||||
Be sure you trust the content you are outputting! Passing unsanitized user input to `getTag()` can result in XSS vulnerabilities.
|
||||
:::
|
||||
|
||||
:::info
|
||||
When using custom tags with `with-remove`, you must include the `data-value` attribute set to the option's value. This allows the select to identify which option to deselect when the tag's remove button is clicked.
|
||||
:::
|
||||
|
||||
### Lazy loading options
|
||||
|
||||
Lazy loading options works similarly to native `<select>` elements. The select component handles various scenarios intelligently:
|
||||
|
||||
@@ -13,7 +13,29 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
|
||||
|
||||
## Next
|
||||
|
||||
- Added llms.txt to assist AI agents with using Web Awesome [discuss:1100]
|
||||
- Added `justify-content` CSS utilities [pr:1930]
|
||||
- Added missing `.wa-gap-4xl` utility class [pr:1931]
|
||||
- Added `pointercancel` and `touchcancel` event handling to draggable elements to prevent drags from getting stuck
|
||||
- Added `wa-justify-content-*` utility classes [pr:1930]
|
||||
- Added missing `wa-gap-4xl` utility class [pr:1931]
|
||||
- Added `track` and `indicator` CSS parts to `<wa-progress-ring>` [pr:1863]
|
||||
- Fixed a bug in `<wa-combobox>` that prevented the listbox from opening when options were preselected [issue:1883]
|
||||
- Fixed a bug in `<wa-popup>` and `<wa-dropdown-item>` that caused an error when removing a popup while it was opening [issue:1910]
|
||||
- Fixed a bug in `<wa-popup>` and `<wa-dropdown>` that caused errors when shadow DOM queries returned null [issue:1911]
|
||||
- Fixed a bug in `<wa-combobox>` that prevented the listbox from opening when options were preselected [issue:1883]
|
||||
- Fixed a bug in draggable elements that caused a TypeError on `touchend` events when `event.touches` was empty
|
||||
- Fixed a bug in `<wa-tree-item>` that caused the cursor to show a pointer when no expand icon was present [pr:1936]
|
||||
- Fixed a bug in `<wa-tree-item>` that caused the chevron to render the wrong direction in RTL [pr:1798]
|
||||
- Modified `wa-align-items-*` utility classes to apply `display: flex` by default [pr:1943]
|
||||
|
||||
## 3.1.0
|
||||
|
||||
- Added `<wa-combobox>` as an experimental pro component [issue:1074]
|
||||
- Added version 2.0.0 of the [official Web Awesome Figma Design Kit](/docs/resources/figma)
|
||||
- Added npm support for Web Awesome Pro
|
||||
- Added `layers.css` to define cascade layer order and updated palettes, themes, native styles, and utilities to import the new rule for more fail-safe modularity [pr:1793]
|
||||
- [PRO]: Fixed a few sizing bugs in `<wa-page>` and `slot="footer"` no longer will always "overflow" the container.
|
||||
- Fixed a bug in `<wa-slider>` that caused some touch devices to end up with the incorrect value [issue:1703]
|
||||
- Fixed a bug in `<wa-card>` that prevented some slots from being detected correctly [discuss:1450]
|
||||
- Fixed a z-index bug in `<wa-scroller>` styles [issue:1724]
|
||||
@@ -21,7 +43,13 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
|
||||
- Fixed a bug in `<wa-tree-item>` that caused the spinner to not show when lazy loading [issue:1678]
|
||||
- Fixed a bug in `<wa-dropdown>` that caused the browser to hang when cancelling the `wa-hide` event [issue:1483]
|
||||
- Fixed a bug in `<wa-dropdown-item>` that prevented the icon dependency from being imported [issue:1825]
|
||||
- Fixed a bug in `<wa-select>` that prevented clicks on the tag's remove button from removing options in multiple mode
|
||||
- Fixed a bug in `<wa-select>` that caused tags to appear in alphabetical order instead of selection order when using `multiple`
|
||||
- Improved performance of `<wa-icon>` so initial rendering occurs faster, especially with multiple icons on the page [issue:1729]
|
||||
- Improved `<wa-slider>` to not throw an error when string values are passed to the `min`, `max`, and `step` properties [issue:1823]
|
||||
- Fixed a bug in Web Awesome form controls that caused `<wa-input form="foo">` to set the form property to equal `"foo"` instead of returning an `HTMLFormElement` breaking platform expectations. [pr:1815]
|
||||
- Fixed a bug in `<wa-button>` causing it to not copy over attributes for form submissions. [pr:1815]
|
||||
- Improved performance of all components by fixing how CSS is imported and reused [issue:1812]
|
||||
- Modified the default `transition` styles of `<wa-dropdown-item>` to use design tokens [pr:1693]
|
||||
|
||||
## 3.0.0
|
||||
|
||||
86
packages/webawesome/docs/docs/resources/llms.md
Normal file
86
packages/webawesome/docs/docs/resources/llms.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: LLMs
|
||||
description: Web Awesome provides an llms.txt file to help AI assistants understand and work with our components.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
The [llms.txt specification](https://llmstxt.org/) is a proposed standard for providing information to large language models (LLMs) in a format they can easily consume. It's like a robots.txt, but instead of telling search engines how to crawl your site, it helps AI assistants understand your project.
|
||||
|
||||
Web Awesome publishes an `llms.txt` file that provides AI tools with structured information about our components, including their APIs, properties, events, methods, slots, and CSS custom properties.
|
||||
|
||||
:::warning
|
||||
This feature is experimental! The llms.txt format and its contents may change as we refine the output based on feedback and evolving AI capabilities.
|
||||
:::
|
||||
|
||||
## Why Use It?
|
||||
|
||||
When working with AI coding assistants like Claude, ChatGPT, Copilot, or Cursor, you can reference the llms.txt file to give the AI context about Web Awesome components. This can lead to more accurate code suggestions and fewer hallucinations when the AI generates Web Awesome code.
|
||||
|
||||
## Accessing the File
|
||||
|
||||
The llms.txt file is available in every Web Awesome build at:
|
||||
|
||||
```
|
||||
/dist/llms.txt
|
||||
/dist-cdn/llms.txt
|
||||
```
|
||||
|
||||
You can also find it in your `node_modules` directory if you've installed Web Awesome via npm:
|
||||
|
||||
```
|
||||
node_modules/@awesome.me/webawesome/dist/llms.txt
|
||||
```
|
||||
|
||||
## How to Use It
|
||||
|
||||
How you reference the file depends on which AI tool you're using.
|
||||
|
||||
### Claude Projects
|
||||
|
||||
If you're using [Claude Projects](https://www.anthropic.com/news/projects), you can add the llms.txt URL to your project knowledge. Claude will use this context when helping you write Web Awesome code.
|
||||
|
||||
### Cursor
|
||||
|
||||
In [Cursor](https://cursor.sh/), you can add the file to your project's documentation sources via **Cursor Settings > Features > Docs**. You can also reference the file directly in chat using `@Docs` after adding it, or paste the content into the chat context.
|
||||
|
||||
### VS Code + Copilot
|
||||
|
||||
GitHub Copilot in VS Code doesn't have a built-in way to reference external documentation files, but you can:
|
||||
|
||||
1. Copy the llms.txt file into your project's root directory
|
||||
2. Open it in a VS Code tab (Copilot considers open files as context)
|
||||
3. Use `#file` in Copilot Chat to explicitly reference it (e.g., `#file:llms.txt how do I create a dialog?`)
|
||||
|
||||
### VS Code + Claude Code
|
||||
|
||||
If you're using the [Claude Code extension](https://marketplace.visualstudio.com/items?itemName=anthropics.claude-code), you can reference the file directly by path:
|
||||
|
||||
```
|
||||
@node_modules/@awesome.me/webawesome/dist/llms.txt
|
||||
```
|
||||
|
||||
Or simply ask Claude to read it — Claude Code can access files in your project directly.
|
||||
|
||||
### Other AI Tools
|
||||
|
||||
Most AI coding assistants allow you to provide context through URLs, file uploads, or direct pasting. Check your tool's documentation for the best way to include external references.
|
||||
|
||||
## What's Included
|
||||
|
||||
The llms.txt file contains:
|
||||
|
||||
- An overview of Web Awesome and its capabilities
|
||||
- Links to documentation sections
|
||||
- A complete list of all components with descriptions
|
||||
- Detailed API reference for each component including:
|
||||
- Slots
|
||||
- Properties and their types
|
||||
- Methods and their signatures
|
||||
- Events
|
||||
- CSS custom properties
|
||||
- CSS parts
|
||||
- CSS states
|
||||
|
||||
## Feedback
|
||||
|
||||
Since this is experimental, we'd love to hear how it works for you! If you find issues with the generated content or have suggestions for improvement, please [open an issue on GitHub](https://github.com/shoelace-style/webawesome/issues).
|
||||
@@ -1,35 +1,37 @@
|
||||
---
|
||||
title: Align Items
|
||||
description: Align items utilities set the gap property of flex and grid containers, like other Web Awesome layout utilities.
|
||||
description: Align items utilities align items within flex and grid containers on the cross axis.
|
||||
layout: docs
|
||||
tags: layoutUtilities
|
||||
---
|
||||
|
||||
<style>
|
||||
.preview-wrapper {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
min-block-size: 3em;
|
||||
min-inline-size: 5em;
|
||||
padding: var(--wa-space-2xs);
|
||||
}
|
||||
|
||||
.preview-block {
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: var(--wa-color-neutral-fill-loud);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
min-block-size: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
Web Awesome includes classes to set the `align-items` property of flex and grid containers. They can be used alongside other Web Awesome layout utilities, like [cluster](/docs/utilities/cluster) and [stack](/docs/utilities/stack), to align children in container on the container's cross axis.
|
||||
Web Awesome includes classes to set the `align-items` property of flex and grid containers. Use them alongside other Web Awesome layout utilities, like [cluster](/docs/utilities/cluster) and [stack](/docs/utilities/stack), to align items in a container on the container's [cross axis](#whats-the-cross-axis).
|
||||
|
||||
| Class Name | `align-items` Value | Preview |
|
||||
| ------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `wa-align-items-baseline` | `baseline` | <div class="wa-cluster wa-align-items-baseline preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-center` | `center` | <div class="wa-cluster wa-align-items-center preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-end` | `flex-end` | <div class="wa-cluster wa-align-items-end preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-start` | `flex-start` | <div class="wa-cluster wa-align-items-start preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-stretch` | `stretch` | <div class="wa-cluster wa-align-items-stretch preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| Class Name | `align-items` Value | Preview |
|
||||
| ------------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `wa-align-items-baseline` | `baseline` | <div class="wa-cluster wa-gap-2xs wa-align-items-baseline preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-center` | `center` | <div class="wa-cluster wa-gap-2xs wa-align-items-center preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-end` | `flex-end` | <div class="wa-cluster wa-gap-2xs wa-align-items-end preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-start` | `flex-start` | <div class="wa-cluster wa-gap-2xs wa-align-items-start preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-align-items-stretch` | `stretch` | <div class="wa-cluster wa-gap-2xs wa-align-items-stretch preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
|
||||
## What's a Cross Axis?
|
||||
## What's the Cross Axis?
|
||||
|
||||
The cross axis runs perpendicular to a flex container's content direction. For containers where `flex-direction` is `row` and content flows in the inline direction, the cross axis runs in the block direction. For containers where `flex-direction` is `column` and content flows in the block direction, the cross axis runs in the inline direction.
|
||||
The cross axis runs perpendicular to a container's content direction. For containers where `flex-direction` is `row` and content flows in the inline direction, the cross axis runs in the block direction. For containers where `flex-direction` is `column` and content flows in the block direction, the cross axis runs in the inline direction.
|
||||
|
||||
@@ -7,19 +7,21 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
:is(.wa-flank, .wa-grid, .wa-stack) > [class*='wa-cluster']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border-radius: var(--wa-border-radius-l);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--layout-example-border-radius);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-cluster'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ description }}
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-cluster">
|
||||
<div></div>
|
||||
|
||||
@@ -7,20 +7,20 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
:is(.wa-flank, .wa-grid, .wa-stack) > [class*='wa-flank']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border-radius: var(--wa-border-radius-l);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--layout-example-border-radius);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-flank'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
When space is limited, the items wrap.
|
||||
{{ description }} When space is limited, the items wrap.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-flank">
|
||||
|
||||
@@ -7,18 +7,20 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
[class*='wa-frame']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-frame'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ description }}
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-frame" style="max-inline-size: 20rem;">
|
||||
<div></div>
|
||||
|
||||
@@ -6,28 +6,37 @@ tags: layoutUtilities
|
||||
---
|
||||
|
||||
<style>
|
||||
.preview-wrapper {
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
min-block-size: 3em;
|
||||
min-inline-size: 5em;
|
||||
padding: var(--wa-space-2xs);
|
||||
}
|
||||
|
||||
.preview-block {
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: var(--wa-color-neutral-fill-loud);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
min-block-size: 1.5em;
|
||||
min-block-size: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
Web Awesome includes classes to set the `gap` property of flex and grid containers. They can be used alongside other Web Awesome layout utilities, like [cluster](/docs/utilities/cluster) and [stack](/docs/utilities/stack), to change the space between items.
|
||||
Or even by themselves — all gap properties also set `display: flex` with a specificity of 0 so that it can be trivially overridden.
|
||||
Web Awesome includes classes to set the `gap` property of flex and grid containers. Use them alone to create a flex container with a gap, or use them alongside other Web Awesome layout utilities, like [cluster](/docs/utilities/cluster) and [stack](/docs/utilities/stack), to change the space between items.
|
||||
|
||||
Besides `wa-gap-0`, which sets `gap` to zero, each class corresponds to one of the [`--wa-space-*`](/docs/tokens/space) tokens in your theme.
|
||||
|
||||
| Class Name | `gap` Value | Preview |
|
||||
| ------------ | ---------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `wa-gap-0` | `0` | <div class="wa-cluster wa-gap-0"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-3xs` | `--wa-space-3xs` | <div class="wa-cluster wa-gap-3xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-2xs` | `--wa-space-2xs` | <div class="wa-cluster wa-gap-2xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-xs` | `--wa-space-xs` | <div class="wa-cluster wa-gap-xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-s` | `--wa-space-s` | <div class="wa-cluster wa-gap-s"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-m` | `--wa-space-m` | <div class="wa-cluster wa-gap-m"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-l` | `--wa-space-l` | <div class="wa-cluster wa-gap-l"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-xl` | `--wa-space-xl` | <div class="wa-cluster wa-gap-xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-2xl` | `--wa-space-2xl` | <div class="wa-cluster wa-gap-2xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-3xl` | `--wa-space-3xl` | <div class="wa-cluster wa-gap-3xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-0` | `0` | <div class="preview-wrapper wa-cluster wa-gap-0"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-3xs` | `--wa-space-3xs` | <div class="preview-wrapper wa-cluster wa-gap-3xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-2xs` | `--wa-space-2xs` | <div class="preview-wrapper wa-cluster wa-gap-2xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-xs` | `--wa-space-xs` | <div class="preview-wrapper wa-cluster wa-gap-xs"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-s` | `--wa-space-s` | <div class="preview-wrapper wa-cluster wa-gap-s"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-m` | `--wa-space-m` | <div class="preview-wrapper wa-cluster wa-gap-m"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-l` | `--wa-space-l` | <div class="preview-wrapper wa-cluster wa-gap-l"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-xl` | `--wa-space-xl` | <div class="preview-wrapper wa-cluster wa-gap-xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-2xl` | `--wa-space-2xl` | <div class="preview-wrapper wa-cluster wa-gap-2xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-gap-3xl` | `--wa-space-3xl` | <div class="preview-wrapper wa-cluster wa-gap-3xl"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
<!-- Pending 3.2.0 release -->
|
||||
<!-- | `wa-gap-4xl` | `--wa-space-4xl` | <div class="preview-wrapper wa-cluster wa-gap-4xl"><div class="preview-block"></div><div class="preview-block"></div></div> | -->
|
||||
|
||||
@@ -7,19 +7,21 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
:is(.wa-flank, .wa-grid, .wa-stack) > [class*='wa-grid']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border-radius: var(--wa-border-radius-l);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--layout-example-border-radius);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-grid'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ description }}
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-grid">
|
||||
<div></div>
|
||||
|
||||
40
packages/webawesome/docs/docs/utilities/justify-content.md
Normal file
40
packages/webawesome/docs/docs/utilities/justify-content.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: Justify Content
|
||||
description: Justify content utilities determine how space is distributed between items in flex and grid containers.
|
||||
layout: docs
|
||||
tags: layoutUtilities
|
||||
unpublished: true
|
||||
unlisted: true
|
||||
---
|
||||
|
||||
<style>
|
||||
.preview-wrapper {
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
min-block-size: 3em;
|
||||
min-inline-size: 5em;
|
||||
padding: var(--wa-space-2xs);
|
||||
}
|
||||
|
||||
.preview-block {
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
min-block-size: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
Web Awesome includes classes to set the `justify-content` property of flex and grid containers. Use them alongside other Web Awesome layout utilities, like [cluster](/docs/utilities/cluster) and [stack](/docs/utilities/stack), to distribute space between items along the container's [main axis](#whats-the-main-axis).
|
||||
|
||||
| Class Name | `justify-content` Value | Preview |
|
||||
| ---------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `wa-justify-content-start` | `flex-start` | <div class="wa-cluster wa-gap-2xs wa-justify-content-start preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-justify-content-end` | `flex-end` | <div class="wa-cluster wa-gap-2xs wa-justify-content-end preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-justify-content-center` | `center` | <div class="wa-cluster wa-gap-2xs wa-justify-content-center preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-justify-content-space-around` | `space-around` | <div class="wa-cluster wa-gap-2xs wa-justify-content-space-around preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-justify-content-space-between` | `space-between` | <div class="wa-cluster wa-gap-2xs wa-justify-content-space-between preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
| `wa-justify-content-space-evenly` | `space-evenly` | <div class="wa-cluster wa-gap-2xs wa-justify-content-space-evenly preview-wrapper"><div class="preview-block"></div><div class="preview-block"></div></div> |
|
||||
|
||||
## What's the Main Axis?
|
||||
|
||||
The main axis runs parallel to a container's content direction. For grid containers and flex containers where `flex-direction` is `row`, the main axis runs in the inline direction. For containers where `flex-direction` is `column`, the main axis runs in the block direction.
|
||||
@@ -7,19 +7,21 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
:is(.wa-flank, .wa-grid, .wa-stack) > [class*='wa-split']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border-radius: var(--wa-border-radius-l);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--layout-example-border-radius);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-split'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ description }}
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-split">
|
||||
<div></div>
|
||||
|
||||
@@ -7,19 +7,21 @@ tags: layoutUtilities
|
||||
|
||||
<style>
|
||||
:is(.wa-flank, .wa-grid, .wa-stack) > [class*='wa-stack']:has(div:empty) {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
border-radius: var(--wa-border-radius-l);
|
||||
padding: var(--wa-space-s);
|
||||
border: var(--layout-example-border);
|
||||
border-radius: var(--layout-example-border-radius);
|
||||
padding: var(--layout-example-padding);
|
||||
}
|
||||
|
||||
[class*='wa-stack'] div:empty {
|
||||
background-color: var(--wa-color-indigo-60);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--layout-example-element-background);
|
||||
border-radius: var(--layout-example-element-border-radius);
|
||||
min-block-size: 4rem;
|
||||
min-inline-size: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{ description }}
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-stack">
|
||||
<div></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"description": "A forward-thinking library of web components.",
|
||||
"version": "3.0.0",
|
||||
"version": "3.1.0",
|
||||
"homepage": "https://webawesome.com/",
|
||||
"author": "Web Awesome",
|
||||
"license": "MIT",
|
||||
@@ -67,7 +67,7 @@
|
||||
"check-updates": "npm-check-updates --cooldown 7 --interactive --format group",
|
||||
"print-version": "echo $npm_package_version",
|
||||
"tag-version": "git tag -a \"v$(npm run print-version | tail -n1)\" -m \"tag v$(npm run print-version | tail -n1)\"",
|
||||
"postversion": "npm run tag-version"
|
||||
"postversion": "node ./scripts/update-root-version.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17.0"
|
||||
@@ -92,6 +92,7 @@
|
||||
"@wc-toolkit/jsx-types": "^1.3.0",
|
||||
"eleventy-plugin-git-commit-date": "^0.1.3",
|
||||
"esbuild": "^0.25.11",
|
||||
"gray-matter": "^4.0.3",
|
||||
"npm-check-updates": "^19.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,9 +230,6 @@ export async function build(options = {}) {
|
||||
js: `/*! Copyright ${currentYear} Fonticons, Inc. - https://webawesome.com/license */`,
|
||||
},
|
||||
plugins: [replace({ __WEBAWESOME_VERSION__: await getVersion() })],
|
||||
loader: {
|
||||
'.css': 'text',
|
||||
},
|
||||
};
|
||||
|
||||
const unbundledConfig = {
|
||||
|
||||
257
packages/webawesome/scripts/llms.js
Normal file
257
packages/webawesome/scripts/llms.js
Normal file
@@ -0,0 +1,257 @@
|
||||
import fs from 'fs';
|
||||
import matter from 'gray-matter';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { getAllComponents } from './shared.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/** Removes newlines from text to keep llms.txt formatting clean. */
|
||||
function removeNewlines(str) {
|
||||
return str ? str.replace(/\n/g, ' ').trim() : '';
|
||||
}
|
||||
|
||||
/** Loads front-matter from all component markdown files. */
|
||||
function loadAllFrontMatter(components, docsDir) {
|
||||
const cache = new Map();
|
||||
|
||||
for (const component of components) {
|
||||
const componentName = component.tagName.replace(/^wa-/, '');
|
||||
const mdPath = path.join(docsDir, 'docs/components', `${componentName}.md`);
|
||||
|
||||
if (fs.existsSync(mdPath)) {
|
||||
try {
|
||||
const content = fs.readFileSync(mdPath, 'utf-8');
|
||||
const { data } = matter(content);
|
||||
cache.set(component.tagName, data);
|
||||
} catch {
|
||||
// Skip if parsing fails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/** Generates the API reference section for a single component. */
|
||||
function generateComponentApiSection(component, frontMatterCache, baseUrl) {
|
||||
const lines = [];
|
||||
const frontMatter = frontMatterCache.get(component.tagName);
|
||||
const componentSlug = component.tagName.replace(/^wa-/, '');
|
||||
const description = removeNewlines(frontMatter?.description || component.summary || '');
|
||||
|
||||
lines.push(`#### \`<${component.tagName}>\``);
|
||||
lines.push('');
|
||||
lines.push(`**Description:** ${description || 'No description available.'}`);
|
||||
lines.push('');
|
||||
lines.push(`**Documentation:** ${baseUrl}/docs/components/${componentSlug}`);
|
||||
lines.push('');
|
||||
|
||||
// Slots
|
||||
if (component.slots?.length > 0) {
|
||||
lines.push('**Slots:**');
|
||||
lines.push('');
|
||||
for (const slot of component.slots) {
|
||||
const slotName = slot.name || '(default)';
|
||||
lines.push(`- \`${slotName}\`: ${removeNewlines(slot.description) || 'No description.'}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// Properties
|
||||
const properties =
|
||||
component.members?.filter(m => m.kind === 'field' && m.privacy !== 'private' && m.description) || [];
|
||||
|
||||
if (properties.length > 0) {
|
||||
lines.push('**Properties:**');
|
||||
lines.push('');
|
||||
for (const prop of properties) {
|
||||
// Find corresponding attribute if any
|
||||
const attr = component.attributes?.find(a => a.fieldName === prop.name);
|
||||
const attrNote = attr && attr.name !== prop.name ? ` (attribute: \`${attr.name}\`)` : '';
|
||||
const typeStr = prop.type?.text ? `Type: \`${removeNewlines(prop.type.text)}\`` : '';
|
||||
const defaultStr = prop.default ? `Default: \`${prop.default}\`` : '';
|
||||
const meta = [typeStr, defaultStr].filter(Boolean).join(', ');
|
||||
|
||||
lines.push(
|
||||
`- \`${prop.name}\`${attrNote}: ${removeNewlines(prop.description) || 'No description.'}${meta ? ` (${meta})` : ''}`,
|
||||
);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// Methods
|
||||
const methods = component.members?.filter(m => m.kind === 'method' && m.privacy !== 'private' && m.description) || [];
|
||||
|
||||
if (methods.length > 0) {
|
||||
lines.push('**Methods:**');
|
||||
lines.push('');
|
||||
for (const method of methods) {
|
||||
const params = method.parameters?.length
|
||||
? `(${method.parameters.map(p => `${p.name}: ${removeNewlines(p.type?.text) || 'unknown'}`).join(', ')})`
|
||||
: '()';
|
||||
lines.push(`- \`${method.name}${params}\`: ${removeNewlines(method.description) || 'No description.'}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// Events
|
||||
const events = component.events?.filter(e => e.name) || [];
|
||||
if (events.length > 0) {
|
||||
lines.push('**Events:**');
|
||||
lines.push('');
|
||||
for (const event of events) {
|
||||
lines.push(`- \`${event.name}\`: ${removeNewlines(event.description) || 'No description.'}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// CSS Custom Properties
|
||||
if (component.cssProperties?.length > 0) {
|
||||
lines.push('**CSS Custom Properties:**');
|
||||
lines.push('');
|
||||
for (const prop of component.cssProperties) {
|
||||
const defaultStr = prop.default ? ` (Default: \`${prop.default}\`)` : '';
|
||||
lines.push(`- \`${prop.name}\`: ${removeNewlines(prop.description) || 'No description.'}${defaultStr}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// CSS Parts
|
||||
if (component.cssParts?.length > 0) {
|
||||
lines.push('**CSS Parts:**');
|
||||
lines.push('');
|
||||
for (const part of component.cssParts) {
|
||||
lines.push(`- \`${part.name}\`: ${removeNewlines(part.description) || 'No description.'}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
// CSS States
|
||||
if (component.cssStates?.length > 0) {
|
||||
lines.push('**CSS States:**');
|
||||
lines.push('');
|
||||
for (const state of component.cssStates) {
|
||||
lines.push(`- \`${state.name}\`: ${removeNewlines(state.description) || 'No description.'}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the complete llms.txt content.
|
||||
*/
|
||||
function generateLlmsTxt({ components, packageData, frontMatterCache, baseUrl }) {
|
||||
const lines = [];
|
||||
|
||||
// H1 Title (required by llmstxt.org spec)
|
||||
lines.push('# Web Awesome');
|
||||
lines.push('');
|
||||
|
||||
// Blockquote summary
|
||||
lines.push(`> ${packageData.description} Version ${packageData.version}.`);
|
||||
lines.push('');
|
||||
|
||||
// Overview section
|
||||
lines.push(
|
||||
`
|
||||
Web Awesome provides a comprehensive set of customizable, accessible web components for building modern
|
||||
web applications. All components use shadow DOM and are framework-agnostic, working with vanilla JavaScript
|
||||
or any framework including React, Vue, Angular, and Svelte.
|
||||
|
||||
Form controls are form-associated custom elements that work with native form validation and the
|
||||
Constraint Validation API.
|
||||
|
||||
Font Awesome is the default icon library, so \`<wa-icon name="...">\` values should reference Font Awesome
|
||||
icon names.
|
||||
`.trim(),
|
||||
);
|
||||
lines.push('');
|
||||
|
||||
//
|
||||
// Documentation
|
||||
//
|
||||
lines.push('## Documentation');
|
||||
lines.push('');
|
||||
lines.push(`For comprehensive documentation, visit ${baseUrl}/docs/`);
|
||||
lines.push('');
|
||||
lines.push(`- [Getting Started](${baseUrl}/docs/getting-started): Installation and setup guide`);
|
||||
lines.push(`- [Components Overview](${baseUrl}/docs/components): Complete component reference`);
|
||||
lines.push(`- [Theming](${baseUrl}/docs/theming): Customization and design tokens`);
|
||||
lines.push(`- [Form Controls](${baseUrl}/docs/form-controls): Form integration and validation`);
|
||||
lines.push('');
|
||||
|
||||
//
|
||||
// Components
|
||||
//
|
||||
lines.push('## Components');
|
||||
lines.push('');
|
||||
|
||||
const sortedComponentsList = [...components].sort((a, b) => a.tagName.localeCompare(b.tagName));
|
||||
|
||||
for (const component of sortedComponentsList) {
|
||||
const frontMatter = frontMatterCache.get(component.tagName);
|
||||
const description = removeNewlines(frontMatter?.description || component.summary || '');
|
||||
const componentSlug = component.tagName.replace(/^wa-/, '');
|
||||
const title = frontMatter?.title || componentSlug;
|
||||
|
||||
lines.push(
|
||||
`- [${title}](${baseUrl}/docs/components/${componentSlug}): ${description || 'No description available.'}`,
|
||||
);
|
||||
}
|
||||
lines.push('');
|
||||
|
||||
//
|
||||
// Optional
|
||||
//
|
||||
lines.push('## Optional');
|
||||
lines.push('');
|
||||
lines.push(
|
||||
`The following is a quick reference describing every component's API. For comprehensive documentation, refer to the component documentation using the URLs provided above.`,
|
||||
);
|
||||
lines.push('');
|
||||
|
||||
// Sort components alphabetically by tag name for the API reference
|
||||
const sortedComponents = [...components].sort((a, b) => a.tagName.localeCompare(b.tagName));
|
||||
|
||||
for (const component of sortedComponents) {
|
||||
lines.push(...generateComponentApiSection(component, frontMatterCache, baseUrl));
|
||||
}
|
||||
|
||||
return lines.join('\n').trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* A CEM plugin that generates an llms.txt file following the llmstxt.org specification.
|
||||
*/
|
||||
export function llmsTxtPlugin(options = {}) {
|
||||
const {
|
||||
outdir = 'dist-cdn',
|
||||
docsDir = path.resolve(__dirname, '../docs'),
|
||||
baseUrl = 'https://webawesome.com',
|
||||
} = options;
|
||||
|
||||
return {
|
||||
name: 'wa-llms-txt',
|
||||
packageLinkPhase({ customElementsManifest }) {
|
||||
const components = getAllComponents(customElementsManifest);
|
||||
const packageData = customElementsManifest.package || {};
|
||||
const frontMatterCache = loadAllFrontMatter(components, docsDir);
|
||||
|
||||
const llmsTxt = generateLlmsTxt({
|
||||
components,
|
||||
packageData,
|
||||
frontMatterCache,
|
||||
baseUrl,
|
||||
});
|
||||
|
||||
// Write to the output directory
|
||||
const outputPath = path.join(outdir, 'llms.txt');
|
||||
fs.writeFileSync(outputPath, llmsTxt, 'utf-8');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default llmsTxtPlugin;
|
||||
@@ -37,7 +37,7 @@ export default function (plop) {
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.css',
|
||||
path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.styles.ts',
|
||||
templateFile: 'templates/component/styles.hbs',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import styles from './{{ tagWithoutPrefix tag }}.css';
|
||||
import styles from './{{ tagWithoutPrefix tag }}.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Short summary of the component's intended use.
|
||||
@@ -21,7 +21,7 @@ import styles from './{{ tagWithoutPrefix tag }}.css';
|
||||
*/
|
||||
@customElement("{{ tag }}")
|
||||
export default class {{ properCase tag }} extends WebAwesomeElement {
|
||||
static css = styles;
|
||||
static css = [styles];
|
||||
|
||||
/** An example attribute. */
|
||||
@property() attr = 'example';
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
:host {
|
||||
display: block;
|
||||
import { css } from "lit";
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
`
|
||||
|
||||
27
packages/webawesome/scripts/update-root-version.js
Executable file
27
packages/webawesome/scripts/update-root-version.js
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
import * as url from 'url';
|
||||
|
||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
const monorepoRoot = path.resolve(__dirname, '..', '..', '..');
|
||||
const rootPackageJSONFile = path.join(monorepoRoot, 'package.json');
|
||||
const webawesomePackageJSONFile = path.join(path.resolve(__dirname, '..'), 'package.json');
|
||||
|
||||
const rootPackageJSON = JSON.parse(fs.readFileSync(rootPackageJSONFile, { encoding: 'utf8' }));
|
||||
const webawesomePackageJSON = JSON.parse(fs.readFileSync(webawesomePackageJSONFile, { encoding: 'utf8' }));
|
||||
|
||||
const currentVersion = webawesomePackageJSON.version;
|
||||
rootPackageJSON.version = currentVersion;
|
||||
|
||||
fs.writeFileSync(rootPackageJSONFile, JSON.stringify(rootPackageJSON, null, 2));
|
||||
|
||||
const versionsFile = path.join(monorepoRoot, 'VERSIONS.txt');
|
||||
const versions = fs.readFileSync(versionsFile, { encoding: 'utf8' }).split(/\r?\n/);
|
||||
|
||||
// TODO: Make this smart and understand semver and "insert" in the correct spot instead of appending.
|
||||
if (!versions.includes(currentVersion)) {
|
||||
fs.appendFileSync(versionsFile, webawesomePackageJSON.version);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
:host {
|
||||
--control-box-size: 3rem;
|
||||
--icon-size: calc(var(--control-box-size) * 0.625);
|
||||
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
img[aria-hidden='true'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.control-box {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: calc(50% - var(--control-box-size) / 2);
|
||||
right: calc(50% - var(--control-box-size) / 2);
|
||||
width: var(--control-box-size);
|
||||
height: var(--control-box-size);
|
||||
font-size: calc(var(--icon-size) * 0.75);
|
||||
background: none;
|
||||
border: solid var(--wa-border-width-s) currentColor;
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
color: white;
|
||||
pointer-events: none;
|
||||
transition: opacity var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host([play]:hover) .control-box {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:where(:host([play]:not(:hover))) .control-box {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
:host([play]) slot[name='play-icon'],
|
||||
:host(:not([play])) slot[name='pause-icon'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show control box on keyboard focus */
|
||||
.animated-image {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible .control-box {
|
||||
opacity: 1;
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--control-box-size: 3rem;
|
||||
--icon-size: calc(var(--control-box-size) * 0.625);
|
||||
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
img[aria-hidden='true'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.control-box {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: calc(50% - var(--control-box-size) / 2);
|
||||
right: calc(50% - var(--control-box-size) / 2);
|
||||
width: var(--control-box-size);
|
||||
height: var(--control-box-size);
|
||||
font-size: calc(var(--icon-size) * 0.75);
|
||||
background: none;
|
||||
border: solid var(--wa-border-width-s) currentColor;
|
||||
background-color: rgb(0 0 0 / 50%);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
color: white;
|
||||
pointer-events: none;
|
||||
transition: opacity var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host([play]:hover) .control-box {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:where(:host([play]:not(:hover))) .control-box {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
:host([play]) slot[name='play-icon'],
|
||||
:host(:not([play])) slot[name='pause-icon'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show control box on keyboard focus */
|
||||
.animated-image {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible .control-box {
|
||||
opacity: 1;
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -6,7 +6,7 @@ import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './animated-image.css';
|
||||
import styles from './animated-image.styles.js';
|
||||
|
||||
/**
|
||||
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
:host {
|
||||
display: contents;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: contents;
|
||||
}
|
||||
`;
|
||||
@@ -5,7 +5,7 @@ import { WaFinishEvent } from '../../events/finish.js';
|
||||
import { WaStartEvent } from '../../events/start.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import styles from './animation.css';
|
||||
import styles from './animation.styles.js';
|
||||
import { animations } from './animations.js';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
:host {
|
||||
--size: 3rem;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
color: var(--wa-color-neutral-on-normal);
|
||||
font: inherit;
|
||||
font-size: calc(var(--size) * 0.4);
|
||||
vertical-align: middle;
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:host([shape='square']) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([shape='rounded']) {
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.initials {
|
||||
line-height: 1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
}
|
||||
57
packages/webawesome/src/components/avatar/avatar.styles.ts
Normal file
57
packages/webawesome/src/components/avatar/avatar.styles.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--size: 3rem;
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
color: var(--wa-color-neutral-on-normal);
|
||||
font: inherit;
|
||||
font-size: calc(var(--size) * 0.4);
|
||||
vertical-align: middle;
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:host([shape='square']) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([shape='rounded']) {
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.initials {
|
||||
line-height: 1;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
}
|
||||
`;
|
||||
@@ -4,7 +4,7 @@ import { WaErrorEvent } from '../../events/error.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './avatar.css';
|
||||
import styles from './avatar.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Avatars are used to represent a person or object.
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
:host {
|
||||
--pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.375em 0.625em;
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
font-size: max(var(--wa-font-size-2xs), 0.75em);
|
||||
font-weight: var(--wa-font-weight-semibold);
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='outlined']) {
|
||||
--pulse-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-brand-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
--pulse-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
|
||||
color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
--pulse-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
|
||||
|
||||
color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
border-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
--pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* Pill modifier */
|
||||
:host([pill]) {
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
/* Pulse attention */
|
||||
:host([attention='pulse']) {
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 var(--pulse-color);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 0.5rem transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bounce attention */
|
||||
:host([attention='bounce']) {
|
||||
animation: bounce 1s cubic-bezier(0.28, 0.84, 0.42, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
20%,
|
||||
50%,
|
||||
80%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
40% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
::slotted(wa-icon) {
|
||||
margin-inline-end: var(--wa-space-2xs, 0.25em);
|
||||
opacity: 90%;
|
||||
line-height: 1;
|
||||
height: 0.85em;
|
||||
}
|
||||
108
packages/webawesome/src/components/badge/badge.styles.ts
Normal file
108
packages/webawesome/src/components/badge/badge.styles.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.375em 0.625em;
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
font-size: max(var(--wa-font-size-2xs), 0.75em);
|
||||
font-weight: var(--wa-font-weight-semibold);
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='outlined']) {
|
||||
--pulse-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-brand-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
--pulse-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
|
||||
color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
--pulse-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
|
||||
|
||||
color: var(--wa-color-on-normal, var(--wa-color-brand-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-brand-fill-normal));
|
||||
border-color: var(--wa-color-border-normal, var(--wa-color-brand-border-normal));
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
--pulse-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* Pill modifier */
|
||||
:host([pill]) {
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
/* Pulse attention */
|
||||
:host([attention='pulse']) {
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 var(--pulse-color);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 0.5rem transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bounce attention */
|
||||
:host([attention='bounce']) {
|
||||
animation: bounce 1s cubic-bezier(0.28, 0.84, 0.42, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%,
|
||||
20%,
|
||||
50%,
|
||||
80%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
40% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
::slotted(wa-icon) {
|
||||
margin-inline-end: var(--wa-space-2xs, 0.25em);
|
||||
opacity: 90%;
|
||||
line-height: 1;
|
||||
height: 0.85em;
|
||||
}
|
||||
`;
|
||||
@@ -1,8 +1,8 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
import styles from './badge.css';
|
||||
import variantStyles from '../../styles/component/variants.styles.js';
|
||||
import styles from './badge.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Badges are used to draw attention and display statuses or counts.
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
:host {
|
||||
color: var(--wa-color-text-link);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font: inherit;
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
line-height: var(--wa-line-height-normal);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:host(:last-of-type) {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
font: inherit;
|
||||
text-decoration: none;
|
||||
color: currentColor;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
transition: color var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host(:not(:last-of-type)) .label:hover {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
}
|
||||
|
||||
:host(:not(:last-of-type)) .label:active {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
|
||||
}
|
||||
|
||||
.label:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.label:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: none;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: inline-flex;
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
::slotted([slot='start']) {
|
||||
margin-inline-end: var(--wa-space-s);
|
||||
}
|
||||
|
||||
::slotted([slot='end']) {
|
||||
margin-inline-start: var(--wa-space-s);
|
||||
}
|
||||
|
||||
:host(:last-of-type) .separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.separator {
|
||||
color: var(--wa-color-text-quiet);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin: 0 var(--wa-space-s);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
color: var(--wa-color-text-link);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font: inherit;
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
line-height: var(--wa-line-height-normal);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:host(:last-of-type) {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
font: inherit;
|
||||
text-decoration: none;
|
||||
color: currentColor;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
transition: color var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host(:not(:last-of-type)) .label:hover {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
}
|
||||
|
||||
:host(:not(:last-of-type)) .label:active {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
|
||||
}
|
||||
|
||||
.label:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.label:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: none;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.start,
|
||||
.end {
|
||||
display: inline-flex;
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
::slotted([slot='start']) {
|
||||
margin-inline-end: var(--wa-space-s);
|
||||
}
|
||||
|
||||
::slotted([slot='end']) {
|
||||
margin-inline-start: var(--wa-space-s);
|
||||
}
|
||||
|
||||
:host(:last-of-type) .separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.separator {
|
||||
color: var(--wa-color-text-quiet);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin: 0 var(--wa-space-s);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
`;
|
||||
@@ -3,7 +3,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import styles from './breadcrumb-item.css';
|
||||
import styles from './breadcrumb-item.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Breadcrumb Items are used inside breadcrumbs to represent different links.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`;
|
||||
@@ -4,7 +4,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import type WaBreadcrumbItem from '../breadcrumb-item/breadcrumb-item.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './breadcrumb.css';
|
||||
import styles from './breadcrumb.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Breadcrumbs provide a group of links so users can easily navigate a website's hierarchy.
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
:host {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
flex-wrap: wrap;
|
||||
gap: 1px;
|
||||
|
||||
@media (hover: hover) {
|
||||
> :hover,
|
||||
&::slotted(:hover) {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus and checked are always on top */
|
||||
> :focus,
|
||||
&::slotted(:focus),
|
||||
> [aria-checked='true'],
|
||||
&::slotted([aria-checked='true']),
|
||||
> [checked],
|
||||
&::slotted([checked]) {
|
||||
z-index: 2 !important;
|
||||
}
|
||||
}
|
||||
:host([orientation='vertical']) .button-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Button groups with at least one outlined button will not have a gap and instead have borders overlap */
|
||||
.button-group.has-outlined {
|
||||
gap: 0;
|
||||
|
||||
&:not([aria-orientation='vertical']):not(.button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-inline-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
|
||||
&:is([aria-orientation='vertical'], .button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-block-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
flex-wrap: wrap;
|
||||
gap: 1px;
|
||||
|
||||
@media (hover: hover) {
|
||||
> :hover,
|
||||
&::slotted(:hover) {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus and checked are always on top */
|
||||
> :focus,
|
||||
&::slotted(:focus),
|
||||
> [aria-checked='true'],
|
||||
&::slotted([aria-checked='true']),
|
||||
> [checked],
|
||||
&::slotted([checked]) {
|
||||
z-index: 2 !important;
|
||||
}
|
||||
}
|
||||
:host([orientation='vertical']) .button-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Button groups with at least one outlined button will not have a gap and instead have borders overlap */
|
||||
.button-group.has-outlined {
|
||||
gap: 0;
|
||||
|
||||
&:not([aria-orientation='vertical']):not(.button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-inline-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
|
||||
&:is([aria-orientation='vertical'], .button-group-vertical)::slotted(:not(:first-child)) {
|
||||
margin-block-start: calc(-1 * var(--border-width));
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -4,7 +4,7 @@ import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type WaButton from '../button/button.js';
|
||||
import styles from './button-group.css';
|
||||
import styles from './button-group.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Button groups can be used to group related buttons into sections.
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
@layer wa-component {
|
||||
:host {
|
||||
display: inline-block;
|
||||
|
||||
/* Workaround because Chrome doesn't like :host(:has()) below
|
||||
* https://issues.chromium.org/issues/40062355
|
||||
* Firefox doesn't like this nested rule, so both are needed */
|
||||
&:has(wa-badge) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply relative positioning only when needed to position wa-badge
|
||||
* This avoids creating a new stacking context for every button */
|
||||
:host(:has(wa-badge)) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
transition-property: background, border, box-shadow, color;
|
||||
transition-duration: var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
cursor: pointer;
|
||||
padding: 0 var(--wa-form-control-padding-inline);
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
line-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
|
||||
height: var(--wa-form-control-height);
|
||||
width: 100%;
|
||||
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
|
||||
border-color: transparent;
|
||||
color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
|
||||
border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
.button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled state */
|
||||
.button.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* When disabled, prevent mouse events from bubbling up from children */
|
||||
.button.disabled * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Keep it last so Safari doesn't stop parsing this block */
|
||||
.button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Icon buttons */
|
||||
.button.is-icon-button {
|
||||
outline-offset: 2px;
|
||||
width: var(--wa-form-control-height);
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.button.is-icon-button:has(wa-icon) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Pill modifier */
|
||||
:host([pill]) .button {
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
/*
|
||||
* Label
|
||||
*/
|
||||
|
||||
.start,
|
||||
.end {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.is-icon-button .label {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.label::slotted(wa-icon) {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
/*
|
||||
* Caret modifier
|
||||
*/
|
||||
|
||||
wa-icon[part='caret'] {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
align-items: center;
|
||||
|
||||
&::part(svg) {
|
||||
width: 0.875em;
|
||||
height: 0.875em;
|
||||
}
|
||||
|
||||
.button:has(&) .end {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loading modifier
|
||||
*/
|
||||
|
||||
.loading {
|
||||
position: relative;
|
||||
cursor: wait;
|
||||
|
||||
.start,
|
||||
.label,
|
||||
.end,
|
||||
.caret {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
wa-spinner {
|
||||
--indicator-color: currentColor;
|
||||
--track-color: color-mix(in oklab, currentColor, transparent 90%);
|
||||
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
top: calc(50% - 0.5em);
|
||||
left: calc(50% - 0.5em);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Badges
|
||||
*/
|
||||
|
||||
.button ::slotted(wa-badge) {
|
||||
border-color: var(--wa-color-surface-default);
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-end: 0;
|
||||
translate: 50% -50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:host(:dir(rtl)) ::slotted(wa-badge) {
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Button spacing
|
||||
*/
|
||||
|
||||
slot[name='start']::slotted(*) {
|
||||
margin-inline-end: 0.75em;
|
||||
}
|
||||
|
||||
slot[name='end']::slotted(*),
|
||||
.button:not(.visually-hidden-label) [part='caret'] {
|
||||
margin-inline-start: 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Button group border radius modifications
|
||||
*/
|
||||
|
||||
/* Remove border radius from all grouped buttons by default */
|
||||
:host(.wa-button-group__button) .button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Horizontal orientation */
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-last) .button {
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Vertical orientation */
|
||||
:host(.wa-button-group__vertical) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical) .button {
|
||||
width: 100%;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-last) .button {
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Handle pill modifier for button groups */
|
||||
:host([pill].wa-button-group__horizontal.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__horizontal.wa-button-group__button-last) .button {
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__vertical.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__vertical.wa-button-group__button-last) .button {
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
376
packages/webawesome/src/components/button/button.styles.ts
Normal file
376
packages/webawesome/src/components/button/button.styles.ts
Normal file
@@ -0,0 +1,376 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
@layer wa-component {
|
||||
:host {
|
||||
display: inline-block;
|
||||
|
||||
/* Workaround because Chrome doesn't like :host(:has()) below
|
||||
* https://issues.chromium.org/issues/40062355
|
||||
* Firefox doesn't like this nested rule, so both are needed */
|
||||
&:has(wa-badge) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply relative positioning only when needed to position wa-badge
|
||||
* This avoids creating a new stacking context for every button */
|
||||
:host(:has(wa-badge)) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
transition-property: background, border, box-shadow, color, opacity;
|
||||
transition-duration: var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
cursor: pointer;
|
||||
padding: 0 var(--wa-form-control-padding-inline);
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: var(--wa-font-weight-action);
|
||||
line-height: calc(var(--wa-form-control-height) - var(--border-width) * 2);
|
||||
height: var(--wa-form-control-height);
|
||||
width: 100%;
|
||||
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
|
||||
border-color: transparent;
|
||||
color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-neutral-border-loud));
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet));
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-quiet, var(--wa-color-neutral-on-quiet));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-quiet, var(--wa-color-neutral-fill-quiet)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal));
|
||||
border-color: var(--wa-color-border-normal, var(--wa-color-neutral-border-normal));
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-normal, var(--wa-color-neutral-fill-normal)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
.button {
|
||||
color: var(--wa-color-on-loud, var(--wa-color-neutral-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud));
|
||||
border-color: transparent;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.button:not(.disabled):not(.loading):hover {
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
|
||||
var(--wa-color-mix-hover)
|
||||
);
|
||||
}
|
||||
}
|
||||
.button:not(.disabled):not(.loading):active {
|
||||
background-color: color-mix(
|
||||
in oklab,
|
||||
var(--wa-color-fill-loud, var(--wa-color-neutral-fill-loud)),
|
||||
var(--wa-color-mix-active)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus states */
|
||||
.button:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled state */
|
||||
.button.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* When disabled, prevent mouse events from bubbling up from children */
|
||||
.button.disabled * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Keep it last so Safari doesn't stop parsing this block */
|
||||
.button::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Icon buttons */
|
||||
.button.is-icon-button {
|
||||
outline-offset: 2px;
|
||||
width: var(--wa-form-control-height);
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.button.is-icon-button:has(wa-icon) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Pill modifier */
|
||||
:host([pill]) .button {
|
||||
border-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
/*
|
||||
* Label
|
||||
*/
|
||||
|
||||
.start,
|
||||
.end {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.is-icon-button .label {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.label::slotted(wa-icon) {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
/*
|
||||
* Caret modifier
|
||||
*/
|
||||
|
||||
wa-icon[part='caret'] {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
align-items: center;
|
||||
|
||||
&::part(svg) {
|
||||
width: 0.875em;
|
||||
height: 0.875em;
|
||||
}
|
||||
|
||||
.button:has(&) .end {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loading modifier
|
||||
*/
|
||||
|
||||
.loading {
|
||||
position: relative;
|
||||
cursor: wait;
|
||||
|
||||
.start,
|
||||
.label,
|
||||
.end,
|
||||
.caret {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
wa-spinner {
|
||||
--indicator-color: currentColor;
|
||||
--track-color: color-mix(in oklab, currentColor, transparent 90%);
|
||||
|
||||
position: absolute;
|
||||
font-size: 1em;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
top: calc(50% - 0.5em);
|
||||
left: calc(50% - 0.5em);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Badges
|
||||
*/
|
||||
|
||||
.button ::slotted(wa-badge) {
|
||||
border-color: var(--wa-color-surface-default);
|
||||
position: absolute;
|
||||
inset-block-start: 0;
|
||||
inset-inline-end: 0;
|
||||
translate: 50% -50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:host(:dir(rtl)) ::slotted(wa-badge) {
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Button spacing
|
||||
*/
|
||||
|
||||
slot[name='start']::slotted(*) {
|
||||
margin-inline-end: 0.75em;
|
||||
}
|
||||
|
||||
slot[name='end']::slotted(*),
|
||||
.button:not(.visually-hidden-label) [part='caret'] {
|
||||
margin-inline-start: 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Button group border radius modifications
|
||||
*/
|
||||
|
||||
/* Remove border radius from all grouped buttons by default */
|
||||
:host(.wa-button-group__button) .button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Horizontal orientation */
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__horizontal.wa-button-group__button-last) .button {
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Vertical orientation */
|
||||
:host(.wa-button-group__vertical) {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical) .button {
|
||||
width: 100%;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-form-control-border-radius);
|
||||
border-start-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
:host(.wa-button-group__vertical.wa-button-group__button-last) .button {
|
||||
border-end-start-radius: var(--wa-form-control-border-radius);
|
||||
border-end-end-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
/* Handle pill modifier for button groups */
|
||||
:host([pill].wa-button-group__horizontal.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__horizontal.wa-button-group__button-last) .button {
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__vertical.wa-button-group__button-first) .button {
|
||||
border-start-start-radius: var(--wa-border-radius-pill);
|
||||
border-start-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
|
||||
:host([pill].wa-button-group__vertical.wa-button-group__button-last) .button {
|
||||
border-end-start-radius: var(--wa-border-radius-pill);
|
||||
border-end-end-radius: var(--wa-border-radius-pill);
|
||||
}
|
||||
`;
|
||||
@@ -7,13 +7,13 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
import sizeStyles from '../../styles/component/size.styles.js';
|
||||
import variantStyles from '../../styles/component/variants.styles.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import type WaIcon from '../icon/icon.js';
|
||||
import '../spinner/spinner.js';
|
||||
import styles from './button.css';
|
||||
import styles from './button.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Buttons represent actions that are available to the user.
|
||||
@@ -115,7 +115,6 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
* The "form owner" to associate the button with. If omitted, the closest containing form will be used instead. The
|
||||
* value of this attribute must be an id of a form in the same document or shadow root as the button.
|
||||
*/
|
||||
@property({ reflect: true }) form: string | null = null;
|
||||
|
||||
/** Used to override the form owner's `action` attribute. */
|
||||
@property({ attribute: 'formaction' }) formAction: string;
|
||||
@@ -135,24 +134,27 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
private constructLightDOMButton() {
|
||||
const button = document.createElement('button');
|
||||
|
||||
for (const attribute of this.attributes) {
|
||||
if (attribute.name === 'style') {
|
||||
// Skip style attributes as they *shouldn't* be necessary
|
||||
continue;
|
||||
}
|
||||
button.setAttribute(attribute.name, attribute.value);
|
||||
}
|
||||
|
||||
button.type = this.type;
|
||||
button.style.position = 'absolute';
|
||||
button.style.width = '0';
|
||||
button.style.height = '0';
|
||||
button.style.clipPath = 'inset(50%)';
|
||||
button.style.overflow = 'hidden';
|
||||
button.style.whiteSpace = 'nowrap';
|
||||
button.style.position = 'absolute !important';
|
||||
button.style.width = '0 !important';
|
||||
button.style.height = '0 !important';
|
||||
button.style.clipPath = 'inset(50%) !important';
|
||||
button.style.overflow = 'hidden !important';
|
||||
button.style.whiteSpace = 'nowrap !important';
|
||||
if (this.name) {
|
||||
button.name = this.name;
|
||||
}
|
||||
button.value = this.value || '';
|
||||
|
||||
['form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget'].forEach(attr => {
|
||||
if (this.hasAttribute(attr)) {
|
||||
button.setAttribute(attr, this.getAttribute(attr)!);
|
||||
}
|
||||
});
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
:host {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: stretch;
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
|
||||
border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
|
||||
border-style: var(--wa-panel-border-style);
|
||||
border-width: var(--wa-panel-border-width);
|
||||
color: var(--wa-color-text-normal);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance~='plain']) {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance~='outlined']) {
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
}
|
||||
|
||||
:host([appearance~='filled']) {
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance~='filled-outlined']) {
|
||||
border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
|
||||
}
|
||||
|
||||
:host([appearance~='accent']) {
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
|
||||
[part~='icon'] {
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--wa-color-on-quiet);
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
::slotted([slot='icon']) {
|
||||
margin-inline-end: var(--wa-form-control-padding-inline);
|
||||
}
|
||||
|
||||
[part~='message'] {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
64
packages/webawesome/src/components/callout/callout.styles.ts
Normal file
64
packages/webawesome/src/components/callout/callout.styles.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: stretch;
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
|
||||
border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
|
||||
border-style: var(--wa-panel-border-style);
|
||||
border-width: var(--wa-panel-border-width);
|
||||
color: var(--wa-color-text-normal);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance~='plain']) {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance~='outlined']) {
|
||||
background-color: transparent;
|
||||
border-color: var(--wa-color-border-loud, var(--wa-color-brand-border-loud));
|
||||
}
|
||||
|
||||
:host([appearance~='filled']) {
|
||||
background-color: var(--wa-color-fill-quiet, var(--wa-color-brand-fill-quiet));
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance~='filled-outlined']) {
|
||||
border-color: var(--wa-color-border-quiet, var(--wa-color-brand-border-quiet));
|
||||
}
|
||||
|
||||
:host([appearance~='accent']) {
|
||||
color: var(--wa-color-on-loud, var(--wa-color-brand-on-loud));
|
||||
background-color: var(--wa-color-fill-loud, var(--wa-color-brand-fill-loud));
|
||||
border-color: transparent;
|
||||
|
||||
[part~='icon'] {
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--wa-color-on-quiet);
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
::slotted([slot='icon']) {
|
||||
margin-inline-end: var(--wa-form-control-padding-inline);
|
||||
}
|
||||
|
||||
[part~='message'] {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
@@ -1,9 +1,9 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import variantStyles from '../../styles/utilities/variants.css';
|
||||
import styles from './callout.css';
|
||||
import sizeStyles from '../../styles/component/size.styles.js';
|
||||
import variantStyles from '../../styles/component/variants.styles.js';
|
||||
import styles from './callout.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Callouts are used to display important messages inline.
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
:host {
|
||||
--spacing: var(--wa-space-l);
|
||||
|
||||
/* Internal calculated properties */
|
||||
--inner-border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
border-style: var(--wa-panel-border-style);
|
||||
box-shadow: var(--wa-shadow-s);
|
||||
border-width: var(--wa-panel-border-width);
|
||||
color: var(--wa-color-text-normal);
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) {
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
color: var(--wa-color-neutral-on-loud);
|
||||
background-color: var(--wa-color-neutral-fill-loud);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* Take care of top and bottom radii */
|
||||
.media,
|
||||
:host(:not([with-media])) .header,
|
||||
:host(:not([with-media], [with-header])) .body {
|
||||
border-start-start-radius: var(--inner-border-radius);
|
||||
border-start-end-radius: var(--inner-border-radius);
|
||||
}
|
||||
|
||||
:host(:not([with-footer])) .body,
|
||||
.footer {
|
||||
border-end-start-radius: var(--inner-border-radius);
|
||||
border-end-end-radius: var(--inner-border-radius);
|
||||
}
|
||||
|
||||
.media {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&::slotted(*) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Round all corners for plain appearance */
|
||||
:host([appearance='plain']) .media {
|
||||
border-radius: var(--inner-border-radius);
|
||||
|
||||
&::slotted(*) {
|
||||
border-radius: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
display: block;
|
||||
border-block-end-style: inherit;
|
||||
border-block-end-color: var(--wa-color-surface-border);
|
||||
border-block-end-width: var(--wa-panel-border-width);
|
||||
padding: calc(var(--spacing) / 2) var(--spacing);
|
||||
}
|
||||
|
||||
.body {
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: block;
|
||||
border-block-start-style: inherit;
|
||||
border-block-start-color: var(--wa-color-surface-border);
|
||||
border-block-start-width: var(--wa-panel-border-width);
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
/* Push slots to sides when the action slots renders */
|
||||
.has-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:host(:not([with-header])) .header,
|
||||
:host(:not([with-footer])) .footer,
|
||||
:host(:not([with-media])) .media {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Orientation Styles */
|
||||
:host([orientation='horizontal']) {
|
||||
flex-direction: row;
|
||||
|
||||
.media {
|
||||
border-start-start-radius: var(--inner-border-radius);
|
||||
border-end-start-radius: var(--inner-border-radius);
|
||||
border-start-end-radius: 0;
|
||||
|
||||
&::slotted(*) {
|
||||
block-size: 100%;
|
||||
inline-size: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host([orientation='horizontal']) ::slotted([slot='body']) {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:host([orientation='horizontal']) ::slotted([slot='actions']) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing);
|
||||
}
|
||||
145
packages/webawesome/src/components/card/card.styles.ts
Normal file
145
packages/webawesome/src/components/card/card.styles.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--spacing: var(--wa-space-l);
|
||||
|
||||
/* Internal calculated properties */
|
||||
--inner-border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
border-style: var(--wa-panel-border-style);
|
||||
box-shadow: var(--wa-shadow-s);
|
||||
border-width: var(--wa-panel-border-width);
|
||||
color: var(--wa-color-text-normal);
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) {
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='filled']) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='accent']) {
|
||||
color: var(--wa-color-neutral-on-loud);
|
||||
background-color: var(--wa-color-neutral-fill-loud);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
/* Take care of top and bottom radii */
|
||||
.media,
|
||||
:host(:not([with-media])) .header,
|
||||
:host(:not([with-media], [with-header])) .body {
|
||||
border-start-start-radius: var(--inner-border-radius);
|
||||
border-start-end-radius: var(--inner-border-radius);
|
||||
}
|
||||
|
||||
:host(:not([with-footer])) .body,
|
||||
.footer {
|
||||
border-end-start-radius: var(--inner-border-radius);
|
||||
border-end-end-radius: var(--inner-border-radius);
|
||||
}
|
||||
|
||||
.media {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
&::slotted(*) {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Round all corners for plain appearance */
|
||||
:host([appearance='plain']) .media {
|
||||
border-radius: var(--inner-border-radius);
|
||||
|
||||
&::slotted(*) {
|
||||
border-radius: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
display: block;
|
||||
border-block-end-style: inherit;
|
||||
border-block-end-color: var(--wa-color-surface-border);
|
||||
border-block-end-width: var(--wa-panel-border-width);
|
||||
padding: calc(var(--spacing) / 2) var(--spacing);
|
||||
}
|
||||
|
||||
.body {
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: block;
|
||||
border-block-start-style: inherit;
|
||||
border-block-start-color: var(--wa-color-surface-border);
|
||||
border-block-start-width: var(--wa-panel-border-width);
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
/* Push slots to sides when the action slots renders */
|
||||
.has-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:host(:not([with-header])) .header,
|
||||
:host(:not([with-footer])) .footer,
|
||||
:host(:not([with-media])) .media {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Orientation Styles */
|
||||
:host([orientation='horizontal']) {
|
||||
flex-direction: row;
|
||||
|
||||
.media {
|
||||
border-start-start-radius: var(--inner-border-radius);
|
||||
border-end-start-radius: var(--inner-border-radius);
|
||||
border-start-end-radius: 0;
|
||||
|
||||
&::slotted(*) {
|
||||
block-size: 100%;
|
||||
inline-size: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:host([orientation='horizontal']) ::slotted([slot='body']) {
|
||||
display: block;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:host([orientation='horizontal']) ::slotted([slot='actions']) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing);
|
||||
}
|
||||
`;
|
||||
@@ -2,8 +2,8 @@ import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { HasSlotController } from '../../internal/slot.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import styles from './card.css';
|
||||
import sizeStyles from '../../styles/component/size.styles.js';
|
||||
import styles from './card.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Cards can be used to group related subjects in a container.
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
:host {
|
||||
--aspect-ratio: inherit;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
aspect-ratio: var(--aspect-ratio);
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
}
|
||||
|
||||
::slotted(img) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--aspect-ratio: inherit;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
aspect-ratio: var(--aspect-ratio);
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
}
|
||||
|
||||
::slotted(img) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover;
|
||||
}
|
||||
`;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import styles from './carousel-item.css';
|
||||
import styles from './carousel-item.styles.js';
|
||||
|
||||
/**
|
||||
* @summary A carousel item represent a slide within a carousel.
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
:host {
|
||||
--aspect-ratio: 16 / 9;
|
||||
--scroll-hint: 0px;
|
||||
--slide-gap: var(--wa-space-m, 1rem); /* fallback value is necessary */
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.carousel {
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr min-content;
|
||||
grid-template-rows: 1fr min-content;
|
||||
grid-template-areas:
|
||||
'. slides .'
|
||||
'. pagination .';
|
||||
gap: var(--wa-space-m);
|
||||
align-items: center;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
grid-area: pagination;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--wa-space-s);
|
||||
}
|
||||
|
||||
.slides {
|
||||
grid-area: slides;
|
||||
|
||||
display: grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
overflow: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
scrollbar-width: none;
|
||||
aspect-ratio: calc(var(--aspect-ratio) * var(--slides-per-page));
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
|
||||
--slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
:where(.slides) {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.slides-horizontal {
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: var(--slide-size);
|
||||
grid-auto-rows: 100%;
|
||||
column-gap: var(--slide-gap);
|
||||
scroll-snap-type: x mandatory;
|
||||
scroll-padding-inline: var(--scroll-hint);
|
||||
padding-inline: var(--scroll-hint);
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.slides-vertical {
|
||||
grid-auto-flow: row;
|
||||
grid-auto-columns: 100%;
|
||||
grid-auto-rows: var(--slide-size);
|
||||
row-gap: var(--slide-gap);
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-padding-block: var(--scroll-hint);
|
||||
padding-block: var(--scroll-hint);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.slides-dragging,
|
||||
.slides-dropping {
|
||||
scroll-snap-type: unset;
|
||||
}
|
||||
|
||||
:host([vertical]) ::slotted(wa-carousel-item) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.slides::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
grid-area: navigation;
|
||||
display: contents;
|
||||
font-size: var(--wa-font-size-l);
|
||||
}
|
||||
|
||||
.navigation-button {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
font-size: inherit;
|
||||
color: var(--wa-color-text-quiet);
|
||||
padding: var(--wa-space-xs);
|
||||
cursor: pointer;
|
||||
transition: var(--wa-transition-normal) color;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.navigation-button-disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.navigation-button-disabled::part(base) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navigation-button-previous {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.navigation-button-next {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.pagination-item {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
width: var(--wa-space-s);
|
||||
height: var(--wa-space-s);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: transform var(--wa-transition-slow);
|
||||
}
|
||||
|
||||
.pagination-item-active {
|
||||
background-color: var(--wa-form-control-activated-color);
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
/* Focus styles */
|
||||
.slides:focus-visible,
|
||||
.navigation-button:focus-visible,
|
||||
.pagination-item:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
158
packages/webawesome/src/components/carousel/carousel.styles.ts
Normal file
158
packages/webawesome/src/components/carousel/carousel.styles.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--aspect-ratio: 16 / 9;
|
||||
--scroll-hint: 0px;
|
||||
--slide-gap: var(--wa-space-m, 1rem); /* fallback value is necessary */
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.carousel {
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr min-content;
|
||||
grid-template-rows: 1fr min-content;
|
||||
grid-template-areas:
|
||||
'. slides .'
|
||||
'. pagination .';
|
||||
gap: var(--wa-space-m);
|
||||
align-items: center;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
grid-area: pagination;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--wa-space-s);
|
||||
}
|
||||
|
||||
.slides {
|
||||
grid-area: slides;
|
||||
|
||||
display: grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
overflow: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
scrollbar-width: none;
|
||||
aspect-ratio: calc(var(--aspect-ratio) * var(--slides-per-page));
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
|
||||
--slide-size: calc((100% - (var(--slides-per-page) - 1) * var(--slide-gap)) / var(--slides-per-page));
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
:where(.slides) {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.slides-horizontal {
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: var(--slide-size);
|
||||
grid-auto-rows: 100%;
|
||||
column-gap: var(--slide-gap);
|
||||
scroll-snap-type: x mandatory;
|
||||
scroll-padding-inline: var(--scroll-hint);
|
||||
padding-inline: var(--scroll-hint);
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.slides-vertical {
|
||||
grid-auto-flow: row;
|
||||
grid-auto-columns: 100%;
|
||||
grid-auto-rows: var(--slide-size);
|
||||
row-gap: var(--slide-gap);
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-padding-block: var(--scroll-hint);
|
||||
padding-block: var(--scroll-hint);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.slides-dragging,
|
||||
.slides-dropping {
|
||||
scroll-snap-type: unset;
|
||||
}
|
||||
|
||||
:host([vertical]) ::slotted(wa-carousel-item) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.slides::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navigation {
|
||||
grid-area: navigation;
|
||||
display: contents;
|
||||
font-size: var(--wa-font-size-l);
|
||||
}
|
||||
|
||||
.navigation-button {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
font-size: inherit;
|
||||
color: var(--wa-color-text-quiet);
|
||||
padding: var(--wa-space-xs);
|
||||
cursor: pointer;
|
||||
transition: var(--wa-transition-normal) color;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.navigation-button-disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.navigation-button-disabled::part(base) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.navigation-button-previous {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.navigation-button-next {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
.pagination-item {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
width: var(--wa-space-s);
|
||||
height: var(--wa-space-s);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: transform var(--wa-transition-slow);
|
||||
}
|
||||
|
||||
.pagination-item-active {
|
||||
background-color: var(--wa-form-control-activated-color);
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
/* Focus styles */
|
||||
.slides:focus-visible,
|
||||
.navigation-button:focus-visible,
|
||||
.pagination-item:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
`;
|
||||
@@ -16,7 +16,7 @@ import { LocalizeController } from '../../utilities/localize.js';
|
||||
import type WaCarouselItem from '../carousel-item/carousel-item.js';
|
||||
import '../icon/icon.js';
|
||||
import { AutoplayController } from './autoplay-controller.js';
|
||||
import styles from './carousel.css';
|
||||
import styles from './carousel.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Carousels display an arbitrary number of content slides along a horizontal or vertical axis.
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
:host {
|
||||
--checked-icon-color: var(--wa-color-brand-on-loud);
|
||||
--checked-icon-scale: 0.8;
|
||||
|
||||
display: inline-flex;
|
||||
color: var(--wa-form-control-value-color);
|
||||
font-family: inherit;
|
||||
font-weight: var(--wa-form-control-value-font-weight);
|
||||
line-height: var(--wa-form-control-value-line-height);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
[part~='control'] {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--wa-form-control-toggle-size);
|
||||
height: var(--wa-form-control-toggle-size);
|
||||
border-color: var(--wa-form-control-border-color);
|
||||
border-radius: min(
|
||||
calc(var(--wa-form-control-toggle-size) * 0.375),
|
||||
var(--wa-border-radius-s)
|
||||
); /* min prevents entirely circular checkbox */
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-form-control-border-width);
|
||||
background-color: var(--wa-form-control-background-color);
|
||||
transition:
|
||||
background var(--wa-transition-normal),
|
||||
border-color var(--wa-transition-fast),
|
||||
box-shadow var(--wa-transition-fast),
|
||||
color var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
|
||||
margin-inline-end: 0.5em;
|
||||
}
|
||||
|
||||
[part~='base'] {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
color: currentColor;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[part~='label'] {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* Checked */
|
||||
[part~='control']:has(:checked, :indeterminate) {
|
||||
color: var(--checked-icon-color);
|
||||
border-color: var(--wa-form-control-activated-color);
|
||||
background-color: var(--wa-form-control-activated-color);
|
||||
}
|
||||
|
||||
/* Focus */
|
||||
[part~='control']:has(> input:focus-visible:not(:disabled)) {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
:host [part~='base']:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
display: flex;
|
||||
scale: var(--checked-icon-scale);
|
||||
|
||||
/* Without this, Safari renders the icon slightly to the left */
|
||||
&::part(svg) {
|
||||
translate: 0.0009765625em;
|
||||
}
|
||||
|
||||
input:not(:checked, :indeterminate) + & {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
:host([required]) [part~='label']::after {
|
||||
content: var(--wa-form-control-required-content);
|
||||
color: var(--wa-form-control-required-content-color);
|
||||
margin-inline-start: var(--wa-form-control-required-content-offset);
|
||||
}
|
||||
104
packages/webawesome/src/components/checkbox/checkbox.styles.ts
Normal file
104
packages/webawesome/src/components/checkbox/checkbox.styles.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--checked-icon-color: var(--wa-color-brand-on-loud);
|
||||
--checked-icon-scale: 0.8;
|
||||
|
||||
display: inline-flex;
|
||||
color: var(--wa-form-control-value-color);
|
||||
font-family: inherit;
|
||||
font-weight: var(--wa-form-control-value-font-weight);
|
||||
line-height: var(--wa-form-control-value-line-height);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
[part~='control'] {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--wa-form-control-toggle-size);
|
||||
height: var(--wa-form-control-toggle-size);
|
||||
border-color: var(--wa-form-control-border-color);
|
||||
border-radius: min(
|
||||
calc(var(--wa-form-control-toggle-size) * 0.375),
|
||||
var(--wa-border-radius-s)
|
||||
); /* min prevents entirely circular checkbox */
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-form-control-border-width);
|
||||
background-color: var(--wa-form-control-background-color);
|
||||
transition:
|
||||
background var(--wa-transition-normal),
|
||||
border-color var(--wa-transition-fast),
|
||||
box-shadow var(--wa-transition-fast),
|
||||
color var(--wa-transition-fast);
|
||||
transition-timing-function: var(--wa-transition-easing);
|
||||
|
||||
margin-inline-end: 0.5em;
|
||||
}
|
||||
|
||||
[part~='base'] {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
color: currentColor;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[part~='label'] {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* Checked */
|
||||
[part~='control']:has(:checked, :indeterminate) {
|
||||
color: var(--checked-icon-color);
|
||||
border-color: var(--wa-form-control-activated-color);
|
||||
background-color: var(--wa-form-control-activated-color);
|
||||
}
|
||||
|
||||
/* Focus */
|
||||
[part~='control']:has(> input:focus-visible:not(:disabled)) {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
/* Disabled */
|
||||
:host [part~='base']:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
display: flex;
|
||||
scale: var(--checked-icon-scale);
|
||||
|
||||
/* Without this, Safari renders the icon slightly to the left */
|
||||
&::part(svg) {
|
||||
translate: 0.0009765625em;
|
||||
}
|
||||
|
||||
input:not(:checked, :indeterminate) + & {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
:host([required]) [part~='label']::after {
|
||||
content: var(--wa-form-control-required-content);
|
||||
color: var(--wa-form-control-required-content-color);
|
||||
margin-inline-start: var(--wa-form-control-required-content-offset);
|
||||
}
|
||||
`;
|
||||
@@ -8,10 +8,10 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { RequiredValidator } from '../../internal/validators/required-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import formControlStyles from '../../styles/component/form-control.styles.js';
|
||||
import sizeStyles from '../../styles/component/size.styles.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './checkbox.css';
|
||||
import styles from './checkbox.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Checkboxes allow the user to toggle an option on or off.
|
||||
@@ -108,13 +108,6 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
|
||||
@property({ type: Boolean, reflect: true, attribute: 'checked' }) defaultChecked: boolean =
|
||||
this.hasAttribute('checked');
|
||||
|
||||
/**
|
||||
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
|
||||
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
|
||||
* the same document or shadow root for this to work.
|
||||
*/
|
||||
@property({ reflect: true }) form = null;
|
||||
|
||||
/** Makes the checkbox a required field. */
|
||||
@property({ type: Boolean, reflect: true }) required = false;
|
||||
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
:host {
|
||||
--grid-width: 17em;
|
||||
--grid-height: 12em;
|
||||
--grid-handle-size: 1.25em;
|
||||
--slider-height: 1em;
|
||||
--slider-handle-size: calc(var(--slider-height) + 0.25em);
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
box-shadow: var(--wa-shadow-m);
|
||||
color: var(--color);
|
||||
font: inherit;
|
||||
font-size: inherit;
|
||||
user-select: none;
|
||||
width: var(--grid-width);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.grid {
|
||||
position: relative;
|
||||
height: var(--grid-height);
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
|
||||
linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
|
||||
border-top-left-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
|
||||
border-top-right-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
|
||||
cursor: crosshair;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.grid-handle {
|
||||
position: absolute;
|
||||
width: var(--grid-handle-size);
|
||||
height: var(--grid-handle-size);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
border: solid 0.125rem white;
|
||||
margin-top: calc(var(--grid-handle-size) / -2);
|
||||
margin-left: calc(var(--grid-handle-size) / -2);
|
||||
transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
.grid-handle-dragging {
|
||||
cursor: none;
|
||||
scale: 1.5;
|
||||
}
|
||||
|
||||
.grid-handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding: 0.75em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sliders {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: relative;
|
||||
height: var(--slider-height);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.slider:not(:last-of-type) {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.slider-handle {
|
||||
position: absolute;
|
||||
top: calc(50% - var(--slider-handle-size) / 2);
|
||||
width: var(--slider-handle-size);
|
||||
height: var(--slider-handle-size);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
border: solid 0.125rem white;
|
||||
box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
margin-left: calc(var(--slider-handle-size) / -2);
|
||||
}
|
||||
|
||||
.slider-handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
}
|
||||
|
||||
.hue {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
rgb(255, 0, 0) 0%,
|
||||
rgb(255, 255, 0) 17%,
|
||||
rgb(0, 255, 0) 33%,
|
||||
rgb(0, 255, 255) 50%,
|
||||
rgb(0, 0, 255) 67%,
|
||||
rgb(255, 0, 255) 83%,
|
||||
rgb(255, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.alpha .alpha-gradient {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.preview {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
margin-inline-start: 0.75em;
|
||||
cursor: copy;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.preview:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
|
||||
/* We use a custom property in lieu of currentColor because of https://bugs.webkit.org/show_bug.cgi?id=216780 */
|
||||
background-color: var(--preview-color);
|
||||
}
|
||||
|
||||
.preview:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.preview-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
.preview-color-copied {
|
||||
animation: pulse 850ms;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 var(--wa-color-brand-fill-loud);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 0.5rem transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.75em 0.75em 0.75em;
|
||||
}
|
||||
|
||||
.user-input wa-input {
|
||||
min-width: 0; /* fix input width in Safari */
|
||||
flex: 1 1 auto;
|
||||
|
||||
&::part(form-control-label) {
|
||||
/* Visually hidden */
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
clip: rect(0 0 0 0) !important;
|
||||
clip-path: inset(50%) !important;
|
||||
border: none !important;
|
||||
overflow: hidden !important;
|
||||
white-space: nowrap !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input wa-button-group {
|
||||
margin-inline-start: 0.75em;
|
||||
|
||||
&::part(base) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input wa-button:first-of-type {
|
||||
min-width: 3em;
|
||||
max-width: 3em;
|
||||
}
|
||||
|
||||
.swatches {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(1.5em, 100%), 1fr));
|
||||
grid-gap: 0.5em;
|
||||
justify-items: center;
|
||||
border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
|
||||
var(--wa-color-surface-border);
|
||||
padding: 0.5em;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
position: relative;
|
||||
aspect-ratio: 1 / 1;
|
||||
width: 100%;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
}
|
||||
|
||||
.swatch .swatch-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
|
||||
border-radius: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.swatch:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.transparent-bg {
|
||||
background-image:
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%);
|
||||
background-size: 0.5rem 0.5rem;
|
||||
background-position:
|
||||
0 0,
|
||||
0 0,
|
||||
-0.25rem -0.25rem,
|
||||
0.25rem 0.25rem;
|
||||
}
|
||||
|
||||
:host([disabled]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
|
||||
.grid,
|
||||
.grid-handle,
|
||||
.slider,
|
||||
.slider-handle,
|
||||
.preview,
|
||||
.swatch,
|
||||
.swatch-color {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Color dropdown
|
||||
*/
|
||||
|
||||
.color-dropdown {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.color-dropdown::part(panel) {
|
||||
max-height: none;
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.trigger {
|
||||
display: block;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: inherit;
|
||||
forced-color-adjust: none;
|
||||
width: var(--wa-form-control-height);
|
||||
height: var(--wa-form-control-height);
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
.trigger:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background-color: currentColor;
|
||||
box-shadow:
|
||||
inset 0 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-color),
|
||||
inset 0 0 0 calc(var(--wa-form-control-border-width) * 3) var(--wa-color-surface-default);
|
||||
}
|
||||
|
||||
.trigger-empty:before {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.trigger:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.trigger:focus-visible:not(.trigger:disabled) {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
:host([disabled]) :is(.label, .trigger) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.form-control.form-control-has-label .label {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--grid-width: 17em;
|
||||
--grid-height: 12em;
|
||||
--grid-handle-size: 1.25em;
|
||||
--slider-height: 1em;
|
||||
--slider-handle-size: calc(var(--slider-height) + 0.25em);
|
||||
}
|
||||
|
||||
.color-picker {
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
border-style: var(--wa-border-style);
|
||||
border-width: var(--wa-border-width-s);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
box-shadow: var(--wa-shadow-m);
|
||||
color: var(--color);
|
||||
font: inherit;
|
||||
font-size: inherit;
|
||||
user-select: none;
|
||||
width: var(--grid-width);
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.grid {
|
||||
position: relative;
|
||||
height: var(--grid-height);
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%),
|
||||
linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
|
||||
border-top-left-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
|
||||
border-top-right-radius: calc(var(--wa-border-radius-m) - var(--wa-border-width-s));
|
||||
cursor: crosshair;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.grid-handle {
|
||||
position: absolute;
|
||||
width: var(--grid-handle-size);
|
||||
height: var(--grid-handle-size);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
border: solid 0.125rem white;
|
||||
margin-top: calc(var(--grid-handle-size) / -2);
|
||||
margin-left: calc(var(--grid-handle-size) / -2);
|
||||
transition: scale var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
.grid-handle-dragging {
|
||||
cursor: none;
|
||||
scale: 1.5;
|
||||
}
|
||||
|
||||
.grid-handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding: 0.75em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sliders {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.slider {
|
||||
position: relative;
|
||||
height: var(--slider-height);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.slider:not(:last-of-type) {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.slider-handle {
|
||||
position: absolute;
|
||||
top: calc(50% - var(--slider-handle-size) / 2);
|
||||
width: var(--slider-handle-size);
|
||||
height: var(--slider-handle-size);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
border: solid 0.125rem white;
|
||||
box-shadow: 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
margin-left: calc(var(--slider-handle-size) / -2);
|
||||
}
|
||||
|
||||
.slider-handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
}
|
||||
|
||||
.hue {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
rgb(255, 0, 0) 0%,
|
||||
rgb(255, 255, 0) 17%,
|
||||
rgb(0, 255, 0) 33%,
|
||||
rgb(0, 255, 255) 50%,
|
||||
rgb(0, 0, 255) 67%,
|
||||
rgb(255, 0, 255) 83%,
|
||||
rgb(255, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.alpha .alpha-gradient {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.preview {
|
||||
flex: 0 0 auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 3em;
|
||||
height: 3em;
|
||||
border: none;
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
margin-inline-start: 0.75em;
|
||||
cursor: copy;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.preview:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
box-shadow: inset 0 0 0 0.0625rem rgba(0, 0, 0, 0.2);
|
||||
|
||||
/* We use a custom property in lieu of currentColor because of https://bugs.webkit.org/show_bug.cgi?id=216780 */
|
||||
background-color: var(--preview-color);
|
||||
}
|
||||
|
||||
.preview:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.preview-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
.preview-color-copied {
|
||||
animation: pulse 850ms;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 var(--wa-color-brand-fill-loud);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 0.5rem transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.75em 0.75em 0.75em;
|
||||
}
|
||||
|
||||
.user-input wa-input {
|
||||
min-width: 0; /* fix input width in Safari */
|
||||
flex: 1 1 auto;
|
||||
|
||||
&::part(form-control-label) {
|
||||
/* Visually hidden */
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
clip: rect(0 0 0 0) !important;
|
||||
clip-path: inset(50%) !important;
|
||||
border: none !important;
|
||||
overflow: hidden !important;
|
||||
white-space: nowrap !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input wa-button-group {
|
||||
margin-inline-start: 0.75em;
|
||||
|
||||
&::part(base) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.user-input wa-button:first-of-type {
|
||||
min-width: 3em;
|
||||
max-width: 3em;
|
||||
}
|
||||
|
||||
.swatches {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(1.5em, 100%), 1fr));
|
||||
grid-gap: 0.5em;
|
||||
justify-items: center;
|
||||
border-block-start: var(--wa-form-control-border-style) var(--wa-form-control-border-width)
|
||||
var(--wa-color-surface-border);
|
||||
padding: 0.5em;
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
position: relative;
|
||||
aspect-ratio: 1 / 1;
|
||||
width: 100%;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
}
|
||||
|
||||
.swatch .swatch-color {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: solid 0.0625rem rgba(0, 0, 0, 0.125);
|
||||
border-radius: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.swatch:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.transparent-bg {
|
||||
background-image:
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, transparent 75%, var(--wa-color-neutral-fill-normal) 75%),
|
||||
linear-gradient(45deg, var(--wa-color-neutral-fill-normal) 25%, transparent 25%);
|
||||
background-size: 0.5rem 0.5rem;
|
||||
background-position:
|
||||
0 0,
|
||||
0 0,
|
||||
-0.25rem -0.25rem,
|
||||
0.25rem 0.25rem;
|
||||
}
|
||||
|
||||
:host([disabled]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
|
||||
.grid,
|
||||
.grid-handle,
|
||||
.slider,
|
||||
.slider-handle,
|
||||
.preview,
|
||||
.swatch,
|
||||
.swatch-color {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Color dropdown
|
||||
*/
|
||||
|
||||
.color-dropdown {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.color-dropdown::part(panel) {
|
||||
max-height: none;
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.trigger {
|
||||
display: block;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: inherit;
|
||||
forced-color-adjust: none;
|
||||
width: var(--wa-form-control-height);
|
||||
height: var(--wa-form-control-height);
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
}
|
||||
|
||||
.trigger:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background-color: currentColor;
|
||||
box-shadow:
|
||||
inset 0 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-color),
|
||||
inset 0 0 0 calc(var(--wa-form-control-border-width) * 3) var(--wa-color-surface-default);
|
||||
}
|
||||
|
||||
.trigger-empty:before {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.trigger:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.trigger:focus-visible:not(.trigger:disabled) {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
:host([disabled]) :is(.label, .trigger) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.form-control.form-control-has-label .label {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
`;
|
||||
@@ -14,9 +14,9 @@ import { HasSlotController } from '../../internal/slot.js';
|
||||
import { RequiredValidator } from '../../internal/validators/required-validator.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import formControlStyles from '../../styles/component/form-control.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import visuallyHidden from '../../styles/utilities/visually-hidden.css';
|
||||
import formControlStyles from '../../styles/component/form-control.styles.js';
|
||||
import sizeStyles from '../../styles/component/size.styles.js';
|
||||
import visuallyHidden from '../../styles/component/visually-hidden.styles.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../button-group/button-group.js';
|
||||
import '../button/button.js';
|
||||
@@ -25,7 +25,7 @@ import '../input/input.js';
|
||||
import type WaInput from '../input/input.js';
|
||||
import '../popup/popup.js';
|
||||
import type WaPopup from '../popup/popup.js';
|
||||
import styles from './color-picker.css';
|
||||
import styles from './color-picker.styles.js';
|
||||
|
||||
interface EyeDropperConstructor {
|
||||
new (): EyeDropperInterface;
|
||||
@@ -220,13 +220,6 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
*/
|
||||
@property() swatches: string | string[] = '';
|
||||
|
||||
/**
|
||||
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
|
||||
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
|
||||
* the same document or shadow root for this to work.
|
||||
*/
|
||||
@property({ reflect: true }) form = null;
|
||||
|
||||
/** Makes the color picker a required field. */
|
||||
@property({ type: Boolean, reflect: true }) required = false;
|
||||
|
||||
@@ -1284,7 +1277,14 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
|
||||
})}
|
||||
part="trigger-container form-control"
|
||||
>
|
||||
<div part="form-control-label" class="label" id="form-control-label">
|
||||
<div
|
||||
part="form-control-label"
|
||||
class=${classMap({
|
||||
label: true,
|
||||
'has-label': hasLabel,
|
||||
})}
|
||||
id="form-control-label"
|
||||
>
|
||||
<slot name="label">${this.label}</slot>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
:host {
|
||||
--divider-width: 0.125rem;
|
||||
--handle-size: 2.5rem;
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.before,
|
||||
.after {
|
||||
display: block;
|
||||
|
||||
&::slotted(img),
|
||||
&::slotted(svg) {
|
||||
display: block;
|
||||
max-width: 100% !important;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&::slotted(:not(img, svg)) {
|
||||
isolation: isolate;
|
||||
}
|
||||
}
|
||||
|
||||
.after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Disable pointer-events while dragging. This is especially important for iframes. */
|
||||
:host(:state(dragging)) {
|
||||
.before,
|
||||
.after {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: var(--divider-width);
|
||||
height: 100%;
|
||||
background-color: var(--wa-color-surface-default);
|
||||
translate: calc(var(--divider-width) / -2);
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.handle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: calc(50% - (var(--handle-size) / 2));
|
||||
width: var(--handle-size);
|
||||
height: var(--handle-size);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
font-size: calc(var(--handle-size) * 0.4);
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
cursor: inherit;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--divider-width: 0.125rem;
|
||||
--handle-size: 2.5rem;
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.before,
|
||||
.after {
|
||||
display: block;
|
||||
|
||||
&::slotted(img),
|
||||
&::slotted(svg) {
|
||||
display: block;
|
||||
max-width: 100% !important;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&::slotted(:not(img, svg)) {
|
||||
isolation: isolate;
|
||||
}
|
||||
}
|
||||
|
||||
.after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Disable pointer-events while dragging. This is especially important for iframes. */
|
||||
:host(:state(dragging)) {
|
||||
.before,
|
||||
.after {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: var(--divider-width);
|
||||
height: 100%;
|
||||
background-color: var(--wa-color-surface-default);
|
||||
translate: calc(var(--divider-width) / -2);
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.handle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: calc(50% - (var(--handle-size) / 2));
|
||||
width: var(--handle-size);
|
||||
height: var(--handle-size);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-radius: var(--wa-border-radius-circle);
|
||||
font-size: calc(var(--handle-size) * 0.4);
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
cursor: inherit;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.handle:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
`;
|
||||
@@ -7,7 +7,7 @@ import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './comparison.css';
|
||||
import styles from './comparison.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Compare visual differences between similar content with a sliding panel.
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
:host {
|
||||
display: inline-block;
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.5em;
|
||||
cursor: pointer;
|
||||
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.button:hover:not([disabled]) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
}
|
||||
|
||||
.button:focus-visible:not([disabled]) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
|
||||
.button:active:not([disabled]) {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
|
||||
}
|
||||
|
||||
slot[name='success-icon'] {
|
||||
color: var(--wa-color-success-on-quiet);
|
||||
}
|
||||
|
||||
slot[name='error-icon'] {
|
||||
color: var(--wa-color-danger-on-quiet);
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
slot {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.show {
|
||||
animation: show 100ms ease;
|
||||
}
|
||||
|
||||
.hide {
|
||||
animation: show 100ms ease reverse;
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
from {
|
||||
scale: 0.25;
|
||||
opacity: 0.25;
|
||||
}
|
||||
to {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: inline-block;
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-radius: var(--wa-form-control-border-radius);
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.5em;
|
||||
cursor: pointer;
|
||||
transition: color var(--wa-transition-fast) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.button:hover:not([disabled]) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
}
|
||||
|
||||
.button:focus-visible:not([disabled]) {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-hover));
|
||||
}
|
||||
|
||||
.button:active:not([disabled]) {
|
||||
color: color-mix(in oklab, currentColor, var(--wa-color-mix-active));
|
||||
}
|
||||
|
||||
slot[name='success-icon'] {
|
||||
color: var(--wa-color-success-on-quiet);
|
||||
}
|
||||
|
||||
slot[name='error-icon'] {
|
||||
color: var(--wa-color-danger-on-quiet);
|
||||
}
|
||||
|
||||
.button:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
slot {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.show {
|
||||
animation: show 100ms ease;
|
||||
}
|
||||
|
||||
.hide {
|
||||
animation: show 100ms ease reverse;
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
from {
|
||||
scale: 0.25;
|
||||
opacity: 0.25;
|
||||
}
|
||||
to {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -5,12 +5,12 @@ import { WaCopyEvent } from '../../events/copy.js';
|
||||
import { WaErrorEvent } from '../../events/error.js';
|
||||
import { animateWithClass } from '../../internal/animate.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import visuallyHidden from '../../styles/utilities/visually-hidden.css';
|
||||
import visuallyHidden from '../../styles/component/visually-hidden.styles.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import '../tooltip/tooltip.js';
|
||||
import type WaTooltip from '../tooltip/tooltip.js';
|
||||
import styles from './copy-button.css';
|
||||
import styles from './copy-button.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Copies text data to the clipboard when the user clicks the trigger.
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
:host {
|
||||
--spacing: var(--wa-space-m);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: block;
|
||||
}
|
||||
|
||||
details {
|
||||
display: block;
|
||||
overflow-anchor: none;
|
||||
border: var(--wa-panel-border-width) var(--wa-color-surface-border) var(--wa-panel-border-style);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
color: var(--wa-color-text-normal);
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
background: none;
|
||||
border: solid var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
|
||||
summary {
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) details {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) details {
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='filled']) details {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) details {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: var(--wa-color-neutral-border-quiet);
|
||||
}
|
||||
|
||||
:host([disabled]) details {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--spacing);
|
||||
padding: var(--spacing); /* Add padding here */
|
||||
border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(var(--wa-panel-border-width) + var(--wa-focus-ring-offset));
|
||||
}
|
||||
}
|
||||
|
||||
:host([open]) summary {
|
||||
border-end-start-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
/* 'Start' icon placement */
|
||||
:host([icon-placement='start']) summary {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--wa-color-text-quiet);
|
||||
transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
:host([open]) [part~='icon'] {
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
:host([open]:dir(rtl)) [part~='icon'] {
|
||||
rotate: -90deg;
|
||||
}
|
||||
|
||||
:host([open]) slot[name='expand-icon'],
|
||||
:host(:not([open])) slot[name='collapse-icon'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.body.animating {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: block;
|
||||
padding-block-start: var(--spacing);
|
||||
padding-inline: var(--spacing); /* Add horizontal padding */
|
||||
padding-block-end: var(--spacing); /* Add bottom padding */
|
||||
}
|
||||
126
packages/webawesome/src/components/details/details.styles.ts
Normal file
126
packages/webawesome/src/components/details/details.styles.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--spacing: var(--wa-space-m);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: block;
|
||||
}
|
||||
|
||||
details {
|
||||
display: block;
|
||||
overflow-anchor: none;
|
||||
border: var(--wa-panel-border-width) var(--wa-color-surface-border) var(--wa-panel-border-style);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
color: var(--wa-color-text-normal);
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
background: none;
|
||||
border: solid var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
|
||||
summary {
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Appearance modifiers */
|
||||
:host([appearance='plain']) details {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
:host([appearance='outlined']) details {
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border-color: var(--wa-color-surface-border);
|
||||
}
|
||||
|
||||
:host([appearance='filled']) details {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
:host([appearance='filled-outlined']) details {
|
||||
background-color: var(--wa-color-neutral-fill-quiet);
|
||||
border-color: var(--wa-color-neutral-border-quiet);
|
||||
}
|
||||
|
||||
:host([disabled]) details {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--spacing);
|
||||
padding: var(--spacing); /* Add padding here */
|
||||
border-radius: calc(var(--wa-panel-border-radius) - var(--wa-panel-border-width));
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(var(--wa-panel-border-width) + var(--wa-focus-ring-offset));
|
||||
}
|
||||
}
|
||||
|
||||
:host([open]) summary {
|
||||
border-end-start-radius: 0;
|
||||
border-end-end-radius: 0;
|
||||
}
|
||||
|
||||
/* 'Start' icon placement */
|
||||
:host([icon-placement='start']) summary {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
[part~='icon'] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--wa-color-text-quiet);
|
||||
transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
:host([open]) [part~='icon'] {
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
:host([open]:dir(rtl)) [part~='icon'] {
|
||||
rotate: -90deg;
|
||||
}
|
||||
|
||||
:host([open]) slot[name='expand-icon'],
|
||||
:host(:not([open])) slot[name='collapse-icon'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.body.animating {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: block;
|
||||
padding-block-start: var(--spacing);
|
||||
padding-inline: var(--spacing); /* Add horizontal padding */
|
||||
padding-block-end: var(--spacing); /* Add bottom padding */
|
||||
}
|
||||
`;
|
||||
@@ -13,7 +13,7 @@ import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './details.css';
|
||||
import styles from './details.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Details show a brief summary and expand to show additional content.
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
:host {
|
||||
--width: 31rem;
|
||||
--spacing: var(--wa-space-l);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host([open]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--width);
|
||||
max-width: calc(100% - var(--wa-space-2xl));
|
||||
max-height: calc(100% - var(--wa-space-2xl));
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
border: none;
|
||||
box-shadow: var(--wa-shadow-l);
|
||||
padding: 0;
|
||||
margin: auto;
|
||||
|
||||
&.show {
|
||||
animation: show-dialog var(--show-duration) ease;
|
||||
|
||||
&::backdrop {
|
||||
animation: show-backdrop var(--show-duration, 200ms) ease;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
animation: show-dialog var(--hide-duration) ease reverse;
|
||||
|
||||
&::backdrop {
|
||||
animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
&.pulse {
|
||||
animation: pulse 250ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Ensure there's enough vertical padding for phones that don't update vh when chrome appears (e.g. iPhone) */
|
||||
@media screen and (max-width: 420px) {
|
||||
.dialog {
|
||||
max-height: 80vh;
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
padding-inline-start: var(--spacing);
|
||||
padding-block-end: 0;
|
||||
|
||||
/* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
|
||||
padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
}
|
||||
|
||||
.title {
|
||||
align-self: center;
|
||||
flex: 1 1 auto;
|
||||
font-family: inherit;
|
||||
font-size: var(--wa-font-size-l);
|
||||
font-weight: var(--wa-font-weight-heading);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
align-self: start;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
gap: var(--wa-space-2xs);
|
||||
padding-inline-start: var(--spacing);
|
||||
}
|
||||
|
||||
.header-actions wa-button,
|
||||
.header-actions ::slotted(wa-button) {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--wa-space-xs);
|
||||
justify-content: end;
|
||||
padding: var(--spacing);
|
||||
padding-block-start: 0;
|
||||
}
|
||||
|
||||
.footer ::slotted(wa-button:not(:first-of-type)) {
|
||||
margin-inline-start: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.dialog::backdrop {
|
||||
/*
|
||||
NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
|
||||
remove the fallback values here.
|
||||
*/
|
||||
background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
scale: 1;
|
||||
}
|
||||
50% {
|
||||
scale: 1.02;
|
||||
}
|
||||
100% {
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-dialog {
|
||||
from {
|
||||
opacity: 0;
|
||||
scale: 0.8;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-backdrop {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.dialog {
|
||||
border: solid 1px white;
|
||||
}
|
||||
}
|
||||
187
packages/webawesome/src/components/dialog/dialog.styles.ts
Normal file
187
packages/webawesome/src/components/dialog/dialog.styles.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--width: 31rem;
|
||||
--spacing: var(--wa-space-l);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host([open]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--width);
|
||||
max-width: calc(100% - var(--wa-space-2xl));
|
||||
max-height: calc(100% - var(--wa-space-2xl));
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
border: none;
|
||||
box-shadow: var(--wa-shadow-l);
|
||||
padding: 0;
|
||||
margin: auto;
|
||||
|
||||
&.show {
|
||||
animation: show-dialog var(--show-duration) ease;
|
||||
|
||||
&::backdrop {
|
||||
animation: show-backdrop var(--show-duration, 200ms) ease;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
animation: show-dialog var(--hide-duration) ease reverse;
|
||||
|
||||
&::backdrop {
|
||||
animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
&.pulse {
|
||||
animation: pulse 250ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Ensure there's enough vertical padding for phones that don't update vh when chrome appears (e.g. iPhone) */
|
||||
@media screen and (max-width: 420px) {
|
||||
.dialog {
|
||||
max-height: 80vh;
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
display: flex;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
padding-inline-start: var(--spacing);
|
||||
padding-block-end: 0;
|
||||
|
||||
/* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
|
||||
padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
}
|
||||
|
||||
.title {
|
||||
align-self: center;
|
||||
flex: 1 1 auto;
|
||||
font-family: inherit;
|
||||
font-size: var(--wa-font-size-l);
|
||||
font-weight: var(--wa-font-weight-heading);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
align-self: start;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
gap: var(--wa-space-2xs);
|
||||
padding-inline-start: var(--spacing);
|
||||
}
|
||||
|
||||
.header-actions wa-button,
|
||||
.header-actions ::slotted(wa-button) {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--wa-space-xs);
|
||||
justify-content: end;
|
||||
padding: var(--spacing);
|
||||
padding-block-start: 0;
|
||||
}
|
||||
|
||||
.footer ::slotted(wa-button:not(:first-of-type)) {
|
||||
margin-inline-start: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.dialog::backdrop {
|
||||
/*
|
||||
NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
|
||||
remove the fallback values here.
|
||||
*/
|
||||
background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
scale: 1;
|
||||
}
|
||||
50% {
|
||||
scale: 1.02;
|
||||
}
|
||||
100% {
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-dialog {
|
||||
from {
|
||||
opacity: 0;
|
||||
scale: 0.8;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-backdrop {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.dialog {
|
||||
border: solid 1px white;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -13,7 +13,7 @@ import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../button/button.js';
|
||||
import styles from './dialog.css';
|
||||
import styles from './dialog.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Dialogs, sometimes called "modals", appear above the page and require the user's immediate attention.
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
:host {
|
||||
--color: var(--wa-color-surface-border);
|
||||
--width: var(--wa-border-width-s);
|
||||
--spacing: var(--wa-space-m);
|
||||
}
|
||||
|
||||
:host(:not([orientation='vertical'])) {
|
||||
display: block;
|
||||
border-top: solid var(--width) var(--color);
|
||||
margin: var(--spacing) 0;
|
||||
}
|
||||
|
||||
:host([orientation='vertical']) {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
border-inline-start: solid var(--width) var(--color);
|
||||
margin: 0 var(--spacing);
|
||||
min-block-size: 1lh;
|
||||
}
|
||||
23
packages/webawesome/src/components/divider/divider.styles.ts
Normal file
23
packages/webawesome/src/components/divider/divider.styles.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--color: var(--wa-color-surface-border);
|
||||
--width: var(--wa-border-width-s);
|
||||
--spacing: var(--wa-space-m);
|
||||
}
|
||||
|
||||
:host(:not([orientation='vertical'])) {
|
||||
display: block;
|
||||
border-top: solid var(--width) var(--color);
|
||||
margin: var(--spacing) 0;
|
||||
}
|
||||
|
||||
:host([orientation='vertical']) {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
border-inline-start: solid var(--width) var(--color);
|
||||
margin: 0 var(--spacing);
|
||||
min-block-size: 1lh;
|
||||
}
|
||||
`;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import styles from './divider.css';
|
||||
import styles from './divider.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Dividers are used to visually separate or group elements.
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
:host {
|
||||
--size: 25rem;
|
||||
--spacing: var(--wa-space-l);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host([open]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.drawer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border: none;
|
||||
box-shadow: var(--wa-shadow-l);
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
animation-duration: var(--show-duration);
|
||||
animation-timing-function: ease;
|
||||
|
||||
&.show::backdrop {
|
||||
animation: show-backdrop var(--show-duration, 200ms) ease;
|
||||
}
|
||||
|
||||
&.hide::backdrop {
|
||||
animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
|
||||
}
|
||||
|
||||
&.show.top {
|
||||
animation: show-drawer-from-top var(--show-duration) ease;
|
||||
}
|
||||
|
||||
&.hide.top {
|
||||
animation: show-drawer-from-top var(--hide-duration) ease reverse;
|
||||
}
|
||||
|
||||
&.show.end {
|
||||
animation: show-drawer-from-end var(--show-duration) ease;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide.end {
|
||||
animation: show-drawer-from-end var(--hide-duration) ease reverse;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.show.bottom {
|
||||
animation: show-drawer-from-bottom var(--show-duration) ease;
|
||||
}
|
||||
|
||||
&.hide.bottom {
|
||||
animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
|
||||
}
|
||||
|
||||
&.show.start {
|
||||
animation: show-drawer-from-start var(--show-duration) ease;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-end;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide.start {
|
||||
animation: show-drawer-from-start var(--hide-duration) ease reverse;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-end;
|
||||
}
|
||||
}
|
||||
|
||||
&.pulse {
|
||||
animation: pulse 250ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.top {
|
||||
top: 0;
|
||||
inset-inline-end: auto;
|
||||
bottom: auto;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.end {
|
||||
top: 0;
|
||||
inset-inline-end: 0;
|
||||
bottom: auto;
|
||||
inset-inline-start: auto;
|
||||
width: var(--size);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
top: auto;
|
||||
inset-inline-end: auto;
|
||||
bottom: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.start {
|
||||
top: 0;
|
||||
inset-inline-end: auto;
|
||||
bottom: auto;
|
||||
inset-inline-start: 0;
|
||||
width: var(--size);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding-inline-start: var(--spacing);
|
||||
padding-block-end: 0;
|
||||
|
||||
/* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
|
||||
padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
}
|
||||
|
||||
.title {
|
||||
align-self: center;
|
||||
flex: 1 1 auto;
|
||||
font: inherit;
|
||||
font-size: var(--wa-font-size-l);
|
||||
font-weight: var(--wa-font-weight-heading);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
align-self: start;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
gap: var(--wa-space-2xs);
|
||||
padding-inline-start: var(--spacing);
|
||||
}
|
||||
|
||||
.header-actions wa-button,
|
||||
.header-actions ::slotted(wa-button) {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--wa-space-xs);
|
||||
justify-content: end;
|
||||
padding: var(--spacing);
|
||||
padding-block-start: 0;
|
||||
}
|
||||
|
||||
.footer ::slotted(wa-button:not(:last-of-type)) {
|
||||
margin-inline-end: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.drawer::backdrop {
|
||||
/*
|
||||
NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
|
||||
remove the fallback values here.
|
||||
*/
|
||||
background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
scale: 1;
|
||||
}
|
||||
50% {
|
||||
scale: 1.01;
|
||||
}
|
||||
100% {
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer {
|
||||
from {
|
||||
opacity: 0;
|
||||
scale: 0.8;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-top {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 -100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-end {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-bottom {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-start {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: -100% 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-backdrop {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.drawer {
|
||||
border: solid 1px white;
|
||||
}
|
||||
}
|
||||
294
packages/webawesome/src/components/drawer/drawer.styles.ts
Normal file
294
packages/webawesome/src/components/drawer/drawer.styles.ts
Normal file
@@ -0,0 +1,294 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--size: 25rem;
|
||||
--spacing: var(--wa-space-l);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host([open]) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.drawer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
border: none;
|
||||
box-shadow: var(--wa-shadow-l);
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
animation-duration: var(--show-duration);
|
||||
animation-timing-function: ease;
|
||||
|
||||
&.show::backdrop {
|
||||
animation: show-backdrop var(--show-duration, 200ms) ease;
|
||||
}
|
||||
|
||||
&.hide::backdrop {
|
||||
animation: show-backdrop var(--hide-duration, 200ms) ease reverse;
|
||||
}
|
||||
|
||||
&.show.top {
|
||||
animation: show-drawer-from-top var(--show-duration) ease;
|
||||
}
|
||||
|
||||
&.hide.top {
|
||||
animation: show-drawer-from-top var(--hide-duration) ease reverse;
|
||||
}
|
||||
|
||||
&.show.end {
|
||||
animation: show-drawer-from-end var(--show-duration) ease;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide.end {
|
||||
animation: show-drawer-from-end var(--hide-duration) ease reverse;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.show.bottom {
|
||||
animation: show-drawer-from-bottom var(--show-duration) ease;
|
||||
}
|
||||
|
||||
&.hide.bottom {
|
||||
animation: show-drawer-from-bottom var(--hide-duration) ease reverse;
|
||||
}
|
||||
|
||||
&.show.start {
|
||||
animation: show-drawer-from-start var(--show-duration) ease;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-end;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide.start {
|
||||
animation: show-drawer-from-start var(--hide-duration) ease reverse;
|
||||
|
||||
&:dir(rtl) {
|
||||
animation-name: show-drawer-from-end;
|
||||
}
|
||||
}
|
||||
|
||||
&.pulse {
|
||||
animation: pulse 250ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.top {
|
||||
top: 0;
|
||||
inset-inline-end: auto;
|
||||
bottom: auto;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.end {
|
||||
top: 0;
|
||||
inset-inline-end: 0;
|
||||
bottom: auto;
|
||||
inset-inline-start: auto;
|
||||
width: var(--size);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
top: auto;
|
||||
inset-inline-end: auto;
|
||||
bottom: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
height: var(--size);
|
||||
}
|
||||
|
||||
.start {
|
||||
top: 0;
|
||||
inset-inline-end: auto;
|
||||
bottom: auto;
|
||||
inset-inline-start: 0;
|
||||
width: var(--size);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
padding-inline-start: var(--spacing);
|
||||
padding-block-end: 0;
|
||||
|
||||
/* Subtract the close button's padding so that the X is visually aligned with the edges of the dialog content */
|
||||
padding-inline-end: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
padding-block-start: calc(var(--spacing) - var(--wa-form-control-padding-block));
|
||||
}
|
||||
|
||||
.title {
|
||||
align-self: center;
|
||||
flex: 1 1 auto;
|
||||
font: inherit;
|
||||
font-size: var(--wa-font-size-l);
|
||||
font-weight: var(--wa-font-weight-heading);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
align-self: start;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
justify-content: end;
|
||||
gap: var(--wa-space-2xs);
|
||||
padding-inline-start: var(--spacing);
|
||||
}
|
||||
|
||||
.header-actions wa-button,
|
||||
.header-actions ::slotted(wa-button) {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--wa-space-xs);
|
||||
justify-content: end;
|
||||
padding: var(--spacing);
|
||||
padding-block-start: 0;
|
||||
}
|
||||
|
||||
.footer ::slotted(wa-button:not(:last-of-type)) {
|
||||
margin-inline-end: var(--wa-spacing-xs);
|
||||
}
|
||||
|
||||
.drawer::backdrop {
|
||||
/*
|
||||
NOTE: the ::backdrop element doesn't inherit properly in Safari yet, but it will in 17.4! At that time, we can
|
||||
remove the fallback values here.
|
||||
*/
|
||||
background-color: var(--wa-color-overlay-modal, rgb(0 0 0 / 0.25));
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
scale: 1;
|
||||
}
|
||||
50% {
|
||||
scale: 1.01;
|
||||
}
|
||||
100% {
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer {
|
||||
from {
|
||||
opacity: 0;
|
||||
scale: 0.8;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-top {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 -100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-end {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-bottom {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: 0 100%;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-drawer-from-start {
|
||||
from {
|
||||
opacity: 0;
|
||||
translate: -100% 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-backdrop {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.drawer {
|
||||
border: solid 1px white;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -13,7 +13,7 @@ import { watch } from '../../internal/watch.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import '../button/button.js';
|
||||
import styles from './drawer.css';
|
||||
import styles from './drawer.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Drawers slide in from a container to expose additional options and information.
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
:host {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
isolation: isolate;
|
||||
color: var(--wa-color-text-normal);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
var(--wa-transition-fast) background-color var(--wa-transition-easing),
|
||||
var(--wa-transition-fast) color var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host(:hover:not(:state(disabled))) {
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
}
|
||||
}
|
||||
|
||||
:host(:focus-visible) {
|
||||
z-index: 1;
|
||||
outline: var(--wa-focus-ring);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
}
|
||||
|
||||
:host(:state(disabled)) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Danger variant */
|
||||
:host([variant='danger']),
|
||||
:host([variant='danger']) #details {
|
||||
color: var(--wa-color-danger-on-quiet);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host([variant='danger']:hover) {
|
||||
background-color: var(--wa-color-danger-fill-normal);
|
||||
color: var(--wa-color-danger-on-normal);
|
||||
}
|
||||
}
|
||||
|
||||
:host([variant='danger']:focus-visible) {
|
||||
background-color: var(--wa-color-danger-fill-normal);
|
||||
color: var(--wa-color-danger-on-normal);
|
||||
}
|
||||
|
||||
:host([checkbox-adjacent]) {
|
||||
padding-inline-start: 2em;
|
||||
}
|
||||
|
||||
/* Only add padding when item actually has a submenu */
|
||||
:host([submenu-adjacent]:not(:state(has-submenu))) #details {
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
|
||||
:host(:state(has-submenu)[submenu-adjacent]) #details {
|
||||
padding-inline-end: 1.75em;
|
||||
}
|
||||
|
||||
#check {
|
||||
visibility: hidden;
|
||||
margin-inline-start: -1.5em;
|
||||
margin-inline-end: 0.5em;
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
:host(:state(checked)) #check {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#icon ::slotted(*) {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
margin-inline-end: 0.75em !important;
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
#label {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#details {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
color: var(--wa-color-text-quiet);
|
||||
font-size: var(--wa-font-size-smaller) !important;
|
||||
}
|
||||
|
||||
#details ::slotted(*) {
|
||||
margin-inline-start: 2em !important;
|
||||
}
|
||||
|
||||
/* Submenu indicator icon */
|
||||
#submenu-indicator {
|
||||
position: absolute;
|
||||
inset-inline-end: 1em;
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
/* Flip chevron icon when RTL */
|
||||
:host(:dir(rtl)) #submenu-indicator {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
/* Submenu styles */
|
||||
#submenu {
|
||||
display: flex;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-direction: column;
|
||||
width: max-content;
|
||||
margin: 0;
|
||||
padding: 0.25em;
|
||||
border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
box-shadow: var(--wa-shadow-m);
|
||||
color: var(--wa-color-text-normal);
|
||||
text-align: start;
|
||||
user-select: none;
|
||||
|
||||
/* Override default popover styles */
|
||||
&[popover] {
|
||||
margin: 0;
|
||||
inset: auto;
|
||||
padding: 0.25em;
|
||||
overflow: visible;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
&.show {
|
||||
animation: submenu-show var(--show-duration, 50ms) ease;
|
||||
}
|
||||
|
||||
&.hide {
|
||||
animation: submenu-show var(--show-duration, 50ms) ease reverse;
|
||||
}
|
||||
|
||||
/* Submenu placement transform origins */
|
||||
&[data-placement^='top'] {
|
||||
transform-origin: bottom;
|
||||
}
|
||||
|
||||
&[data-placement^='bottom'] {
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
&[data-placement^='left'] {
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
&[data-placement^='right'] {
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
&[data-placement='left-start'] {
|
||||
transform-origin: right top;
|
||||
}
|
||||
|
||||
&[data-placement='left-end'] {
|
||||
transform-origin: right bottom;
|
||||
}
|
||||
|
||||
&[data-placement='right-start'] {
|
||||
transform-origin: left top;
|
||||
}
|
||||
|
||||
&[data-placement='right-end'] {
|
||||
transform-origin: left bottom;
|
||||
}
|
||||
|
||||
/* Safe triangle styling */
|
||||
&::before {
|
||||
display: none;
|
||||
z-index: 9;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: transparent;
|
||||
content: '';
|
||||
clip-path: polygon(
|
||||
var(--safe-triangle-cursor-x, 0) var(--safe-triangle-cursor-y, 0),
|
||||
var(--safe-triangle-submenu-start-x, 0) var(--safe-triangle-submenu-start-y, 0),
|
||||
var(--safe-triangle-submenu-end-x, 0) var(--safe-triangle-submenu-end-y, 0)
|
||||
);
|
||||
pointer-events: auto; /* Enable mouse events on the triangle */
|
||||
}
|
||||
|
||||
&[data-visible]::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
::slotted(wa-dropdown-item) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
::slotted(wa-divider) {
|
||||
--spacing: 0.25em;
|
||||
}
|
||||
|
||||
@keyframes submenu-show {
|
||||
from {
|
||||
scale: 0.9;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
isolation: isolate;
|
||||
color: var(--wa-color-text-normal);
|
||||
line-height: var(--wa-line-height-condensed);
|
||||
cursor: pointer;
|
||||
transition:
|
||||
var(--wa-transition-fast) background-color var(--wa-transition-easing),
|
||||
var(--wa-transition-fast) color var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host(:hover:not(:state(disabled))) {
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
}
|
||||
}
|
||||
|
||||
:host(:focus-visible) {
|
||||
z-index: 1;
|
||||
outline: var(--wa-focus-ring);
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
}
|
||||
|
||||
:host(:state(disabled)) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Danger variant */
|
||||
:host([variant='danger']),
|
||||
:host([variant='danger']) #details {
|
||||
color: var(--wa-color-danger-on-quiet);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:host([variant='danger']:hover) {
|
||||
background-color: var(--wa-color-danger-fill-normal);
|
||||
color: var(--wa-color-danger-on-normal);
|
||||
}
|
||||
}
|
||||
|
||||
:host([variant='danger']:focus-visible) {
|
||||
background-color: var(--wa-color-danger-fill-normal);
|
||||
color: var(--wa-color-danger-on-normal);
|
||||
}
|
||||
|
||||
:host([checkbox-adjacent]) {
|
||||
padding-inline-start: 2em;
|
||||
}
|
||||
|
||||
/* Only add padding when item actually has a submenu */
|
||||
:host([submenu-adjacent]:not(:state(has-submenu))) #details {
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
|
||||
:host(:state(has-submenu)[submenu-adjacent]) #details {
|
||||
padding-inline-end: 1.75em;
|
||||
}
|
||||
|
||||
#check {
|
||||
visibility: hidden;
|
||||
margin-inline-start: -1.5em;
|
||||
margin-inline-end: 0.5em;
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
:host(:state(checked)) #check {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#icon ::slotted(*) {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
margin-inline-end: 0.75em !important;
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
#label {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#details {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
color: var(--wa-color-text-quiet);
|
||||
font-size: var(--wa-font-size-smaller) !important;
|
||||
}
|
||||
|
||||
#details ::slotted(*) {
|
||||
margin-inline-start: 2em !important;
|
||||
}
|
||||
|
||||
/* Submenu indicator icon */
|
||||
#submenu-indicator {
|
||||
position: absolute;
|
||||
inset-inline-end: 1em;
|
||||
color: var(--wa-color-neutral-on-quiet);
|
||||
font-size: var(--wa-font-size-smaller);
|
||||
}
|
||||
|
||||
/* Flip chevron icon when RTL */
|
||||
:host(:dir(rtl)) #submenu-indicator {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
/* Submenu styles */
|
||||
#submenu {
|
||||
display: flex;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex-direction: column;
|
||||
width: max-content;
|
||||
margin: 0;
|
||||
padding: 0.25em;
|
||||
border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
box-shadow: var(--wa-shadow-m);
|
||||
color: var(--wa-color-text-normal);
|
||||
text-align: start;
|
||||
user-select: none;
|
||||
|
||||
/* Override default popover styles */
|
||||
&[popover] {
|
||||
margin: 0;
|
||||
inset: auto;
|
||||
padding: 0.25em;
|
||||
overflow: visible;
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
}
|
||||
|
||||
&.show {
|
||||
animation: submenu-show var(--show-duration, 50ms) ease;
|
||||
}
|
||||
|
||||
&.hide {
|
||||
animation: submenu-show var(--show-duration, 50ms) ease reverse;
|
||||
}
|
||||
|
||||
/* Submenu placement transform origins */
|
||||
&[data-placement^='top'] {
|
||||
transform-origin: bottom;
|
||||
}
|
||||
|
||||
&[data-placement^='bottom'] {
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
&[data-placement^='left'] {
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
&[data-placement^='right'] {
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
&[data-placement='left-start'] {
|
||||
transform-origin: right top;
|
||||
}
|
||||
|
||||
&[data-placement='left-end'] {
|
||||
transform-origin: right bottom;
|
||||
}
|
||||
|
||||
&[data-placement='right-start'] {
|
||||
transform-origin: left top;
|
||||
}
|
||||
|
||||
&[data-placement='right-end'] {
|
||||
transform-origin: left bottom;
|
||||
}
|
||||
|
||||
/* Safe triangle styling */
|
||||
&::before {
|
||||
display: none;
|
||||
z-index: 9;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: transparent;
|
||||
content: '';
|
||||
clip-path: polygon(
|
||||
var(--safe-triangle-cursor-x, 0) var(--safe-triangle-cursor-y, 0),
|
||||
var(--safe-triangle-submenu-start-x, 0) var(--safe-triangle-submenu-start-y, 0),
|
||||
var(--safe-triangle-submenu-end-x, 0) var(--safe-triangle-submenu-end-y, 0)
|
||||
);
|
||||
pointer-events: auto; /* Enable mouse events on the triangle */
|
||||
}
|
||||
|
||||
&[data-visible]::before {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
::slotted(wa-dropdown-item) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
::slotted(wa-divider) {
|
||||
--spacing: 0.25em;
|
||||
}
|
||||
|
||||
@keyframes submenu-show {
|
||||
from {
|
||||
scale: 0.9;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -5,7 +5,7 @@ import { animateWithClass } from '../../internal/animate.js';
|
||||
import { HasSlotController } from '../../internal/slot.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import '../icon/icon.js';
|
||||
import styles from './dropdown-item.css';
|
||||
import styles from './dropdown-item.styles.js';
|
||||
|
||||
/**
|
||||
* @summary Represents an individual item within a dropdown menu, supporting standard items, checkboxes, and submenus.
|
||||
@@ -155,20 +155,21 @@ export default class WaDropdownItem extends WebAwesomeElement {
|
||||
|
||||
/** Opens the submenu. */
|
||||
async openSubmenu() {
|
||||
if (!this.hasSubmenu || !this.submenuElement) return;
|
||||
const submenu = this.submenuElement;
|
||||
if (!this.hasSubmenu || !submenu || !this.isConnected) return;
|
||||
|
||||
// Notify parent dropdown to handle positioning
|
||||
this.notifyParentOfOpening();
|
||||
|
||||
// Use Popover API to show the submenu
|
||||
this.submenuElement.showPopover();
|
||||
this.submenuElement.hidden = false;
|
||||
this.submenuElement.setAttribute('data-visible', '');
|
||||
submenu.showPopover?.();
|
||||
submenu.hidden = false;
|
||||
submenu.setAttribute('data-visible', '');
|
||||
this.submenuOpen = true;
|
||||
this.setAttribute('aria-expanded', 'true');
|
||||
|
||||
// Animate the submenu
|
||||
await animateWithClass(this.submenuElement, 'show');
|
||||
await animateWithClass(submenu, 'show');
|
||||
|
||||
// Set focus to the first submenu item
|
||||
setTimeout(() => {
|
||||
@@ -210,16 +211,19 @@ export default class WaDropdownItem extends WebAwesomeElement {
|
||||
|
||||
/** Closes the submenu. */
|
||||
async closeSubmenu() {
|
||||
if (!this.hasSubmenu || !this.submenuElement) return;
|
||||
const submenu = this.submenuElement;
|
||||
if (!this.hasSubmenu || !submenu) return;
|
||||
|
||||
this.submenuOpen = false;
|
||||
this.setAttribute('aria-expanded', 'false');
|
||||
|
||||
if (!this.submenuElement.hidden) {
|
||||
await animateWithClass(this.submenuElement, 'hide');
|
||||
this.submenuElement.hidden = true;
|
||||
this.submenuElement.removeAttribute('data-visible');
|
||||
this.submenuElement.hidePopover();
|
||||
if (!submenu.hidden) {
|
||||
await animateWithClass(submenu, 'hide');
|
||||
if (submenu?.isConnected) {
|
||||
submenu.hidden = true;
|
||||
submenu.removeAttribute('data-visible');
|
||||
submenu.hidePopover?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
:host {
|
||||
--show-duration: 50ms;
|
||||
--hide-duration: 50ms;
|
||||
display: contents;
|
||||
}
|
||||
|
||||
#menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: max-content;
|
||||
margin: 0;
|
||||
padding: 0.25em;
|
||||
border: var(--wa-border-style) var(--wa-border-width-s) var(--wa-color-surface-border);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
background-color: var(--wa-color-surface-raised);
|
||||
box-shadow: var(--wa-shadow-m);
|
||||
color: var(--wa-color-text-normal);
|
||||
text-align: start;
|
||||
user-select: none;
|
||||
overflow: auto;
|
||||
max-width: var(--auto-size-available-width) !important;
|
||||
max-height: var(--auto-size-available-height) !important;
|
||||
|
||||
&.show {
|
||||
animation: show var(--show-duration) ease;
|
||||
}
|
||||
|
||||
&.hide {
|
||||
animation: show var(--hide-duration) ease reverse;
|
||||
}
|
||||
|
||||
::slotted(h1),
|
||||
::slotted(h2),
|
||||
::slotted(h3),
|
||||
::slotted(h4),
|
||||
::slotted(h5),
|
||||
::slotted(h6) {
|
||||
display: block !important;
|
||||
margin: 0.25em 0 !important;
|
||||
padding: 0.25em 0.75em !important;
|
||||
color: var(--wa-color-text-quiet) !important;
|
||||
font-family: var(--wa-font-family-body) !important;
|
||||
font-weight: var(--wa-font-weight-semibold) !important;
|
||||
font-size: var(--wa-font-size-smaller) !important;
|
||||
}
|
||||
|
||||
::slotted(wa-divider) {
|
||||
--spacing: 0.25em; /* Component-specific, left as-is */
|
||||
}
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement^='top'] #menu {
|
||||
transform-origin: bottom;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement^='bottom'] #menu {
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement^='left'] #menu {
|
||||
transform-origin: right;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement^='right'] #menu {
|
||||
transform-origin: left;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement='left-start'] #menu {
|
||||
transform-origin: right top;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement='left-end'] #menu {
|
||||
transform-origin: right bottom;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement='right-start'] #menu {
|
||||
transform-origin: left top;
|
||||
}
|
||||
|
||||
wa-popup[data-current-placement='right-end'] #menu {
|
||||
transform-origin: left bottom;
|
||||
}
|
||||
|
||||
@keyframes show {
|
||||
from {
|
||||
scale: 0.9;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
scale: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user