diff --git a/.gitignore b/.gitignore index 35e4be025362..bf75a460a4a9 100644 --- a/.gitignore +++ b/.gitignore @@ -194,6 +194,8 @@ config/external/icu4x # Ignore Storybook generated files browser/components/storybook/node_modules/ browser/components/storybook/storybook-static/ +browser/components/storybook/.storybook/rewrites.js +browser/components/storybook/custom-elements.json # Ignore jscodeshift installed by mach esmify on windows tools/esmify/jscodeshift diff --git a/.hgignore b/.hgignore index 349b9404ebf9..06be3f1d2745 100644 --- a/.hgignore +++ b/.hgignore @@ -264,6 +264,7 @@ toolkit/components/certviewer/content/package-lock.json ^browser/components/storybook/node_modules/ ^browser/components/storybook/storybook-static/ ^browser/components/storybook/.storybook/rewrites.js +^browser/components/storybook/custom-elements.json # Ignore jscodeshift installed by mach esmify on windows ^tools/esmify/jscodeshift diff --git a/browser/components/storybook/.storybook/preview.mjs b/browser/components/storybook/.storybook/preview.mjs index a0b438e315f6..a76a4941b644 100644 --- a/browser/components/storybook/.storybook/preview.mjs +++ b/browser/components/storybook/.storybook/preview.mjs @@ -6,6 +6,8 @@ import { DOMLocalization } from "@fluent/dom"; import { FluentBundle, FluentResource } from "@fluent/bundle"; import { css, html } from "lit.all.mjs"; import { MozLitElement } from "toolkit/content/widgets/lit-utils.mjs"; +import { setCustomElementsManifest } from "@storybook/web-components"; +import customElementsManifest from "../custom-elements.json"; // Base Fluent set up. let storybookBundle = new FluentBundle("en-US"); @@ -143,3 +145,6 @@ export const decorators = [ > `, ]; + +// Enable props tables documentation. +setCustomElementsManifest(customElementsManifest); diff --git a/browser/components/storybook/custom-elements-manifest.config.mjs b/browser/components/storybook/custom-elements-manifest.config.mjs new file mode 100644 index 000000000000..28ec6c3c4c94 --- /dev/null +++ b/browser/components/storybook/custom-elements-manifest.config.mjs @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Custom element manifest analyzer plugin to remove specific properties from + * custom-elements.json that we don't want to document in our Storybook props tables. + */ +function removeExcludedProperties() { + const EXCLUDED_PROPERTIES = [ + "SUPPORT_URL", + "LOCAL_NAME", + "queries", + "stylesheetUrl", + "shadowRootOptions", + ]; + return { + packageLinkPhase({ customElementsManifest }) { + customElementsManifest?.modules?.forEach(module => { + module?.declarations?.forEach(declaration => { + if (declaration.members != null) { + declaration.members = declaration.members.filter(member => { + return ( + !member.kind === "field" || + !EXCLUDED_PROPERTIES.includes(member.name) + ); + }); + } + }); + }); + }, + }; +} + +/** + * Custom element manifest config. Controls how we parse directories for + * custom elements to populate custom-elements.json. + */ +const config = { + globs: ["../../../toolkit/content/widgets/**/*.mjs"], + exclude: [ + "../../../toolkit/content/widgets/**/*.stories.mjs", + "../../../toolkit/content/widgets/vendor/**", + "../../../toolkit/content/widgets/lit-utils.mjs", + ], + outdir: ".", + litelement: true, + plugins: [removeExcludedProperties()], +}; + +export default config; diff --git a/browser/components/storybook/package-lock.json b/browser/components/storybook/package-lock.json index 02a67a0317bc..15610f69c57b 100644 --- a/browser/components/storybook/package-lock.json +++ b/browser/components/storybook/package-lock.json @@ -10,6 +10,7 @@ "license": "MPL-2.0", "devDependencies": { "@babel/core": "^7.16.0", + "@custom-elements-manifest/analyzer": "^0.6.6", "@fluent/bundle": "^0.17.1", "@fluent/dom": "^0.8.1", "@storybook/addon-a11y": "^6.5.15", @@ -1893,6 +1894,91 @@ "node": ">=0.1.90" } }, + "node_modules/@custom-elements-manifest/analyzer": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.6.6.tgz", + "integrity": "sha512-aPBZBdkrGcQPhgPPEucgw66vfOfLpS80GOGzDXE8NZuO/VmTdy3QQNAsuD4MPJmv9eRPV9W2V7ezodS5g8erng==", + "dev": true, + "dependencies": { + "@custom-elements-manifest/find-dependencies": "^0.0.5", + "@github/catalyst": "^1.6.0", + "@web/config-loader": "0.1.3", + "chokidar": "3.5.2", + "command-line-args": "5.1.2", + "comment-parser": "1.2.4", + "custom-elements-manifest": "1.0.0", + "debounce": "1.2.1", + "globby": "11.0.4", + "typescript": "~4.3.2" + }, + "bin": { + "cem": "cem.js", + "custom-elements-manifest": "cem.js" + } + }, + "node_modules/@custom-elements-manifest/analyzer/node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@custom-elements-manifest/analyzer/node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@custom-elements-manifest/analyzer/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "es-module-lexer": "^0.9.3" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -1931,6 +2017,12 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, + "node_modules/@github/catalyst": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.6.0.tgz", + "integrity": "sha512-u8A+DameixqpeyHzvnJWTGj+wfiskQOYHzSiJscCWVfMkIT3rxnbHMtGh3lMthaRY21nbUOK71WcsCnCrXhBJQ==", + "dev": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -8326,6 +8418,51 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "dependencies": { + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@web/config-loader/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@web/config-loader/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@web/config-loader/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -8851,6 +8988,15 @@ "node": ">=0.10.0" } }, + "node_modules/array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true, + "engines": { + "node": ">=12.17" + } + }, "node_modules/array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -10464,6 +10610,21 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/command-line-args": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.2.tgz", + "integrity": "sha512-fytTsbndLbl+pPWtS0CxLV3BEWw9wJayB8NnU2cbQqVPsNdYezQeT+uIQv009m+GShnMNyuoBrRo8DTmuTfSCA==", + "dev": true, + "dependencies": { + "array-back": "^6.1.2", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -10473,6 +10634,15 @@ "node": ">= 6" } }, + "node_modules/comment-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -11401,12 +11571,24 @@ "node": ">=0.10.0" } }, + "node_modules/custom-elements-manifest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", + "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", + "dev": true + }, "node_modules/cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", "dev": true }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12734,6 +12916,27 @@ "node": ">=6" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-replace/node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -15162,6 +15365,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -20088,6 +20297,15 @@ "node": ">=4.2.0" } }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -22744,6 +22962,71 @@ "dev": true, "optional": true }, + "@custom-elements-manifest/analyzer": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@custom-elements-manifest/analyzer/-/analyzer-0.6.6.tgz", + "integrity": "sha512-aPBZBdkrGcQPhgPPEucgw66vfOfLpS80GOGzDXE8NZuO/VmTdy3QQNAsuD4MPJmv9eRPV9W2V7ezodS5g8erng==", + "dev": true, + "requires": { + "@custom-elements-manifest/find-dependencies": "^0.0.5", + "@github/catalyst": "^1.6.0", + "@web/config-loader": "0.1.3", + "chokidar": "3.5.2", + "command-line-args": "5.1.2", + "comment-parser": "1.2.4", + "custom-elements-manifest": "1.0.0", + "debounce": "1.2.1", + "globby": "11.0.4", + "typescript": "~4.3.2" + }, + "dependencies": { + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true + } + } + }, + "@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==", + "dev": true, + "requires": { + "es-module-lexer": "^0.9.3" + } + }, "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -22771,6 +23054,12 @@ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", "dev": true }, + "@github/catalyst": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@github/catalyst/-/catalyst-1.6.0.tgz", + "integrity": "sha512-u8A+DameixqpeyHzvnJWTGj+wfiskQOYHzSiJscCWVfMkIT3rxnbHMtGh3lMthaRY21nbUOK71WcsCnCrXhBJQ==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -27798,6 +28087,41 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "@web/config-loader": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@web/config-loader/-/config-loader-0.1.3.tgz", + "integrity": "sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ==", + "dev": true, + "requires": { + "semver": "^7.3.4" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -28268,6 +28592,12 @@ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true }, + "array-back": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", + "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", + "dev": true + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -29503,12 +29833,30 @@ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "dev": true }, + "command-line-args": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.2.tgz", + "integrity": "sha512-fytTsbndLbl+pPWtS0CxLV3BEWw9wJayB8NnU2cbQqVPsNdYezQeT+uIQv009m+GShnMNyuoBrRo8DTmuTfSCA==", + "dev": true, + "requires": { + "array-back": "^6.1.2", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, "commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true }, + "comment-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", + "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "dev": true + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -30247,12 +30595,24 @@ "array-find-index": "^1.0.1" } }, + "custom-elements-manifest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz", + "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", + "dev": true + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", "dev": true }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -31327,6 +31687,23 @@ } } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "requires": { + "array-back": "^3.0.1" + }, + "dependencies": { + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "dev": true + } + } + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -33122,6 +33499,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -37046,6 +37429,12 @@ "dev": true, "peer": true }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "dev": true + }, "uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", diff --git a/browser/components/storybook/package.json b/browser/components/storybook/package.json index 594452ce3960..e6d7b7606243 100644 --- a/browser/components/storybook/package.json +++ b/browser/components/storybook/package.json @@ -4,14 +4,16 @@ "description": "", "main": "index.js", "scripts": { + "analyze": "cem analyze", "test": "echo \"Error: no test specified\" && exit 1", - "build-storybook": "build-storybook", - "storybook": "start-storybook -p 5703 --no-open" + "build-storybook": "npm run analyze && build-storybook", + "storybook": "npm run analyze && start-storybook -p 5703 --no-open" }, "author": "", "license": "MPL-2.0", "devDependencies": { "@babel/core": "^7.16.0", + "@custom-elements-manifest/analyzer": "^0.6.6", "@fluent/bundle": "^0.17.1", "@fluent/dom": "^0.8.1", "@storybook/addon-a11y": "^6.5.15", diff --git a/toolkit/content/widgets/mach_commands.py b/toolkit/content/widgets/mach_commands.py index 2db09291bdb0..57a16421a6d5 100644 --- a/toolkit/content/widgets/mach_commands.py +++ b/toolkit/content/widgets/mach_commands.py @@ -15,6 +15,12 @@ JS_HEADER = """{license} import {{ html }} from "../vendor/lit.all.mjs"; import {{ MozLitElement }} from "../lit-utils.mjs"; +/** + * Component description goes here. + * + * @tagname {element_name} + * @property {{string}} variant - Property description goes here + */ export default class {class_name} extends MozLitElement {{ static properties = {{ variant: {{ type: String }}, @@ -47,6 +53,7 @@ import "./{element_name}.mjs"; export default {{ title: "Design System/Experiments/{class_name}", + component: "{element_name}", argTypes: {{ variant: {{ options: ["default", "other"], diff --git a/toolkit/content/widgets/moz-button-group/moz-button-group.mjs b/toolkit/content/widgets/moz-button-group/moz-button-group.mjs index 0fb906b9e529..0d98bb94dfb8 100644 --- a/toolkit/content/widgets/moz-button-group/moz-button-group.mjs +++ b/toolkit/content/widgets/moz-button-group/moz-button-group.mjs @@ -9,6 +9,14 @@ export const PLATFORM_LINUX = "linux"; export const PLATFORM_MACOS = "macosx"; export const PLATFORM_WINDOWS = "win"; +/** + * A grouping of buttons. Primary button order will be set automatically based + * on class="primary", type="submit" or autofocus attribute. Set slot="primary" + * on a primary button that does not have primary styling to set its position. + * + * @tagname moz-button-group + * @property {string} platform - The detected platform, set automatically. + */ export default class MozButtonGroup extends MozLitElement { static queries = { defaultSlotEl: "slot:not([name])", diff --git a/toolkit/content/widgets/moz-button-group/moz-button-group.stories.mjs b/toolkit/content/widgets/moz-button-group/moz-button-group.stories.mjs index 9fb6ec31b5c8..b4ae0cbed214 100644 --- a/toolkit/content/widgets/moz-button-group/moz-button-group.stories.mjs +++ b/toolkit/content/widgets/moz-button-group/moz-button-group.stories.mjs @@ -11,6 +11,7 @@ import { export default { title: "Design System/Experiments/MozButtonGroup", + component: "moz-button-group", argTypes: { platform: { options: [PLATFORM_LINUX, PLATFORM_MACOS, PLATFORM_WINDOWS], diff --git a/toolkit/content/widgets/moz-support-link/moz-support-link.mjs b/toolkit/content/widgets/moz-support-link/moz-support-link.mjs index b4e15852015c..5b1d730360db 100644 --- a/toolkit/content/widgets/moz-support-link/moz-support-link.mjs +++ b/toolkit/content/widgets/moz-support-link/moz-support-link.mjs @@ -4,6 +4,16 @@ MozXULElement.insertFTLIfNeeded("browser/components/mozSupportLink.ftl"); +/** + * An extension of the anchor element that helps create links to Mozilla's + * support documentation. This should be used for SUMO links only - other "Learn + * more" links can use the regular anchor element. + * + * @tagname moz-support-link + * @attribute {string} support-page - Short-hand string from SUMO to the specific support page. + * @attribute {string} utm-content - UTM parameter for a URL, if it is an AMO URL. + * @attribute {string} data-l10n-id - Fluent ID used to generate the text content. + */ export default class MozSupportLink extends HTMLAnchorElement { static SUPPORT_URL = "https://www.mozilla.org/"; static get observedAttributes() { diff --git a/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs b/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs index 893fce3ad6f2..00cf77414667 100644 --- a/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs +++ b/toolkit/content/widgets/moz-support-link/moz-support-link.stories.mjs @@ -19,28 +19,21 @@ const fluentStrings = [ export default { title: "Design System/Experiments/MozSupportLink", + component: "moz-support-link", argTypes: { - dataL10nId: { - type: "string", + "data-l10n-id": { options: [fluentStrings[0], fluentStrings[1], fluentStrings[2]], control: { type: "select" }, - description: "Fluent ID used to generate the text content.", - }, - supportPage: { - type: "string", - description: - "Short-hand string from SUMO to the specific support page. **Note:** changing this will not create a valid URL since we don't have access to the generated support link used in Firefox", - }, - utmContent: { - type: "string", - description: - "UTM parameter for a URL, if it is an AMO URL. **Note:** changing this will not create a valid URL since we don't have access to the generated support link used in Firefox", }, onClick: { action: "clicked" }, }, }; -const Template = ({ dataL10nId, supportPage, utmContent }) => html` +const Template = ({ + "data-l10n-id": dataL10nId, + "support-page": supportPage, + "utm-content": utmContent, +}) => html` html` export const withAMOUrl = Template.bind({}); withAMOUrl.args = { - dataL10nId: fluentStrings[0], - supportPage: "addons", - utmContent: "promoted-addon-badge", + "data-l10n-id": fluentStrings[0], + "support-page": "addons", + "utm-content": "promoted-addon-badge", }; export const Primary = Template.bind({}); Primary.args = { - supportPage: "preferences", + "support-page": "preferences", + "utm-content": "", }; export const withFluentId = Template.bind({}); withFluentId.args = { - dataL10nId: fluentStrings[1], - supportPage: "preferences", + "data-l10n-id": fluentStrings[1], + "support-page": "preferences", + "utm-content": "", }; diff --git a/toolkit/content/widgets/moz-toggle/moz-toggle.mjs b/toolkit/content/widgets/moz-toggle/moz-toggle.mjs index b4459bebf069..d545e1f77c2f 100644 --- a/toolkit/content/widgets/moz-toggle/moz-toggle.mjs +++ b/toolkit/content/widgets/moz-toggle/moz-toggle.mjs @@ -5,6 +5,19 @@ import { html, ifDefined } from "../vendor/lit.all.mjs"; import { MozLitElement } from "../lit-utils.mjs"; +/** + * A simple toggle element that can be used to switch between two states. + * + * @tagname moz-toggle + * @property {boolean} pressed - Whether or not the element is pressed. + * @property {boolean} disabled - Whether or not the element is disabled. + * @property {string} label - The label text. + * @property {string} description - The description text. + * @property {string} ariaLabel + * The aria-label text for cases where there is no visible label. + * @fires toggle + * Custom event indicating that the toggle's pressed state has changed. + */ export default class MozToggle extends MozLitElement { static shadowRootOptions = { ...MozLitElement.shadowRootOptions, diff --git a/toolkit/content/widgets/moz-toggle/moz-toggle.stories.mjs b/toolkit/content/widgets/moz-toggle/moz-toggle.stories.mjs index 7441cad91b58..e6f0f35783e4 100644 --- a/toolkit/content/widgets/moz-toggle/moz-toggle.stories.mjs +++ b/toolkit/content/widgets/moz-toggle/moz-toggle.stories.mjs @@ -8,6 +8,7 @@ import "./moz-toggle.mjs"; export default { title: "Design System/Experiments/MozToggle", + component: "moz-toggle", parameters: { actions: { handles: ["toggle"],