diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 044a8fe77..16709b075 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -26,6 +26,10 @@ jobs: with: node-version: ${{ steps.nvm.outputs.nvmrc }} + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install 🔧 run: npm ci diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3bbe718e5..46c0d7cbb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,6 +22,10 @@ jobs: node-version: ${{ steps.nvm.outputs.nvmrc }} cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install and Build 🔧 run: | npm ci diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 8c38ede8c..16f509246 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -38,6 +38,10 @@ jobs: node-version: ${{ steps.nvm.outputs.nvmrc }} cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install 🔧 run: npm ci --ignore-scripts @@ -58,6 +62,10 @@ jobs: node-version: ${{ needs.setup.outputs.nvmrc }} cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Restore npm installs and Lerna setup run: npm ci @@ -84,6 +92,10 @@ jobs: node-version: ${{ needs.setup.outputs.nvmrc }} cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Restore npm installs and Lerna setup run: npm ci @@ -116,6 +128,10 @@ jobs: with: node-version: ${{ steps.nvm.outputs.nvmrc }} + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install 🔧 run: npm ci @@ -147,6 +163,10 @@ jobs: with: node-version: ${{ steps.nvm.outputs.nvmrc }} + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install 🔧 run: npm ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e85c24981..f0bd01265 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,6 +30,10 @@ jobs: node-version: ${{ steps.nvm.outputs.nvmrc }} cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - name: Install 🔧 run: npm ci diff --git a/.npmrc b/.npmrc index 521a9f7c0..41af43f58 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,3 @@ +registry=https://registry.npmjs.org/ legacy-peer-deps=true +save-exact=true diff --git a/.nvmrc b/.nvmrc index 5e0828ad1..05aa448d5 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.16.1 +v21.6.2 diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..ae19c4d45 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 21.6.2 +bun 1.1.33 diff --git a/README.md b/README.md index 0461a1f8e..a8f141a90 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,15 @@ Next generation UI component library, view our docs at [tablekit.tablecheck.com] ## Installation +Install [ASDF](https://asdf-vm.com/) and it's nodejs and bun plugins. + +```shell +asdf plugin add nodejs +asdf plugin add bun +``` + ```shell -nvm use +asdf current npm ci npm start ``` diff --git a/package-lock.json b/package-lock.json index aab848544..99c788f01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19368,6 +19368,22 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -19377,6 +19393,12 @@ "node": "*" } }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "dev": true + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -23370,6 +23392,25 @@ "node": ">=0.10" } }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -23382,6 +23423,226 @@ "node": ">=4" } }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/decompress-tar/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-tar/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/decompress-tar/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/decompress-tar/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/decompress-tar/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/decompress-tar/node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "dev": true, + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -26792,6 +27053,15 @@ "node": ">=12" } }, + "node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -30439,6 +30709,12 @@ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "dev": true + }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -46923,6 +47199,25 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -48691,6 +48986,15 @@ "node": ">=8" } }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -49982,6 +50286,12 @@ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -50650,6 +50960,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -54085,6 +54429,7 @@ "devDependencies": { "@emotion/react": "11.10.6", "chalk": "5.2.0", + "decompress": "4.2.1", "fs-extra": "11.1.0", "lodash": "4.17.21", "pluralize": "8.0.0", @@ -54138,7 +54483,6 @@ "pluralize": "8.0.0", "postcss": "8.4.38", "postcss-nesting": "12.1.5", - "ts-node": "10.9.2", "typescript": "4.9.5" } }, diff --git a/system/core/package.json b/system/core/package.json index 82553d55d..370ffe214 100644 --- a/system/core/package.json +++ b/system/core/package.json @@ -24,9 +24,9 @@ "test:watch": "tablecheck-scripts test --env=jsdom", "tsc": "tablecheck-scripts tsc", "tsc:watch": "tablecheck-scripts tsc -w", - "update:components": "node scripts/generateComponents.mjs", - "update:exports": "node scripts/generateIndex.mjs", - "update:figma": "node scripts/updateFromFigma.mjs" + "update:components": "bun scripts/generateComponents.ts", + "update:exports": "bun scripts/generateIndex.ts", + "update:figma": "bun scripts/updateFromFigma.ts" }, "dependencies": { "csstype": "3.1.1" @@ -34,6 +34,7 @@ "devDependencies": { "@emotion/react": "11.10.6", "chalk": "5.2.0", + "decompress": "4.2.1", "fs-extra": "11.1.0", "lodash": "4.17.21", "pluralize": "8.0.0", diff --git a/system/core/scripts/generateComponents.mjs b/system/core/scripts/generateComponents.ts similarity index 94% rename from system/core/scripts/generateComponents.mjs rename to system/core/scripts/generateComponents.ts index ac9feec3d..bea991323 100644 --- a/system/core/scripts/generateComponents.mjs +++ b/system/core/scripts/generateComponents.ts @@ -4,7 +4,7 @@ import path from 'path'; import fs from 'fs-extra'; -import { prettierWrite } from './prettierWrite.mjs'; +import { prettierWrite } from './prettierWrite'; if (process.env.CI) process.exit(0); @@ -15,12 +15,28 @@ function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } -class ComponentBuilder { +abstract class ComponentBuilder { static headerComment = `/** * DO NOT EDIT: This file is generated in the post-build step of @tablecheck/tablekit-core * If you need to provide more "structure" to this component move it to the 'structuredComponents' folder */`; + protected importKey: string; + + protected element: string; + + protected filePath: string; + + protected structuredFileNames: string[]; + + protected fixedProps: string[]; + + protected defaultProps: [string, string][]; + + protected configurableProps: [string, string][]; + + protected variantStyles?: object; + get imports() { return [ `import { ${this.importKey} } from '@tablecheck/tablekit-core';`, @@ -28,8 +44,8 @@ class ComponentBuilder { ]; } - get localImports() { - const imports = []; + get localImports(): string[] { + const imports = [] as string[]; if (this.configurableProps.length) { imports.push(`import { getConfigDefault } from '../config';`); } @@ -89,6 +105,8 @@ class ComponentBuilder { await prettierWrite(this.filePath, this.buildFileContent().join('\n')); } + abstract buildFileContent(): string[]; + initFileContent() { const content = [ ComponentBuilder.headerComment, @@ -140,10 +158,8 @@ class ComponentBuilder { fixedProps = this.fixedProps || [] }) { return `export const ${varName} = ${this.writeForwardRefComponentFunction({ - varName, elementName, omitVariants, - displayName, fixedProps })}; ${varName}.displayName = \`${displayName || varName}\`;`; @@ -185,6 +201,10 @@ class ComponentBuilder { } class CssComponentBuilder extends ComponentBuilder { + private className: string; + + private selectors: string[]; + constructor(importedKey, importedValues) { super(cssOutputFolderPath, importedKey, importedValues); this.className = @@ -240,10 +260,8 @@ class CssComponentBuilder extends ComponentBuilder { (result, [key, value]) => { result[\`\${key.charAt(0).toUpperCase()}\${key.slice(1).toLowerCase()}\`] = ${this.writeForwardRefComponentFunction( { - varName: 'Component', elementName: this.element, omitVariants: true, - displayName: `\`\${key.charAt(0).toUpperCase()}\${key.slice(1).toLowerCase()}\``, fixedProps: [...this.fixedProps, `data-variant={key}`] } )}; @@ -261,6 +279,10 @@ class CssComponentBuilder extends ComponentBuilder { } class ReactComponentBuilder extends ComponentBuilder { + private fullStyles?: string; + + private coreStyles?: string; + get variantComponentsName() { return `${this.importKey}VariantComponents`; } @@ -389,7 +411,7 @@ class ReactComponentBuilder extends ComponentBuilder { } buildStyledComponents() { - const elements = []; + const elements = [] as string[]; if (this.coreStyles) { elements.push('Core'); } @@ -412,7 +434,7 @@ class ReactComponentBuilder extends ComponentBuilder { varName, elementName, omitVariants, - displayName, + displayName = '', fixedProps: fixedPropsArg = this.fixedProps || [], shouldExport = false }) { diff --git a/system/core/scripts/generateIndex.mjs b/system/core/scripts/generateIndex.ts similarity index 82% rename from system/core/scripts/generateIndex.mjs rename to system/core/scripts/generateIndex.ts index 1e7e4179f..19904cc21 100644 --- a/system/core/scripts/generateIndex.mjs +++ b/system/core/scripts/generateIndex.ts @@ -5,7 +5,7 @@ import fs from 'fs-extra'; import _ from 'lodash'; import ts from 'typescript'; -import { prettierWrite } from './prettierWrite.mjs'; +import { prettierWrite } from './prettierWrite'; if (process.env.CI) process.exit(0); @@ -23,7 +23,7 @@ const filenames = subDirectories .map((filepath) => path.join(folder, filepath)), [] ), - [] + [] as string[] ) .filter( (filepath) => @@ -59,7 +59,7 @@ async function getExports(filename) { const sourceFile = ts.createSourceFile( filename, fs.readFileSync(filepath).toString(), - ts.ScriptTarget.ES6, + ts.ScriptTarget.ESNext, false ); const reExports = sourceFile.statements.filter( @@ -67,9 +67,12 @@ async function getExports(filename) { ); const exportNodes = sourceFile.statements .filter( - (s) => - s.modifiers && - s.modifiers.find((m) => m.kind === ts.SyntaxKind.ExportKeyword) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (s): s is any => + ts.canHaveModifiers(s) && + !!ts + .getModifiers(s) + ?.find((m) => m.kind === ts.SyntaxKind.ExportKeyword) ) .reduce((r, s) => { if (s.declarationList) { @@ -78,7 +81,7 @@ async function getExports(filename) { ); } return r.concat(s); - }, []) + }, [] as unknown[]) .filter( (node) => !( @@ -102,7 +105,7 @@ function nodeIsType(node) { ); } -const defaults = {}; +const defaults: Record = {}; async function collectDefaults(exportName, exportNodes) { const configurableProps = exportNodes.find( @@ -119,17 +122,19 @@ async function collectDefaults(exportName, exportNodes) { }); } -async function buildExport(filename) { +async function buildExport( + filename: string +): Promise<[exports: string, filepath: string]> { if ( ['src/index.ts', 'src/config.tsx'].includes(filename) || filename.includes('.gen.') ) - return ''; + return ['', '']; const parsedName = path.parse(filename); const importPath = `./${path.join(parsedName.dir, parsedName.name)}`; const exportPath = `'${importPath}'`; if (exportPath.match(/^'\.\/themeVariables\/(types|theme)'$/g)) { - return `export * from ${exportPath};`; + return ['*', exportPath]; } const exportNodes = await getExports(filename); const exportNames = exportNodes @@ -137,15 +142,21 @@ async function buildExport(filename) { .map((node) => node.name.escapedText); if (exportNames.length === 1 && exportNames[0] === parsedName.name) { collectDefaults(parsedName.name, exportNodes); - return `export { ${parsedName.name} } from ${exportPath};`; + return [`{ ${parsedName.name} }`, exportPath]; } const exportName = _.camelCase(parsedName.name); collectDefaults(exportName, exportNodes); - return `export * as ${exportName} from ${exportPath};`; + return [`* as ${exportName}`, exportPath]; } await Promise.all(filenames.map(buildExport)).then((exportLines) => { - const fileContent = exportLines.filter((s) => !!s.trim()).join('\n'); + const fileContent = exportLines + .filter((s) => !!s[0].trim()) + .sort(([, a], [, b]) => a.localeCompare(b)) + .map( + ([exportLine, exportPath]) => `export ${exportLine} from ${exportPath};` + ) + .join('\n'); return prettierWrite( 'index.ts', @@ -170,7 +181,10 @@ await prettierWrite( export interface ConfigDefaults { ${Object.entries(defaults) - .map(([value, types]) => `${value}: NonNullable<${types.join(' & ')}>;`) + .map( + ([value, types]) => + `${value}: NonNullable<${types.sort().join(' & ')}>;` + ) .join('\n')} } ` diff --git a/system/core/scripts/prettierWrite.mjs b/system/core/scripts/prettierWrite.ts similarity index 83% rename from system/core/scripts/prettierWrite.mjs rename to system/core/scripts/prettierWrite.ts index 85d528cde..b8de67bd2 100644 --- a/system/core/scripts/prettierWrite.mjs +++ b/system/core/scripts/prettierWrite.ts @@ -3,7 +3,10 @@ import path from 'path'; import fs from 'fs-extra'; import prettier from 'prettier'; -export async function prettierWrite(relativeOrAbsolutePath, fileContent) { +export async function prettierWrite( + relativeOrAbsolutePath: string, + fileContent: string +): Promise { const filepath = relativeOrAbsolutePath.startsWith('/') ? relativeOrAbsolutePath : path.join(process.cwd(), 'src', relativeOrAbsolutePath); diff --git a/system/core/scripts/updateFromFigma.mjs b/system/core/scripts/updateFromFigma.mjs deleted file mode 100644 index 5a0f89afd..000000000 --- a/system/core/scripts/updateFromFigma.mjs +++ /dev/null @@ -1,245 +0,0 @@ -import chalk from 'chalk'; -import fs from 'fs-extra'; -// eslint-disable-next-line @tablecheck/forbidden-imports -import _ from 'lodash'; -import pluralize from 'pluralize'; - -import { prettierWrite } from './prettierWrite.mjs'; - -/** - * To use this file, install design tokens figma plugin; https://www.figma.com/community/plugin/888356646278934516 - * Open up Tablekit Components (3.0), clone it to your drafts (as we can't run plugins on files we can't edit) - * Run the plugin, exporting everything. - * Run `npm run update:figma ` - */ - -function hexToRgba(color) { - const hexValues = color - .toUpperCase() - .replace('#', '') - .split('') - .reduce((r, char) => { - const lastValue = r[r.length - 1]; - if (lastValue && lastValue.length < 2) r[r.length - 1] += char; - else r.push(char); - return r; - }, []) - .map((hex) => parseInt(hex, 16)); - hexValues[3] = +(hexValues[3] / 255).toFixed(2); - return `rgba(${hexValues.join(', ')})`; -} - -const filePath = process.argv[2]; -const { color: colorTokens, effect: effectTokens } = fs.readJSONSync(filePath); - -const colorVars = { - light: [], - dark: [], - brand: [], - utilities: [] -}; - -const lightEffectVars = []; -const darkEffectVars = []; - -Object.keys(colorTokens).forEach((groupKey) => { - const group = _.kebabCase(groupKey).replace('tk-3-0-', ''); - Object.keys(colorTokens[groupKey]).forEach((nameKey) => { - const { value, type } = colorTokens[groupKey][nameKey]; - if (type !== 'color') { - console.warn( - 'Unknown Color', - groupKey, - nameKey, - colorTokens[groupKey][nameKey] - ); - return; - } - const name = _.kebabCase(nameKey); - colorVars[group].push([name, value]); - }); -}); - -function valueToCssValue(value) { - if (typeof value === 'string') return value; - if (value === 0) return '0'; - return `${value}px`; -} - -const FIGMA_ONLY_TOKENS = ['demolight']; - -Object.keys(effectTokens).forEach((name) => { - const { value, type } = effectTokens[name]; - switch (type) { - case 'custom-shadow': { - const effectName = _.kebabCase(name); - const effectValue = `${[ - value.offsetX, - value.offsetY, - value.radius, - value.spread - ] - .map((v) => valueToCssValue(v)) - .join(' ')} ${hexToRgba(value.color)}`; - - if (/light/.test(effectName)) { - lightEffectVars.push([effectName.replace(/light-/gi, ''), effectValue]); - } else if (/dark/.test(effectName)) { - darkEffectVars.push([effectName.replace(/dark-/gi, ''), effectValue]); - } - return; - } - default: { - if (FIGMA_ONLY_TOKENS.includes(name)) return; - console.warn( - chalk.yellow('Unknown Effect'), - chalk.cyan(name), - type, - effectTokens[name] - ); - } - } -}); -Object.keys(colorVars).forEach((groupKey) => { - if (groupKey === 'light' || groupKey === 'dark') { - const text = colorVars[groupKey].find(([name]) => name === 'text'); - const textSecondary = colorVars[groupKey].find( - ([name]) => name === 'text-secondary' - ); - colorVars[groupKey].push(['brand-secondary-text', text[1]]); - colorVars[groupKey].push([ - 'surface-secondary-text', - groupKey === 'light' ? textSecondary[1] : text[1] - ]); - } - if (groupKey === 'light') { - colorVars[groupKey].push([ - 'surface-raised-active-text', - 'var(--brand-primary)' - ]); - } - if (groupKey === 'dark') { - colorVars[groupKey].push([ - 'surface-raised-active-text', - 'var(--brand-primary-text)' - ]); - } - colorVars[groupKey] = _.sortBy(colorVars[groupKey], '0').map( - ([name, value]) => [ - name, - value.startsWith('var(') ? value : hexToRgba(value) - ] - ); -}); - -const allCssProperties = []; -function addProperty(name) { - if (allCssProperties.includes(name)) return; - allCssProperties.push(name); -} - -function formatCssProp(name, value) { - addProperty(name); - return `--${name}: ${value};`; -} - -const lightVars = colorVars.light.map(([name]) => name); -const darkVars = colorVars.dark.map(([name]) => name); -const missingLightVars = darkVars.filter((name) => !lightVars.includes(name)); -const missingDarkVars = lightVars.filter((name) => !darkVars.includes(name)); - -if (missingLightVars.length) { - console.warn( - chalk.bold.red('Missing light vars:'), - missingLightVars.join(', ') - ); -} -if (missingDarkVars.length) { - console.warn( - chalk.bold.red('Missing dark vars:'), - missingDarkVars.join(', ') - ); -} - -const themeContent = `// eslint-disable-next-line eslint-comments/disable-enable-pair -/* eslint-disable max-lines */ -import { css, themedCss } from '../utils'; - -/** - * DO NOT EDIT; File is generated from figma, see './updateFromFigma.mjs' for update instructions - */ - -export type SentimentColors = - | 'error' - | 'info' - | 'neutral' - | 'primary' - | 'success' - | 'warning'; - -// The following are duplicated as extensions and plugins need the '--name' format -// but we need objects exported for usage with certain 3rd party libraries or when computing colours - -${Object.keys(colorVars) - .map( - (groupKey) => - `export const ${pluralize.singular(groupKey)}Colors = css\` - ${ - ['dark', 'light'].includes(groupKey) ? `color-scheme: ${groupKey};` : '' - } - ${colorVars[groupKey] - .map(([name, value]) => formatCssProp(name, value)) - .join('\n ')} -\`; - -export const ${pluralize.singular(groupKey)}ColorsObject = { - ${colorVars[groupKey] - .map(([name, value]) => `'${name}': '${value}',`) - .join('\n ')} - };` - ) - .join('\n\n')} - -export const lightEffectStyles = css\` - ${lightEffectVars - .map(([name, value]) => formatCssProp(name, value)) - .join('\n ')} -\`; - -export const darkEffectStyles = css\` - ${darkEffectVars - .map(([name, value]) => formatCssProp(name, value)) - .join('\n ')} -\`; - -export const theme = css\` - \${themedCss({ - selector: '', - light: css\` - \${lightColors}; - \${lightEffectStyles} - \`, - dark: css\` - \${darkColors}; - \${darkEffectStyles} - \` - })} - :root { - ${Object.keys(colorVars) - .filter((key) => !['light', 'dark'].includes(key)) - .map((key) => `\${${pluralize.singular(key)}Colors}`) - .join('\n')} - } -\``; - -await prettierWrite('themeVariables/theme.ts', themeContent); - -const typesContent = `/** -* DO NOT EDIT; File is generated from figma, see './updateFromFigma.mjs' for update instructions -*/ - -export interface TableKitCSSProperties { - ${allCssProperties.map((name) => `'--${name}'?: string;`).join('\n')} -}`; - -await prettierWrite('themeVariables/types.gen.ts', typesContent); diff --git a/system/core/scripts/updateFromFigma.ts b/system/core/scripts/updateFromFigma.ts new file mode 100644 index 000000000..c4e34bde2 --- /dev/null +++ b/system/core/scripts/updateFromFigma.ts @@ -0,0 +1,374 @@ +// eslint-disable-next-line eslint-comments/disable-enable-pair +/* eslint-disable max-lines, @typescript-eslint/naming-convention, class-methods-use-this, max-classes-per-file */ +import path from 'node:path'; + +import chalk from 'chalk'; +import decompress from 'decompress'; +import fs from 'fs-extra'; + +import { prettierWrite } from './prettierWrite'; + +const DO_NOT_EDIT_COMMENT = `/** +* DO NOT EDIT; File is generated from figma, see './updateFromFigma.ts' for update instructions +*/`; + +type CssFileType = { + name: string; + value: string; +}[]; + +type EffectsFileType = Record<'light' | 'dark', Record>; + +/** + * To use this file, install Advanced Variables plugin; https://www.figma.com/community/plugin/1260472771849439434 + * Open up Tablekit Components (3.0), clone it to your drafts (as we can't run plugins on files we can't edit) + * Run the plugin, turn on "Place variables in different folders..." and "Effect styles". + * Use `CSS` and `RGBa` as the output options + * Run `npm run update:figma ` + */ + +class Formatter { + constructor( + private readonly contents: { + effects: EffectsFileType; + borderRadius: CssFileType; + spacing: CssFileType; + primitives: CssFileType; + lightTheme: CssFileType; + darkTheme: CssFileType; + } + ) { + Object.values(this.contents).forEach((content) => { + if (!Array.isArray(content)) return; + content.sort((a, b) => a.name.localeCompare(b.name)); + }); + } + + public outputFile() { + return `${this.prologue()} + +${this.sentimentColorsType()} + +// The following are duplicated as extensions and plugins need the '--name' format +// but we need objects exported for usage with certain 3rd party libraries or when computing colours + +${this.css(this.contents.lightTheme, 'lightColors')} + +${this.object(this.contents.lightTheme, 'lightColors')} + +${this.css(this.contents.darkTheme, 'darkColors')} + +${this.object(this.contents.darkTheme, 'darkColors')} + +${this.css(this.contents.primitives, 'utilityColors')} + +${this.object(this.contents.primitives, 'utilityColors')} + +${this.css(this.contents.spacing, 'spacing')} + +${this.object(this.contents.spacing, 'spacing', (v) => parseInt(v, 10))} + +${this.css(this.contents.borderRadius, 'borderRadius')} + +${this.object(this.contents.borderRadius, 'borderRadius', (v) => + parseInt(v, 10) +)} + +${this.effect(this.contents.effects.light, 'light')} + +${this.effect(this.contents.effects.dark, 'dark')} + +export const theme = css\` + :root { + \${spacing} + \${borderRadius} + \${utilityColors} + } + \${themedCss({ + selector: '', + light: css\` + \${lightColors}; + \${lightEffectStyles} + \`, + dark: css\` + \${darkColors}; + \${darkEffectStyles} + \` + })} +\`; +`; + } + + private prologue() { + return `// eslint-disable-next-line eslint-comments/disable-enable-pair +/* eslint-disable max-lines */ +import { css, themedCss } from '../utils'; + +${DO_NOT_EDIT_COMMENT}`; + } + + private sentimentColorsType() { + return `export type SentimentColors = + | 'error' + | 'info' + | 'neutral' + | 'primary' + | 'success' + | 'warning';`; + } + + private combineCss(...contents: CssFileType[]) { + return ([] as CssFileType) + .concat(...contents) + .sort((a, b) => a.name.localeCompare(b.name)); + } + + private object( + content: CssFileType, + varName: string, + parse?: (v: string) => unknown + ) { + return `export const ${varName}Object = { + ${content + .map( + ({ name, value }) => + `'${name.replace(/--/, '')}': ${JSON.stringify( + parse ? parse(value) : value + )},` + ) + .join('\n ')} + };`; + } + + private css( + content: CssFileType, + varName: string, + colorScheme?: 'light' | 'dark' + ) { + return `export const ${varName} = css\` + ${ + colorScheme + ? `color-scheme: ${colorScheme}; +` + : '' + } ${content + .map(({ name, value }) => this.formatCssProp(name, value)) + .join('\n ')} +\`;`; + } + + private formatCssProp(name: string, value: string) { + return `${name}: ${value};`; + } + + private effect(effect: Record, mode: string) { + return `export const ${mode}EffectStyles = css\` + ${Object.entries(effect) + .map(([size, value]) => `--elevation-${size}: ${value};`) + .join('\n ')} +\`;`; + } +} + +class Updater { + private tempDir = './temp'; + + private allCssProperties = new Set(); + + private replacements = new Map(); + + constructor(private readonly filePath: string) { + if (!filePath) { + console.error('Please provide a file path'); + process.exit(1); + } + } + + public async exec() { + await this.setupTempDir(); + await this.decompress(); + const contents = await this.loadFiles(); + await this.process(contents); + await this.writeThemeFile(contents); + await this.writeTypesFile(); + await this.cleanup(); + } + + private async setupTempDir() { + await fs.remove(this.tempDir); + await fs.ensureDir(this.tempDir); + } + + private async decompress() { + await decompress(this.filePath, this.tempDir); + } + + private async cleanup() { + await fs.remove(this.tempDir); + } + + private async writeTypesFile() { + const typesContent = `${DO_NOT_EDIT_COMMENT} +export interface TableKitCSSProperties { + ${Array.from(this.allCssProperties.values()) + .sort() + .map((name) => `'${name}'?: string;`) + .join('\n')} +}`; + + await prettierWrite('themeVariables/types.gen.ts', typesContent); + } + + private async writeThemeFile( + contents: Awaited> + ) { + await prettierWrite( + 'themeVariables/theme.ts', + new Formatter(contents).outputFile() + ); + } + + private async loadFiles() { + const primitiveFiles = await fs.readdir( + path.join(this.tempDir, 'variables/Primitives/Color') + ); + const [effects, borderRadius, spacing, primitives, lightTheme, darkTheme] = + await Promise.all([ + this.loadEffects('styles/effects/index.css'), + this.loadCss('variables/Radius/Mode 1/index.css'), + this.loadCss('variables/Spacing/Mode 1/index.css'), + Promise.all( + primitiveFiles.map((fileName) => + this.loadCss(`variables/Primitives/Color/${fileName}`) + ) + ), + this.loadCss('variables/Theme/Light/index.css'), + this.loadCss('variables/Theme/Dark/index.css') + ]); + return { + effects, + borderRadius, + spacing, + primitives: primitives.flat(), + lightTheme, + darkTheme + }; + } + + private async process({ + borderRadius, + spacing, + primitives, + lightTheme, + darkTheme + }: Awaited>) { + [borderRadius, spacing, primitives, lightTheme, darkTheme].forEach( + (block) => { + this.replaceRemovals(block); + this.extractCssProperties(block); + block.sort((a, b) => a.name.localeCompare(b.name)); + } + ); + this.checkForMissingVars(lightTheme, darkTheme); + } + + private extractCssProperties(content: CssFileType) { + content.forEach(({ name }) => { + this.allCssProperties.add(name); + }); + } + + private replaceRemovals(content: CssFileType) { + content.forEach((c) => { + this.replacements.forEach((add, remove) => { + c.name = c.name.replace(remove, add); + c.value = c.value.replace(remove, add); + }); + }); + } + + private checkForMissingVars(lightTheme: CssFileType, darkTheme: CssFileType) { + const lightVarNames = lightTheme.map(({ name }) => name); + const darkVarNames = darkTheme.map(({ name }) => name); + const missingLightVars = darkVarNames.filter( + (name) => !lightVarNames.includes(name) + ); + const missingDarkVars = lightVarNames.filter( + (name) => !darkVarNames.includes(name) + ); + + if (missingLightVars.length) { + console.warn( + chalk.bold.red('Missing light vars:'), + missingLightVars.join(', ') + ); + } + if (missingDarkVars.length) { + console.warn( + chalk.bold.red('Missing dark vars:'), + missingDarkVars.join(', ') + ); + } + } + + private async loadEffects(filePath: string) { + const content = await fs.readFile( + path.join(this.tempDir, filePath), + 'utf-8' + ); + const lines = content + .split('\n') + .map((l) => l.trim()) + .filter((l) => l.startsWith('.') || l.startsWith('box-shadow')); + const effectsObject = {}; + let currentKey: undefined | [string, string]; + + lines.forEach((line) => { + if (line.startsWith('.')) { + const key = line.replace(/[. {]+/gi, ''); + const [, mode, size] = key.split('-'); + if (!mode || !size) { + currentKey = undefined; + return; + } + currentKey = [mode, size]; + } else if (currentKey) { + if (!effectsObject[currentKey[0]]) { + effectsObject[currentKey[0]] = {}; + } + effectsObject[currentKey[0]][currentKey[1]] = line + .replace(/box-shadow:/gi, '') + .trim(); + } + }); + + return effectsObject as EffectsFileType; + } + + private async loadCss(filePath: string) { + const content = await fs.readFile( + path.join(this.tempDir, filePath), + 'utf-8' + ); + const lines = content + .split('\n') + .map((l) => l.trim()) + .filter((line) => line.trim().startsWith('--')); + const mappedLines = lines.map((l) => { + const [name, value] = l.split(':'); + return { name: name.trim(), value: value.replace(/;$/, '').trim() }; + }); + if (filePath.includes('Primitives')) { + const fileName = path.basename(filePath, '.css'); + mappedLines.forEach(({ name }) => { + this.replacements.set( + new RegExp(`(^|var[(])${name}([)]|$)`, 'ig'), + `$1${name.replace(`--${fileName}-`, '--')}$2` + ); + }); + } + return mappedLines; + } +} + +await new Updater(process.argv[2]).exec(); diff --git a/system/core/src/components/Button.ts b/system/core/src/components/Button.ts index 33819aa9e..b19167723 100644 --- a/system/core/src/components/Button.ts +++ b/system/core/src/components/Button.ts @@ -151,7 +151,7 @@ export const coreStyles = css` text-decoration: none; font-weight: 400; - border: 1px solid var(--primary); + border: 1px solid var(--brand-primary); border-radius: var(--border-radius-small); align-items: center; diff --git a/system/core/src/components/Skeleton.ts b/system/core/src/components/Skeleton.ts index 3bbc1d06a..93276e69b 100644 --- a/system/core/src/components/Skeleton.ts +++ b/system/core/src/components/Skeleton.ts @@ -1,17 +1,9 @@ -import { css } from '../utils'; +import { css, themedCss } from '../utils'; // This file is a replacement for https://github.com/dvtng/react-loading-skeleton export const className = 'skeleton'; -export const keyframes = css` - @keyframes tk-skeleton { - to { - background-position: -200% 0; - } - } -`; - export interface Props { width?: number | string; height?: number | string; @@ -19,52 +11,31 @@ export interface Props { } export interface SkeletonCSSProperties { - '--animation-delay': string; - '--skeleton-width': string; - '--skeleton-height': string; - '--skeleton-border-radius': string; + '--tk-skeleton-width': string; + '--tk-skeleton-height': string; + '--tk-skeleton-border-radius': string; } export const fullStyles = css` - --animation-duration: 2s; - --animation-direction: normal; - - background-color: var(--surface-low); - color: transparent; + ${themedCss({ + dark: css` + --tk-skeleton-background: var(--grey-800); + `, + light: css` + --tk-skeleton-background: var(--grey-300); + `, + selector: '&' + })} + + color: transparent !important; &:empty { min-height: 1rem; - width: var(--skeleton-width); + width: var(--tk-skeleton-width); } - height: var(--skeleton-height); - border-radius: var(--skeleton-border-radius); + height: var(--tk-skeleton-height); + border-radius: var(--tk-skeleton-border-radius, var(--border-radius-micro)); display: inline-flex; line-height: 1.2rem; - position: relative; - overflow: hidden; - z-index: 1; /* Necessary for overflow: hidden to work correctly in Safari */ - - &:after { - content: ' '; - display: block; - position: absolute; - left: 0; - right: 0; - height: 100%; - background: linear-gradient( - -75deg, - transparent 30%, - var(--surface-active) 40%, - transparent 50% - ) - 0 0 / 200% 100%, - var(--surface-raised); - background-attachment: fixed; - animation-name: tk-skeleton; - animation-direction: var(--animation-direction); - animation-duration: var(--animation-duration); - animation-delay: var(--animation-delay); - animation-timing-function: linear; - animation-iteration-count: infinite; - } + background: var(--tk-skeleton-background); `; diff --git a/system/core/src/themeVariables/constants.ts b/system/core/src/themeVariables/constants.ts index f1b040fda..54924837e 100644 --- a/system/core/src/themeVariables/constants.ts +++ b/system/core/src/themeVariables/constants.ts @@ -3,17 +3,6 @@ import { css } from '../utils'; export const constants = css` :root { - --border-radius-small: 4px; - --border-radius-large: 8px; - --border-radius-full: 9999px; - --spacing-l1: 4px; - --spacing-l2: 8px; - --spacing-l3: 12px; - --spacing-l4: 16px; - --spacing-l5: 24px; - --spacing-l6: 32px; - --spacing-l7: 40px; - --spacing-l8: 48px; --zindex-card: 100; --zindex-dialog: 200; --zindex-sidenav: 300; diff --git a/system/core/src/themeVariables/theme.ts b/system/core/src/themeVariables/theme.ts index c5ea01c85..e9d7b2d4b 100644 --- a/system/core/src/themeVariables/theme.ts +++ b/system/core/src/themeVariables/theme.ts @@ -3,7 +3,7 @@ import { css, themedCss } from '../utils'; /** - * DO NOT EDIT; File is generated from figma, see './updateFromFigma.mjs' for update instructions + * DO NOT EDIT; File is generated from figma, see './updateFromFigma.ts' for update instructions */ export type SentimentColors = @@ -18,36 +18,34 @@ export type SentimentColors = // but we need objects exported for usage with certain 3rd party libraries or when computing colours export const lightColors = css` - color-scheme: light; - --border: rgba(229, 229, 229, 1); - --border-active: rgba(41, 41, 41, 1); + --border: var(--grey-300); + --border-active: var(--grey-900); --border-transparent: rgba(0, 0, 0, 0.1); - --brand-primary: rgba(142, 74, 231, 1); - --brand-primary-active: rgba(159, 96, 241, 1); - --brand-primary-hover: rgba(159, 96, 241, 1); - --brand-primary-text: rgba(255, 255, 255, 1); - --brand-secondary: rgba(226, 204, 255, 1); - --brand-secondary-active: rgba(220, 193, 255, 1); - --brand-secondary-hover: rgba(220, 193, 255, 1); - --brand-secondary-text: rgba(41, 41, 41, 1); + --brand-primary: var(--purple-600); + --brand-primary-active: var(--purple-500); + --brand-primary-hover: var(--purple-500); + --brand-primary-text: var(--white); + --brand-secondary: var(--purple-150); + --brand-secondary-active: var(--purple-200); + --brand-secondary-hover: var(--purple-200); --error: rgba(204, 0, 0, 1); --error-surface: rgba(254, 223, 223, 1); --error-surface-hover: rgba(254, 205, 205, 1); --error-text: rgba(204, 0, 0, 1); - --field: rgba(255, 255, 255, 1); + --field: var(--white); --focus: rgba(0, 23, 231, 1); --info: rgba(0, 102, 204, 1); --info-surface: rgba(223, 239, 254, 1); --info-surface-hover: rgba(205, 229, 254, 1); --info-text: rgba(0, 102, 204, 1); - --link: rgba(142, 74, 231, 1); - --link-disabled: rgba(206, 206, 206, 1); - --link-hover: rgba(159, 96, 241, 1); + --link: var(--purple-600); + --link-disabled: var(--grey-500); + --link-hover: var(--purple-500); --link-visited: rgba(200, 0, 204, 1); - --neutral: rgba(75, 75, 75, 1); - --neutral-surface: rgba(238, 238, 238, 1); - --neutral-surface-hover: rgba(229, 229, 229, 1); - --neutral-text: rgba(75, 75, 75, 1); + --neutral: var(--grey-800); + --neutral-surface: var(--grey-200); + --neutral-surface-hover: var(--grey-300); + --neutral-text: var(--grey-800); --orange-surface: rgba(255, 237, 202, 1); --orange-surface-hover: rgba(252, 230, 187, 1); --orange-text: rgba(175, 93, 0, 1); @@ -58,31 +56,30 @@ export const lightColors = css` --success-surface: rgba(233, 254, 223, 1); --success-surface-hover: rgba(220, 254, 205, 1); --success-text: rgba(6, 121, 0, 1); - --surface: rgba(255, 255, 255, 1); - --surface-active: rgba(238, 238, 238, 1); - --surface-disabled: rgba(247, 247, 247, 1); - --surface-hover: rgba(247, 247, 247, 1); + --surface: var(--white); + --surface-active: var(--grey-200); + --surface-disabled: var(--grey-150); + --surface-hover: var(--grey-200); --surface-hover-transparent: rgba(0, 0, 0, 0.04); - --surface-low: rgba(252, 252, 252, 1); - --surface-low-active: rgba(243, 242, 255, 1); - --surface-low-hover: rgba(247, 247, 247, 1); + --surface-low: var(--grey-50); + --surface-low-active: var(--purple-50); + --surface-low-hover: var(--grey-200); --surface-low-hover-transparent: rgba(0, 0, 0, 0.03); - --surface-raised: rgba(249, 249, 249, 1); - --surface-raised-active: rgba(243, 242, 255, 1); - --surface-raised-active-text: var(--brand-primary); - --surface-raised-hover: rgba(247, 247, 247, 1); + --surface-raised: var(--grey-100); + --surface-raised-active: var(--purple-50); + --surface-raised-hover: var(--grey-200); --surface-raised-hover-transparent: rgba(0, 0, 0, 0.03); - --surface-secondary: rgba(41, 41, 41, 1); - --surface-secondary-active: rgba(75, 75, 75, 1); - --surface-secondary-hover: rgba(75, 75, 75, 1); - --surface-secondary-text: rgba(255, 255, 255, 1); - --text: rgba(41, 41, 41, 1); - --text-disabled: rgba(206, 206, 206, 1); - --text-placeholder: rgba(191, 191, 191, 1); - --text-secondary: rgba(255, 255, 255, 1); - --text-subtle: rgba(132, 132, 132, 1); - --toggle-disabled: rgba(238, 238, 238, 1); - --toggle-inactive: rgba(206, 206, 206, 1); + --surface-secondary: var(--grey-900); + --surface-secondary-active: var(--grey-800); + --surface-secondary-hover: var(--grey-800); + --text: var(--grey-900); + --text-active: var(--purple-700); + --text-disabled: var(--grey-600); + --text-placeholder: var(--grey-700); + --text-secondary: var(--white); + --text-subtle: var(--grey-750); + --toggle-disabled: var(--grey-200); + --toggle-inactive: var(--grey-500); --warning: rgba(232, 183, 47, 1); --warning-surface: rgba(255, 250, 223, 1); --warning-surface-hover: rgba(255, 248, 212, 1); @@ -90,35 +87,34 @@ export const lightColors = css` `; export const lightColorsObject = { - border: 'rgba(229, 229, 229, 1)', - 'border-active': 'rgba(41, 41, 41, 1)', + border: 'var(--grey-300)', + 'border-active': 'var(--grey-900)', 'border-transparent': 'rgba(0, 0, 0, 0.1)', - 'brand-primary': 'rgba(142, 74, 231, 1)', - 'brand-primary-active': 'rgba(159, 96, 241, 1)', - 'brand-primary-hover': 'rgba(159, 96, 241, 1)', - 'brand-primary-text': 'rgba(255, 255, 255, 1)', - 'brand-secondary': 'rgba(226, 204, 255, 1)', - 'brand-secondary-active': 'rgba(220, 193, 255, 1)', - 'brand-secondary-hover': 'rgba(220, 193, 255, 1)', - 'brand-secondary-text': 'rgba(41, 41, 41, 1)', + 'brand-primary': 'var(--purple-600)', + 'brand-primary-active': 'var(--purple-500)', + 'brand-primary-hover': 'var(--purple-500)', + 'brand-primary-text': 'var(--white)', + 'brand-secondary': 'var(--purple-150)', + 'brand-secondary-active': 'var(--purple-200)', + 'brand-secondary-hover': 'var(--purple-200)', error: 'rgba(204, 0, 0, 1)', 'error-surface': 'rgba(254, 223, 223, 1)', 'error-surface-hover': 'rgba(254, 205, 205, 1)', 'error-text': 'rgba(204, 0, 0, 1)', - field: 'rgba(255, 255, 255, 1)', + field: 'var(--white)', focus: 'rgba(0, 23, 231, 1)', info: 'rgba(0, 102, 204, 1)', 'info-surface': 'rgba(223, 239, 254, 1)', 'info-surface-hover': 'rgba(205, 229, 254, 1)', 'info-text': 'rgba(0, 102, 204, 1)', - link: 'rgba(142, 74, 231, 1)', - 'link-disabled': 'rgba(206, 206, 206, 1)', - 'link-hover': 'rgba(159, 96, 241, 1)', + link: 'var(--purple-600)', + 'link-disabled': 'var(--grey-500)', + 'link-hover': 'var(--purple-500)', 'link-visited': 'rgba(200, 0, 204, 1)', - neutral: 'rgba(75, 75, 75, 1)', - 'neutral-surface': 'rgba(238, 238, 238, 1)', - 'neutral-surface-hover': 'rgba(229, 229, 229, 1)', - 'neutral-text': 'rgba(75, 75, 75, 1)', + neutral: 'var(--grey-800)', + 'neutral-surface': 'var(--grey-200)', + 'neutral-surface-hover': 'var(--grey-300)', + 'neutral-text': 'var(--grey-800)', 'orange-surface': 'rgba(255, 237, 202, 1)', 'orange-surface-hover': 'rgba(252, 230, 187, 1)', 'orange-text': 'rgba(175, 93, 0, 1)', @@ -129,31 +125,30 @@ export const lightColorsObject = { 'success-surface': 'rgba(233, 254, 223, 1)', 'success-surface-hover': 'rgba(220, 254, 205, 1)', 'success-text': 'rgba(6, 121, 0, 1)', - surface: 'rgba(255, 255, 255, 1)', - 'surface-active': 'rgba(238, 238, 238, 1)', - 'surface-disabled': 'rgba(247, 247, 247, 1)', - 'surface-hover': 'rgba(247, 247, 247, 1)', + surface: 'var(--white)', + 'surface-active': 'var(--grey-200)', + 'surface-disabled': 'var(--grey-150)', + 'surface-hover': 'var(--grey-200)', 'surface-hover-transparent': 'rgba(0, 0, 0, 0.04)', - 'surface-low': 'rgba(252, 252, 252, 1)', - 'surface-low-active': 'rgba(243, 242, 255, 1)', - 'surface-low-hover': 'rgba(247, 247, 247, 1)', + 'surface-low': 'var(--grey-50)', + 'surface-low-active': 'var(--purple-50)', + 'surface-low-hover': 'var(--grey-200)', 'surface-low-hover-transparent': 'rgba(0, 0, 0, 0.03)', - 'surface-raised': 'rgba(249, 249, 249, 1)', - 'surface-raised-active': 'rgba(243, 242, 255, 1)', - 'surface-raised-active-text': 'var(--brand-primary)', - 'surface-raised-hover': 'rgba(247, 247, 247, 1)', + 'surface-raised': 'var(--grey-100)', + 'surface-raised-active': 'var(--purple-50)', + 'surface-raised-hover': 'var(--grey-200)', 'surface-raised-hover-transparent': 'rgba(0, 0, 0, 0.03)', - 'surface-secondary': 'rgba(41, 41, 41, 1)', - 'surface-secondary-active': 'rgba(75, 75, 75, 1)', - 'surface-secondary-hover': 'rgba(75, 75, 75, 1)', - 'surface-secondary-text': 'rgba(255, 255, 255, 1)', - text: 'rgba(41, 41, 41, 1)', - 'text-disabled': 'rgba(206, 206, 206, 1)', - 'text-placeholder': 'rgba(191, 191, 191, 1)', - 'text-secondary': 'rgba(255, 255, 255, 1)', - 'text-subtle': 'rgba(132, 132, 132, 1)', - 'toggle-disabled': 'rgba(238, 238, 238, 1)', - 'toggle-inactive': 'rgba(206, 206, 206, 1)', + 'surface-secondary': 'var(--grey-900)', + 'surface-secondary-active': 'var(--grey-800)', + 'surface-secondary-hover': 'var(--grey-800)', + text: 'var(--grey-900)', + 'text-active': 'var(--purple-700)', + 'text-disabled': 'var(--grey-600)', + 'text-placeholder': 'var(--grey-700)', + 'text-secondary': 'var(--white)', + 'text-subtle': 'var(--grey-750)', + 'toggle-disabled': 'var(--grey-200)', + 'toggle-inactive': 'var(--grey-500)', warning: 'rgba(232, 183, 47, 1)', 'warning-surface': 'rgba(255, 250, 223, 1)', 'warning-surface-hover': 'rgba(255, 248, 212, 1)', @@ -161,36 +156,34 @@ export const lightColorsObject = { }; export const darkColors = css` - color-scheme: dark; - --border: rgba(58, 58, 58, 1); - --border-active: rgba(255, 255, 255, 1); + --border: var(--grey-850); + --border-active: var(--white); --border-transparent: rgba(255, 255, 255, 0.17); - --brand-primary: rgba(142, 74, 231, 1); - --brand-primary-active: rgba(120, 50, 210, 1); - --brand-primary-hover: rgba(120, 50, 210, 1); - --brand-primary-text: rgba(255, 255, 255, 1); - --brand-secondary: rgba(85, 26, 163, 1); - --brand-secondary-active: rgba(63, 15, 126, 1); - --brand-secondary-hover: rgba(63, 15, 126, 1); - --brand-secondary-text: rgba(253, 253, 253, 1); + --brand-primary: var(--purple-600); + --brand-primary-active: var(--purple-700); + --brand-primary-hover: var(--purple-700); + --brand-primary-text: var(--white); + --brand-secondary: var(--purple-800); + --brand-secondary-active: var(--purple-900); + --brand-secondary-hover: var(--purple-900); --error: rgba(239, 72, 72, 1); --error-surface: rgba(140, 0, 0, 1); --error-surface-hover: rgba(159, 0, 0, 1); --error-text: rgba(254, 223, 223, 1); - --field: rgba(41, 41, 41, 1); + --field: var(--grey-900); --focus: rgba(104, 119, 253, 1); --info: rgba(72, 155, 239, 1); --info-surface: rgba(0, 70, 140, 1); --info-surface-hover: rgba(0, 88, 175, 1); --info-text: rgba(223, 239, 254, 1); - --link: rgba(176, 128, 238, 1); - --link-disabled: rgba(152, 152, 152, 1); - --link-hover: rgba(165, 110, 236, 1); + --link: var(--purple-300); + --link-disabled: var(--grey-700); + --link-hover: var(--purple-400); --link-visited: rgba(181, 11, 215, 1); - --neutral: rgba(102, 102, 102, 1); - --neutral-surface: rgba(58, 58, 58, 1); - --neutral-surface-hover: rgba(41, 41, 41, 1); - --neutral-text: rgba(219, 219, 219, 1); + --neutral: var(--grey-750); + --neutral-surface: var(--grey-850); + --neutral-surface-hover: var(--grey-900); + --neutral-text: var(--grey-400); --orange-surface: rgba(175, 93, 0, 1); --orange-surface-hover: rgba(197, 109, 10, 1); --orange-text: rgba(255, 237, 202, 1); @@ -201,31 +194,30 @@ export const darkColors = css` --success-surface: rgba(3, 102, 0, 1); --success-surface-hover: rgba(6, 121, 0, 1); --success-text: rgba(233, 254, 223, 1); - --surface: rgba(30, 30, 30, 1); - --surface-active: rgba(58, 58, 58, 1); - --surface-disabled: rgba(75, 75, 75, 1); - --surface-hover: rgba(41, 41, 41, 1); + --surface: var(--grey-950); + --surface-active: var(--grey-900); + --surface-disabled: var(--grey-800); + --surface-hover: var(--grey-900); --surface-hover-transparent: rgba(255, 255, 255, 0.05); - --surface-low: rgba(26, 26, 26, 1); - --surface-low-active: rgba(76, 68, 92, 1); - --surface-low-hover: rgba(41, 41, 41, 1); + --surface-low: var(--grey); + --surface-low-active: var(--purple-900); + --surface-low-hover: var(--grey-900); --surface-low-hover-transparent: rgba(255, 255, 255, 0.05); - --surface-raised: rgba(41, 41, 41, 1); - --surface-raised-active: rgba(76, 68, 92, 1); - --surface-raised-active-text: var(--brand-primary-text); - --surface-raised-hover: rgba(75, 75, 75, 1); + --surface-raised: var(--grey-900); + --surface-raised-active: var(--purple-900); + --surface-raised-hover: var(--grey-800); --surface-raised-hover-transparent: rgba(255, 255, 255, 0.2); - --surface-secondary: rgba(75, 75, 75, 1); - --surface-secondary-active: rgba(58, 58, 58, 1); - --surface-secondary-hover: rgba(58, 58, 58, 1); - --surface-secondary-text: rgba(253, 253, 253, 1); - --text: rgba(253, 253, 253, 1); - --text-disabled: rgba(152, 152, 152, 1); - --text-placeholder: rgba(152, 152, 152, 1); - --text-secondary: rgba(18, 18, 18, 1); - --text-subtle: rgba(191, 191, 191, 1); - --toggle-disabled: rgba(58, 58, 58, 1); - --toggle-inactive: rgba(102, 102, 102, 1); + --surface-secondary: var(--grey-800); + --surface-secondary-active: var(--grey-900); + --surface-secondary-hover: var(--grey-900); + --text: var(--grey-50); + --text-active: var(--purple-150); + --text-disabled: var(--grey-700); + --text-placeholder: var(--grey-700); + --text-secondary: var(--grey-50); + --text-subtle: var(--grey-400); + --toggle-disabled: var(--grey-850); + --toggle-inactive: var(--grey-750); --warning: rgba(239, 194, 72, 1); --warning-surface: rgba(140, 103, 0, 1); --warning-surface-hover: rgba(159, 116, 0, 1); @@ -233,35 +225,34 @@ export const darkColors = css` `; export const darkColorsObject = { - border: 'rgba(58, 58, 58, 1)', - 'border-active': 'rgba(255, 255, 255, 1)', + border: 'var(--grey-850)', + 'border-active': 'var(--white)', 'border-transparent': 'rgba(255, 255, 255, 0.17)', - 'brand-primary': 'rgba(142, 74, 231, 1)', - 'brand-primary-active': 'rgba(120, 50, 210, 1)', - 'brand-primary-hover': 'rgba(120, 50, 210, 1)', - 'brand-primary-text': 'rgba(255, 255, 255, 1)', - 'brand-secondary': 'rgba(85, 26, 163, 1)', - 'brand-secondary-active': 'rgba(63, 15, 126, 1)', - 'brand-secondary-hover': 'rgba(63, 15, 126, 1)', - 'brand-secondary-text': 'rgba(253, 253, 253, 1)', + 'brand-primary': 'var(--purple-600)', + 'brand-primary-active': 'var(--purple-700)', + 'brand-primary-hover': 'var(--purple-700)', + 'brand-primary-text': 'var(--white)', + 'brand-secondary': 'var(--purple-800)', + 'brand-secondary-active': 'var(--purple-900)', + 'brand-secondary-hover': 'var(--purple-900)', error: 'rgba(239, 72, 72, 1)', 'error-surface': 'rgba(140, 0, 0, 1)', 'error-surface-hover': 'rgba(159, 0, 0, 1)', 'error-text': 'rgba(254, 223, 223, 1)', - field: 'rgba(41, 41, 41, 1)', + field: 'var(--grey-900)', focus: 'rgba(104, 119, 253, 1)', info: 'rgba(72, 155, 239, 1)', 'info-surface': 'rgba(0, 70, 140, 1)', 'info-surface-hover': 'rgba(0, 88, 175, 1)', 'info-text': 'rgba(223, 239, 254, 1)', - link: 'rgba(176, 128, 238, 1)', - 'link-disabled': 'rgba(152, 152, 152, 1)', - 'link-hover': 'rgba(165, 110, 236, 1)', + link: 'var(--purple-300)', + 'link-disabled': 'var(--grey-700)', + 'link-hover': 'var(--purple-400)', 'link-visited': 'rgba(181, 11, 215, 1)', - neutral: 'rgba(102, 102, 102, 1)', - 'neutral-surface': 'rgba(58, 58, 58, 1)', - 'neutral-surface-hover': 'rgba(41, 41, 41, 1)', - 'neutral-text': 'rgba(219, 219, 219, 1)', + neutral: 'var(--grey-750)', + 'neutral-surface': 'var(--grey-850)', + 'neutral-surface-hover': 'var(--grey-900)', + 'neutral-text': 'var(--grey-400)', 'orange-surface': 'rgba(175, 93, 0, 1)', 'orange-surface-hover': 'rgba(197, 109, 10, 1)', 'orange-text': 'rgba(255, 237, 202, 1)', @@ -272,56 +263,40 @@ export const darkColorsObject = { 'success-surface': 'rgba(3, 102, 0, 1)', 'success-surface-hover': 'rgba(6, 121, 0, 1)', 'success-text': 'rgba(233, 254, 223, 1)', - surface: 'rgba(30, 30, 30, 1)', - 'surface-active': 'rgba(58, 58, 58, 1)', - 'surface-disabled': 'rgba(75, 75, 75, 1)', - 'surface-hover': 'rgba(41, 41, 41, 1)', + surface: 'var(--grey-950)', + 'surface-active': 'var(--grey-900)', + 'surface-disabled': 'var(--grey-800)', + 'surface-hover': 'var(--grey-900)', 'surface-hover-transparent': 'rgba(255, 255, 255, 0.05)', - 'surface-low': 'rgba(26, 26, 26, 1)', - 'surface-low-active': 'rgba(76, 68, 92, 1)', - 'surface-low-hover': 'rgba(41, 41, 41, 1)', + 'surface-low': 'var(--grey)', + 'surface-low-active': 'var(--purple-900)', + 'surface-low-hover': 'var(--grey-900)', 'surface-low-hover-transparent': 'rgba(255, 255, 255, 0.05)', - 'surface-raised': 'rgba(41, 41, 41, 1)', - 'surface-raised-active': 'rgba(76, 68, 92, 1)', - 'surface-raised-active-text': 'var(--brand-primary-text)', - 'surface-raised-hover': 'rgba(75, 75, 75, 1)', + 'surface-raised': 'var(--grey-900)', + 'surface-raised-active': 'var(--purple-900)', + 'surface-raised-hover': 'var(--grey-800)', 'surface-raised-hover-transparent': 'rgba(255, 255, 255, 0.2)', - 'surface-secondary': 'rgba(75, 75, 75, 1)', - 'surface-secondary-active': 'rgba(58, 58, 58, 1)', - 'surface-secondary-hover': 'rgba(58, 58, 58, 1)', - 'surface-secondary-text': 'rgba(253, 253, 253, 1)', - text: 'rgba(253, 253, 253, 1)', - 'text-disabled': 'rgba(152, 152, 152, 1)', - 'text-placeholder': 'rgba(152, 152, 152, 1)', - 'text-secondary': 'rgba(18, 18, 18, 1)', - 'text-subtle': 'rgba(191, 191, 191, 1)', - 'toggle-disabled': 'rgba(58, 58, 58, 1)', - 'toggle-inactive': 'rgba(102, 102, 102, 1)', + 'surface-secondary': 'var(--grey-800)', + 'surface-secondary-active': 'var(--grey-900)', + 'surface-secondary-hover': 'var(--grey-900)', + text: 'var(--grey-50)', + 'text-active': 'var(--purple-150)', + 'text-disabled': 'var(--grey-700)', + 'text-placeholder': 'var(--grey-700)', + 'text-secondary': 'var(--grey-50)', + 'text-subtle': 'var(--grey-400)', + 'toggle-disabled': 'var(--grey-850)', + 'toggle-inactive': 'var(--grey-750)', warning: 'rgba(239, 194, 72, 1)', 'warning-surface': 'rgba(140, 103, 0, 1)', 'warning-surface-hover': 'rgba(159, 116, 0, 1)', 'warning-text': 'rgba(254, 246, 223, 1)' }; -export const brandColors = css` - --primary: rgba(121, 53, 210, 1); - --primary-active: rgba(109, 48, 189, 1); - --primary-hover: rgba(109, 48, 189, 1); - --primary-surface: rgba(230, 219, 243, 1); - --primary-text: rgba(255, 255, 255, 1); -`; - -export const brandColorsObject = { - primary: 'rgba(121, 53, 210, 1)', - 'primary-active': 'rgba(109, 48, 189, 1)', - 'primary-hover': 'rgba(109, 48, 189, 1)', - 'primary-surface': 'rgba(230, 219, 243, 1)', - 'primary-text': 'rgba(255, 255, 255, 1)' -}; - export const utilityColors = css` --black: rgba(0, 0, 0, 1); - --grey: rgba(18, 18, 18, 1); + --brand-static: rgba(121, 53, 210, 1); + --grey: rgba(26, 26, 26, 1); --grey-100: rgba(249, 249, 249, 1); --grey-150: rgba(247, 247, 247, 1); --grey-200: rgba(238, 238, 238, 1); @@ -337,12 +312,25 @@ export const utilityColors = css` --grey-850: rgba(58, 58, 58, 1); --grey-900: rgba(41, 41, 41, 1); --grey-950: rgba(30, 30, 30, 1); + --purple-100: rgba(241, 229, 255, 1); + --purple-150: rgba(226, 204, 255, 1); + --purple-200: rgba(220, 193, 255, 1); + --purple-300: rgba(176, 128, 238, 1); + --purple-400: rgba(165, 110, 236, 1); + --purple-50: rgba(247, 239, 255, 1); + --purple-500: rgba(159, 96, 241, 1); + --purple-600: rgba(142, 74, 231, 1); + --purple-700: rgba(120, 50, 210, 1); + --purple-800: rgba(84, 38, 142, 1); + --purple-900: rgba(61, 31, 98, 1); + --purple-950: rgba(49, 25, 78, 1); --white: rgba(255, 255, 255, 1); `; export const utilityColorsObject = { black: 'rgba(0, 0, 0, 1)', - grey: 'rgba(18, 18, 18, 1)', + 'brand-static': 'rgba(121, 53, 210, 1)', + grey: 'rgba(26, 26, 26, 1)', 'grey-100': 'rgba(249, 249, 249, 1)', 'grey-150': 'rgba(247, 247, 247, 1)', 'grey-200': 'rgba(238, 238, 238, 1)', @@ -358,22 +346,75 @@ export const utilityColorsObject = { 'grey-850': 'rgba(58, 58, 58, 1)', 'grey-900': 'rgba(41, 41, 41, 1)', 'grey-950': 'rgba(30, 30, 30, 1)', + 'purple-100': 'rgba(241, 229, 255, 1)', + 'purple-150': 'rgba(226, 204, 255, 1)', + 'purple-200': 'rgba(220, 193, 255, 1)', + 'purple-300': 'rgba(176, 128, 238, 1)', + 'purple-400': 'rgba(165, 110, 236, 1)', + 'purple-50': 'rgba(247, 239, 255, 1)', + 'purple-500': 'rgba(159, 96, 241, 1)', + 'purple-600': 'rgba(142, 74, 231, 1)', + 'purple-700': 'rgba(120, 50, 210, 1)', + 'purple-800': 'rgba(84, 38, 142, 1)', + 'purple-900': 'rgba(61, 31, 98, 1)', + 'purple-950': 'rgba(49, 25, 78, 1)', white: 'rgba(255, 255, 255, 1)' }; +export const spacing = css` + --spacing-l1: 4px; + --spacing-l2: 8px; + --spacing-l3: 12px; + --spacing-l4: 16px; + --spacing-l5: 24px; + --spacing-l6: 32px; + --spacing-l7: 40px; + --spacing-l8: 48px; +`; + +export const spacingObject = { + 'spacing-l1': 4, + 'spacing-l2': 8, + 'spacing-l3': 12, + 'spacing-l4': 16, + 'spacing-l5': 24, + 'spacing-l6': 32, + 'spacing-l7': 40, + 'spacing-l8': 48 +}; + +export const borderRadius = css` + --border-radius-large: 8px; + --border-radius-micro: 2px; + --border-radius-full: 999px; + --border-radius-small: 4px; +`; + +export const borderRadiusObject = { + 'border-radius-large': 8, + 'border-radius-micro': 2, + 'border-radius-full': 999, + 'border-radius-small': 4 +}; + export const lightEffectStyles = css` - --elevation-large: 0 0 12px 0 rgba(0, 0, 0, 0.1); - --elevation-medium: 0 0 6px 0 rgba(0, 0, 0, 0.1); - --elevation-small: 0 0 3px 0 rgba(0, 0, 0, 0.1); + --elevation-large: 0px 0px 12px 0px rgba(0, 0, 0, 0.1); + --elevation-medium: 0px 0px 6px 0px rgba(0, 0, 0, 0.1); + --elevation-small: 0px 0px 3px 0px rgba(0, 0, 0, 0.1); `; export const darkEffectStyles = css` - --elevation-large: 0 0 12px 0 rgba(255, 255, 255, 0.1); - --elevation-medium: 0 0 6px 0 rgba(255, 255, 255, 0.1); - --elevation-small: 0 0 3px 0 rgba(255, 255, 255, 0.1); + --elevation-large: 0px 0px 12px 0px rgba(0, 0, 0, 0.8); + --elevation-medium: 0px 0px 6px 0px rgba(0, 0, 0, 0.8); + --elevation-small: 0px 0px 3px 0px rgba(0, 0, 0, 0.8); `; export const theme = css` + :root { + ${spacing} + ${borderRadius} + ${utilityColors} + } ${themedCss({ selector: '', light: css` @@ -385,8 +426,4 @@ export const theme = css` ${darkEffectStyles} ` })} - :root { - ${brandColors} - ${utilityColors} - } `; diff --git a/system/core/src/themeVariables/types.gen.ts b/system/core/src/themeVariables/types.gen.ts index c88a3c3c0..03e5ff9a9 100644 --- a/system/core/src/themeVariables/types.gen.ts +++ b/system/core/src/themeVariables/types.gen.ts @@ -1,10 +1,14 @@ /** - * DO NOT EDIT; File is generated from figma, see './updateFromFigma.mjs' for update instructions + * DO NOT EDIT; File is generated from figma, see './updateFromFigma.ts' for update instructions */ - export interface TableKitCSSProperties { + '--black'?: string; '--border'?: string; '--border-active'?: string; + '--border-radius-large'?: string; + '--border-radius-micro'?: string; + '--border-radius-full'?: string; + '--border-radius-small'?: string; '--border-transparent'?: string; '--brand-primary'?: string; '--brand-primary-active'?: string; @@ -13,13 +17,29 @@ export interface TableKitCSSProperties { '--brand-secondary'?: string; '--brand-secondary-active'?: string; '--brand-secondary-hover'?: string; - '--brand-secondary-text'?: string; + '--brand-static'?: string; '--error'?: string; '--error-surface'?: string; '--error-surface-hover'?: string; '--error-text'?: string; '--field'?: string; '--focus'?: string; + '--grey'?: string; + '--grey-100'?: string; + '--grey-150'?: string; + '--grey-200'?: string; + '--grey-300'?: string; + '--grey-400'?: string; + '--grey-50'?: string; + '--grey-500'?: string; + '--grey-600'?: string; + '--grey-700'?: string; + '--grey-725'?: string; + '--grey-750'?: string; + '--grey-800'?: string; + '--grey-850'?: string; + '--grey-900'?: string; + '--grey-950'?: string; '--info'?: string; '--info-surface'?: string; '--info-surface-hover'?: string; @@ -35,9 +55,29 @@ export interface TableKitCSSProperties { '--orange-surface'?: string; '--orange-surface-hover'?: string; '--orange-text'?: string; + '--purple-100'?: string; + '--purple-150'?: string; + '--purple-200'?: string; + '--purple-300'?: string; + '--purple-400'?: string; + '--purple-50'?: string; + '--purple-500'?: string; + '--purple-600'?: string; + '--purple-700'?: string; + '--purple-800'?: string; + '--purple-900'?: string; + '--purple-950'?: string; '--purple-surface'?: string; '--purple-surface-hover'?: string; '--purple-text'?: string; + '--spacing-l1'?: string; + '--spacing-l2'?: string; + '--spacing-l3'?: string; + '--spacing-l4'?: string; + '--spacing-l5'?: string; + '--spacing-l6'?: string; + '--spacing-l7'?: string; + '--spacing-l8'?: string; '--success'?: string; '--success-surface'?: string; '--success-surface-hover'?: string; @@ -53,14 +93,13 @@ export interface TableKitCSSProperties { '--surface-low-hover-transparent'?: string; '--surface-raised'?: string; '--surface-raised-active'?: string; - '--surface-raised-active-text'?: string; '--surface-raised-hover'?: string; '--surface-raised-hover-transparent'?: string; '--surface-secondary'?: string; '--surface-secondary-active'?: string; '--surface-secondary-hover'?: string; - '--surface-secondary-text'?: string; '--text'?: string; + '--text-active'?: string; '--text-disabled'?: string; '--text-placeholder'?: string; '--text-secondary'?: string; @@ -71,30 +110,5 @@ export interface TableKitCSSProperties { '--warning-surface'?: string; '--warning-surface-hover'?: string; '--warning-text'?: string; - '--primary'?: string; - '--primary-active'?: string; - '--primary-hover'?: string; - '--primary-surface'?: string; - '--primary-text'?: string; - '--black'?: string; - '--grey'?: string; - '--grey-100'?: string; - '--grey-150'?: string; - '--grey-200'?: string; - '--grey-300'?: string; - '--grey-400'?: string; - '--grey-50'?: string; - '--grey-500'?: string; - '--grey-600'?: string; - '--grey-700'?: string; - '--grey-725'?: string; - '--grey-750'?: string; - '--grey-800'?: string; - '--grey-850'?: string; - '--grey-900'?: string; - '--grey-950'?: string; '--white'?: string; - '--elevation-large'?: string; - '--elevation-medium'?: string; - '--elevation-small'?: string; } diff --git a/system/core/src/utils/keyframes.ts b/system/core/src/utils/keyframes.ts index 707035b89..9e88ab863 100644 --- a/system/core/src/utils/keyframes.ts +++ b/system/core/src/utils/keyframes.ts @@ -1,10 +1,8 @@ -import { keyframes as skeleton } from '../components/Skeleton'; import { keyframes as spinner } from '../components/Spinner'; import { keyframes as tooltip } from '../components/Tooltip'; import { css } from '../utils'; export const keyframes = css` - ${skeleton} ${spinner} ${tooltip} `; diff --git a/system/css/package.json b/system/css/package.json index bc4e73f20..52a34f1a9 100644 --- a/system/css/package.json +++ b/system/css/package.json @@ -12,7 +12,7 @@ "classy/**/*.css" ], "scripts": { - "build": "ts-node-esm --transpileOnly src/build.ts && cp lib/*.css .", + "build": "bun src/build.ts && cp lib/*.css .", "build:netlify": "npm run setup-typescript && npm run build", "prepare": "npm run setup-typescript", "prepublishOnly": "npm run build && mv -f lib/* .", @@ -32,7 +32,6 @@ "pluralize": "8.0.0", "postcss": "8.4.38", "postcss-nesting": "12.1.5", - "ts-node": "10.9.2", "typescript": "4.9.5" }, "publishConfig": { diff --git a/system/react-css/src/structuredComponents/Skeleton.tsx b/system/react-css/src/structuredComponents/Skeleton.tsx index e1570b35a..bf4ccc977 100644 --- a/system/react-css/src/structuredComponents/Skeleton.tsx +++ b/system/react-css/src/structuredComponents/Skeleton.tsx @@ -16,19 +16,18 @@ export const Skeleton = React.forwardRef< HTMLSpanElement, Props & React.HTMLAttributes >(({ width, height, borderRadius, ...props }, ref): JSX.Element => { - const style = React.useMemo(() => { - // the animation takes 2s to run so we just -ve delay to start early - const delay = 2000 - (new Date().getTime() % 2000); - return { - '--animation-delay': `${-delay}ms`, - '--skeleton-width': pixelParam(width, '100%'), - '--skeleton-height': pixelParam(height, '100%'), - '--skeleton-border-radius': pixelParam( - borderRadius, - 'var(--border-radius-large)' - ) - } as React.CSSProperties & skeleton.SkeletonCSSProperties; - }, [width, height, borderRadius]); + const style = React.useMemo( + () => + ({ + '--tk-skeleton-width': pixelParam(width, '100%'), + '--tk-skeleton-height': pixelParam(height, '100%'), + '--tk-skeleton-border-radius': pixelParam( + borderRadius, + 'var(--border-radius-large)' + ) + } as React.CSSProperties & skeleton.SkeletonCSSProperties), + [width, height, borderRadius] + ); return ( ); }); +Skeleton.displayName = 'Skeleton'; diff --git a/system/react/src/structuredComponents/Skeleton.tsx b/system/react/src/structuredComponents/Skeleton.tsx index 6ffc015fb..322282b9a 100644 --- a/system/react/src/structuredComponents/Skeleton.tsx +++ b/system/react/src/structuredComponents/Skeleton.tsx @@ -21,18 +21,18 @@ export const Skeleton = React.forwardRef< HTMLSpanElement, Props & React.HTMLAttributes >(({ width, height, borderRadius, ...props }, ref): JSX.Element => { - const style = React.useMemo(() => { - // the animation takes 2s to run so we just -ve delay to start early - const delay = 2000 - (new Date().getTime() % 2000); - return { - '--animation-delay': `${-delay}ms`, - '--skeleton-width': pixelParam(width, '100%'), - '--skeleton-height': pixelParam(height, '100%'), - '--skeleton-border-radius': pixelParam( - borderRadius, - 'var(--border-radius-large)' - ) - } as React.CSSProperties & skeleton.SkeletonCSSProperties; - }, [width, height, borderRadius]); + const style = React.useMemo( + () => + ({ + '--tk-skeleton-width': pixelParam(width, '100%'), + '--tk-skeleton-height': pixelParam(height, '100%'), + '--tk-skeleton-border-radius': pixelParam( + borderRadius, + 'var(--border-radius-large)' + ) + } as React.CSSProperties & skeleton.SkeletonCSSProperties), + [width, height, borderRadius] + ); return ; }); +Skeleton.displayName = 'Skeleton'; diff --git a/system/stories/src/Skeleton.stories.tsx b/system/stories/src/Skeleton.stories.tsx new file mode 100644 index 000000000..90d616c34 --- /dev/null +++ b/system/stories/src/Skeleton.stories.tsx @@ -0,0 +1,43 @@ +import { Story, Meta } from '@storybook/react'; +import { skeleton } from '@tablecheck/tablekit-core'; +import * as emotion from '@tablecheck/tablekit-react'; +import * as css from '@tablecheck/tablekit-react-css'; + +export default { + title: 'Components/Skeleton', + component: emotion.Skeleton, + parameters: { chromatic: { disableSnapshot: true }, ...skeleton } +} as Meta; + +const Template: Story = ({ Skeleton }) => ( +
+

Can be manually sized

+ +

Can Auto-Size to fit content

+ +

Will size to contain all contents

+
+
+ + + + + +
+
+); + +export const Emotion: Story = Template.bind({}); +Emotion.args = { Skeleton: emotion.Skeleton }; +Emotion.parameters = { useEmotion: true }; + +export const Class: Story = Template.bind({}); +Class.args = { Skeleton: css.Skeleton }; +Class.parameters = { useEmotion: false }; diff --git a/system/stories/src/Theming.stories.tsx b/system/stories/src/Theming.stories.tsx index 18258e1b4..8edec8b00 100644 --- a/system/stories/src/Theming.stories.tsx +++ b/system/stories/src/Theming.stories.tsx @@ -3,7 +3,6 @@ import styled from '@emotion/styled'; import { Meta, StoryFn } from '@storybook/react'; import { lightColorsObject, - brandColorsObject, utilityColorsObject } from '@tablecheck/tablekit-core'; import { getConfigDefault } from '@tablecheck/tablekit-react'; @@ -27,6 +26,7 @@ const PaletteWrapper = styled.button` border: 1px solid var(--border); border-radius: var(--border-radius-small); cursor: pointer; + color: var(--text); &:hover { background-color: var(--surface-hover); box-shadow: var(--elevation-medium); @@ -44,13 +44,23 @@ const ColorPreview = styled.span` justify-content: center; `; -const ColorPreviewLabel = styled.span` +const TextGrid = styled.span` + display: grid; + grid-template: auto auto / auto 1fr; + align-items: center; + text-align: start; + gap: 0 var(--spacing-l2); + & > * { + white-space: nowrap; + display: inline-flex; + } +`; + +const ColorPreviewLabel = styled.small` color: var(--info-text); font-weight: bold; - display: inline-block; - width: 80px; text-align: end; - padding-inline-end: var(--spacing-l2); + place-self: center end; `; function PaletteColor({ @@ -78,22 +88,18 @@ function PaletteColor({ > Text - - {backgroundVar === colorVar ? null : ( - - Text: - - )} - {colorVar} - {backgroundVar === colorVar ? null : ( - <> -
- - Background: {backgroundVar} - - - )} -
+ {backgroundVar === colorVar ? ( + + {colorVar} + + ) : ( + + Text: + {colorVar} + Background: + {backgroundVar} + + )} ); @@ -133,14 +139,6 @@ export const Palette: StoryFn = () => ( ))} ))} -

Brand Colors

- {Object.keys(brandColorsObject).map((key, _, keys) => ( - - ))}

Utility Colors

{Object.keys(utilityColorsObject).map((key, _, keys) => (