From 1fb65f144b5f5e95bbc6ebedd65f1a0a75938c4a Mon Sep 17 00:00:00 2001 From: shirlsli Date: Fri, 16 Aug 2024 14:45:27 -0700 Subject: [PATCH 1/3] docs: added some comments to website code --- docs/token-diff/src/fetchFromGithub.ts | 35 ++++++++++++++----- .../src/lib/added-token-detection.js | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/docs/token-diff/src/fetchFromGithub.ts b/docs/token-diff/src/fetchFromGithub.ts index 948c88b5..5e331557 100644 --- a/docs/token-diff/src/fetchFromGithub.ts +++ b/docs/token-diff/src/fetchFromGithub.ts @@ -1,5 +1,10 @@ import { githubAPIKey } from '../github-api-key.js'; +/** + * Fetches branch or tag options + * @param {string} type - either branch or tag + * @returns {Promise} a JSON object containing either branches or release versions/tags + */ export async function fetchBranchTagOptions(type: string) { const url = type === 'branch' @@ -15,6 +20,7 @@ export async function fetchBranchTagOptions(type: string) { const obj = await response.json(); Object.values(obj).forEach((value: any) => { if (!value.name.includes('token-diff-generator')) { + // need to exclude releases without tokens arr.push(value.name); } }); @@ -22,10 +28,16 @@ export async function fetchBranchTagOptions(type: string) { }); } +/** + * Fetches list of token files for a specific branch or tag using Github API + * @param {string} branchOrTagKey - type of desired options (branch or tag) + * @param {string} branchOrTag - the specific branch or tag name whose token files you want to fetch + * @returns + */ export async function fetchSchemaOptions( branchOrTagKey: string, branchOrTag: string, -) { +): Promise { let schemaOptions: string[] = []; const source = 'https://raw.githubusercontent.com/adobe/spectrum-tokens/'; let branchOrTagArr = branchOrTag.split('@'); @@ -40,7 +52,13 @@ export async function fetchSchemaOptions( return schemaOptions; } -async function fetchTokens(tokenName: string, url: string) { +/** + * Fetchs tokens from specified token file and branch/tag + * @param {string} tokenName - the name of the token file + * @param {string} url - the source url + the branch or tag + * @returns {Promise} a JSON object containing the tokens from specified token file + */ +async function fetchTokens(tokenName: string, url: string): Promise { return (await fetch(`${url}/packages/tokens/${tokenName}`)).json(); } @@ -48,21 +66,22 @@ const source = 'https://raw.githubusercontent.com/adobe/spectrum-tokens/'; /** * Returns file with given file name as a JSON object (took this from diff.js) - * @param {string} tokenName - the name of the target file - * @param {string} version - the intended package version (full name) + * @param {string} givenTokenNames - the name of the target file + * @param {string} givenVersion - the intended package version (full name) + * @param {string} givenBranch - the intended branch * @returns {object} the target file as a JSON object */ export async function fileImport( givenTokenNames: string[], givenVersion: string | undefined, - givenLocation: string | undefined, -) { + givenBranch: string | undefined, +): Promise { const version = givenVersion || 'latest'; - const location = givenLocation || 'main'; + const branch = givenBranch || 'main'; const link = version !== 'latest' ? source + version.replace('@', '%40') - : source + location; + : source + branch; let tokenNames: string[]; if (givenTokenNames[0] === 'all') { tokenNames = await fetchTokens('manifest.json', link); diff --git a/tools/diff-generator/src/lib/added-token-detection.js b/tools/diff-generator/src/lib/added-token-detection.js index b454c53d..226149d2 100644 --- a/tools/diff-generator/src/lib/added-token-detection.js +++ b/tools/diff-generator/src/lib/added-token-detection.js @@ -15,6 +15,7 @@ governing permissions and limitations under the License. * @param {object} renamed - the token data that were renamed * @param {object} deprecatedTokens - the newly deprecated tokens * @param {object} changes - the changed token data + * @param {object} original - token data to compare against * @returns {object} addedTokens - a JSON object containing the added tokens */ From 5681af2e350a4cd042047ca90a437e3c557f45f1 Mon Sep 17 00:00:00 2001 From: shirlsli Date: Fri, 16 Aug 2024 15:58:53 -0700 Subject: [PATCH 2/3] chore: deleted an unused dependency --- docs/token-diff/src/PageContainer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/token-diff/src/PageContainer.ts b/docs/token-diff/src/PageContainer.ts index 627e2400..f5ca922f 100644 --- a/docs/token-diff/src/PageContainer.ts +++ b/docs/token-diff/src/PageContainer.ts @@ -19,7 +19,6 @@ import '@spectrum-web-components/theme/src/themes.js'; import '@spectrum-web-components/overlay/sp-overlay.js'; import '@spectrum-web-components/popover/sp-popover.js'; import '@spectrum-web-components/divider/sp-divider.js'; -import { property } from 'lit/decorators.js'; export class PageContainer extends LitElement { static styles = css` From e1250580f95a9c2df4ec5335dfc766473840b297 Mon Sep 17 00:00:00 2001 From: cable Date: Thu, 17 Oct 2024 15:18:09 -0700 Subject: [PATCH 3/3] chore: add back tdiff it's the token-diff frontend --- .moon/workspace.yml | 1 + docs/token-diff/.editorconfig | 29 ++ docs/token-diff/.gitignore | 27 ++ docs/token-diff/.husky/pre-commit | 1 + docs/token-diff/LICENSE | 21 ++ docs/token-diff/README.md | 48 +++ docs/token-diff/demo/index.html | 44 +++ docs/token-diff/index.d.ts | 1 + docs/token-diff/moon.yml | 36 ++ docs/token-diff/package.json | 104 ++++++ docs/token-diff/src/CodePanel.ts | 165 +++++++++ docs/token-diff/src/CompareCard.ts | 313 ++++++++++++++++ docs/token-diff/src/DiffReport.ts | 408 +++++++++++++++++++++ docs/token-diff/src/GettingStarted.ts | 411 ++++++++++++++++++++++ docs/token-diff/src/NavBar.ts | 106 ++++++ docs/token-diff/src/PageContainer.ts | 229 ++++++++++++ docs/token-diff/src/TokenDiff.ts | 283 +++++++++++++++ docs/token-diff/src/assets/adobe_logo.svg | 12 + docs/token-diff/src/code-panel.ts | 14 + docs/token-diff/src/compare-card.ts | 14 + docs/token-diff/src/diff-report.ts | 14 + docs/token-diff/src/fetchFromGithub.ts | 97 +++++ docs/token-diff/src/getting-started.ts | 14 + docs/token-diff/src/index.ts | 15 + docs/token-diff/src/nav-bar.ts | 14 + docs/token-diff/src/page-container.ts | 14 + docs/token-diff/src/token-diff.ts | 14 + docs/token-diff/src/typekit.js | 50 +++ docs/token-diff/tsconfig.json | 27 ++ docs/token-diff/web-dev-server.config.js | 27 ++ 30 files changed, 2553 insertions(+) create mode 100644 docs/token-diff/.editorconfig create mode 100644 docs/token-diff/.gitignore create mode 100644 docs/token-diff/.husky/pre-commit create mode 100644 docs/token-diff/LICENSE create mode 100644 docs/token-diff/README.md create mode 100644 docs/token-diff/demo/index.html create mode 100644 docs/token-diff/index.d.ts create mode 100644 docs/token-diff/moon.yml create mode 100644 docs/token-diff/package.json create mode 100644 docs/token-diff/src/CodePanel.ts create mode 100644 docs/token-diff/src/CompareCard.ts create mode 100644 docs/token-diff/src/DiffReport.ts create mode 100644 docs/token-diff/src/GettingStarted.ts create mode 100644 docs/token-diff/src/NavBar.ts create mode 100644 docs/token-diff/src/PageContainer.ts create mode 100644 docs/token-diff/src/TokenDiff.ts create mode 100644 docs/token-diff/src/assets/adobe_logo.svg create mode 100644 docs/token-diff/src/code-panel.ts create mode 100644 docs/token-diff/src/compare-card.ts create mode 100644 docs/token-diff/src/diff-report.ts create mode 100644 docs/token-diff/src/fetchFromGithub.ts create mode 100644 docs/token-diff/src/getting-started.ts create mode 100644 docs/token-diff/src/index.ts create mode 100644 docs/token-diff/src/nav-bar.ts create mode 100644 docs/token-diff/src/page-container.ts create mode 100644 docs/token-diff/src/token-diff.ts create mode 100644 docs/token-diff/src/typekit.js create mode 100644 docs/token-diff/tsconfig.json create mode 100644 docs/token-diff/web-dev-server.config.js diff --git a/.moon/workspace.yml b/.moon/workspace.yml index c6718bfb..49440b68 100644 --- a/.moon/workspace.yml +++ b/.moon/workspace.yml @@ -7,6 +7,7 @@ projects: root: "." csvGenerator: tools/token-csv-generator diff: "tools/diff-generator" + tdiff: "docs/token-diff" vcs: manager: "git" defaultBranch: "main" diff --git a/docs/token-diff/.editorconfig b/docs/token-diff/.editorconfig new file mode 100644 index 00000000..c8c2d2aa --- /dev/null +++ b/docs/token-diff/.editorconfig @@ -0,0 +1,29 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 2 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.json] +indent_size = 2 + +[*.{html,js,md}] +block_comment_start = /** +block_comment = * +block_comment_end = */ diff --git a/docs/token-diff/.gitignore b/docs/token-diff/.gitignore new file mode 100644 index 00000000..fac7af07 --- /dev/null +++ b/docs/token-diff/.gitignore @@ -0,0 +1,27 @@ +## editors +/.idea +/.vscode + +## system files +.DS_Store + +## npm +/node_modules/ +/npm-debug.log + +## testing +/coverage/ + +## temp folders +/.tmp/ + +# build +/_site/ +/dist/ +/out-tsc/ + +storybook-static +custom-elements.json + +# api keys +github-api-key.ts diff --git a/docs/token-diff/.husky/pre-commit b/docs/token-diff/.husky/pre-commit new file mode 100644 index 00000000..f568382f --- /dev/null +++ b/docs/token-diff/.husky/pre-commit @@ -0,0 +1 @@ +./node_modules/.bin/lint-staged \ No newline at end of file diff --git a/docs/token-diff/LICENSE b/docs/token-diff/LICENSE new file mode 100644 index 00000000..5be0a67f --- /dev/null +++ b/docs/token-diff/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 token-diff + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/docs/token-diff/README.md b/docs/token-diff/README.md new file mode 100644 index 00000000..6bbdf155 --- /dev/null +++ b/docs/token-diff/README.md @@ -0,0 +1,48 @@ +# \ + +This webcomponent follows the [open-wc](https://github.com/open-wc/open-wc) recommendation. + +## Installation + +```bash +npm i token-diff +``` + +## Usage + +```html + + + +``` + +## Linting and formatting + +To scan the project for linting and formatting errors, run + +```bash +npm run lint +``` + +To automatically fix linting and formatting errors, run + +```bash +npm run format +``` + + +## Tooling configs + +For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project. + +If you customize the configuration a lot, you can consider moving them to individual files. + +## Local Demo with `web-dev-server` + +```bash +npm start +``` + +To run a local development server that serves the basic demo located in `demo/index.html` diff --git a/docs/token-diff/demo/index.html b/docs/token-diff/demo/index.html new file mode 100644 index 00000000..ef0057ec --- /dev/null +++ b/docs/token-diff/demo/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+ + + + diff --git a/docs/token-diff/index.d.ts b/docs/token-diff/index.d.ts new file mode 100644 index 00000000..00041903 --- /dev/null +++ b/docs/token-diff/index.d.ts @@ -0,0 +1 @@ +declare module '@adobe/token-diff-generator'; diff --git a/docs/token-diff/moon.yml b/docs/token-diff/moon.yml new file mode 100644 index 00000000..4dbfa246 --- /dev/null +++ b/docs/token-diff/moon.yml @@ -0,0 +1,36 @@ +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. +$schema: "https://moonrepo.dev/schemas/project.json" +stack: frontend +type: application +tags: + - docs + - token-diff +fileGroups: + sources: + - "src/**/*" + config: + - "tsconfig.json" + - "web-dev-server.config.js" +tasks: + build: + command: + - build + deps: + - ~:typescript + platform: node + inputs: + - "config" + - "@globs(sources)" + outputs: + - "/token-diff" + typescript: + command: tsc + platform: node diff --git a/docs/token-diff/package.json b/docs/token-diff/package.json new file mode 100644 index 00000000..e9330146 --- /dev/null +++ b/docs/token-diff/package.json @@ -0,0 +1,104 @@ +{ + "name": "token-diff", + "description": "Webcomponent token-diff following open-wc recommendations", + "license": "MIT", + "author": "token-diff", + "version": "0.0.0", + "type": "module", + "main": "dist/src/index.js", + "module": "dist/src/index.js", + "exports": { + ".": "./dist/src/index.js", + "./token-diff.js": "./dist/src/token-diff.js" + }, + "scripts": { + "analyze": "cem analyze --litelement", + "start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"web-dev-server\"", + "build": "tsc && npm run analyze -- --exclude dist", + "prepublish": "tsc && npm run analyze -- --exclude dist", + "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore", + "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore", + "prepare": "husky" + }, + "dependencies": { + "@adobe/token-diff-generator": "workspace:*", + "@spectrum-css/button": "^13.1.1", + "@spectrum-css/icon": "^7.1.1", + "@spectrum-css/page": "^7.1.4", + "@spectrum-css/tokens": "^13.2.0", + "@spectrum-css/typography": "^5.1.5", + "@spectrum-web-components/action-button": "0.45.0", + "@spectrum-web-components/action-group": "^0.45.0", + "@spectrum-web-components/button": "0.45.0", + "@spectrum-web-components/card": "^0.45.0", + "@spectrum-web-components/dialog": "0.45.0", + "@spectrum-web-components/divider": "0.45.0", + "@spectrum-web-components/field-label": "^0.45.0", + "@spectrum-web-components/icons-ui": "0.45.0", + "@spectrum-web-components/icons-workflow": "0.45.0", + "@spectrum-web-components/menu": "^0.45.0", + "@spectrum-web-components/overlay": "0.45.0", + "@spectrum-web-components/picker": "^0.45.0", + "@spectrum-web-components/popover": "0.45.0", + "@spectrum-web-components/sidenav": "^0.45.0", + "@spectrum-web-components/styles": "0.45.0", + "@spectrum-web-components/table": "0.45.0", + "@spectrum-web-components/tabs": "0.45.0", + "@spectrum-web-components/theme": "0.45.0", + "@spectrum-web-components/toast": "0.45.0", + "@spectrum-web-components/underlay": "0.45.0", + "@types/node": "v20.12.2", + "@types/promise-fs": "^2.1.5", + "@vaadin/router": "^1.7.5", + "lit": "^3.1.4", + "tmp-promise": "^3.0.3", + "tslib": "^2.6.3" + }, + "devDependencies": { + "@custom-elements-manifest/analyzer": "^0.10.3", + "@open-wc/eslint-config": "^12.0.3", + "@types/jquery": "^3.5.30", + "@typescript-eslint/eslint-plugin": "^7.16.0", + "@typescript-eslint/parser": "^7.16.0", + "@web/dev-server": "^0.4.6", + "concurrently": "^8.2.2", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "husky": "^9.0.11", + "lint-staged": "^15.2.7", + "prettier": "^3.3.2", + "typescript": "^5.5.3" + }, + "customElements": "custom-elements.json", + "eslintConfig": { + "parser": "@typescript-eslint/parser", + "extends": [ + "@open-wc", + "prettier" + ], + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error", + "import/no-unresolved": "off", + "import/extensions": [ + "error", + "always", + { + "ignorePackages": true + } + ] + } + }, + "prettier": { + "singleQuote": true, + "arrowParens": "avoid" + }, + "lint-staged": { + "*.ts": [ + "prettier --write" + ] + } +} diff --git a/docs/token-diff/src/CodePanel.ts b/docs/token-diff/src/CodePanel.ts new file mode 100644 index 00000000..d4b19bbb --- /dev/null +++ b/docs/token-diff/src/CodePanel.ts @@ -0,0 +1,165 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/card/sp-card.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-compare.js'; +import '@spectrum-web-components/tabs/sp-tabs.js'; +import '@spectrum-web-components/tabs/sp-tab.js'; +import '@spectrum-web-components/tabs/sp-tab-panel.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-copy.js'; +import '@spectrum-web-components/toast/sp-toast.js'; + +export class CodePanel extends LitElement { + static styles = css` + :host { + color: var(--token-diff-text-color, #000); + top: 0; + overflow-x: auto; + margin-left: auto; + margin-right: auto; + flex-wrap: wrap; + } + .page { + background-color: #f8f8f8; + border-radius: 10px; + padding: 10px 25px; + } + code { + display: block; + left: 0; + text-align: left; + flex-wrap: wrap; + white-space: pre-wrap; + word-wrap: break-word; + } + sp-toast { + position: fixed; + top: 1em; + right: 1em; + } + pre { + margin-bottom: 10px; + } + .copy-button { + display: flex; + float: right; + margin-left: auto; + } + .theme { + margin-left: auto; + display: flex; + align-items: flex-end; + } + `; + + constructor(codeSnippet: string, tagOptions: string[]) { + super(); + this.codeSnippet = codeSnippet; + this.tagOptions = tagOptions; + } + + @property({ type: String }) codeSnippet = ''; + @property({ type: Array }) tagOptions: string[] = []; + @property({ type: String }) copyMessage = 'Copy to clipboard'; + @property({ type: String }) curTab = ''; + + firstUpdated() { + this.codeSnippet = this.codeSnippet.trim(); + if (this.tagOptions.length > 0) { + this.curTab = this.tagOptions[0]; + } + } + + __addTabs() { + return html` + + ${this.tagOptions.map(label => { + return this.__newTab(label); + })} + ${this.tagOptions.map(label => { + return this.__newPanel(label); + })} + + `; + } + + __newTab(label: string) { + return html` + (this.curTab = label)} + > + `; + } + + __newPanel(label: string) { + return html` + + ${this.__regularCodeSnippetDisplay(`${label} ${this.codeSnippet}`)} + + `; + } + + __regularCodeSnippetDisplay(code: string) { + return html` +
${code}
+ `; + } + + __copySnippet() { + if (this.tagOptions !== undefined) { + navigator.clipboard.writeText(this.curTab + ' ' + this.codeSnippet); + } else { + navigator.clipboard.writeText(this.codeSnippet); + } + } + + protected override render(): TemplateResult { + return html` +
+
+ ${this.tagOptions.length > 0 + ? this.__addTabs() + : this.__regularCodeSnippetDisplay(this.codeSnippet)} +
+
+ + + + The code snippet has been copied to your clipboard! + + + + + ${this.copyMessage} + + +
+
+ `; + } +} diff --git a/docs/token-diff/src/CompareCard.ts b/docs/token-diff/src/CompareCard.ts new file mode 100644 index 00000000..5ecece30 --- /dev/null +++ b/docs/token-diff/src/CompareCard.ts @@ -0,0 +1,313 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import '@spectrum-web-components/action-group/sp-action-group.js'; +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/picker/sp-picker.js'; +import '@spectrum-web-components/menu/sp-menu-item.js'; +import '@spectrum-web-components/field-label/sp-field-label.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-branch-circle.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-box.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import { property } from 'lit/decorators.js'; +import { + fetchBranchTagOptions, + fetchSchemaOptions, +} from './fetchFromGithub.js'; + +export class CompareCard extends LitElement { + static styles = css` + :host { + display: block; + padding: 25px; + color: var(--token-diff-text-color, #000); + } + .card { + display: inline-block; + width: 391px; + flex-direction: column; + align-items: flex-start; + border-radius: 4px; + border: 1px solid var(--Palette-gray-200, #e6e6e6); + background: var(--Alias-background-app-frame-layer-2, #fff); + } + .label { + color: var( + --Alias-content-typography-heading, + var(--Alias-content-typography-heading, #000) + ); + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 18px; /* 128.571% */ + } + .container { + padding: 24px; + } + .section { + margin-bottom: 15px; + } + .picker-item { + display: flex; + height: fit-content; + margin: 0; + } + img { + vertical-align: middle; + margin-right: 5px; + } + .picker { + width: 341px; + } + @media only screen and (max-width: 480px) { + .card { + width: 280px; + } + .picker { + width: 218px; + } + :host { + padding-left: 0; + padding-right: 0; + } + } + `; + + static properties = { + heading: { type: String }, + toggle: { type: String }, + icon: { type: String }, + branchTagOptions: { type: Array }, + schemaOptions: { type: Array }, + branchOrTag: { type: String }, + schema: { type: String }, + }; + + constructor(heading: string) { + super(); + this.heading = heading; + } + + async firstUpdated() { + this.branchOptions = await fetchBranchTagOptions('branch'); + this.tagOptions = await fetchBranchTagOptions('tag'); + const currentUrl = window.location.href; + const firstQuestionMark = currentUrl.indexOf('?'); + if (firstQuestionMark > 0) { + const parameters = currentUrl.substring(firstQuestionMark + 1); + const paramSplit = parameters.split('&'); + if (this.heading === 'Version A') { + this.branchOrTag = paramSplit[0] + .substring(paramSplit[0].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.schema = paramSplit[2] + .substring(paramSplit[2].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + } else { + this.branchOrTag = paramSplit[1] + .substring(paramSplit[1].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.schema = paramSplit[3] + .substring(paramSplit[3].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + } + this.toggle = this.branchOptions.includes(this.branchOrTag) + ? 'Github branch' + : 'Package release'; + } + if (this.toggle === 'Github branch') { + this.toggle = 'Github branch'; + this.branchSchemaOptions = await fetchSchemaOptions( + 'branch', + this.branchOrTag, + ); + this.tagSchemaOptions = await fetchSchemaOptions( + 'tag', + this.tagOptions[0], + ); + const branchToggle = this.shadowRoot?.getElementById('branch-toggle'); + if (branchToggle) { + branchToggle.setAttribute('selected', ''); + } + } else { + this.toggle = 'Package release'; + this.branchSchemaOptions = await fetchSchemaOptions( + 'branch', + this.branchOptions[0], + ); + this.tagSchemaOptions = await fetchSchemaOptions('tag', this.branchOrTag); + const tagToggle = this.shadowRoot?.getElementById('tag-toggle'); + if (tagToggle) { + tagToggle.setAttribute('selected', ''); + } + } + } + + __setGithubBranchToggle() { + this.toggle = 'Github branch'; + this.branchOrTag = this.branchOptions[0]; + this.__handleSelection(this.branchOptions[0]); + this.__handleSelection(this.branchSchemaOptions[0]); + } + + __setReleaseToggle() { + this.toggle = 'Package release'; + this.branchOrTag = this.tagOptions[0]; + this.__handleSelection(this.tagOptions[0]); + this.__handleSelection(this.tagSchemaOptions[0]); + } + + __createMenuItem(options: string[], showIcons: boolean) { + return options.map( + option => html` + { + if (showIcons) { + this.branchOrTag = option; + this.__handleSelection(this.branchOrTag); + } else { + this.schema = option; + this.__handleSelection(this.schema); + } + }} + > + ${this.__addIcon(option, showIcons)} + + `, + ); + } + + __addIcon(option: string, showIcons: boolean) { + if (showIcons && this.toggle === 'Github branch') { + return html` + ${option}`; + } else if (showIcons && this.toggle === 'Package release') { + return html` ${option}`; + } + return html`${option}`; + } + + async __handleSelection(option: string) { + let detailObj = {}; + if ( + this.toggle === 'Github branch' && + !this.branchSchemaOptions.includes(option) + ) { + detailObj = { branch: option }; + } else if ( + this.toggle === 'Package release' && + !this.tagSchemaOptions.includes(option) + ) { + detailObj = { tag: option }; + } else { + detailObj = { schema: option }; + } + let options = { + detail: detailObj, + bubbles: true, + composed: true, + }; + this.dispatchEvent(new CustomEvent('selection', options)); + } + + @property({ type: String }) heading = 'Version A'; + + @property({ type: String }) toggle = 'Github branch'; + + @property({ type: Array }) branchOptions: string[] = []; + + @property({ type: Array }) tagOptions: string[] = []; + + @property({ type: Array }) branchSchemaOptions: string[] = []; + + @property({ type: Array }) tagSchemaOptions: string[] = []; + + @property({ type: String }) branchOrTag = 'beta'; + + @property({ type: String }) schema = 'all'; + + protected override render(): TemplateResult { + return html` +
+
+
${this.heading}
+ + + + Github branch + + + Package release + + + + ${this.toggle === 'Github branch' + ? this.__createMenuItem(this.branchOptions, true) + : this.__createMenuItem(this.tagOptions, true)} + + Token File + + ${this.toggle === 'Github branch' + ? this.__createMenuItem(this.branchSchemaOptions, false) + : this.__createMenuItem(this.tagSchemaOptions, false)} + + +
+
+ `; + } +} diff --git a/docs/token-diff/src/DiffReport.ts b/docs/token-diff/src/DiffReport.ts new file mode 100644 index 00000000..b41b4302 --- /dev/null +++ b/docs/token-diff/src/DiffReport.ts @@ -0,0 +1,408 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/card/sp-card.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-compare.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-share.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-copy.js'; +import '@spectrum-web-components/toast/sp-toast.js'; +import './compare-card.js'; + +interface TokenDiffJSON { + renamed: any; + deprecated: any; + reverted: any; + added: any; + deleted: any; + updated: { + added: any; + deleted: any; + updated: any; + renamed: any; + }; +} + +export class DiffReport extends LitElement { + static styles = css` + :host { + display: flex; + color: var(--token-diff-text-color, #000); + flex: auto; + top: 0; + overflow-x: hidden; + min-height: 100vh; + flex-wrap: wrap; + } + .title { + color: #000; + font-family: 'Adobe Clean Serif'; + font-size: 58px; + font-style: normal; + font-weight: 900; + line-height: 66.7px; /* 115% */ + margin-top: 15px; + } + h1 { + margin-top: 0; + } + h2 { + color: #000; + font-size: 20px; + font-style: normal; + font-weight: 600; + line-height: 40px; + line-height: 66.7px; + margin-top: 30px; + } + h3 { + color: #000; + font-size: 18px; + font-style: normal; + font-weight: 600; + line-height: 40px; + padding-left: 20px; + } + sp-toast { + position: fixed; + top: 1em; + right: 1em; + } + .theme { + width: 100%; + } + .report-text { + color: #222; + padding-left: 20px; + font-size: 14px; + } + .page { + display: flex; + flex-wrap: wrap; + background-color: #f8f8f8; + padding-top: 25px; + padding-bottom: 25px; + padding-left: 50px; + padding-right: 50px; + border-radius: 10px; + margin-bottom: 15px; + width: 100%; + height: fit-content; + } + .share-header { + display: inline-block; + align-items: flex-end; + width: 100%; + } + .share-button { + display: flex; + float: right; + } + #reportBody { + max-width: inherit; + overflow-x: wrap; + } + .updated-section { + flex-wrap: wrap; + } + @media only screen and (max-width: 600px) { + .page { + padding-left: 25px; + padding-right: 25px; + } + h1 { + margin-top: 15px; + } + h2 { + font-size: 18px; + } + h3 { + font-size: 16px; + } + } + `; + + constructor( + tokenDiffJSON: TokenDiffJSON, + originalBranchOrTag: string, + originalSchema: string, + updatedBranchOrTag: string, + updatedSchema: string, + url: string, + ) { + super(); + this.tokenDiffJSON = tokenDiffJSON; + this.originalBranchOrTag = originalBranchOrTag; + this.originalSchema = originalSchema; + this.updatedBranchOrTag = updatedBranchOrTag; + this.updatedSchema = updatedSchema; + this.url = url; + } + + firstUpdated() { + this.totalTokens = + Object.keys(this.tokenDiffJSON.renamed).length + + Object.keys(this.tokenDiffJSON.deprecated).length + + Object.keys(this.tokenDiffJSON.reverted).length + + Object.keys(this.tokenDiffJSON.added).length + + Object.keys(this.tokenDiffJSON.deleted).length + + Object.keys(this.tokenDiffJSON.updated.added).length + + Object.keys(this.tokenDiffJSON.updated.deleted).length + + Object.keys(this.tokenDiffJSON.updated.updated).length + + Object.keys(this.tokenDiffJSON.updated.renamed).length; + this.totalUpdatedTokens = + Object.keys(this.tokenDiffJSON.updated.added).length + + Object.keys(this.tokenDiffJSON.updated.deleted).length + + Object.keys(this.tokenDiffJSON.updated.updated).length + + Object.keys(this.tokenDiffJSON.updated.renamed).length; + } + + @property() tokenDiffJSON: any = { + renamed: {}, + deprecated: {}, + reverted: {}, + added: {}, + deleted: {}, + updated: { + added: {}, + deleted: {}, + updated: {}, + renamed: {}, + }, + }; + + @property({ type: Number }) totalTokens = 0; + @property({ type: String }) originalBranchOrTag = ''; + @property({ type: String }) originalSchema = ''; + @property({ type: String }) updatedBranchOrTag = ''; + @property({ type: String }) updatedSchema = ''; + @property({ type: String }) url = ''; + @property({ type: Number }) totalUpdatedTokens = 0; + + readonly order: any = [ + 'renamed', + 'deprecated', + 'reverted', + 'added', + 'deleted', + 'updated', + ]; + readonly emojis: any = ['📝', '🕒', '⏰', '🔼', '🔽', '🆕']; + + readonly orderForUpdatedSection: any = [ + 'renamed', + 'added', + 'deleted', + 'updated', + ]; + + __createArrowItems(original: string, updated: string) { + return html` +

+ ${original.replace(/{|}/g, '')} -> ${updated.replace(/{|}/g, '')} +

+ `; + } + + __createItemsWithDescription(token: string, description: string) { + return html`

${token}: ${description}

`; + } + + __createItems(token: string) { + return html`

${token.replace(/{|}/g, '')}

`; + } + + __createEmbeddedItems(tokens: any) { + return Object.keys(tokens).map((token: any) => { + return html` +

${token}

+
+ ${this.__printNestedChanges(tokens[token])} +
+ `; + }); + } + + __printNestedChanges(token: any): any { + if (token['path'] !== undefined) { + return html` +

${token['path']}

+
${this.__determineChanges(token)}
+ `; + } + return Object.keys(token).map((property: any) => { + return this.__printNestedChanges(token[property]); + }); + } + + __determineChanges(token: any) { + if (token['original-value'] === undefined) { + return this.__createItems( + token['path'].includes('$schema') + ? `"${token['new-value']}"` + : token['new-value'], + ); + } else if (token['path'].includes('$schema')) { + const newValue = token['new-value'].split('/'); + const originalPart = `"${token['original-value']}" ->`; + const updatedPart = + `"${token['new-value'].substring(0, token['new-value'].length - newValue[newValue.length - 1].length)}` + + `${newValue[newValue.length - 1].split('.')[0]}` + + `.${newValue[newValue.length - 1].split('.')[1]}"`; + const part = html`${this.__createItems(originalPart)} + ${this.__createItems(updatedPart)}`; + return part; + } else { + return this.__createArrowItems( + token['original-value'], + token['new-value'], + ); + } + } + + __shareReport() { + const currentUrl = window.location.href; + if (currentUrl) { + navigator.clipboard.writeText(currentUrl); + } + } + + __copyReport() { + const reportBody = this.shadowRoot?.getElementById('reportBody'); + if (reportBody) { + const textContent = reportBody.textContent; + if (textContent) { + navigator.clipboard.writeText(textContent); + } + } + } + + protected override render(): TemplateResult { + return html` +
+ + + + The report url has been copied to your clipboard! + + + + + The report's contents has been copied to your clipboard! + + + +
+

Tokens Changed (${this.totalTokens})

+

${this.originalBranchOrTag} | ${this.updatedBranchOrTag}

+

${this.originalSchema} | ${this.updatedSchema}

+ ${this.order.map((section: string, idx: number) => { + this.totalUpdatedTokens = + Object.keys(this.tokenDiffJSON.updated.added).length + + Object.keys(this.tokenDiffJSON.updated.deleted).length + + Object.keys(this.tokenDiffJSON.updated.updated).length + + Object.keys(this.tokenDiffJSON.updated.renamed).length; + let name: string; + let totalTokens: number; + if (section === 'deprecated') { + name = 'Newly Deprecated'; + } else if (section === 'reverted') { + name = 'Newly "Un-deprecated"'; + } else { + name = `${section.charAt(0).toUpperCase()}${section.substring(1)}`; + } + totalTokens = + section === 'updated' + ? this.totalUpdatedTokens + : Object.keys(this.tokenDiffJSON[section]).length; + if ( + (section === 'updated' && this.totalUpdatedTokens > 0) || + (section !== 'updated' && + Object.keys(this.tokenDiffJSON[section]).length > 0) + ) { + return html` +
+

${`${this.emojis[idx]} ${name} (${totalTokens})`}

+ ${Object.keys(this.tokenDiffJSON[section]).map( + (token: any) => { + switch (section) { + case 'renamed': + return this.__createArrowItems( + this.tokenDiffJSON.renamed[token]['old-name'], + token, + ); + case 'deprecated': + return this.__createItemsWithDescription( + token, + this.tokenDiffJSON.deprecated[token][ + 'deprecated_comment' + ], + ); + case 'updated': + break; + default: + return this.__createItems(token); + } + }, + )} +
+ `; + } + })} +
+ ${this.orderForUpdatedSection.map((name: any) => { + if (Object.keys(this.tokenDiffJSON.updated[name]).length > 0) { + return html` +
+

+ ${`${this.emojis[this.emojis.length - 1]} ${name.charAt(0).toUpperCase()}${name.substring(1)} Properties`} + (${Object.keys(this.tokenDiffJSON.updated[name]) + .length}) +

+
+ ${this.__createEmbeddedItems( + this.tokenDiffJSON.updated[name], + )} +
+
+ `; + } + })} +
+
+
+
+ `; + } +} diff --git a/docs/token-diff/src/GettingStarted.ts b/docs/token-diff/src/GettingStarted.ts new file mode 100644 index 00000000..d1ff7be9 --- /dev/null +++ b/docs/token-diff/src/GettingStarted.ts @@ -0,0 +1,411 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/card/sp-card.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-compare.js'; +import './compare-card.js'; +import './code-panel.js'; +import '@spectrum-web-components/table/sp-table.js'; +import '@spectrum-web-components/table/sp-table-body.js'; +import '@spectrum-web-components/table/sp-table-cell.js'; +import '@spectrum-web-components/table/sp-table-head.js'; +import '@spectrum-web-components/table/sp-table-head-cell.js'; +import '@spectrum-web-components/table/sp-table-row.js'; + +export class GettingStarted extends LitElement { + static styles = css` + :host { + display: flex; + padding-top: 25px; + color: var(--token-diff-text-color, #000); + flex: auto; + top: 0; + overflow-x: hidden; + min-height: 100vh; + flex-wrap: wrap; + width: auto; + box-sizing: border-box; + } + .title { + color: #000; + font-family: 'Adobe Clean Serif'; + font-size: 58px; + font-style: normal; + font-weight: 900; + line-height: 66.7px; /* 115% */ + margin-top: 15px; + } + .subtitle { + color: #000; + font-family: 'Adobe Clean Serif'; + font-size: 40px; + font-style: normal; + font-weight: 900; + margin-top: 15px; + } + .text { + color: #222; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: 27px; + margin-bottom: 10px; + margin-top: 10px; + } + .section { + padding-bottom: 20px; + padding-top: 20px; + } + .container { + padding-bottom: 20px; + } + .ending-panel { + margin-bottom: 10px; + } + .table { + overflow-x: auto; + resize: none; + position: relative; + margin-top: 10px; + margin-bottom: 10px; + } + .page { + display: flex; + justify-content: center; + flex-wrap: wrap; + } + @media only screen and (max-width: 1100px) { + :host { + display: flex; + flex-wrap: wrap; + box-sizing: border-box; + } + .title { + padding-top: 50px; + } + } + @media only screen and (max-width: 600px) { + :host { + display: block; + box-sizing: border-box; + } + .title { + padding-top: 50px; + } + .table { + overflow-x: auto; + resize: none; + width: 100%; + } + .theme { + min-width: calc(100% - 50px); + } + .row { + width: 100vw; + } + } + `; + + protected override render(): TemplateResult { + return html` +
+ +
+
+ Getting started +
+

+ Other than the web version of the token diff generator, there is + also a npm package containing the CLI and standalone Javascript + library that you can use in your development environment. Both the + CLI and the standalone Javascript library are located in the + Spectrum Tokens monorepo. +

+
+
+
+ Installation +
+

+ Installing the package is done preferably with pnpm, but npm or + yarn will also work. +

+
+ +
+
+
+
+ Imports +
+

+ Import the token diff generator as a module per ES6 standards. +

+
+ +
+
+
+
+ Token diff generator library +
+

+ The token diff generator library holds the functions used to + generate diffs between two compilations of design tokens. It uses + the deep-object-diff open-source library to extract a JSON object + containing the changes, and then runs that JSON object through + various functions to tailor the result specifically for design + tokens.

+ An example of tailoring involves detecting when tokens are + renamed. The deep-object-diff library is unable to tell whether or + not a token has been renamed due to it being designed for general + JSON objects. Instead, it will mark the new name as a new token + being added to the schema and the old name as a deleted token. + This is where the token diff generator comes in. It goes through + the changes detected by deep-object-diff and checks if a token is + renamed via its uuid.

+ Since the token diff generator relies on all tokens having their + own uuid, the library—including the CLI and web version—will not + work for versions of spectrum-tokens before the + @adobe/spectrum-tokens@12.26.0 release. +

+
+
+
+ Usage examples +
+

+ The most basic usage case is calling tokenDiff with two JSON + objects, one for the original token(s) and the other for the + updated token(s). +

+ +

+ If you are interested in comparing tokens locally between + different versions or branches, you can use the following code + snippet. +

+ +

+ Both of these examples output a JSON object containing the changes + made between the two schema. +

+
+
+
+ Token diff cli +
+

+ The token diff cli is a command line interface tool used to + generate reports in the terminal with data from the token diff + generator. It is included in the same package as the standalone + Javascript library and uses the commander open-source library. +

+
+
+
+ Commands +
+

+ There currently is only one command to run in the CLI. It + generates a diff report for two inputted schema. +

+
+ +
+
+
+
+ Options +
+
+ + + Shorthand + Name + Argument(s) + Description + + + + -y + -y + null + answers yes to removing deprecated status of + token(s) + + + -otv + --old-token-version + ${``} + npm package version/github tag to pull old tokens + from + + + -ntv + --new-token-version + ${``} + npm package version/github tag to pull new tokens + from + + + -otb + --old-token-branch + ${``} + branch to fetch old token data from + + + -ntb + --new-token-branch + ${``} + branch to fetch new token data from + + + -t + --test + ${``} + indicates test mode and runs only on tokens passed + in + + + -tn + --token-names + ${``} + indicates specific tokens to compare + + + +
+
+
+
+ Usage examples +
+

+ An example of using the cli involves running the + report + command with two branches and/or releases. +

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ `; + } +} diff --git a/docs/token-diff/src/NavBar.ts b/docs/token-diff/src/NavBar.ts new file mode 100644 index 00000000..a7a8cdaa --- /dev/null +++ b/docs/token-diff/src/NavBar.ts @@ -0,0 +1,106 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import '@spectrum-web-components/sidenav/sp-sidenav.js'; +import '@spectrum-web-components/sidenav/sp-sidenav-item.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; + +export class NavBar extends LitElement { + static styles = css` + :host { + padding: 25px; + color: var(--token-diff-text-color, #000); + min-width: fit-content; + } + .logo-text { + display: flex; + color: #000; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: 111%; /* 22.2px */ + float: right; + padding-left: 10px; + padding-top: 15px; + } + .logo-section { + display: flex; + align-items: center; + padding-bottom: 15px; + margin: auto; + /* justify-content: center; */ + } + .entire-bar { + background-color: '#F8F8F8'; + width: fit-content; + } + img { + align-content: center; + vertical-align: middle; + padding-left: 14px; + } + a { + text-decoration: none; + } + @media only screen and (max-width: 1100px) { + :host { + padding: auto; + } + } + `; + + async __handleSelection() { + this.dispatchEvent( + new Event('close', { + bubbles: true, + composed: true, + }), + ); + } + + protected override render(): TemplateResult { + return html` + + `; + } +} diff --git a/docs/token-diff/src/PageContainer.ts b/docs/token-diff/src/PageContainer.ts new file mode 100644 index 00000000..f5ca922f --- /dev/null +++ b/docs/token-diff/src/PageContainer.ts @@ -0,0 +1,229 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import { Router } from '@vaadin/router'; +import './token-diff.js'; +import './getting-started.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/overlay/sp-overlay.js'; +import '@spectrum-web-components/popover/sp-popover.js'; +import '@spectrum-web-components/divider/sp-divider.js'; + +export class PageContainer extends LitElement { + static styles = css` + .page { + display: flex; + max-width: 100vw; + } + .right { + padding-left: 100px; + padding-right: 100px; + background-color: white; + display: flex; + flex-wrap: wrap; + width: 100%; + box-sizing: border-box; + } + #outlet { + overflow-y: scroll; + background-color: white; + display: flex; + overflow-x: hidden; + flex-wrap: wrap; + width: inherit; + } + .navigation { + padding: 12px; + border-bottom: 1px solid var(--spectrum-gray-200); + background-color: white; + display: none; + background-color: white; + overflow: hidden; + position: fixed; + width: 100%; + z-index: 9999; + } + .mobile-nav-bar { + height: 100vh; + overflow-y: hidden; + border-style: none; + } + footer { + display: flex; + align-items: center; + width: 100%; + overflow-y: hidden; + } + .footer-group { + display: flex; + justify-content: flex-end; + align-items: center; + width: 100%; + flex-wrap: wrap; + } + ul { + display: inline-block; + justify-content: center; + } + a { + text-decoration: none; + color: #222; + } + .footer-text { + font-size: 11px; + font-style: normal; + font-weight: 400; + line-height: 11px; /* 100% */ + padding-left: 0; + } + .adchoice-icon { + display: block; + line-height: 1.4; + width: 25px; + height: 25px; + text-align: center; + padding-right: 5px; + } + .adchoice-span { + align-items: center; + display: flex; + width: fit-content; + overflow-y: hidden; + flex-wrap: wrap; + } + .separator { + margin: 0 8px; + color: #4b4b4b; + font-size: 11px; + } + .divider { + margin-top: 20px; + } + @media only screen and (max-width: 1100px) { + .navigation { + display: inline-block; + background-color: white; + } + .nav-bar { + display: none; + } + .right { + padding-left: 25px; + padding-right: 25px; + } + } + @media only screen and (min-width: 1100px) { + .navigation { + display: none; + background-color: white; + } + .nav-bar { + display: block; + } + } + `; + + firstUpdated() { + const router = new Router(this.shadowRoot!.querySelector('#outlet')); + router.setRoutes([ + { path: `/demo/:object?`, component: 'token-diff' }, + { path: '/getting-started', component: 'getting-started' }, + ]); + } + + protected override render(): TemplateResult { + return html` +
+
+ + + +
+
+ +
+ + + + + + +
+
+ + +
+
+
+ + `; + } +} diff --git a/docs/token-diff/src/TokenDiff.ts b/docs/token-diff/src/TokenDiff.ts new file mode 100644 index 00000000..a5a2bb5b --- /dev/null +++ b/docs/token-diff/src/TokenDiff.ts @@ -0,0 +1,283 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { html, css, LitElement, TemplateResult } from 'lit'; +import { property } from 'lit/decorators.js'; +import '@spectrum-web-components/theme/sp-theme.js'; +import '@spectrum-web-components/theme/src/themes.js'; +import '@spectrum-web-components/card/sp-card.js'; +import '@spectrum-web-components/button/sp-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-compare.js'; +import './compare-card.js'; +import './DiffReport.js'; +import './diff-report.js'; +import { DiffReport } from './DiffReport.js'; +import { + fetchBranchTagOptions, + fetchSchemaOptions, +} from './fetchFromGithub.js'; +import tokenDiff from '@adobe/token-diff-generator/src/lib/index.js'; +import { fileImport } from './fetchFromGithub.js'; + +export class TokenDiff extends LitElement { + static styles = css` + :host { + display: flex; + padding-top: 25px; + color: var(--token-diff-text-color, #000); + flex: auto; + top: 0; + overflow-x: hidden; + min-height: 100vh; + flex-wrap: wrap; + } + .title { + color: #000; + font-family: 'Adobe Clean Serif'; + font-size: 58px; + font-style: normal; + font-weight: 900; + line-height: 66.7px; /* 115% */ + margin-top: 15px; + } + .warning-text { + color: #222; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: 27px; /* 150% */ + margin-bottom: 40px; + } + .page { + display: flex; + justify-content: center; + flex-wrap: wrap; + } + .compare-button { + margin-top: 40px; + margin-bottom: 65px; + } + .skeleton { + animation: skeleton-loading 1s linear infinite alternate; + } + + @keyframes skeleton-loading { + 0% { + background-color: hsl(200, 20%, 80%); + } + 100% { + background-color: hsl(200, 20%, 95%); + } + } + @media only screen and (max-width: 1100px) { + :host { + overflow-x: auto; + } + .page { + padding-left: 0; + padding-right: 0; + } + .title { + padding-top: 50px; + } + } + `; + + @property({ type: String }) originalBranchOrTag = ''; + @property({ type: String }) updatedBranchOrTag = ''; + @property({ type: String }) originalSchema = ''; + @property({ type: String }) updatedSchema = ''; + @property({ type: String }) originalVers = ''; + @property({ type: String }) updatedVers = ''; + @property({ type: Array }) branchOptions: string[] = []; + @property({ type: Array }) tagOptions: string[] = []; + @property({ type: Array }) branchSchemaOptions: string[] = []; + @property({ type: Array }) tagSchemaOptions: string[] = []; + + __originalCardListener(e: CustomEvent) { + this.__updatedProperty(true, e.detail); + } + + __updatedProperty(original: boolean, newValue: string) { + const key = Object.keys(newValue)[0]; + if (original) { + if (key !== 'schema') { + this.originalBranchOrTag = Object.values(newValue)[0]; + this.originalVers = key === 'branch' ? 'branch' : 'tag'; + } else { + this.originalSchema = Object.values(newValue)[0]; + } + } else { + if (key !== 'schema') { + this.updatedBranchOrTag = Object.values(newValue)[0]; + this.updatedVers = key === 'branch' ? 'branch' : 'tag'; + } else { + this.updatedSchema = Object.values(newValue)[0]; + } + } + } + + __updatedCardListener(e: CustomEvent) { + this.__updatedProperty(false, e.detail); + } + + async __generateReport() { + const compareButton = this.shadowRoot?.getElementById('compareButton'); + compareButton?.classList.add('skeleton', 'skeleton-loading'); + const report = this.shadowRoot?.getElementById('report')!; + if (report.firstChild) { + report.removeChild(report.firstChild); + } + const originalSchemaName: string[] = [this.originalSchema]; + const updatedSchemaName: string[] = [this.updatedSchema]; + const [originalSchema, updatedSchema] = await Promise.all([ + fileImport( + originalSchemaName, + this.originalVers === 'branch' ? undefined : this.originalBranchOrTag, + this.originalVers === 'branch' ? this.originalBranchOrTag : undefined, + ), + fileImport( + updatedSchemaName, + this.updatedVers === 'branch' ? undefined : this.updatedBranchOrTag, + this.updatedVers === 'branch' ? this.updatedBranchOrTag : undefined, + ), + ]); + const reportJSON = await tokenDiff(originalSchema, updatedSchema); + const diffReport = document.createElement('diff-report') as DiffReport; + diffReport.tokenDiffJSON = reportJSON; + this.originalBranchOrTag = + this.originalBranchOrTag === undefined + ? 'beta' + : this.originalBranchOrTag; + this.updatedBranchOrTag = + this.updatedBranchOrTag === undefined ? 'beta' : this.updatedBranchOrTag; + diffReport.originalBranchOrTag = this.originalBranchOrTag; + diffReport.updatedBranchOrTag = this.updatedBranchOrTag; + diffReport.originalSchema = this.originalSchema; + diffReport.updatedSchema = this.updatedSchema; + let url = new URL( + 'http://localhost:8000' + + '/demo?original_branch_tag=' + + this.originalBranchOrTag + + '&updated_branch_tag=' + + this.updatedBranchOrTag + + '&original_schema=' + + this.originalSchema + + '&updated_schema=' + + this.updatedSchema, + ); + diffReport.url = url.href; + setTimeout(() => { + if (report) { + report.appendChild(diffReport); + let options = { + detail: url.href, + bubbles: true, + composed: true, + }; + this.dispatchEvent(new CustomEvent('urlChange', options)); + window.history.pushState(reportJSON, 'Report', url.href); + compareButton?.classList.remove('skeleton', 'skeleton-loading'); + } + }, 1000); + } + + async firstUpdated() { + const currentUrl = window.location.href; + const firstQuestionMark = currentUrl.indexOf('?'); + this.branchOptions = await fetchBranchTagOptions('branch'); + this.branchSchemaOptions = await fetchSchemaOptions( + 'branch', + this.branchOptions[0], + ); + if (firstQuestionMark > 0) { + const parameters = currentUrl.substring(firstQuestionMark + 1); + const paramSplit = parameters.split('&'); + this.originalBranchOrTag = paramSplit[0] + .substring(paramSplit[0].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.originalVers = this.branchOptions.includes(this.originalBranchOrTag) + ? 'branch' + : 'tag'; + this.updatedBranchOrTag = paramSplit[1] + .substring(paramSplit[1].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.updatedVers = this.branchOptions.includes(this.updatedBranchOrTag) + ? 'branch' + : 'tag'; + this.originalSchema = paramSplit[2] + .substring(paramSplit[2].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.updatedSchema = paramSplit[3] + .substring(paramSplit[3].indexOf('=') + 1) + .replaceAll('%20', ' ') + .replaceAll('%40', '@'); + this.__generateReport(); + } else { + this.originalBranchOrTag = this.updatedBranchOrTag = + this.branchOptions[0]; + this.originalSchema = this.updatedSchema = this.branchSchemaOptions[0]; + } + this.originalVers = this.branchOptions.includes(this.originalBranchOrTag) + ? 'branch' + : 'tag'; + this.updatedVers = this.branchOptions.includes(this.updatedBranchOrTag) + ? 'branch' + : 'tag'; + } + + protected override render(): TemplateResult { + return html` +
+ +
+ Token diff generator +
+
+ WARNING: Will either be inaccurate or will throw an error if used + for releases or branches that use tokens from before + @adobe/spectrum-tokens@12.26.0! +
+
+ + +
+
+ + + Compare + +
+
+
+
+ `; + } +} diff --git a/docs/token-diff/src/assets/adobe_logo.svg b/docs/token-diff/src/assets/adobe_logo.svg new file mode 100644 index 00000000..5926c977 --- /dev/null +++ b/docs/token-diff/src/assets/adobe_logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/docs/token-diff/src/code-panel.ts b/docs/token-diff/src/code-panel.ts new file mode 100644 index 00000000..de6545c0 --- /dev/null +++ b/docs/token-diff/src/code-panel.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { CodePanel } from './CodePanel.js'; + +window.customElements.define('code-panel', CodePanel); diff --git a/docs/token-diff/src/compare-card.ts b/docs/token-diff/src/compare-card.ts new file mode 100644 index 00000000..8cb5770e --- /dev/null +++ b/docs/token-diff/src/compare-card.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { CompareCard } from './CompareCard.js'; + +window.customElements.define('compare-card', CompareCard); diff --git a/docs/token-diff/src/diff-report.ts b/docs/token-diff/src/diff-report.ts new file mode 100644 index 00000000..ed865ab7 --- /dev/null +++ b/docs/token-diff/src/diff-report.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { DiffReport } from './DiffReport.js'; + +window.customElements.define('diff-report', DiffReport); diff --git a/docs/token-diff/src/fetchFromGithub.ts b/docs/token-diff/src/fetchFromGithub.ts new file mode 100644 index 00000000..5e331557 --- /dev/null +++ b/docs/token-diff/src/fetchFromGithub.ts @@ -0,0 +1,97 @@ +import { githubAPIKey } from '../github-api-key.js'; + +/** + * Fetches branch or tag options + * @param {string} type - either branch or tag + * @returns {Promise} a JSON object containing either branches or release versions/tags + */ +export async function fetchBranchTagOptions(type: string) { + const url = + type === 'branch' + ? 'https://api.github.com/repos/adobe/spectrum-tokens/branches' + : 'https://api.github.com/repos/adobe/spectrum-tokens/releases'; + return await fetch(url, { + method: 'GET', + headers: { + Authorization: `token ${githubAPIKey}`, + }, + }).then(async response => { + const arr: any[] | PromiseLike = []; + const obj = await response.json(); + Object.values(obj).forEach((value: any) => { + if (!value.name.includes('token-diff-generator')) { + // need to exclude releases without tokens + arr.push(value.name); + } + }); + return arr; + }); +} + +/** + * Fetches list of token files for a specific branch or tag using Github API + * @param {string} branchOrTagKey - type of desired options (branch or tag) + * @param {string} branchOrTag - the specific branch or tag name whose token files you want to fetch + * @returns + */ +export async function fetchSchemaOptions( + branchOrTagKey: string, + branchOrTag: string, +): Promise { + let schemaOptions: string[] = []; + const source = 'https://raw.githubusercontent.com/adobe/spectrum-tokens/'; + let branchOrTagArr = branchOrTag.split('@'); + const url = + branchOrTagKey !== 'branch' + ? source + + '%40adobe/spectrum-tokens%40' + + branchOrTagArr[branchOrTagArr.length - 1] + : source + branchOrTag; + schemaOptions = await fetchTokens('manifest.json', url); + schemaOptions.unshift('all'); + return schemaOptions; +} + +/** + * Fetchs tokens from specified token file and branch/tag + * @param {string} tokenName - the name of the token file + * @param {string} url - the source url + the branch or tag + * @returns {Promise} a JSON object containing the tokens from specified token file + */ +async function fetchTokens(tokenName: string, url: string): Promise { + return (await fetch(`${url}/packages/tokens/${tokenName}`)).json(); +} + +const source = 'https://raw.githubusercontent.com/adobe/spectrum-tokens/'; + +/** + * Returns file with given file name as a JSON object (took this from diff.js) + * @param {string} givenTokenNames - the name of the target file + * @param {string} givenVersion - the intended package version (full name) + * @param {string} givenBranch - the intended branch + * @returns {object} the target file as a JSON object + */ +export async function fileImport( + givenTokenNames: string[], + givenVersion: string | undefined, + givenBranch: string | undefined, +): Promise { + const version = givenVersion || 'latest'; + const branch = givenBranch || 'main'; + const link = + version !== 'latest' + ? source + version.replace('@', '%40') + : source + branch; + let tokenNames: string[]; + if (givenTokenNames[0] === 'all') { + tokenNames = await fetchTokens('manifest.json', link); + } else { + tokenNames = givenTokenNames; + } + const result = {}; + for (let i = 0; i < tokenNames.length; i++) { + const tokens = await fetchTokens(tokenNames[i], link); + Object.assign(result, tokens); + } + return result; +} diff --git a/docs/token-diff/src/getting-started.ts b/docs/token-diff/src/getting-started.ts new file mode 100644 index 00000000..8444f424 --- /dev/null +++ b/docs/token-diff/src/getting-started.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { GettingStarted } from './GettingStarted.js'; + +window.customElements.define('getting-started', GettingStarted); diff --git a/docs/token-diff/src/index.ts b/docs/token-diff/src/index.ts new file mode 100644 index 00000000..410d3c11 --- /dev/null +++ b/docs/token-diff/src/index.ts @@ -0,0 +1,15 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +export { TokenDiff } from './TokenDiff.js'; +export { NavBar } from './NavBar.js'; +export { CompareCard } from './CompareCard.js'; +export { GettingStarted } from './GettingStarted.js'; diff --git a/docs/token-diff/src/nav-bar.ts b/docs/token-diff/src/nav-bar.ts new file mode 100644 index 00000000..9917ff36 --- /dev/null +++ b/docs/token-diff/src/nav-bar.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { NavBar } from './NavBar.js'; + +window.customElements.define('nav-bar', NavBar); diff --git a/docs/token-diff/src/page-container.ts b/docs/token-diff/src/page-container.ts new file mode 100644 index 00000000..9998f1b0 --- /dev/null +++ b/docs/token-diff/src/page-container.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { PageContainer } from './PageContainer.js'; + +window.customElements.define('page-container', PageContainer); diff --git a/docs/token-diff/src/token-diff.ts b/docs/token-diff/src/token-diff.ts new file mode 100644 index 00000000..0f5027e4 --- /dev/null +++ b/docs/token-diff/src/token-diff.ts @@ -0,0 +1,14 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { TokenDiff } from './TokenDiff.js'; + +window.customElements.define('token-diff', TokenDiff); diff --git a/docs/token-diff/src/typekit.js b/docs/token-diff/src/typekit.js new file mode 100644 index 00000000..08b346b2 --- /dev/null +++ b/docs/token-diff/src/typekit.js @@ -0,0 +1,50 @@ +window.addEventListener("DOMContentLoaded", function () { + "use strict"; + + var config = { + kitId: + document.querySelector('[lang]:not([lang="en-US"])') === null + ? "mge7bvf" + : "rok6rmo", + scriptTimeout: 3000, + active: function () { + var loader = document.getElementById("loader"); + if (loader) { + setTimeout(function () { + // Hide the loader + loader.style.display = "none"; + }, 125); + } + }, + }; + + if (!window.Typekit) { + // we load the typescript only once + var h = document.getElementsByTagName("html")[0]; + h.className += " wf-loading"; + var t = setTimeout(function () { + h.className = h.className.replace(/(\s|^)wf-loading(\s|$)/g, " "); + h.className += " wf-inactive"; + }, config.scriptTimeout); + var tk = document.createElement("script"), + d = false; + + // Always load over https + tk.src = "https://use.typekit.net/" + config.kitId + ".js"; + tk.type = "text/javascript"; + tk.async = "true"; + tk.onload = tk.onreadystatechange = function () { + var a = this.readyState; + if (d || (a && a !== "complete" && a !== "loaded")) { + return; + } + d = true; + clearTimeout(t); + try { + Typekit.load(config); + } catch (b) {} + }; + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(tk, s); + } + }); \ No newline at end of file diff --git a/docs/token-diff/tsconfig.json b/docs/token-diff/tsconfig.json new file mode 100644 index 00000000..d2a1648f --- /dev/null +++ b/docs/token-diff/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es2021", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "noEmitOnError": true, + "lib": ["es2021", "dom", "DOM.Iterable"], + "strict": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "importHelpers": true, + "outDir": "dist", + "sourceMap": true, + "inlineSources": true, + "rootDir": "./", + "declaration": true, + "incremental": true, + "skipLibCheck": true, + "allowJs": true, + "esModuleInterop": true, + "noImplicitAny": false + }, + "include": ["**/*.ts", "src/typekit.js"], + "typeRoots": [ + "node_modules/@types" + ] +} diff --git a/docs/token-diff/web-dev-server.config.js b/docs/token-diff/web-dev-server.config.js new file mode 100644 index 00000000..e09b6bbe --- /dev/null +++ b/docs/token-diff/web-dev-server.config.js @@ -0,0 +1,27 @@ +// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr'; + +/** Use Hot Module replacement by adding --hmr to the start command */ +const hmr = process.argv.includes('--hmr'); + +export default /** @type {import('@web/dev-server').DevServerConfig} */ ({ + open: '/demo/', + /** Use regular watch mode if HMR is not enabled. */ + watch: !hmr, + /** Resolve bare module imports */ + nodeResolve: { + exportConditions: ['browser', 'development'], + }, + + /** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */ + // esbuildTarget: 'auto' + + /** Set appIndex to enable SPA routing */ + // appIndex: 'demo/index.html', + + plugins: [ + /** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */ + // hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.lit] }), + ], + + // See documentation for all available options +});