mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-16 14:09:13 +00:00
Compare commits
12 Commits
lm/theming
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e73f329e0 | ||
|
|
23df0591a6 | ||
|
|
40ba153499 | ||
|
|
5200b95f79 | ||
|
|
ac955f7ca9 | ||
|
|
1c4b7c7410 | ||
|
|
8144ba3d69 | ||
|
|
093ed3944b | ||
|
|
6a03c17b34 | ||
|
|
71fce016cf | ||
|
|
c8ddc2c1c0 | ||
|
|
64a9374aa9 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ yarn.lock
|
||||
_bundle_
|
||||
/packages/webawesome-pro
|
||||
/packages/webawesome-app
|
||||
custom-elements.json
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
"listbox",
|
||||
"listitem",
|
||||
"litelement",
|
||||
"llm",
|
||||
"llms",
|
||||
"llmstxt",
|
||||
"longform",
|
||||
"lowercasing",
|
||||
"Lucide",
|
||||
|
||||
644
package-lock.json
generated
644
package-lock.json
generated
@@ -13,13 +13,15 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
"@custom-elements-manifest/analyzer": "^0.10.4",
|
||||
"@custom-elements-manifest/analyzer": "^0.11.0",
|
||||
"@lit-labs/eleventy-plugin-lit": "^1.0.3",
|
||||
"@lit-labs/testing": "^0.2.5",
|
||||
"@lit/react": "^1.0.8",
|
||||
"@open-wc/testing": "^3.2.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/react": "^18.2.28",
|
||||
"@wc-toolkit/cem-inheritance": "^1.2.2",
|
||||
"@wc-toolkit/type-parser": "^1.2.0",
|
||||
"@web/dev-server-esbuild": "^0.3.6",
|
||||
"@web/test-runner": "^0.19.0",
|
||||
"@web/test-runner-commands": "^0.9.0",
|
||||
@@ -32,9 +34,10 @@
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
"custom-element-jet-brains-integration": "^1.6.2",
|
||||
"custom-element-vs-code-integration": "^1.4.1",
|
||||
"custom-element-vuejs-integration": "^1.3.3",
|
||||
"custom-element-jet-brains-integration": "^1.7.0",
|
||||
"custom-element-svelte-integration": "^1.2.0",
|
||||
"custom-element-vs-code-integration": "^1.5.0",
|
||||
"custom-element-vuejs-integration": "^1.4.0",
|
||||
"del": "^7.1.0",
|
||||
"download": "^8.0.0",
|
||||
"esbuild": "0.23.1",
|
||||
@@ -1195,12 +1198,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/analyzer": {
|
||||
"version": "0.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.10.4.tgz",
|
||||
"integrity": "sha512-hse8o20Jd82BwWank29/J9OC4PmSTwUoEmll3LEjDF3WLY/Lc8g3TUYSib/3GARCS8Q5myT2RPqEWfRa+6bkIg==",
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.11.0.tgz",
|
||||
"integrity": "sha512-F2jQFk6igV5vrTZYDBLVr0GDQF3cTJ2VwwzPdsmkzUE+SHiYAQNKYebIq8qphZdJeTcZtVhvw336FQVZsMqh4A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@custom-elements-manifest/find-dependencies": "^0.0.5",
|
||||
"@custom-elements-manifest/find-dependencies": "^0.0.7",
|
||||
"@github/catalyst": "^1.6.0",
|
||||
"@web/config-loader": "0.1.3",
|
||||
"chokidar": "3.5.2",
|
||||
@@ -1313,19 +1317,49 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/find-dependencies": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/find-dependencies/-/find-dependencies-0.0.5.tgz",
|
||||
"integrity": "sha512-fKIMMZCDFSoL2ySUoz8knWgpV4jpb0lUXgLOvdZQMQFHxgxz1PqOJpUIypwvEVyKk3nEHRY4f10gNol02HjeCg==",
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@custom-elements-manifest/find-dependencies/-/find-dependencies-0.0.7.tgz",
|
||||
"integrity": "sha512-icHEBPHcOXSrpDOFkQhvM7vljEbqrEReW251RBxSzDctXzYWIL0Hk2yMDINn3d6mZ4KSsqLZlaFiGFp/2nn9rA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"es-module-lexer": "^0.9.3"
|
||||
"oxc-resolver": "^11.9.0",
|
||||
"rs-module-lexer": "^2.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@custom-elements-manifest/find-dependencies/node_modules/es-module-lexer": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
|
||||
"integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
|
||||
"dev": true
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz",
|
||||
"integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.1.0",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz",
|
||||
"integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
|
||||
"integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.23.1",
|
||||
@@ -1846,6 +1880,12 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@kurkle/color": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
|
||||
"integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lit-labs/eleventy-plugin-lit": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@lit-labs/eleventy-plugin-lit/-/eleventy-plugin-lit-1.0.5.tgz",
|
||||
@@ -2098,6 +2138,19 @@
|
||||
"integrity": "sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz",
|
||||
"integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1",
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -2184,6 +2237,289 @@
|
||||
"lit-html": "^2.0.0 || ^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-android-arm-eabi": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.16.0.tgz",
|
||||
"integrity": "sha512-/kFX4o8KISHCZzHRs8fBp/wZOPdkhYGquhMP2PQjc8ePAVbtaXXDPAFkjUKhz2jXNPS4jGA1wNW+8grhnJgstw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-android-arm64": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.16.0.tgz",
|
||||
"integrity": "sha512-kPySx7j7mPxW4mRDrdbADyzJV2XrxVeMPDmNnFvTt0/LT1IA26Uk9hzWKQb4k4aeJY58bnRY1soYSawW5wAlKQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-darwin-arm64": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.16.0.tgz",
|
||||
"integrity": "sha512-eB00fkys5TX6oI3lY+1hgHl6dwfmrbhHTmInmJmfD6BysHpE+DUqSdQIRS2v5NI6+j+J9EWBmbW3hRtolr+MSg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-darwin-x64": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.16.0.tgz",
|
||||
"integrity": "sha512-B/yMSxqe4MZfh/VoMax0qixl4XxG/sAQVlYtdVGNteBAYKfX/uw2mglkYsApk6D4qD6fVgJ21RwI50lV7oD0Qg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-freebsd-x64": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.16.0.tgz",
|
||||
"integrity": "sha512-aKj+PNsSdn0owueMt/6TtR8QuLBNL/q2HgMdN8nRCDmoCBPvQlwB2s+AcW+UW1vyiok+9qiI5tVjihbKwQ+Khg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.16.0.tgz",
|
||||
"integrity": "sha512-fxod0D0eMsIlGF98KRAwR3zjLCbpRoknDHjCHx22A9TmyQthGo7t66gwkRCj5g2LBbpaPZ+i6cYd2l9bRrx8+Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-arm-musleabihf": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.16.0.tgz",
|
||||
"integrity": "sha512-5BoVnD0hpEID/13hnj0fCIojE26wfa9p4puCnm12/D5BhGlXA103n8iRaPZPLHS/prQGtrwMiFONiysD6vmIBA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-arm64-gnu": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.16.0.tgz",
|
||||
"integrity": "sha512-dMoKX6A8iuIdShbc4PB/+q6Tx8grgQxNAJQfIAmpaDTZp5NxfgzKrssPL0TCdu3RQMblF8yfXLYUFnOdPYZeRg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-arm64-musl": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.16.0.tgz",
|
||||
"integrity": "sha512-oLJsyqVHw53ZZPl3+wPiRNXTvavBFSInRYBB5MaNf+y42+b4XJfH7hVYyc67er0c26cQUCfx2KzqltSx7Jg9jg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-ppc64-gnu": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.16.0.tgz",
|
||||
"integrity": "sha512-qL7GsXwyytVTIh/o8cLftRYvzrpniD8pFf0jDW3VXlVsl1joCrb4GM26udGls7Zxe76nsZpPvQVB5eZ9xmHxIA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-riscv64-gnu": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.16.0.tgz",
|
||||
"integrity": "sha512-CFJEvagoakxPtIoKtRgPoGUqeXSgd63c3/T9hOXrgelOaMv6aEWFfjvc/4Lk5ppk2wv4KeK4IqOKBe8Faqv1Mw==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-riscv64-musl": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.16.0.tgz",
|
||||
"integrity": "sha512-LVuE2tbZ7gjEjY1G8mjf7+pacj0/Rge9EoHxr8DY2gAxxy0qXe5Yh2Qxe3dwwFGObVNioqRH0IPkePmQ/KJK6w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-s390x-gnu": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.16.0.tgz",
|
||||
"integrity": "sha512-D4Zk48WN7sKsbyq4xD2F09U4S0sIkHXTW9A33BaqjfNXOD/jFXM5nTPahHx2RxBLo5ZEgS3kUW1U8V0oCBcPcg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-x64-gnu": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.16.0.tgz",
|
||||
"integrity": "sha512-WyqsQwz+x1lDe/rwf5pl/FiTiS4eEM7hEHn1OwjP+EThzXXBup9BeZE5QVB421QGm9n4SyJT1gJgI1LCRvqbaA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-linux-x64-musl": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.16.0.tgz",
|
||||
"integrity": "sha512-5XCuIoviaMsiAAuaQL4HqnYj1BkADcbtdf2s6Ru4YHF3P/bt2p05hd4xVo85cFT1VXlGYL66XVfepsAGymJs0g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-openharmony-arm64": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.16.0.tgz",
|
||||
"integrity": "sha512-gn54HKxOhWTxZG8pNeBMmbRwHT4k/eIf0KxBII2oHUrSTinNTcqu6xn1etqt1Yezi9KzJzkTMS0cl5kTFmCHUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-wasm32-wasi": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.16.0.tgz",
|
||||
"integrity": "sha512-dUsUjffSI7nlt+TH9C4gGqmD/kNyx3Kghh8u+i8eZZAEFWDO+s51Yw3UADDa0BYrZDeaLjz8rgHWCE8lxpL2XQ==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-win32-arm64-msvc": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.16.0.tgz",
|
||||
"integrity": "sha512-6EhsnwzA6iT752sU5tv/r+XI5cz6sWUPHJZu3brTW3m96j6yCZ8vnfeKAkFCzuDwZAXOkRLPW8WKrL0GXWfCUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-win32-ia32-msvc": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-11.16.0.tgz",
|
||||
"integrity": "sha512-YpUXuKrslGs4+In1gZhY25menhzyBbMct4RvWT9je6mYA5VCQ6aGAZf/ky5b+5sNPpR2UBNbCcYk5pP/6MowMw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@oxc-resolver/binding-win32-x64-msvc": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.16.0.tgz",
|
||||
"integrity": "sha512-x3hU0m0c/+frUSFaw3r5Xmde5q/PdsAfznh+8lZloGK2/qfIze0jyQG0H5M6AgrUIQE1oNn8vdGXanza5+naMw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@parse5/tools": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@parse5/tools/-/tools-0.3.0.tgz",
|
||||
@@ -2643,6 +2979,17 @@
|
||||
"integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.7.tgz",
|
||||
@@ -3015,12 +3362,43 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@wc-toolkit/cem-inheritance": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@wc-toolkit/cem-inheritance/-/cem-inheritance-1.2.2.tgz",
|
||||
"integrity": "sha512-Da7U9Zew9X8DhoITRemKhKOP8AFoZwuQTj164TCFUB50YJ/0LbukOhFunTzo19MHw22ohpnzAahbjofSmrKjBg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@wc-toolkit/jsdoc-tags": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@wc-toolkit/cem-validator": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@wc-toolkit/cem-validator/-/cem-validator-1.0.3.tgz",
|
||||
"integrity": "sha512-teKgwoyUaIUmJQCnYVjaxOLo6wOSNN/cCRh3jeeF84rNDuzyygl+zHfwgU5H8Z02hSvgvCJjKX+r7un9A70svw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@wc-toolkit/jsdoc-tags": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@wc-toolkit/jsdoc-tags/-/jsdoc-tags-1.1.0.tgz",
|
||||
"integrity": "sha512-7MHpQ3FtRNJBJONMChkfIWxOWy1rvDtwOJJ4ubeGJBUEj2hp8Xy/9G8GqqNvPGzp38haAfdMcmwx6rySu4AAqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@wc-toolkit/jsx-types": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@wc-toolkit/jsx-types/-/jsx-types-1.3.0.tgz",
|
||||
"integrity": "sha512-2rcRyPNEAdesFlokSSFBuCjpPPrMySk4NqyVJsqCs/WczcAUnIGwjnJk2fd/SNmzSjxGFRIFLAhXOgFOHLPvxQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@wc-toolkit/type-parser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@wc-toolkit/type-parser/-/type-parser-1.2.0.tgz",
|
||||
"integrity": "sha512-d1Vsf4bk3+fIzca14Mtg5h9rZxOATLv5V9r0KArgJYIc59HiegkyII9v4SnVw55hBVSD0j3O7RMuCAprU5572A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@web/browser-logs": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.4.0.tgz",
|
||||
@@ -4005,6 +4383,159 @@
|
||||
"integrity": "sha512-ry84Vft6xtRBbd4M/ptRodbOLodV5AD15TYhyRghCRgIcJJKmYmJ2v2BaaWxygENwh6Uq3zTfGPmlckKT/GXsQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-darwin-arm64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-darwin-arm64/-/rml-darwin-arm64-2.6.0.tgz",
|
||||
"integrity": "sha512-RuFHj6ro6Q24gPqNQGvH4uxpsvbgqBBy+ZUK+jbMuMaw4wyti7F6klQWuikBJAxhWpmRbhAB/jrq0PC82qlh5A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-darwin-x64": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-darwin-x64/-/rml-darwin-x64-2.6.0.tgz",
|
||||
"integrity": "sha512-85bsP7viqtgw5nVYBdl8I4c2+q4sYFcBMTeFnTf4RqhUUwBLerP7D+XXnWwv3waO+aZ0Fe0ij9Fji3oTiREOCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-linux-arm-gnueabihf": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-linux-arm-gnueabihf/-/rml-linux-arm-gnueabihf-2.6.0.tgz",
|
||||
"integrity": "sha512-ySI529TPraG1Mf/YiKhLLNGJ1js0Y3BnZRAihUpF4IlyFKmeL3slXEdvK2tVndyX2O21EYWv/DcSAmFMNOolfA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-linux-arm64-gnu": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-linux-arm64-gnu/-/rml-linux-arm64-gnu-2.6.0.tgz",
|
||||
"integrity": "sha512-Ytzkmty4vVWAqe+mbu/ql5dqwUH49eVgPT38uJK78LTZRsdogxlQbuAoLKlb/N8CIXAE7BRoywz3lSEGToXylw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-linux-arm64-musl": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-linux-arm64-musl/-/rml-linux-arm64-musl-2.6.0.tgz",
|
||||
"integrity": "sha512-DIBSDWlTmWk+r6Xp7mL9Cw8DdWNyJGg7YhOV1sSSRykdGs2TNtS3z0nbHRuUBMqrbtDk0IwqFSepLx12Bix/zw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-linux-x64-gnu": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-linux-x64-gnu/-/rml-linux-x64-gnu-2.6.0.tgz",
|
||||
"integrity": "sha512-8Pks6hMicFGWYQmylKul7Gmn64pG4HkRL7skVWEPAF0LZHeI5yvV/EnQUnXXbxPp4Viy2H4420jl6BVS7Uetng==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-linux-x64-musl": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-linux-x64-musl/-/rml-linux-x64-musl-2.6.0.tgz",
|
||||
"integrity": "sha512-xHX/rNKcATVrJt2no0FdO6kqnV4P5cP/3MgHA0KwhD/YJmWa66JIfWtzrPv9n/s0beGSorLkh8PLt5lVLFGvlQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-win32-arm64-msvc": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-win32-arm64-msvc/-/rml-win32-arm64-msvc-2.6.0.tgz",
|
||||
"integrity": "sha512-aIOu5frDsxRp5naN6YjBtbCHS4K2WHIx2EClGclv3wGFrOn1oSROxpVOV/MODUuWITj/26pWbZ/tnbvva6ZV8A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@xn-sakina/rml-win32-x64-msvc": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@xn-sakina/rml-win32-x64-msvc/-/rml-win32-x64-msvc-2.6.0.tgz",
|
||||
"integrity": "sha512-XXbzy2gLEs6PpHdM2IUC5QujOIjz6LpSQpJ+ow43gVc7BhagIF5YlMyTFZCbJehjK9yNgPCzdrzsukCjsH5kIA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/a-sync-waterfall": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
||||
@@ -4895,6 +5426,18 @@
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz",
|
||||
"integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
@@ -5845,6 +6388,16 @@
|
||||
"@prettier/sync": "^0.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/custom-element-svelte-integration": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/custom-element-svelte-integration/-/custom-element-svelte-integration-1.2.0.tgz",
|
||||
"integrity": "sha512-idA8o5oj8uDYPnq7zpkr03l5WHXC8X4adKJ399TtwdXmeYWKDP0VzPAVgJGj+LQaLoa2OCyHE+GMOaUS++dN1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@prettier/sync": "^0.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/custom-element-vs-code-integration": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/custom-element-vs-code-integration/-/custom-element-vs-code-integration-1.5.0.tgz",
|
||||
@@ -10878,6 +11431,38 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/oxc-resolver": {
|
||||
"version": "11.16.0",
|
||||
"resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.16.0.tgz",
|
||||
"integrity": "sha512-I4sHGa1fZUpTQ9ftS0E0cBYbBjNnIKXRSX/trFMIJDIJ4n21dCrLAZhnJS0TSfRIRqZNFyceNZr2kablfgNyTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@oxc-resolver/binding-android-arm-eabi": "11.16.0",
|
||||
"@oxc-resolver/binding-android-arm64": "11.16.0",
|
||||
"@oxc-resolver/binding-darwin-arm64": "11.16.0",
|
||||
"@oxc-resolver/binding-darwin-x64": "11.16.0",
|
||||
"@oxc-resolver/binding-freebsd-x64": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-arm-gnueabihf": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-arm-musleabihf": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-arm64-gnu": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-arm64-musl": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-ppc64-gnu": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-riscv64-gnu": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-riscv64-musl": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-s390x-gnu": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-x64-gnu": "11.16.0",
|
||||
"@oxc-resolver/binding-linux-x64-musl": "11.16.0",
|
||||
"@oxc-resolver/binding-openharmony-arm64": "11.16.0",
|
||||
"@oxc-resolver/binding-wasm32-wasi": "11.16.0",
|
||||
"@oxc-resolver/binding-win32-arm64-msvc": "11.16.0",
|
||||
"@oxc-resolver/binding-win32-ia32-msvc": "11.16.0",
|
||||
"@oxc-resolver/binding-win32-x64-msvc": "11.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/p-cancelable": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
|
||||
@@ -12149,6 +12734,28 @@
|
||||
"typescript": ">=3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/rs-module-lexer": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/rs-module-lexer/-/rs-module-lexer-2.6.0.tgz",
|
||||
"integrity": "sha512-aT0lO0icZ3Hq0IWvo+ORgVc6BJDoKfaDBdRIDQkL2PtBnFQJ0DuvExiiWI4GxjEjH8Yyro++NPArHFaD8bvS9w==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@xn-sakina/rml-darwin-arm64": "2.6.0",
|
||||
"@xn-sakina/rml-darwin-x64": "2.6.0",
|
||||
"@xn-sakina/rml-linux-arm-gnueabihf": "2.6.0",
|
||||
"@xn-sakina/rml-linux-arm64-gnu": "2.6.0",
|
||||
"@xn-sakina/rml-linux-arm64-musl": "2.6.0",
|
||||
"@xn-sakina/rml-linux-x64-gnu": "2.6.0",
|
||||
"@xn-sakina/rml-linux-x64-musl": "2.6.0",
|
||||
"@xn-sakina/rml-win32-arm64-msvc": "2.6.0",
|
||||
"@xn-sakina/rml-win32-x64-msvc": "2.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/run-async": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
|
||||
@@ -14037,9 +14644,11 @@
|
||||
"qr-creator": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wc-toolkit/cem-validator": "^1.0.3",
|
||||
"@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": {
|
||||
@@ -14055,6 +14664,7 @@
|
||||
"@lit/react": "^1.0.8",
|
||||
"@shoelace-style/animations": "^1.2.0",
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"chart.js": "^4.5.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"nanoid": "^5.1.5",
|
||||
|
||||
17
package.json
17
package.json
@@ -13,20 +13,24 @@
|
||||
"scripts": {
|
||||
"check-updates": "npx npm-check-updates --interactive --format group",
|
||||
"start": "cd packages/webawesome && npm run start",
|
||||
"start:pro": "cd packages/webawesome-pro && npm run start"
|
||||
"build": "cd packages/webawesome && npm run build",
|
||||
"start:pro": "cd packages/webawesome-pro && npm run start",
|
||||
"build:pro": "cd packages/webawesome-pro && npm run build"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
"@custom-elements-manifest/analyzer": "^0.10.4",
|
||||
"@custom-elements-manifest/analyzer": "^0.11.0",
|
||||
"@lit-labs/eleventy-plugin-lit": "^1.0.3",
|
||||
"@lit-labs/testing": "^0.2.5",
|
||||
"@lit/react": "^1.0.8",
|
||||
"@open-wc/testing": "^3.2.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/react": "^18.2.28",
|
||||
"@wc-toolkit/cem-inheritance": "^1.2.2",
|
||||
"@wc-toolkit/type-parser": "^1.2.0",
|
||||
"@web/dev-server-esbuild": "^0.3.6",
|
||||
"@web/test-runner": "^0.19.0",
|
||||
"@web/test-runner-commands": "^0.9.0",
|
||||
@@ -39,9 +43,10 @@
|
||||
"command-line-args": "^5.2.1",
|
||||
"comment-parser": "^1.4.1",
|
||||
"cspell": "^6.18.1",
|
||||
"custom-element-jet-brains-integration": "^1.6.2",
|
||||
"custom-element-vs-code-integration": "^1.4.1",
|
||||
"custom-element-vuejs-integration": "^1.3.3",
|
||||
"custom-element-jet-brains-integration": "^1.7.0",
|
||||
"custom-element-svelte-integration": "^1.2.0",
|
||||
"custom-element-vs-code-integration": "^1.5.0",
|
||||
"custom-element-vuejs-integration": "^1.4.0",
|
||||
"del": "^7.1.0",
|
||||
"download": "^8.0.0",
|
||||
"esbuild": "0.23.1",
|
||||
@@ -85,4 +90,4 @@
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { cemInheritancePlugin } from '@wc-toolkit/cem-inheritance';
|
||||
import { cemValidatorPlugin } from '@wc-toolkit/cem-validator';
|
||||
import { jsxTypesPlugin } from '@wc-toolkit/jsx-types';
|
||||
import { customElementJetBrainsPlugin } from 'custom-element-jet-brains-integration';
|
||||
import { customElementVsCodePlugin } from 'custom-element-vs-code-integration';
|
||||
// import { customElementVuejsPlugin } from 'custom-element-vuejs-integration';
|
||||
import { getTsProgram, typeParserPlugin } from '@wc-toolkit/type-parser';
|
||||
import { parse } from 'comment-parser';
|
||||
import { customElementJetBrainsPlugin } from 'custom-element-jet-brains-integration';
|
||||
import { customElementSveltePlugin } from 'custom-element-svelte-integration';
|
||||
import { customElementVsCodePlugin } from 'custom-element-vs-code-integration';
|
||||
import { customElementVuejsPlugin } from 'custom-element-vuejs-integration';
|
||||
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'));
|
||||
@@ -22,11 +27,20 @@ function replace(string, terms) {
|
||||
}
|
||||
|
||||
export default {
|
||||
globs: ['src/components/**/*.ts'],
|
||||
// `src/components/**/*.ts` will ignore src/internal breaking inheritance chains.
|
||||
globs: ['src/**/*.ts'],
|
||||
exclude: ['**/*.styles.ts', '**/*.test.ts'],
|
||||
litelement: true,
|
||||
dependencies: true,
|
||||
outdir,
|
||||
// Give the plugin access to the TypeScript type checker
|
||||
overrideModuleCreation({ ts, globs }) {
|
||||
const program = getTsProgram(ts, globs, 'tsconfig.json');
|
||||
return program.getSourceFiles().filter(sf => globs.find(glob => sf.fileName.includes(glob)));
|
||||
},
|
||||
|
||||
plugins: [
|
||||
typeParserPlugin(),
|
||||
// Append package data
|
||||
{
|
||||
name: 'wa-package-data',
|
||||
@@ -35,6 +49,11 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
cemInheritancePlugin({
|
||||
fileName: 'custom-elements.json',
|
||||
outdir,
|
||||
}),
|
||||
|
||||
// Parse custom jsDoc tags
|
||||
{
|
||||
name: 'wa-custom-tags',
|
||||
@@ -115,7 +134,6 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: 'wa-translate-module-paths',
|
||||
packageLinkPhase({ customElementsManifest }) {
|
||||
@@ -152,7 +170,6 @@ export default {
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
// Generate custom VS Code data
|
||||
customElementVsCodePlugin({
|
||||
outdir,
|
||||
@@ -167,7 +184,7 @@ export default {
|
||||
|
||||
// Generate custom JetBrains data
|
||||
customElementJetBrainsPlugin({
|
||||
outdir: './dist-cdn',
|
||||
outdir,
|
||||
excludeCss: true,
|
||||
packageJson: false,
|
||||
referencesTemplate: (_, tag) => {
|
||||
@@ -188,13 +205,27 @@ 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
|
||||
//
|
||||
// customElementVuejsPlugin({
|
||||
// outdir: './dist/types/vue',
|
||||
// fileName: 'index.d.ts',
|
||||
// componentTypePath: (_, tag) => `../../components/${tag.replace('wa-', '')}/${tag.replace('wa-', '')}.js`
|
||||
// })
|
||||
customElementVuejsPlugin({
|
||||
outdir: './dist-cdn/types/vue',
|
||||
fileName: 'index.d.ts',
|
||||
componentTypePath: (_, tag) => `../../components/${tag.replace('wa-', '')}/${tag.replace('wa-', '')}.js`,
|
||||
}),
|
||||
customElementSveltePlugin({
|
||||
outdir: './dist-cdn/types/svelte',
|
||||
fileName: 'index.d.ts',
|
||||
}),
|
||||
// cemValidatorPlugin({
|
||||
// cemFileName: "./dist-cdn/custom-elements.json"
|
||||
// }),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -41,72 +41,82 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
>
|
||||
{% block pageBanner %}
|
||||
{% if hasBanner %}
|
||||
{#- WA Launch Banner -#}
|
||||
{% include "_banner-wa-launch.njk" ignore missing %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{# wa-page-based Skip to Content #}
|
||||
{% block pageSkipToContent %}{% endblock %}
|
||||
|
||||
{% block pageHeader %}
|
||||
<header slot="header" class="wa-split">
|
||||
{# Nav toggle #}
|
||||
<wa-button appearance="plain" size="small" data-toggle-nav>
|
||||
<wa-icon name="bars" label="Toggle navigation" class="icon-default icon-embiggen"></wa-icon>
|
||||
<wa-icon name="burger" aria-hidden="true" class="icon-hover icon-embiggen"></wa-icon>
|
||||
</wa-button>
|
||||
{# wa-page-based Banner #}
|
||||
{% block pageBanner %}
|
||||
{% if hasBanner %}
|
||||
{#- WA Launch Banner -#}
|
||||
{% include "_banner-wa-launch.njk" ignore missing %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{# Logo - Desktop #}
|
||||
<a class="brand-logo wa-desktop-only" href="/" aria-label="Web Awesome">
|
||||
{% include "logo.njk" %}
|
||||
</a>
|
||||
{# wa-page-based Subheader #}
|
||||
{% block pageSubheader %}{% endblock %}
|
||||
|
||||
{#- Logo - mobile branding -#}
|
||||
<a href="/" class="brand-logo wa-mobile-only" aria-label="Web Awesome">
|
||||
{# Logo - Mobile #}
|
||||
{% include "logo-simple.njk" %}
|
||||
</a>
|
||||
{# wa-page-based Header #}
|
||||
{% block pageHeader %}
|
||||
<header slot="header" class="wa-split">
|
||||
{# Nav toggle #}
|
||||
<wa-button appearance="plain" size="small" data-toggle-nav>
|
||||
<wa-icon name="bars" label="Toggle navigation" class="icon-default icon-embiggen"></wa-icon>
|
||||
<wa-icon name="burger" aria-hidden="true" class="icon-hover icon-embiggen"></wa-icon>
|
||||
</wa-button>
|
||||
|
||||
<div id="docs-toolbar" class="wa-cluster gap-s">
|
||||
<div class="wa-desktop-only wa-cluster wa-gap-2xs">
|
||||
{% include "theme-selector.njk" %}
|
||||
{% include "color-scheme-selector.njk" %}
|
||||
{% include "github-icon-buttons.njk" %}
|
||||
</div>
|
||||
{#- Login -#}
|
||||
{% include "login-or-avatar.njk" ignore missing %}
|
||||
</div>
|
||||
</header>
|
||||
{% endblock %}
|
||||
{# Logo - Desktop #}
|
||||
<a href="/" class="brand-logo wa-desktop-only" aria-label="Web Awesome">{% include "logo.njk" %}</a>
|
||||
|
||||
{# Sidebar #}
|
||||
{% if hasSidebar %}
|
||||
{# Mobile selectors #}
|
||||
<div class="wa-mobile-only" slot="navigation-header">
|
||||
<div class="wa-cluster wa-gap-s">
|
||||
<a class="brand-logo" href="/" aria-label="Web Awesome">{% include "logo-simple.njk" %}</a>
|
||||
<div class="wa-cluster wa-gap-2xs" style="flex-wrap: nowrap;">
|
||||
{# Logo - Mobile #}
|
||||
<a href="/" class="brand-logo wa-mobile-only" aria-label="Web Awesome">{% include "logo-simple.njk" %}</a>
|
||||
|
||||
<div id="docs-toolbar" class="wa-cluster gap-s">
|
||||
<div class="wa-desktop-only wa-cluster wa-gap-2xs">
|
||||
{% include "theme-selector.njk" %}
|
||||
{% include "color-scheme-selector.njk" %}
|
||||
{% include "github-icon-buttons.njk" %}
|
||||
</div>
|
||||
|
||||
{#- Login -#}
|
||||
{% include "login-or-avatar.njk" ignore missing %}
|
||||
</div>
|
||||
</div>
|
||||
<div slot="navigation" id="sidebar" class="docs-aside" data-remember-scroll>
|
||||
{% include "sidebar.njk" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
{# Outline #}
|
||||
{% if hasOutline %}
|
||||
<aside slot="aside" id="outline" class="docs-aside">
|
||||
<nav id="outline-standard" class="outline-links">
|
||||
<h2><a href="#content">{{ title }}</a></h2>
|
||||
</nav>
|
||||
</aside>
|
||||
{% endif %}
|
||||
{# wa-page-based Navigation Header #}
|
||||
{% block pageNavigationHeader %}
|
||||
{# Sidebar - Mobile Selectors #}
|
||||
{% if hasSidebar %}
|
||||
<div class="wa-mobile-only" slot="navigation-header">
|
||||
<div class="wa-cluster wa-gap-s">
|
||||
<a class="brand-logo" href="/" aria-label="Web Awesome">{% include "logo-simple.njk" %}</a>
|
||||
<div class="wa-cluster wa-gap-2xs" style="flex-wrap: nowrap;">
|
||||
{% include "theme-selector.njk" %}
|
||||
{% include "color-scheme-selector.njk" %}
|
||||
{% include "github-icon-buttons.njk" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{# Main #}
|
||||
{# wa-page-based Navigation #}
|
||||
{% block pageNavigation %}
|
||||
{# Sidebar - Navigation #}
|
||||
{% if hasSidebar %}
|
||||
<div slot="navigation" id="sidebar" class="docs-aside" data-remember-scroll>
|
||||
{% include "sidebar.njk" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{# wa-page-based Navigation Footer #}
|
||||
{% block pageNavigationFooter %}{% endblock %}
|
||||
|
||||
{# wa-page-based Main Header #}
|
||||
{% block pageMainHeader %}{% endblock %}
|
||||
|
||||
{# wa-page-based Main Content (default) #}
|
||||
<main id="content">
|
||||
{# Expandable outline #}
|
||||
{% if hasOutline %}
|
||||
@@ -117,7 +127,10 @@
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<div id="flashes">{% server "flashes" %}</div>
|
||||
{# Flashes #}
|
||||
{% block flashes %}
|
||||
<div id="flashes">{% server "flashes" %}</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% if hasGeneratedTitle %}
|
||||
@@ -134,6 +147,24 @@
|
||||
{% block afterContent %}{% endblock %}
|
||||
</main>
|
||||
|
||||
{# wa-page-based Main Footer #}
|
||||
{% block pageMainFooter %}{% endblock %}
|
||||
|
||||
{# wa-page-based Aside #}
|
||||
{% block pageAside %}
|
||||
{# Outline #}
|
||||
{% if hasOutline %}
|
||||
<aside slot="aside" id="outline" class="docs-aside">
|
||||
<nav id="outline-standard" class="outline-links">
|
||||
<h2><a href="#content">{{ title }}</a></h2>
|
||||
</nav>
|
||||
</aside>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{# wa-page-based Footer #}
|
||||
{% block pageFooter %}{% endblock %}
|
||||
|
||||
{% include 'search.njk' %}
|
||||
|
||||
{#- Site-Wide Dialog -#}
|
||||
@@ -143,9 +174,6 @@
|
||||
|
||||
{#- Cookie Consent Dialog -#}
|
||||
{% include "cookie-consent.njk" ignore missing %}
|
||||
|
||||
{# Footer #}
|
||||
{% block pageFooter %}{% endblock %}
|
||||
</wa-page>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
{% for palette in themer.palettes %}
|
||||
<link rel="stylesheet" href="/dist/styles/color/palettes/{{palette.filename}}" />
|
||||
{% endfor %}
|
||||
|
||||
<div id="color-palettes" class="wa-stack wa-gap-xl">
|
||||
<wa-radio-group id="palette-picker" value="default" class="radio-cards">
|
||||
<span slot="label" class="wa-visually-hidden">Color Palette</span>
|
||||
<div class="wa-grid">
|
||||
{%- for palette in themer.palettes -%}
|
||||
{%- if not palette.isPro -%}
|
||||
<wa-radio value="{{ palette.name | lower }}">
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
<span>{{ palette.name }}</span>
|
||||
<div class="wa-palette-{{ palette.name | lower }} palette-preview wa-grid wa-gap-3xs">
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
</div>
|
||||
</div>
|
||||
</wa-radio>
|
||||
{%- else -%}
|
||||
{% raw %}{%- if currentUser.hasPro -%}{% endraw %}
|
||||
<wa-radio value="{{ palette.name | lower }}">
|
||||
<div class="wa-stack wa-gap-xs">
|
||||
<span>{{ palette.name }}</span>
|
||||
<div class="wa-palette-{{ palette.name | lower }} palette-preview wa-grid wa-gap-3xs">
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
<span class="preview-swatch"></span>
|
||||
</div>
|
||||
</div>
|
||||
</wa-radio>
|
||||
{% raw %}{%- endif -%}{% endraw %}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</wa-radio-group>
|
||||
|
||||
<div id="palette" class="wa-stack wa-gap-xs">
|
||||
{%- for color in themer.colors -%}
|
||||
<div class="color-scale wa-flank wa-gap-xs">
|
||||
<div class="color-name">{{ color }}</div>
|
||||
<div class="color-swatches wa-grid wa-gap-2xs">
|
||||
{%- for tint in themer.tints -%}
|
||||
<wa-copy-button
|
||||
class="color-swatch"
|
||||
copy-label="{{ color }} {{ tint }}"
|
||||
value="var(--wa-color-{{ color }}-{{ tint }})"
|
||||
style="--color: var(--wa-color-{{ color }}-{{ tint }}); --tint: '{{ tint }}'"
|
||||
>
|
||||
<span class="wa-visually-hidden">--wa-color-{{ color }}-{{ tint }}</span>
|
||||
</wa-copy-button>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
const paletteContainer = document.getElementById('color-palettes');
|
||||
const palettePreviewPicker = document.getElementById('palette-picker');
|
||||
|
||||
// Set first radio as checked and add initial palette class
|
||||
const firstPaletteRadio = palettePreviewPicker.querySelector('wa-radio');
|
||||
if (firstPaletteRadio) {
|
||||
firstPaletteRadio.checked = true;
|
||||
paletteContainer.classList.add(`wa-palette-${firstPaletteRadio.value}`);
|
||||
}
|
||||
|
||||
// Listen for radio changes
|
||||
palettePreviewPicker.addEventListener('input', function(event) {
|
||||
const selectedValue = event.target.value;
|
||||
|
||||
// Update palette container class
|
||||
const existingThemeClasses = [...paletteContainer.classList].filter(className => className.startsWith('wa-palette-'));
|
||||
existingThemeClasses.forEach(className => paletteContainer.classList.remove(className));
|
||||
paletteContainer.classList.add(`wa-palette-${selectedValue}`);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#color-palettes:has(+ *) {
|
||||
margin-block-end: var(--wa-content-spacing);
|
||||
}
|
||||
|
||||
wa-radio-group.radio-cards {
|
||||
&::part(form-control-input) {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
> .wa-grid {
|
||||
--max-column-count: 3;
|
||||
--min-column-size: 12ch;
|
||||
|
||||
--_max-gap-count: calc(var(--max-column-count) - 1);
|
||||
--_gap-width-sum: calc(var(--_max-gap-count) * var(--wa-space-m));
|
||||
--_max-column-width: calc((100% - var(--_gap-width-sum)) / var(--max-column-count));
|
||||
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(var(--min-column-size), var(--_max-column-width)), 1fr));
|
||||
}
|
||||
|
||||
wa-radio {
|
||||
display: block;
|
||||
inline-size: var(--popover-min-inline-size);
|
||||
background-color: var(--wa-form-control-background-color);
|
||||
border: var(--wa-form-control-border-width) var(--wa-form-control-border-style) var(--wa-color-neutral-border-quiet);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
padding: 0.75em;
|
||||
font-size: var(--wa-font-size-s);
|
||||
color: var(--wa-color-text-quiet);
|
||||
|
||||
&::part(control) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::part(label) {
|
||||
font-weight: var(--wa-font-weight-bold);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
&:hover {
|
||||
border-color: var(--wa-color-neutral-border-normal);
|
||||
}
|
||||
}
|
||||
|
||||
&:state(checked) {
|
||||
border-color: var(--wa-color-neutral-border-loud);
|
||||
box-shadow: 0 0 0 0.0625rem var(--wa-color-neutral-border-loud);
|
||||
color: var(--wa-color-text-normal);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: var(--wa-focus-ring-offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.palette-preview {
|
||||
--min-column-size: 0rem;
|
||||
}
|
||||
|
||||
.preview-swatch {
|
||||
aspect-ratio: 1 / 1;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
|
||||
&:nth-child(1) {
|
||||
background-color: var(--wa-color-red);
|
||||
}
|
||||
&:nth-child(2) {
|
||||
background-color: var(--wa-color-orange);
|
||||
}
|
||||
&:nth-child(3) {
|
||||
background-color: var(--wa-color-yellow);
|
||||
}
|
||||
&:nth-child(4) {
|
||||
background-color: var(--wa-color-green);
|
||||
}
|
||||
&:nth-child(5) {
|
||||
background-color: var(--wa-color-cyan);
|
||||
}
|
||||
&:nth-child(6) {
|
||||
background-color: var(--wa-color-blue);
|
||||
}
|
||||
&:nth-child(7) {
|
||||
background-color: var(--wa-color-indigo);
|
||||
}
|
||||
&:nth-child(8) {
|
||||
background-color: var(--wa-color-purple);
|
||||
}
|
||||
&:nth-child(9) {
|
||||
background-color: var(--wa-color-pink);
|
||||
}
|
||||
&:nth-child(10) {
|
||||
background-color: var(--wa-color-gray);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,302 +0,0 @@
|
||||
{% from "pro-badge.njk" import proBadge %}
|
||||
{% from "free-badge.njk" import freeBadge %}
|
||||
|
||||
<div id="using-themes">
|
||||
<fieldset class="theme-options wa-stack" style="margin-block-end: var(--wa-content-spacing);">
|
||||
<legend style="align-self: start;">Theme Options</legend>
|
||||
<wa-select id="pick-theme" label="Theme" value="default" size="small">
|
||||
<wa-badge slot="end" appearance="accent" pill class="pro pro-only-value">Pro</wa-badge>
|
||||
{%- for theme in themer.themes -%}
|
||||
{%- if not theme.isPro -%}
|
||||
<wa-option
|
||||
value="{{ theme.name | lower }}"
|
||||
data-palette="{{ theme.palette.filename | stripExtension}}"
|
||||
data-brand="{{ theme.colorBrand.color }}"
|
||||
>
|
||||
{{ theme.name | capitalize }}
|
||||
</wa-option>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{% raw %}{% if currentUser.hasPro %}{% endraw %}
|
||||
{%- for theme in themer.themes -%}
|
||||
{% if loop.first %}<wa-divider></wa-divider>{% endif %}
|
||||
{%- if theme.isPro -%}
|
||||
<wa-option
|
||||
value="{{ theme.name | lower }}"
|
||||
data-palette="{{ theme.palette.filename | stripExtension}}"
|
||||
data-brand="{{ theme.colorBrand.color }}"
|
||||
{% if theme.isPro %}data-is-pro{% endif %}
|
||||
>
|
||||
{{ theme.name | capitalize }}
|
||||
</wa-option>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{% raw %}{% endif %}{% endraw %}
|
||||
</wa-select>
|
||||
<wa-select id="pick-palette" label="Color Palette" value="default" size="small">
|
||||
<wa-badge slot="end" appearance="accent" pill class="pro pro-only-value">Pro</wa-badge>
|
||||
{%- for palette in themer.palettes -%}
|
||||
{%- if not palette.isPro -%}
|
||||
<wa-option
|
||||
value="{{ palette.name | lower }}"
|
||||
>
|
||||
{{ palette.name | capitalize }}
|
||||
</wa-option>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{% raw %}{% if currentUser.hasPro %}{% endraw %}
|
||||
{%- for palette in themer.palettes -%}
|
||||
{% if loop.first %}<wa-divider></wa-divider>{% endif %}
|
||||
{%- if palette.isPro -%}
|
||||
<wa-option
|
||||
value="{{ palette.name | lower }}"
|
||||
{% if palette.isPro %}data-is-pro{% endif %}
|
||||
>
|
||||
{{ palette.name | capitalize }}
|
||||
</wa-option>
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{% raw %}{% endif %}{% endraw %}
|
||||
</wa-select>
|
||||
<div class="wa-grid">
|
||||
{%- set colorVariants = ['brand', 'neutral', 'success', 'warning', 'danger'] -%}
|
||||
{%- for colorVariant in colorVariants -%}
|
||||
<wa-select id="pick-{{ colorVariant }}" label="{{ colorVariant | capitalize }}" size="small">
|
||||
<wa-icon slot="start" name="square" class="selected-color"></wa-icon>
|
||||
{%- for color in themer.colors -%}
|
||||
<wa-option value="{{ color }}">
|
||||
{{ color | capitalize }}
|
||||
<wa-icon slot="start" name="square" style="--color: var(--wa-color-{{ color }}); color: var(--color);"></wa-icon>
|
||||
</wa-option>
|
||||
{%- endfor -%}
|
||||
</wa-select>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<wa-tab-group>
|
||||
<wa-tab panel="cdn"><wa-icon name="rocket-launch" variant="regular"></wa-icon> CDN</wa-tab>
|
||||
<wa-tab panel="npm"><wa-icon name="box-open" variant="regular"></wa-icon> npm</wa-tab>
|
||||
<wa-tab panel="self-hosted"><wa-icon name="arrow-down-to-line" variant="regular"></wa-icon> Self-Hosted</wa-tab>
|
||||
|
||||
<wa-tab-panel name="cdn">
|
||||
<div class="wa-stack wa-gap-xl">
|
||||
<wa-callout variant="neutral" size="small" id="pro-only-callout">
|
||||
<wa-icon name="info-circle" variant="regular"></wa-icon>
|
||||
This combination can only be used on teams with a Pro subscription.
|
||||
</wa-callout>
|
||||
<div id="free-instructions">
|
||||
<strong>For projects on <wa-badge appearance="filled" variant="neutral" pill class="free">Free</wa-badge> teams:</strong>
|
||||
<ol>
|
||||
<li>Head over to your project's <wa-icon name="gear" variant="regular"></wa-icon> <strong>Settings</strong>.</li>
|
||||
<li>For <strong>Theme</strong>, select <wa-icon name="paintbrush" variant="regular"></wa-icon> <strong class="theme-name"></strong>.</li>
|
||||
<li>For <strong>Color Palette</strong>, select <wa-icon name="swatchbook" variant="regular"></wa-icon> <strong class="palette-name"></strong>.</li>
|
||||
<li>Press <strong>Save Changes</strong> to update anywhere you're using your project.</li>
|
||||
<li class="custom-variants">In your own files, apply the following classes to the <code><html></code> element:<br />
|
||||
<pre><code class="variant-classes" class="language-html"></code></pre>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div id="pro-instructions">
|
||||
<strong>For projects on <wa-badge appearance="accent" pill class="pro">Pro</wa-badge> teams:</strong>
|
||||
<ol>
|
||||
<li>Head over to your project's <wa-icon name="gear" variant="regular"></wa-icon> <strong>Settings</strong>.</li>
|
||||
<li>Press <wa-icon name="paintbrush" variant="regular"></wa-icon> <strong>Edit Your Theme</strong> to open the Theme Builder.</li>
|
||||
<li>Open <strong>Theme</strong> and select <strong class="theme-name"></strong>.</li>
|
||||
<li>Open <strong>Colors</strong>. On the <strong>Basic</strong> tab, select <strong class="palette-name"></strong>. <span class="custom-variants">On the <strong>Advanced</strong> tab, select your preferred variant colors.</span></li>
|
||||
<li>Press <strong>Save Changes</strong> to update anywhere you're using your project.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</wa-tab-panel>
|
||||
|
||||
<wa-tab-panel name="npm">
|
||||
<p>To use this theme, include the following stylesheet(s):</p>
|
||||
<pre><code id="stylesheet-imports" class="language-html"></code></pre>
|
||||
<p>Then, apply the following classes to the <code><html></code> element:</p>
|
||||
<pre><code class="html-classes" class="language-html"></code></pre>
|
||||
</wa-tab-panel>
|
||||
|
||||
<wa-tab-panel name="self-hosted">
|
||||
<p>To use this theme, include the following stylesheet(s):</p>
|
||||
<pre><code id="stylesheet-links" class="language-html"></code></pre>
|
||||
<p>Then, apply the following classes to the <code><html></code> element:</p>
|
||||
<pre><code class="html-classes" class="language-html"></code></pre>
|
||||
</wa-tab-panel>
|
||||
</wa-tab-group>
|
||||
|
||||
<script type="module">
|
||||
const themePicker = document.getElementById('pick-theme');
|
||||
const palettePicker = document.getElementById('pick-palette');
|
||||
const brandPicker = document.getElementById('pick-brand');
|
||||
const neutralPicker = document.getElementById('pick-neutral');
|
||||
const successPicker = document.getElementById('pick-success');
|
||||
const warningPicker = document.getElementById('pick-warning');
|
||||
const dangerPicker = document.getElementById('pick-danger');
|
||||
|
||||
const stylesheetLinks = document.getElementById('stylesheet-links');
|
||||
const stylesheetImports = document.getElementById('stylesheet-imports');
|
||||
const htmlClassList = document.querySelectorAll('.html-classes');
|
||||
const variantClassList = document.querySelectorAll('.variant-classes');
|
||||
const themeNames = document.querySelectorAll('.theme-name');
|
||||
const paletteNames = document.querySelectorAll('.palette-name');
|
||||
|
||||
// Default values for color variants
|
||||
const defaultColors = {
|
||||
brand: 'blue',
|
||||
neutral: 'gray',
|
||||
success: 'green',
|
||||
warning: 'yellow',
|
||||
danger: 'red'
|
||||
};
|
||||
|
||||
// Update dynamic instructions based on current picker values
|
||||
function updateInstructions() {
|
||||
const theme = themePicker.value;
|
||||
const palette = palettePicker.value;
|
||||
const brand = brandPicker.value;
|
||||
const neutral = neutralPicker.value;
|
||||
const success = successPicker.value;
|
||||
const warning = warningPicker.value;
|
||||
const danger = dangerPicker.value;
|
||||
|
||||
// Get the default palette for the selected theme
|
||||
const selectedThemeOption = themePicker.querySelector(`wa-option[value="${theme}"]`);
|
||||
const themeDefaultPalette = selectedThemeOption?.getAttribute('data-palette') || 'default';
|
||||
const proOnlyTheme = selectedThemeOption?.hasAttribute('data-is-pro') || false;
|
||||
const proOnlyPalette = palettePicker.querySelector(`wa-option[value="${palette}"]`)?.hasAttribute('data-is-pro') || false;
|
||||
|
||||
// Show/hide Pro-only callout
|
||||
const proOnlyCallout = document.getElementById('pro-only-callout');
|
||||
const freeInstructions = document.getElementById('free-instructions');
|
||||
if (proOnlyTheme || proOnlyPalette) {
|
||||
proOnlyCallout.style.display = '';
|
||||
freeInstructions.style.display = 'none';
|
||||
} else {
|
||||
proOnlyCallout.style.display = 'none';
|
||||
freeInstructions.style.display = '';
|
||||
}
|
||||
|
||||
// Show/hide Pro badge on selected Pro values
|
||||
document.querySelectorAll('.pro-only-value').forEach(badge => {
|
||||
if ((badge.parentElement.id === 'pick-theme' && proOnlyTheme) ||
|
||||
(badge.parentElement.id === 'pick-palette' && proOnlyPalette)) {
|
||||
badge.style.display = '';
|
||||
} else {
|
||||
badge.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Build stylesheet links
|
||||
const links = [`<link rel="stylesheet" href="/dist/styles/themes/${theme}.css" />`];
|
||||
const imports = [`import '@awesome.me/webawesome/dist/styles/themes/${theme}.css';`];
|
||||
|
||||
// Only include palette link if it differs from theme's default
|
||||
if (palette !== themeDefaultPalette) {
|
||||
links.push(`<link rel="stylesheet" href="/dist/styles/color/palettes/${palette}.css" />`);
|
||||
imports.push(`import '@awesome.me/webawesome/dist/styles/color/palettes/${palette}.css';`);
|
||||
}
|
||||
|
||||
stylesheetLinks.textContent = links.join('\n');
|
||||
stylesheetImports.textContent = imports.join('\n');
|
||||
|
||||
// Build HTML classes
|
||||
const classes = [`wa-theme-${theme}`];
|
||||
const variantClasses = [];
|
||||
|
||||
// Only include palette class if it differs from theme's default
|
||||
if (palette !== themeDefaultPalette) {
|
||||
classes.push(`wa-palette-${palette}`);
|
||||
}
|
||||
|
||||
// Only include color classes if they differ from defaults
|
||||
if (brand !== defaultColors.brand) {
|
||||
[classes, variantClasses].forEach(classList => classList.push(`wa-brand-${brand}`));
|
||||
}
|
||||
if (neutral !== defaultColors.neutral) {
|
||||
[classes, variantClasses].forEach(classList => classList.push(`wa-neutral-${neutral}`));
|
||||
}
|
||||
if (success !== defaultColors.success) {
|
||||
[classes, variantClasses].forEach(classList => classList.push(`wa-success-${success}`));
|
||||
}
|
||||
if (warning !== defaultColors.warning) {
|
||||
[classes, variantClasses].forEach(classList => classList.push(`wa-warning-${warning}`));
|
||||
}
|
||||
if (danger !== defaultColors.danger) {
|
||||
[classes, variantClasses].forEach(classList => classList.push(`wa-danger-${danger}`));
|
||||
}
|
||||
|
||||
htmlClassList.forEach(instance => {
|
||||
instance.textContent = `class="${classes.join(' ')}"`;
|
||||
});
|
||||
|
||||
variantClassList.forEach(instance => {
|
||||
instance.textContent = `class="${variantClasses.join(' ')}"`;
|
||||
});
|
||||
|
||||
if (variantClasses.length === 0) {
|
||||
document.querySelectorAll('.custom-variants').forEach(el => el.style.display = 'none');
|
||||
} else {
|
||||
document.querySelectorAll('.custom-variants').forEach(el => el.style.display = '');
|
||||
}
|
||||
|
||||
// Update theme and palette names in CDN instructions
|
||||
themeNames.forEach(instance => {
|
||||
instance.textContent = theme;
|
||||
instance.style.textTransform = 'capitalize';
|
||||
});
|
||||
paletteNames.forEach(instance => {
|
||||
instance.textContent = palette;
|
||||
instance.style.textTransform = 'capitalize';
|
||||
});
|
||||
|
||||
// Match color picker icons to selected palette and color
|
||||
[brandPicker, neutralPicker, successPicker, warningPicker, dangerPicker].forEach(picker => {
|
||||
const color = picker.value;
|
||||
const selectedColorIcon = picker.querySelector('wa-icon.selected-color');
|
||||
const optionsColorIcons = picker.querySelectorAll('wa-option wa-icon[slot="start"]');
|
||||
|
||||
if (selectedColorIcon) {
|
||||
selectedColorIcon.style.setProperty('color', `var(--wa-color-${color})`);
|
||||
selectedColorIcon.classList.remove(...[...selectedColorIcon.classList].filter(className => className.startsWith('wa-palette-')));
|
||||
selectedColorIcon.classList.add(`wa-palette-${palette}`);
|
||||
}
|
||||
|
||||
|
||||
optionsColorIcons.forEach(icon => {
|
||||
icon.classList.remove(...[...icon.classList].filter(className => className.startsWith('wa-palette-')));
|
||||
icon.classList.add(`wa-palette-${palette}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Set palette and brand based on theme selection
|
||||
themePicker.addEventListener('input', function() {
|
||||
const selectedOption = themePicker.querySelector(`wa-option[value="${themePicker.value}"]`);
|
||||
const palette = selectedOption.getAttribute('data-palette');
|
||||
const brand = selectedOption.getAttribute('data-brand');
|
||||
|
||||
palettePicker.value = palette;
|
||||
brandPicker.value = brand;
|
||||
|
||||
updateInstructions();
|
||||
});
|
||||
|
||||
// Update instructions when any picker changes
|
||||
[palettePicker, brandPicker, neutralPicker, successPicker, warningPicker, dangerPicker].forEach(picker => {
|
||||
picker.addEventListener('input', updateInstructions);
|
||||
});
|
||||
|
||||
// Set initial values
|
||||
themePicker.value = 'default';
|
||||
palettePicker.value = 'default';
|
||||
brandPicker.value = 'blue';
|
||||
neutralPicker.value = 'gray';
|
||||
successPicker.value = 'green';
|
||||
warningPicker.value = 'yellow';
|
||||
dangerPicker.value = 'red';
|
||||
|
||||
// Initial update
|
||||
updateInstructions();
|
||||
</script>
|
||||
@@ -1,27 +0,0 @@
|
||||
{% set colorVariants = ["brand", "neutral", "success", "warning", "danger"] %}
|
||||
|
||||
<div id="color-variants" class="wa-stack wa-gap-xs">
|
||||
{%- for colorVariant in colorVariants -%}
|
||||
<div class="color-scale wa-flank wa-gap-xs">
|
||||
<div class="color-name">{{ colorVariant }}</div>
|
||||
<div class="color-swatches wa-grid wa-gap-2xs">
|
||||
{%- for tint in themer.tints -%}
|
||||
<wa-copy-button
|
||||
class="color-swatch"
|
||||
copy-label="{{ colorVariant }} {{ tint }}"
|
||||
value="var(--wa-color-{{ colorVariant }}-{{ tint }})"
|
||||
style="--color: var(--wa-color-{{ colorVariant }}-{{ tint }}); --tint: '{{ tint }}'"
|
||||
>
|
||||
<span class="wa-visually-hidden">--wa-color-{{ colorVariant }}-{{ tint }}</span>
|
||||
</wa-copy-button>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#color-variants:has(+ *) {
|
||||
margin-block-end: var(--wa-content-spacing);
|
||||
}
|
||||
</style>
|
||||
@@ -11,6 +11,7 @@ export function getComponents() {
|
||||
const manifest = JSON.parse(readFileSync(join(distDir, 'custom-elements.json'), 'utf-8'));
|
||||
const components = [];
|
||||
|
||||
const sortByName = (a, b) => (a.name || '').localeCompare(b.name || '');
|
||||
manifest.modules?.forEach(module => {
|
||||
module.declarations?.forEach(declaration => {
|
||||
if (declaration.customElement) {
|
||||
@@ -18,7 +19,16 @@ export function getComponents() {
|
||||
declaration.path = module.path.replace(/^src\//, 'dist/').replace(/\.ts$/, '.js');
|
||||
|
||||
// Remove private members and those that lack a description
|
||||
const members = declaration.members?.filter(member => member.description && member.privacy !== 'private');
|
||||
const slots = declaration.slots?.sort(sortByName);
|
||||
const events = declaration.events?.sort(sortByName);
|
||||
const cssProperties = declaration.cssProperties?.sort(sortByName);
|
||||
const cssParts = declaration.cssParts?.sort(sortByName);
|
||||
const cssStates = declaration.cssStates?.sort(sortByName);
|
||||
const dependencies = declaration.dependencies?.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
const members = declaration.members
|
||||
?.filter(member => member.description && member.privacy !== 'private')
|
||||
?.sort(sortByName);
|
||||
const methods = members?.filter(prop => prop.kind === 'method' && prop.privacy !== 'private');
|
||||
const properties = members?.filter(prop => {
|
||||
// Look for a corresponding attribute
|
||||
@@ -31,6 +41,12 @@ export function getComponents() {
|
||||
});
|
||||
components.push({
|
||||
...declaration,
|
||||
slots,
|
||||
events,
|
||||
cssProperties,
|
||||
cssStates,
|
||||
cssParts,
|
||||
dependencies,
|
||||
methods,
|
||||
properties,
|
||||
});
|
||||
|
||||
@@ -634,68 +634,6 @@ table.colors {
|
||||
--icon-color: var(--wa-color-success-fill-quiet);
|
||||
}
|
||||
|
||||
/* Theming */
|
||||
|
||||
.color-scale.wa-flank {
|
||||
--flank-size: 6ch;
|
||||
--content-percentage: 88%;
|
||||
--reserved-tint-space: calc(var(--wa-font-size-xs) + var(--wa-space-xs)); /* TODO: rename */
|
||||
margin-bottom: var(--reserved-tint-space);
|
||||
|
||||
.color-swatches.wa-grid {
|
||||
--min-column-size: 2.5rem;
|
||||
grid-row-gap: calc(var(--reserved-tint-space) + var(--wa-space-xs));
|
||||
}
|
||||
|
||||
.color-name {
|
||||
font-weight: var(--wa-font-weight-bold);
|
||||
text-transform: capitalize;
|
||||
font-size: var(--wa-font-size-s);
|
||||
color: var(--wa-color-text-normal);
|
||||
}
|
||||
|
||||
wa-copy-button.color-swatch {
|
||||
padding: 0;
|
||||
aspect-ratio: 1;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: var(--tint);
|
||||
position: absolute;
|
||||
bottom: calc(-1 * var(--reserved-tint-space));
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: var(--wa-font-size-xs);
|
||||
line-height: 1;
|
||||
color: var(--wa-color-text-quiet);
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&::part(button) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
background-color: var(--color);
|
||||
border-radius: var(--wa-border-radius-s);
|
||||
transition: transform 0.1s ease, box-shadow 0.1s ease;
|
||||
}
|
||||
|
||||
&:hover::part(button) {
|
||||
transform: scale(1.075);
|
||||
box-shadow: var(--wa-shadow-s);
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&::part(copy-icon),
|
||||
&::part(success-icon),
|
||||
&::part(error-icon) {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Layout Examples */
|
||||
.layout-example-boundary {
|
||||
border: var(--wa-border-width-s) dashed var(--wa-color-neutral-border-normal);
|
||||
|
||||
@@ -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">
|
||||
|
||||
101
packages/webawesome/docs/docs/frameworks/angular.md
Normal file
101
packages/webawesome/docs/docs/frameworks/angular.md
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Angular
|
||||
description: Tips for using Web Awesome in your Angular app.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# Angular
|
||||
|
||||
Angular [plays nice](https://custom-elements-everywhere.com/#angular) with custom elements, so you can use Web Awesome in your Angular apps with ease.
|
||||
|
||||
## Installation
|
||||
|
||||
### Download the npm package
|
||||
|
||||
To add Web Awesome to your Angular app, install the package from npm.
|
||||
|
||||
```bash
|
||||
npm install @awesome.me/webawesome
|
||||
```
|
||||
|
||||
### Update the Angular Configuration
|
||||
|
||||
Next, [include a theme](/getting-started/themes). In this example, we'll import the light theme.
|
||||
|
||||
Its also important to load the components by using a `<script>` tag into the index.html file. However, the Angular way to do it is by adding a script configurations into your angular.json file as follows:
|
||||
|
||||
```json
|
||||
"architect": {
|
||||
"build": {
|
||||
...
|
||||
"options": {
|
||||
...
|
||||
"styles": [
|
||||
"src/styles.scss",
|
||||
"@awesome.me/webawesome/dist/styles/webawesome.css"
|
||||
]
|
||||
...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Then make sure to apply the custom elements schema as shown below.
|
||||
|
||||
```js
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
## Reference Web Awesome components in your Angular component code
|
||||
|
||||
```js
|
||||
// need to have both or Angular will tree shake the component out.
|
||||
import type { WaDrawer } from '@awesome.me/webawesome/dist/components/drawer/drawer.js';
|
||||
import "@awesome.me/webawesome/dist/components/drawer/drawer.js";
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawer-example',
|
||||
template: '<div id="page"><button (click)="showDrawer()">Show drawer</button><wa-drawer #drawer label="Drawer" class="drawer-focus" style="--size: 50vw"><p>Drawer content</p></wa-drawer></div>'
|
||||
})
|
||||
export class DrawerExampleComponent implements OnInit {
|
||||
|
||||
// use @ViewChild to get a reference to the #drawer element within component template
|
||||
@ViewChild('drawer')
|
||||
drawer?: ElementRef<WaDrawer>;
|
||||
|
||||
...
|
||||
|
||||
constructor(...) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
showDrawer() {
|
||||
// use nativeElement to access Web Awesome components
|
||||
this.drawer?.nativeElement.show();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can start using Web Awesome components in your app!
|
||||
|
||||
:::tip
|
||||
Are you using Web Awesome with Angular? [Help us improve this page!](https://github.com/shoelace-style/webawesome/blob/next/docs/frameworks/angular.md)
|
||||
:::
|
||||
193
packages/webawesome/docs/docs/frameworks/react.md
Normal file
193
packages/webawesome/docs/docs/frameworks/react.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: React
|
||||
description: Tips for using Web Awesome in your React app.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# React
|
||||
|
||||
Web Awesome offers a React version of every component to provide an idiomatic experience for React users. You can easily toggle between HTML and React examples throughout the documentation.
|
||||
|
||||
## Installation
|
||||
|
||||
To add Web Awesome to your React app, install the package from npm.
|
||||
|
||||
```bash
|
||||
npm install @awesome.me/webawesome
|
||||
```
|
||||
|
||||
Next, import the Web Awesome stylesheet, import the components you need, and then start using Web Awesome!
|
||||
|
||||
```jsx
|
||||
// App.jsx (React 19, using native custom elements)
|
||||
import '@awesome.me/webawesome/dist/styles/webawesome.css';
|
||||
import '@awesome.me/webawesome/dist/components/button/button.js';
|
||||
|
||||
export default function App () {
|
||||
return <wa-button>I'm a button!</wa-button>
|
||||
}
|
||||
```
|
||||
|
||||
Now you can start using components!
|
||||
|
||||
### Preact
|
||||
|
||||
Preact users facing type errors using components may benefit from setting "paths" in their tsconfig.json so that react types will instead resolve to preact/compat as described in [Preact's typescript documentation](https://preactjs.com/guide/v10/typescript/#typescript-preactcompat-configuration).
|
||||
|
||||
## Usage
|
||||
|
||||
### Importing Components
|
||||
|
||||
Every Web Awesome component is available to import as a React component. Note that we're importing the `<WaButton>` _React component_ instead of the `<wa-button>` _custom element_ in the example below.
|
||||
|
||||
```jsx
|
||||
import WaButton from '@awesome.me/webawesome/react/button/index.js';
|
||||
|
||||
const MyComponent = () => <WaButton variant="primary">Click me</WaButton>;
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
#### Notes about tree shaking
|
||||
|
||||
Previously, it was recommended to import from a single entrypoint like so:
|
||||
|
||||
```jsx
|
||||
import { WaButton } from '@awesome.me/webawesome/dist/react';
|
||||
```
|
||||
|
||||
However, tree-shaking extra Web Awesome components proved to be a challenge. As a result, we now recommend cherry-picking components you want to use, rather than importing from a single entrypoint.
|
||||
|
||||
```diff
|
||||
- import { WaButton } from '@awesome.me/webawesome/dist/react';
|
||||
+ import WaButton from '@awesome.me/webawesome/dist/react/button/index.js';
|
||||
```
|
||||
|
||||
You can find a copy + paste import for each component in the "importing" section of its documentation.
|
||||
|
||||
### Event Handling
|
||||
|
||||
Many Web Awesome components emit [native events](https://developer.mozilla.org/en-US/docs/Web/API/Event). For example, the [input component](/components/input) emits the `input` event when it receives input. In React, you can listen for the event using `onInput`.
|
||||
|
||||
Here's how you can bind the input's value to a state variable.
|
||||
|
||||
```jsx
|
||||
import { useState } from 'react';
|
||||
import WaInput from '@awesome.me/webawesome/dist/react/input/index.js';
|
||||
|
||||
function MyComponent() {
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
return <>
|
||||
<WaInput value={value} onInput={event => setValue(event.target.value)} />;
|
||||
<WaInput defaultValue={"Foo"} /> {/* This is an "uncontrolled input" */}
|
||||
</>
|
||||
}
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
If you're using TypeScript, it's important to note that `event.target` will be a reference to the underlying custom element. You can use `(event.target as any).value` as a quick fix, or you can strongly type the event target as shown below.
|
||||
|
||||
```tsx
|
||||
import { useState } from 'react';
|
||||
import WaInput from '@awesome.me/webawesome/dist/react/input/index.js';
|
||||
import type WaInputElement from '@awesome.me/webawesome/dist/components/input/input.js';
|
||||
|
||||
function MyComponent() {
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
return <WaInput value={value} onInput={event => setValue((event.target as WaInputElement).value)} />;
|
||||
}
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
You can also import the event type for use in your callbacks, shown below.
|
||||
|
||||
```tsx
|
||||
import { useCallback, useState } from 'react';
|
||||
import WaInput, { type WaInputEvent } from '@awesome.me/webawesome/dist/react/input/index.js';
|
||||
import type WaInputElement from '@awesome.me/webawesome/dist/components/input/input.js';
|
||||
|
||||
function MyComponent() {
|
||||
const [value, setValue] = useState('');
|
||||
const onInput = useCallback((event: WaInputEvent) => {
|
||||
setValue(event.detail);
|
||||
}, []);
|
||||
|
||||
return <WaInput value={value} onInput={event => setValue((event.target as WaInputElement).value)} />;
|
||||
}
|
||||
|
||||
export default MyComponent;
|
||||
```
|
||||
|
||||
## Testing with Jest
|
||||
|
||||
Testing with web components can be challenging if your test environment runs in a Node environment (i.e. it doesn't run in a real browser). Fortunately, [Jest](https://jestjs.io/) has made a number of strides to support web components and provide additional browser APIs. However, it's still not a complete replication of a browser environment.
|
||||
|
||||
Here are some tips that will help smooth things over if you're having trouble with Jest + Web Awesome.
|
||||
|
||||
:::tip
|
||||
If you're looking for a fast, modern testing alternative, consider [Web Test Runner](https://modern-web.dev/docs/test-runner/overview/).
|
||||
:::
|
||||
|
||||
### Upgrade Jest
|
||||
|
||||
Jest underwent a major revamp and received support for web components in [version 26.5.0](https://github.com/facebook/jest/blob/main/CHANGELOG.md#2650) when it introduced [JSDOM 16.2.0](https://github.com/jsdom/jsdom/blob/master/Changelog.md#1620). This release also included a number of mocks for built-in browser functions such as `MutationObserver`, `document.createRange`, and others.
|
||||
|
||||
If you're using [Create React App](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app), you can update `react-scripts` which will also update Jest.
|
||||
|
||||
```
|
||||
npm install react-scripts@latest
|
||||
```
|
||||
|
||||
### Mock Missing APIs
|
||||
|
||||
Some components use `window.matchMedia`, but this function isn't supported by JSDOM so you'll need to mock it yourself.
|
||||
|
||||
In `src/setupTests.js`, add the following.
|
||||
|
||||
```js
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation(query => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // deprecated
|
||||
removeListener: jest.fn(), // deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn()
|
||||
}))
|
||||
});
|
||||
```
|
||||
|
||||
For more details, refer to Jest's [manual mocking](https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom) documentation.
|
||||
|
||||
### Transform ES Modules
|
||||
|
||||
ES Modules are a [well-supported browser standard](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/). This is how Web Awesome is distributed, but most React apps expect CommonJS. As a result, you'll probably run into the following error.
|
||||
|
||||
```
|
||||
Error: Unable to import outside of a module
|
||||
```
|
||||
|
||||
To fix this, add the following to your `package.json` which tells the transpiler to process Web Awesome modules.
|
||||
|
||||
```js
|
||||
{
|
||||
"jest": {
|
||||
"transformIgnorePatterns": ["node_modules/(?!(@awesome.me|lit|@lit-labs))"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These instructions are for apps created via Create React App. If you're using Jest directly, you can add `transformIgnorePatterns` directly into `jest.config.js`.
|
||||
|
||||
For more details, refer to Jest's [`transformIgnorePatterns` customization](https://jestjs.io/docs/tutorial-react-native#transformignorepatterns-customization) documentation.
|
||||
|
||||
:::tip
|
||||
Are you using Web Awesome with React? [Help us improve this page!](https://github.com/shoelace-style/webawesome/blob/next/docs/frameworks/react.md)
|
||||
:::
|
||||
90
packages/webawesome/docs/docs/frameworks/svelte.md
Normal file
90
packages/webawesome/docs/docs/frameworks/svelte.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Svelte
|
||||
description: Tips for using Web Awesome in your Svelte app.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# Svelte
|
||||
|
||||
Svelte [plays nice](https://custom-elements-everywhere.com/#svelte) with custom elements, so you can use Web Awesome in your Svelte apps with ease.
|
||||
|
||||
## Installation
|
||||
|
||||
To add Web Awesome to your Svelte app, install the package from npm.
|
||||
|
||||
```bash
|
||||
npm install @awesome.me/webawesome
|
||||
```
|
||||
|
||||
Next, import the Web Awesome stylesheet, import the components you need, and then start using Web Awesome!
|
||||
|
||||
```jsx
|
||||
// main.js or main.ts
|
||||
import '@awesome.me/webawesome/dist/styles/webawesome.css';
|
||||
import '@awesome.me/webawesome/dist/components/button/button.js';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### QR code generator example
|
||||
|
||||
```jsx
|
||||
<h1>Live editing</h1>
|
||||
|
||||
<wa-input label="Message" value={message} oninput={event => message = event.target.value}></wa-input>
|
||||
|
||||
<wa-alert open>
|
||||
<wa-icon slot="icon" name="info-circle"></wa-icon>
|
||||
{message}
|
||||
</wa-alert>
|
||||
|
||||
<script>
|
||||
import '@awesome.me/webawesome/dist/components/alert/alert.js'
|
||||
import '@awesome.me/webawesome/dist/components/input/input.js';
|
||||
|
||||
let message = $state('')
|
||||
</script>
|
||||
```
|
||||
|
||||
### Two-way Binding
|
||||
|
||||
One caveat is there's currently Svelte only supports `bind:value` directive in `<input>`, `<textarea>` and `<select>`, but you can still achieve two-way binding manually.
|
||||
|
||||
```jsx
|
||||
// ❌ These do not work
|
||||
<wa-input bind:value="name"></wa-input>
|
||||
|
||||
<wa-select bind:value="job">
|
||||
<wa-option value="designer">Designer</wa-option>
|
||||
<wa-option value="developer">Developer</wa-option>
|
||||
</wa-select>
|
||||
|
||||
// ✅ These are a bit longer, but work
|
||||
<wa-input value={name} oninput={event => name = event.target.value}></wa-input>
|
||||
|
||||
<wa-select value={job} oninput={event => job = event.target.value}>
|
||||
<wa-option value="designer">Designer</wa-option>
|
||||
<wa-option value="developer">Developer</wa-option>
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
:::tip
|
||||
Are you using Web Awesome with Svelte? [Help us improve this page!](https://github.com/shoelace-style/webawesome/blob/next/docs/frameworks/svelte.md)
|
||||
:::
|
||||
|
||||
### Slots
|
||||
|
||||
Slots in Web Awesome/web components are functionally the same as basic slots in Svelte. Slots can be assigned to elements using the `slot` attribute followed by the name of the slot it is being assigned to.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```jsx
|
||||
<wa-drawer label="Drawer" placement="start" class="drawer-placement-start" bind:open={drawerIsOpen}>
|
||||
This drawer slides in from the start.
|
||||
<div slot="footer">
|
||||
<wa-button variant="primary" onclick={() => (drawerIsOpen = false)}>
|
||||
Close
|
||||
</wa-button>
|
||||
</div>
|
||||
</wa-drawer>
|
||||
```
|
||||
102
packages/webawesome/docs/docs/frameworks/vue-2.md
Normal file
102
packages/webawesome/docs/docs/frameworks/vue-2.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Vue (version 2)
|
||||
description: Tips for using Web Awesome in your Vue 2 app.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# Vue (version 2)
|
||||
|
||||
Vue [plays nice](https://custom-elements-everywhere.com/#vue) with custom elements, so you can use Web Awesome in your Vue apps with ease.
|
||||
|
||||
:::tip
|
||||
These instructions are for Vue 2. If you're using Vue 3 or above, please see the [Vue 3 instructions](/frameworks/vue).
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
To add Web Awesome to your Vue app, install the package from npm.
|
||||
|
||||
```bash
|
||||
npm install @awesome.me/webawesome
|
||||
```
|
||||
|
||||
Next, import the Web Awesome stylesheet, import the components you need, and then start using Web Awesome!
|
||||
|
||||
```jsx
|
||||
// main.js or main.ts
|
||||
import '@awesome.me/webawesome/dist/styles/webawesome.css';
|
||||
import '@awesome.me/webawesome/dist/components/button/button.js';
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
You'll need to tell Vue to ignore Web Awesome components. This is pretty easy because they all start with `wa-`.
|
||||
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import App from './App.vue';
|
||||
|
||||
Vue.config.ignoredElements = [/wa-/];
|
||||
|
||||
const app = new Vue({
|
||||
render: h => h(App)
|
||||
});
|
||||
|
||||
app.$mount('#app');
|
||||
```
|
||||
|
||||
Now you can start using Web Awesome components in your app!
|
||||
|
||||
## Usage
|
||||
|
||||
### Binding Complex Data
|
||||
|
||||
When binding complex data such as objects and arrays, use the `.prop` modifier to make Vue bind them as a property instead of an attribute.
|
||||
|
||||
```html
|
||||
<wa-color-picker :swatches.prop="mySwatches" />
|
||||
```
|
||||
|
||||
### Two-way Binding
|
||||
|
||||
One caveat is there's currently [no support for v-model on custom elements](https://github.com/vuejs/vue/issues/7830), but you can still achieve two-way binding manually.
|
||||
|
||||
```html
|
||||
<!-- ❌ This doesn't work -->
|
||||
<wa-input v-model="name"></wa-input>
|
||||
<!-- ✅ This works, but it's a bit longer -->
|
||||
<wa-input :value="name" @input="name = $event.target.value"></wa-input>
|
||||
```
|
||||
|
||||
If that's too verbose for your liking, you can use a custom directive instead. [This utility](https://www.npmjs.com/package/@shoelace-style/vue-sl-model) adds a custom directive that will work just like `v-model` but for Web Awesome components. To install it, use this command.
|
||||
|
||||
```bash
|
||||
npm install @shoelace-style/vue-sl-model@1
|
||||
```
|
||||
|
||||
Next, import the directive and enable it like this.
|
||||
|
||||
```js
|
||||
import Vue from 'vue';
|
||||
import Web AwesomeModelDirective from '@shoelace-style/vue-sl-model';
|
||||
import App from './App.vue';
|
||||
|
||||
Vue.use(Web AwesomeModelDirective);
|
||||
Vue.config.ignoredElements = [/wa-/];
|
||||
|
||||
const app = new Vue({
|
||||
render: h => h(App)
|
||||
});
|
||||
|
||||
app.$mount('#app');
|
||||
```
|
||||
|
||||
Now you can use the `v-sl-model` directive to keep your data in sync!
|
||||
|
||||
```html
|
||||
<wa-input v-sl-model="name"></wa-input>
|
||||
```
|
||||
|
||||
:::tip
|
||||
Are you using Web Awesome with Vue 2? [Help us improve this page!](https://github.com/shoelace-style/shoelace/blob/next/docs/frameworks/vue-2.md)
|
||||
:::
|
||||
119
packages/webawesome/docs/docs/frameworks/vue.md
Normal file
119
packages/webawesome/docs/docs/frameworks/vue.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Vue
|
||||
description: Tips for using Web Awesome in your Vue 3 app.
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
# Vue
|
||||
|
||||
Vue [plays nice](https://custom-elements-everywhere.com/#vue) with custom elements, so you can use Web Awesome in your Vue apps with ease.
|
||||
|
||||
:::tip
|
||||
These instructions are for Vue 3 and above. If you're using Vue 2, please see the [Vue 2 instructions](/frameworks/vue-2).
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
To add Web Awesome to your Vue app, install the package from npm.
|
||||
|
||||
```bash
|
||||
npm install @awesome.me/webawesome
|
||||
```
|
||||
|
||||
Next, import the Web Awesome stylesheet, import the components you need, and then start using Web Awesome!
|
||||
|
||||
```jsx
|
||||
// main.js or main.ts
|
||||
import '@awesome.me/webawesome/dist/styles/webawesome.css';
|
||||
import '@awesome.me/webawesome/dist/components/button/button.js';
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
If you haven't configured your Vue.js project to work with custom elements/web components, follow [the instructions here](https://vuejs.org/guide/extras/web-components.html#using-custom-elements-in-vue) based on your project type to ensure your project will not throw an error when it encounters a custom element.
|
||||
|
||||
Now you can start using Web Awesome components in your app!
|
||||
|
||||
## Types
|
||||
|
||||
Once you have configured your application for custom elements, you should be able to use Shoelace in your application without it causing any errors. Unfortunately, this doesn't register the custom elements to behave like components built using Vue. To provide autocomplete information and type safety for your components, you can import the Shoelace Vue types into your `tsconfig.json` to get better integration in your standard Vue and JSX templates.
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"types": ["@awesome.me/webawesome/dist/types/vue/index.d.ts"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### QR code generator example
|
||||
|
||||
```html
|
||||
<template>
|
||||
<div class="container">
|
||||
<h1>QR code generator</h1>
|
||||
|
||||
<wa-input maxlength="255" clearable label="Value" v-model="qrCode"></wa-input>
|
||||
|
||||
<wa-qr-code :value="qrCode"></wa-qr-code>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import '@awesome.me/webawesome/dist/components/qr-code/qr-code.js';
|
||||
import '@awesome.me/webawesome/dist/components/input/input.js';
|
||||
|
||||
const qrCode = ref();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### Binding Complex Data
|
||||
|
||||
When binding complex data such as objects and arrays, use the `.prop` modifier to make Vue bind them as a property instead of an attribute.
|
||||
|
||||
```html
|
||||
<wa-color-picker :swatches.prop="mySwatches" />
|
||||
```
|
||||
|
||||
### Two-way Binding
|
||||
|
||||
One caveat is there's currently [varying levels of support for v-model on custom elements](https://github.com/vuejs/vue/issues/7830), but you can still achieve two-way binding manually.
|
||||
|
||||
```html
|
||||
<!-- ❌ This doesn't work -->
|
||||
<wa-input v-model="name"></wa-input>
|
||||
<!-- ✅ This works, but it's a bit longer -->
|
||||
<wa-input :value="name" @input="name = $event.target.value"></wa-input>
|
||||
```
|
||||
|
||||
<!-- Remove this until we can test it works, and if there is interest. Vue3 kinda clobbered it all up
|
||||
If that's too verbose for your liking, you can use a custom directive instead. [This utility](https://www.npmjs.com/package/@shoelace-style/vue-wa-model) adds a custom directive that will work just like `v-model` but for Web Awesome components. -->
|
||||
|
||||
### Slots
|
||||
|
||||
Slots in Web Awesome / web components are functionally the same as basic slots in Vue. Slots can be assigned to elements using the `slot` attribute followed by the name of the slot it is being assigned to.
|
||||
|
||||
Here is an example:
|
||||
|
||||
```html
|
||||
<wa-drawer label="Drawer" placement="start" class="drawer-placement-start" :open="drawerIsOpen">
|
||||
This drawer slides in from the start.
|
||||
<div slot="footer">
|
||||
<wa-button variant="primary" @click=" drawerIsOpen = false">Close</wa-button>
|
||||
</div>
|
||||
</wa-drawer>
|
||||
```
|
||||
|
||||
:::tip
|
||||
Are you using Web Awesome with Vue? [Help us improve this page!](https://github.com/shoelace-style/webawesome/blob/next/docs/frameworks/vue.md)
|
||||
:::
|
||||
@@ -13,17 +13,27 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
|
||||
|
||||
## Next
|
||||
|
||||
- Added types for Vue and Svelte generated by CEM [pr:]
|
||||
- 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]
|
||||
- [Docs]: component APIs like slots, state, methods, etc, are now alphabetized [pr:1895]
|
||||
- [Docs]: component APIs now properly check their inheritance chain [pr:1895]
|
||||
- [Docs]: Included framework specific documentation for Svelte, Vue, and Angular. [pr:1895]
|
||||
- Fixed a bug in `<wa-dropdown>` where submenu detection would not work in shadow dom. [pr:]
|
||||
- Fixed a bug in `<wa-combobox>` that prevented the listbox from opening when options were preselected [issue:1883]
|
||||
- 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]
|
||||
- Improved the Persian translation [#1923]
|
||||
- Modified `wa-align-items-*` utility classes to apply `display: flex` by default [pr:1943]
|
||||
|
||||
## 3.1.0
|
||||
@@ -46,6 +56,7 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
|
||||
- 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]
|
||||
- Fixed a bug where the build script was not building `/dist/(utilities|events).js` [pr:1816]
|
||||
- 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]
|
||||
|
||||
@@ -531,4 +542,4 @@ Many of these changes and improvements were the direct result of feedback from u
|
||||
|
||||
</details>
|
||||
|
||||
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions)
|
||||
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions)
|
||||
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,165 +0,0 @@
|
||||
---
|
||||
title: Theming
|
||||
description: TODO
|
||||
layout: page-outline
|
||||
---
|
||||
|
||||
Web Awesome themes apply a cohesive look and feel across the entire library. A theme is a collection of predefined CSS custom properties that cover a range of styles from colors to transitions. We call these CSS custom properties design tokens.
|
||||
|
||||
There are 11 handcrafted themes to choose from; 3 are free to use with an additional 9 available in Web Awesome Pro. You can also build your own manually with CSS or with our Pro Theme Builder.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
Themes are made up of several layers of increasing specificity, each represented by a CSS class on the document.
|
||||
|
||||
### Color Palette
|
||||
`.wa-palette-{name}`
|
||||
|
||||
Color palettes give you a full spectrum of colors to use in your project. A color palette defines 10 hues — red, orange, yellow, green, cyan, blue, indigo, purple, pink, and gray — each with 11 tints. Tints are assigned numbers that correlate to their lightness.
|
||||
|
||||
There are 9 specially crafted color palettes; 3 are free to use with an additional 6 available in Web Awesome Pro.
|
||||
|
||||
{% include 'theming/color-palettes.njk' %}
|
||||
|
||||
Your color palette is determined by `class="wa-palette-{name}"` on the `<html>` element. If no class is specified, the default color palette for your chosen theme is used.
|
||||
|
||||
### Variants
|
||||
`.wa-{variant}-{hue}`
|
||||
|
||||
Variants convey a specific meaning through color. There are five variants:
|
||||
- **Brand** for product recognition
|
||||
- **Neutral** for generic and ordinary content
|
||||
- **Success** for validity or confirmation
|
||||
- **Warning** for caution or uncertainty
|
||||
- **Danger** for errors or risk
|
||||
|
||||
Brand and neutral are used by nearly every element, component, and pattern across the library. Success, warning, and danger are used selectively by components that could benefit from semantic reinforcement, such as buttons and callouts.
|
||||
|
||||
{% include 'theming/variants.njk' %}
|
||||
|
||||
Any hue from a color palette can be assigned to a variant. Each variant is determined by `class="wa-{variant}-{hue}"` on the `<html>` element. If no class is specified:
|
||||
- **Brand** defaults to <wa-icon name="square" style="color: var(--wa-color-blue);"></wa-icon> **blue**
|
||||
- **Neutral** defaults to <wa-icon name="square" style="color: var(--wa-color-gray);"></wa-icon> **gray**
|
||||
- **Success** defaults to <wa-icon name="square" style="color: var(--wa-color-green);"></wa-icon> **green**
|
||||
- **Warning** defaults to <wa-icon name="square" style="color: var(--wa-color-yellow);"></wa-icon> **yellow**
|
||||
- **Danger** defaults to <wa-icon name="square" style="color: var(--wa-color-red);"></wa-icon> **red**
|
||||
|
||||
### Theme Styles
|
||||
`.wa-theme-{name}`
|
||||
|
||||
Theme styles assign specific tints from your chosen variant colors — along with qualities like fonts, borders, space, and shadows — to design tokens that style elements and components. Themes may also contain custom CSS overrides to change the default look of components.
|
||||
|
||||
TODO: Add theme preview
|
||||
|
||||
Your theme is determined by `class="wa-theme-{name}"` on the `<html>` element. If no class is specified, the default theme is used.
|
||||
|
||||
### Light and Dark Mode
|
||||
`.wa-light` | `.wa-dark`
|
||||
|
||||
Every theme is designed to adapt to light and dark mode. Light mode styles are applied by default, but you can apply a specific color scheme to an entire page or just a section with `class="wa-light"` or `class="wa-dark"`.
|
||||
|
||||
```html {.example}
|
||||
<div class="wa-grid">
|
||||
|
||||
<wa-card class="wa-light">
|
||||
<div slot="header" class="wa-split">
|
||||
<h4 class="wa-heading-m">Light</h4>
|
||||
<wa-icon name="brightness"></wa-icon>
|
||||
</div>
|
||||
<div class="wa-stack">
|
||||
<wa-input label="# of Waffles" type="number" value="3"></wa-input>
|
||||
<wa-select label="Toppings" multiple value="jelly-beans">
|
||||
<wa-option value="whipped-cream">Whipped cream</wa-option>
|
||||
<wa-option value="hershey">Hershey's Kisses</wa-option>
|
||||
<wa-option value="jelly-beans">Jelly beans</wa-option>
|
||||
</wa-select>
|
||||
<wa-button appearance="filled" variant="brand">
|
||||
<wa-icon slot="start" name="waffle"></wa-icon>
|
||||
Make Waffles
|
||||
</wa-button>
|
||||
</div>
|
||||
</wa-card>
|
||||
|
||||
<wa-card class="wa-dark">
|
||||
<div slot="header" class="wa-split">
|
||||
<h4 class="wa-heading-m">Dark</h4>
|
||||
<wa-icon name="moon-stars"></wa-icon>
|
||||
</div>
|
||||
<div class="wa-stack">
|
||||
<wa-input label="# of Waffles" type="number" value="3"></wa-input>
|
||||
<wa-select label="Toppings" multiple value="jelly-beans">
|
||||
<wa-option value="whipped-cream">Whipped cream</wa-option>
|
||||
<wa-option value="hershey">Hershey's Kisses</wa-option>
|
||||
<wa-option value="jelly-beans">Jelly beans</wa-option>
|
||||
</wa-select>
|
||||
<wa-button appearance="filled" variant="brand">
|
||||
<wa-icon slot="start" name="waffle"></wa-icon>
|
||||
Make Waffles
|
||||
</wa-button>
|
||||
</div>
|
||||
</wa-card>
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
#### Inverting the Color Scheme
|
||||
`.wa-invert`
|
||||
|
||||
You can force a section to behave like `.wa-dark` in light mode and like `.wa-light` in dark mode by using `class="wa-invert"`.
|
||||
|
||||
```html {.example}
|
||||
<p>This card will always use the opposite of the color scheme applied to the docs.</p>
|
||||
|
||||
<wa-card class="wa-invert">
|
||||
<div slot="header" class="wa-split">
|
||||
<h4 class="wa-heading-m">Invert</h4>
|
||||
<wa-icon name="swap"></wa-icon>
|
||||
</div>
|
||||
<div class="wa-flank:end wa-align-items-end">
|
||||
<wa-select label="Location" value="upside-down">
|
||||
<wa-option value="lab">Hawkins Lab</wa-option>
|
||||
<wa-option value="mall">Starcourt Mall</wa-option>
|
||||
<wa-option value="upside-down">The Upside Down</wa-option>
|
||||
</wa-select>
|
||||
<wa-button id="go-button" appearance="filled" variant="brand">
|
||||
<wa-icon label="Go" name="person-to-portal" family="duotone"></wa-icon>
|
||||
</wa-button>
|
||||
<wa-tooltip for="go-button">
|
||||
Go!
|
||||
</wa-tooltip>
|
||||
</div>
|
||||
</wa-card>
|
||||
```
|
||||
|
||||
#### Detecting Color Scheme Preference
|
||||
|
||||
While both light and dark mode styles are built-in to all themes, Web Awesome doesn't automatically detect the user's color scheme preference. We recommend doing this at the application level.
|
||||
|
||||
Follow these best practices for supporting both light and dark mode:
|
||||
- Check for [`prefers-color-scheme`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-color-scheme) and use its value by default
|
||||
- Allow the user to override this setting in your app
|
||||
- Remember the user's preference and restore it on subsequent visits
|
||||
|
||||
Let's assume you store the user's color scheme preference for your app in a variable called `colorScheme` (values: `auto` | `light` | `dark`). You can use the following JS snippet to apply `class="wa-dark"` to the `<html>` element accordingly:
|
||||
|
||||
```js
|
||||
const systemDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const applyDark = function (event = systemDark) {
|
||||
const isDark = colorScheme === 'auto' ? event.matches : colorScheme === 'dark';
|
||||
document.documentElement.classList.toggle('wa-dark', isDark);
|
||||
};
|
||||
systemDark.addEventListener('change', applyDark);
|
||||
applyDark();
|
||||
```
|
||||
|
||||
## Using Themes
|
||||
|
||||
Use and update themes instantly via CDN with [Web Awesome projects](/teams). Or, assemble the pieces together using npm or in your self-hosted app.
|
||||
|
||||
Select your favorite options and follow the instructions for your preferred method.
|
||||
|
||||
{% include 'theming/instructions.njk' %}
|
||||
|
||||
## Creating Your Own
|
||||
|
||||
TODO
|
||||
@@ -8,7 +8,7 @@
|
||||
"homepage": "https://webawesome.com/",
|
||||
"author": "Web Awesome",
|
||||
"license": "MIT",
|
||||
"customElements": "dist/custom-elements.json",
|
||||
"customElements": "dist-cdn/custom-elements.json",
|
||||
"web-types": "./dist/web-types.json",
|
||||
"type": "module",
|
||||
"types": "dist/webawesome.d.ts",
|
||||
@@ -30,12 +30,19 @@
|
||||
"./dist/react/*": "./dist/react/*",
|
||||
"./dist/translations": "./dist/translations",
|
||||
"./dist/translations/*": "./dist/translations/*",
|
||||
"./dist/utilities": "./dist/utilities",
|
||||
"./dist/utilities/*": "./dist/utilities/*",
|
||||
"./dist/events": "./dist/events",
|
||||
"./dist/events/*": "./dist/events/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"dist",
|
||||
"dist-cdn"
|
||||
"dist-cdn",
|
||||
"dist/custom-elements.json",
|
||||
"./dist/custom-elements.json",
|
||||
"custom-elements.json"
|
||||
],
|
||||
"keywords": [
|
||||
"web components",
|
||||
@@ -89,9 +96,11 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wc-toolkit/cem-validator": "^1.0.3",
|
||||
"@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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +215,11 @@ export async function build(options = {}) {
|
||||
...(await globby(posix.join(rootDir, 'src/components/**/!(*.(style|test)).ts'))),
|
||||
// Translations
|
||||
...(await globby(posix.join(rootDir, 'src/translations/**/*.ts'))),
|
||||
// Utilities
|
||||
...(await globby(posix.join(rootDir, 'src/utilities/**/*.ts'))),
|
||||
// Events
|
||||
...(await globby(posix.join(rootDir, 'src/events/**/*.ts'))),
|
||||
// TODO: Should `src/internal` be included?
|
||||
// React wrappers
|
||||
...(await globby(posix.join(rootDir, 'src/react/**/*.ts'))),
|
||||
],
|
||||
@@ -435,6 +440,7 @@ export async function build(options = {}) {
|
||||
}
|
||||
|
||||
// copy everything to unbundled before we generate bundles.
|
||||
// this may cause watcher events to break. if things are broken with file watching, comment this out.
|
||||
await copy(getCdnDir(), getDistDir(), { overwrite: true });
|
||||
await regenerateBundle();
|
||||
|
||||
|
||||
268
packages/webawesome/scripts/llms.js
Normal file
268
packages/webawesome/scripts/llms.js
Normal file
@@ -0,0 +1,268 @@
|
||||
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) {
|
||||
if (!component.tagName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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 = [];
|
||||
|
||||
if (!component.tagName) {
|
||||
return 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 }) {
|
||||
// Account for base "abstract elements" that don't have a tagName.
|
||||
components = components.filter(c => c.tagName);
|
||||
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.filter(c => c.tagName).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.filter(c => c.tagName).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;
|
||||
@@ -22,6 +22,9 @@ const components = getAllComponents(metadata);
|
||||
const index = [];
|
||||
|
||||
for await (const component of components) {
|
||||
if (!component.tagName) {
|
||||
continue;
|
||||
}
|
||||
const tagWithoutPrefix = component.tagName.replace(/^wa-/, '');
|
||||
const componentDir = path.join(reactDir, tagWithoutPrefix);
|
||||
const componentFile = path.join(componentDir, 'index.ts');
|
||||
|
||||
@@ -661,16 +661,22 @@ export default class WaDropdown extends WebAwesomeElement {
|
||||
currentSubmenuItem.submenuElement.style.setProperty('--safe-triangle-cursor-x', `${constrainedX}px`);
|
||||
currentSubmenuItem.submenuElement.style.setProperty('--safe-triangle-cursor-y', `${constrainedY}px`);
|
||||
|
||||
const isOverItem = currentSubmenuItem.matches(':hover');
|
||||
// Calculate these up front since this event cant fire a lot.
|
||||
const composedPath = event.composedPath();
|
||||
const submenuItemHovered = currentSubmenuItem.matches(':hover');
|
||||
const submenuElementHovered = Boolean(currentSubmenuItem.submenuElement?.matches(':hover'));
|
||||
|
||||
const isOverItem = submenuItemHovered || !!composedPath.find(el => el === currentSubmenuItem);
|
||||
|
||||
const isOverSubmenu =
|
||||
currentSubmenuItem.submenuElement?.matches(':hover') ||
|
||||
!!event
|
||||
.composedPath()
|
||||
.find(el => el instanceof HTMLElement && el.closest('[part="submenu"]') === currentSubmenuItem.submenuElement);
|
||||
submenuElementHovered ||
|
||||
!!composedPath.find(
|
||||
el => el instanceof HTMLElement && el.closest('[part="submenu"]') === currentSubmenuItem.submenuElement,
|
||||
);
|
||||
|
||||
if (!isOverItem && !isOverSubmenu) {
|
||||
setTimeout(() => {
|
||||
if (!currentSubmenuItem.matches(':hover') && !currentSubmenuItem.submenuElement?.matches(':hover')) {
|
||||
if (!submenuItemHovered && !submenuElementHovered) {
|
||||
currentSubmenuItem.submenuOpen = false;
|
||||
}
|
||||
}, 100);
|
||||
|
||||
@@ -15,6 +15,8 @@ import styles from './progress-ring.styles.js';
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
* @csspart label - The progress ring label.
|
||||
* @csspart track - The progress ring's track.
|
||||
* @csspart indicator - The progress ring's indicator.
|
||||
*
|
||||
* @cssproperty --size - The diameter of the progress ring (cannot be a percentage).
|
||||
* @cssproperty --track-width - The width of the track.
|
||||
@@ -70,8 +72,8 @@ export default class WaProgressRing extends WebAwesomeElement {
|
||||
style="--percentage: ${this.value / 100}"
|
||||
>
|
||||
<svg class="image">
|
||||
<circle class="track"></circle>
|
||||
<circle class="indicator" style="stroke-dashoffset: ${this.indicatorOffset}"></circle>
|
||||
<circle part="track" class="track"></circle>
|
||||
<circle part="indicator" class="indicator" style="stroke-dashoffset: ${this.indicatorOffset}"></circle>
|
||||
</svg>
|
||||
|
||||
<slot id="label" part="label" class="label"></slot>
|
||||
|
||||
@@ -243,7 +243,7 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.hasUpdated ? this.localize.dir() === 'rtl' : this.dir === 'rtl';
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const showExpandButton = !this.loading && (!this.isLeaf || this.lazy);
|
||||
|
||||
return html`
|
||||
|
||||
@@ -154,6 +154,8 @@ export default class WebAwesomeElement extends LitElement {
|
||||
relayNativeEvent(event: Event, eventOptions?: EventInit) {
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
// This triggers an error in CEM, so we need to ignore it.
|
||||
/** @internal */
|
||||
this.dispatchEvent(
|
||||
new (event.constructor as typeof Event)(event.type, {
|
||||
...event,
|
||||
|
||||
@@ -6,31 +6,30 @@ const translation: Translation = {
|
||||
$name: 'فارسی',
|
||||
$dir: 'rtl',
|
||||
|
||||
carousel: 'چرخ فلک',
|
||||
carousel: 'چرخفلک',
|
||||
clearEntry: 'پاک کردن ورودی',
|
||||
close: 'بستن',
|
||||
copied: 'کپی شد',
|
||||
copy: 'رونوشت',
|
||||
copy: 'کپی',
|
||||
currentValue: 'مقدار فعلی',
|
||||
error: 'خطا',
|
||||
goToSlide: (slide, count) => `رفتن به اسلاید ${slide} از ${count}`,
|
||||
hidePassword: 'پنهان کردن رمز',
|
||||
loading: 'بارگذاری',
|
||||
loading: 'بارگزاری',
|
||||
nextSlide: 'اسلاید بعدی',
|
||||
numOptionsSelected: num => {
|
||||
if (num === 0) return 'هیچ گزینه ای انتخاب نشده است';
|
||||
if (num === 1) return '1 گزینه انتخاب شده است';
|
||||
if (num === 0) return 'هیچ گزینهای انتخاب نشده است';
|
||||
return `${num} گزینه انتخاب شده است`;
|
||||
},
|
||||
pauseAnimation: 'مکث انیمیشن',
|
||||
pauseAnimation: 'توقف انیمیشن',
|
||||
playAnimation: 'پخش انیمیشن',
|
||||
previousSlide: 'اسلاید قبلی',
|
||||
progress: 'پیشرفت',
|
||||
remove: 'حذف',
|
||||
resize: 'تغییر اندازه',
|
||||
scrollableRegion: 'ناحیه قابل اسکرول',
|
||||
scrollToEnd: 'پیمایش به انتها',
|
||||
scrollToStart: 'پیمایش به ابتدا',
|
||||
scrollToEnd: 'اسکرول به انتها',
|
||||
scrollToStart: 'اسکرول به ابتدا',
|
||||
selectAColorFromTheScreen: 'انتخاب یک رنگ از صفحه نمایش',
|
||||
showPassword: 'نمایش رمز',
|
||||
slideNum: slide => `اسلاید ${slide}`,
|
||||
|
||||
@@ -11,6 +11,10 @@ const metadata = JSON.parse(readFileSync('./dist/custom-elements.json'), 'utf8')
|
||||
const serverComponents = [];
|
||||
const componentImports = [];
|
||||
getAllComponents(metadata).forEach(component => {
|
||||
if (!component.tagName) {
|
||||
return;
|
||||
}
|
||||
|
||||
const name = component.tagName.replace(/^wa-/, '');
|
||||
|
||||
serverComponents.push(`/dist/components/${name}/${name}.js`);
|
||||
|
||||
Reference in New Issue
Block a user