From 6d89036a7c03e0b16ed0f111b66724d905c7d8bf Mon Sep 17 00:00:00 2001 From: isstuev Date: Mon, 18 Dec 2023 11:08:47 +0100 Subject: [PATCH 01/15] fix search hide on scroll bug --- ui/snippets/searchBar/SearchBarInput.tsx | 28 +++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/ui/snippets/searchBar/SearchBarInput.tsx b/ui/snippets/searchBar/SearchBarInput.tsx index 2491e8783c..5d3a51bae2 100644 --- a/ui/snippets/searchBar/SearchBarInput.tsx +++ b/ui/snippets/searchBar/SearchBarInput.tsx @@ -20,25 +20,33 @@ interface Props { } const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHide, onClear, value }: Props, ref: React.ForwardedRef) => { + const innerRef = React.useRef(null); + React.useImperativeHandle(ref, () => innerRef.current!, []); const [ isSticky, setIsSticky ] = React.useState(false); const scrollDirection = useScrollDirection(); const isMobile = useIsMobile(); const handleScroll = React.useCallback(() => { const TOP_BAR_HEIGHT = 36; - if (window.pageYOffset >= TOP_BAR_HEIGHT) { - setIsSticky(true); - } else { - setIsSticky(false); + if (!isHomepage) { + if (window.scrollY >= TOP_BAR_HEIGHT) { + setIsSticky(true); + } else { + setIsSticky(false); + } } - }, [ ]); + + if (isMobile && innerRef?.current?.getBoundingClientRect() && innerRef?.current?.getBoundingClientRect().y < TOP_BAR_HEIGHT) { + onHide?.(); + } + }, [ isMobile, onHide, isHomepage ]); const handleChange = React.useCallback((event: ChangeEvent) => { onChange(event.target.value); }, [ onChange ]); React.useEffect(() => { - if (!isMobile || isHomepage) { + if (!isMobile) { return; } const throttledHandleScroll = throttle(handleScroll, 300); @@ -55,15 +63,9 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid const bgColor = useColorModeValue('white', 'black'); const transformMobile = scrollDirection !== 'down' ? 'translateY(0)' : 'translateY(-100%)'; - React.useEffect(() => { - if (isMobile && scrollDirection === 'down') { - onHide?.(); - } - }, [ scrollDirection, onHide, isMobile ]); - return ( Date: Tue, 19 Dec 2023 17:06:37 +0400 Subject: [PATCH 02/15] Tick icon doesn't appear on automatically verified contracts until refresh Fixes #1377 --- ui/address/contract/ContractCode.pw.tsx | 25 +++++++++++++++++++++++++ ui/address/contract/ContractCode.tsx | 7 +++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ui/address/contract/ContractCode.pw.tsx b/ui/address/contract/ContractCode.pw.tsx index ef4234d907..52c7fc9682 100644 --- a/ui/address/contract/ContractCode.pw.tsx +++ b/ui/address/contract/ContractCode.pw.tsx @@ -78,6 +78,31 @@ test('verified with changed byte code socket', async({ mount, page, createSocket await expect(component).toHaveScreenshot(); }); +test('verified via lookup in eth_bytecode_db', async({ mount, page, createSocket }) => { + await page.route(CONTRACT_API_URL, (route) => route.fulfill({ + status: 200, + body: JSON.stringify(contractMock.nonVerified), + })); + await page.route('https://cdn.jsdelivr.net/npm/monaco-editor@0.33.0/**', (route) => route.abort()); + + await mount( + + + , + { hooksConfig }, + ); + + const socket = await createSocket(); + const channel = await socketServer.joinChannel(socket, 'addresses:' + addressHash.toLowerCase()); + + await page.waitForResponse(CONTRACT_API_URL); + socketServer.sendMessage(socket, channel, 'smart_contract_was_verified', {}); + + const request = await page.waitForRequest(CONTRACT_API_URL); + + expect(request).toBeTruthy(); +}); + test('verified with multiple sources', async({ mount, page }) => { await page.route(CONTRACT_API_URL, (route) => route.fulfill({ status: 200, diff --git a/ui/address/contract/ContractCode.tsx b/ui/address/contract/ContractCode.tsx index 465602befd..cfa2e5f003 100644 --- a/ui/address/contract/ContractCode.tsx +++ b/ui/address/contract/ContractCode.tsx @@ -38,7 +38,6 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { const [ isChangedBytecodeSocket, setIsChangedBytecodeSocket ] = React.useState(); const queryClient = useQueryClient(); - const refetchQueries = queryClient.refetchQueries; const addressInfo = queryClient.getQueryData(getResourceKey('address', { pathParams: { hash: addressHash } })); const { data, isPlaceholderData, isError } = useApiQuery('contract', { @@ -55,13 +54,13 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { }, [ ]); const handleContractWasVerifiedMessage: SocketMessage.SmartContractWasVerified['handler'] = React.useCallback(() => { - refetchQueries({ + queryClient.refetchQueries({ queryKey: getResourceKey('address', { pathParams: { hash: addressHash } }), }); - refetchQueries({ + queryClient.refetchQueries({ queryKey: getResourceKey('contract', { pathParams: { hash: addressHash } }), }); - }, [ addressHash, refetchQueries ]); + }, [ addressHash, queryClient ]); const enableQuery = React.useCallback(() => setIsQueryEnabled(true), []); From d02c22443596e73b0f9be65f38edc60a59bcf3fc Mon Sep 17 00:00:00 2001 From: tom Date: Tue, 19 Dec 2023 19:54:16 +0400 Subject: [PATCH 03/15] build sprite script and common component --- .gitignore | 2 + .vscode/tasks.json | 2 +- docs/CONTRIBUTING.md | 3 +- package.json | 4 +- pages/_document.tsx | 3 + public/icons/name.d.ts | 127 +++++++++++++++++ svgo.config.js | 21 +-- tools/scripts/dev.preset.sh | 3 + tools/scripts/dev.sh | 3 + ui/shared/IconSvg.tsx | 23 +++ yarn.lock | 277 ++++++++++++++++++++++++++++++++++-- 11 files changed, 442 insertions(+), 26 deletions(-) create mode 100644 public/icons/name.d.ts create mode 100644 ui/shared/IconSvg.tsx diff --git a/.gitignore b/.gitignore index 534aa23650..45e35b7cbf 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ /out/ /public/assets/ /public/envs.js +/public/icons/sprite.svg +/public/icons/README.md /analyze # production diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1a957c87c2..95b6bb2310 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -265,7 +265,7 @@ }, { "type": "npm", - "script": "format-svg", + "script": "svg:format", "problemMatcher": [], "label": "format svg", "detail": "format svg files with svgo", diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 76410edf44..578cbd2129 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -182,7 +182,8 @@ We have 3 pre-configured projects. You can run your test with the desired projec | `yarn lint:eslint` | lint project files with ESLint | | `yarn lint:eslint:fix` | lint project files with ESLint and automatically fix problems | | `yarn lint:tsc` | compile project typescript files using TypeScript Compiler | -| `yarn format-svg` | format and optimize SVG icons in the `/icons` folder using SVGO tool | +| `yarn svg:format` | format and optimize SVG icons in the `/icons` folder using SVGO tool | +| `yarn svg:build-sprite` | build SVG icons sprite | | **Testing** | | `yarn test:jest` | run all Jest unit tests | | `yarn test:jest:watch` | run all Jest unit tests in watch mode | diff --git a/package.json b/package.json index 656e2dac83..2bada056e8 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "lint:tsc": "tsc -p ./tsconfig.json", "lint:envs-validator:test": "cd ./deploy/tools/envs-validator && ./test.sh", "prepare": "husky install", - "format-svg": "svgo -r ./icons", + "svg:format": "svgo -r ./icons", + "svg:build-sprite": "icons build -i ./icons -o ./public/icons --optimize", "test:pw": "./tools/scripts/pw.sh", "test:pw:local": "export NODE_PATH=$(pwd)/node_modules && yarn test:pw", "test:pw:docker": "docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.35.1-focal ./tools/scripts/pw.docker.sh", @@ -137,6 +138,7 @@ "lint-staged": ">=10", "mockdate": "^3.0.5", "style-loader": "^3.3.1", + "svg-icons-cli": "^0.0.5", "svgo": "^2.8.0", "ts-jest": "^29.0.3", "ts-node": "^10.9.1", diff --git a/pages/_document.tsx b/pages/_document.tsx index 6d21b3532c..74ebe08fb5 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -6,6 +6,7 @@ import React from 'react'; import * as serverTiming from 'nextjs/utils/serverTiming'; import theme from 'theme'; +import * as svgSprite from 'ui/shared/IconSvg'; class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { @@ -48,6 +49,8 @@ class MyDocument extends Document { + + diff --git a/public/icons/name.d.ts b/public/icons/name.d.ts new file mode 100644 index 0000000000..f9f9c57181 --- /dev/null +++ b/public/icons/name.d.ts @@ -0,0 +1,127 @@ +// This file is generated by npm run build:icons + + export type IconName = + | "ABI" + | "API" + | "apps" + | "arrows/down-right" + | "arrows/east-mini" + | "arrows/east" + | "arrows/north-east" + | "arrows/south-east" + | "arrows/up-down" + | "block_slim" + | "block" + | "brands/safe" + | "burger" + | "check" + | "clock-light" + | "clock" + | "coins/bitcoin" + | "collection" + | "contract_verified" + | "contract" + | "copy" + | "cross" + | "delete" + | "discussions" + | "docs" + | "donate" + | "edit" + | "email-sent" + | "email" + | "empty_search_result" + | "error-pages/404" + | "error-pages/422" + | "error-pages/429" + | "error-pages/500" + | "explorer" + | "files/csv" + | "files/image" + | "files/json" + | "files/placeholder" + | "files/sol" + | "files/yul" + | "filter" + | "finalized" + | "flame" + | "gas" + | "gear" + | "globe-b" + | "globe" + | "graphQL" + | "info" + | "key" + | "link" + | "lock" + | "minus" + | "moon-with-star" + | "moon" + | "networks" + | "networks/icon-placeholder" + | "networks/logo-placeholder" + | "nft_shield" + | "output_roots" + | "plus" + | "privattags" + | "profile" + | "publictags_slim" + | "publictags" + | "qr_code" + | "repeat_arrow" + | "restAPI" + | "rocket" + | "RPC" + | "scope" + | "score/score-not-ok" + | "score/score-ok" + | "search" + | "social/canny" + | "social/coingecko" + | "social/coinmarketcap" + | "social/defi_llama" + | "social/discord_filled" + | "social/discord" + | "social/facebook_filled" + | "social/git" + | "social/github_filled" + | "social/linkedin_filled" + | "social/medium_filled" + | "social/opensea_filled" + | "social/reddit_filled" + | "social/slack_filled" + | "social/stats" + | "social/telega" + | "social/telegram_filled" + | "social/tweet" + | "social/twitter_filled" + | "star_filled" + | "star_outline" + | "stats" + | "status/error" + | "status/pending" + | "status/success" + | "status/warning" + | "sun" + | "testnet" + | "token-placeholder" + | "token" + | "tokens" + | "tokens/xdai" + | "top-accounts" + | "transactions_slim" + | "transactions" + | "txn_batches_slim" + | "txn_batches" + | "unfinalized" + | "uniswap" + | "verified_token" + | "verified" + | "verify-contract" + | "vertical_dots" + | "wallet" + | "wallets/coinbase" + | "wallets/metamask" + | "wallets/token-pocket" + | "watchlist"; + \ No newline at end of file diff --git a/svgo.config.js b/svgo.config.js index 69994b1608..fd50b1f8f0 100644 --- a/svgo.config.js +++ b/svgo.config.js @@ -1,15 +1,18 @@ module.exports = { plugins: [ - { - name: 'preset-default', - params: { - overrides: { - removeViewBox: false, - }, - }, - }, + // TODO @tom2drum pick up plugins from default preset + // { + // name: 'preset-default', + // params: { + // overrides: { + // removeViewBox: false, + // cleanupIds: false, + // removeUselessDefs: false, + // collapseGroups: false, + // }, + // }, + // }, 'removeDimensions', - 'prefixIds', ], js2svg: { indent: 2, diff --git a/tools/scripts/dev.preset.sh b/tools/scripts/dev.preset.sh index 37e01e3f38..c8566819e0 100755 --- a/tools/scripts/dev.preset.sh +++ b/tools/scripts/dev.preset.sh @@ -19,6 +19,9 @@ dotenv \ -e $config_file \ -- bash -c './deploy/scripts/download_assets.sh ./public/assets' +yarn svg:build-sprite +echo "" + # generate envs.js file and run the app dotenv \ -v NEXT_PUBLIC_GIT_COMMIT_SHA=$(git rev-parse --short HEAD) \ diff --git a/tools/scripts/dev.sh b/tools/scripts/dev.sh index a01e2af95f..fabcad2ff4 100755 --- a/tools/scripts/dev.sh +++ b/tools/scripts/dev.sh @@ -8,6 +8,9 @@ dotenv \ -e .env \ -- bash -c './deploy/scripts/download_assets.sh ./public/assets' +yarn svg:build-sprite +echo "" + # generate envs.js file and run the app dotenv \ -v NEXT_PUBLIC_GIT_COMMIT_SHA=$(git rev-parse --short HEAD) \ diff --git a/ui/shared/IconSvg.tsx b/ui/shared/IconSvg.tsx new file mode 100644 index 0000000000..32c0909ff1 --- /dev/null +++ b/ui/shared/IconSvg.tsx @@ -0,0 +1,23 @@ +import { Skeleton, chakra } from '@chakra-ui/react'; +import { type IconName } from 'public/icons/name'; +import React from 'react'; + +export const href = '/icons/sprite.svg'; + +interface Props { + name: IconName; + isLoading?: boolean; + className?: string; +} + +const IconSvg = ({ name, isLoading, className }: Props) => { + return ( + + + + + + ); +}; + +export default chakra(IconSvg); diff --git a/yarn.lock b/yarn.lock index 8d58225f1f..2856aeef2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1218,6 +1218,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.23.5": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d" + integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.8.4": version "7.20.1" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" @@ -2120,6 +2127,23 @@ resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.0.15.tgz#60df64e0ab97d95fee4e6c61ccabd15fd5ace398" integrity sha512-WWULIiucYRBIewHKFA7BssQ2ABLHLVd9lrUo3N3SZgR0u4ZRDDVEUNOy+r+9ruDze8+36dGbN9wsN1IdELtdOw== +"@clack/core@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@clack/core/-/core-0.3.3.tgz#233ccebf779aa5a66fc68ee48df5e58cd226fd94" + integrity sha512-5ZGyb75BUBjlll6eOa1m/IZBxwk91dooBWhPSL67sWcLS0zt9SnswRL0l26TVdBhb0wnWORRxUn//uH6n4z7+A== + dependencies: + picocolors "^1.0.0" + sisteransi "^1.0.5" + +"@clack/prompts@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@clack/prompts/-/prompts-0.7.0.tgz#6aaef48ea803d91cce12bc80811cfcb8de2e75ea" + integrity sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA== + dependencies: + "@clack/core" "^0.3.3" + picocolors "^1.0.0" + sisteransi "^1.0.5" + "@coinbase/wallet-sdk@^3.6.6": version "3.6.6" resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-3.6.6.tgz#4a0758fe0fe0ba3ed7e33b5bb6eb094ff8bd6c98" @@ -2938,6 +2962,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -4506,6 +4542,11 @@ dependencies: "@opentelemetry/core" "^1.1.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@pkgr/utils@^2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03" @@ -7391,6 +7432,11 @@ ansi-styles@^6.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.1.tgz#63cd61c72283a71cb30bd881dbb60adada74bc70" integrity sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -8058,6 +8104,11 @@ clsx@^1.1.0: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== +clsx@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -8240,7 +8291,7 @@ cross-fetch@^3.1.4, cross-fetch@^3.1.5: dependencies: node-fetch "2.6.7" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -8286,6 +8337,17 @@ css-select@^4.1.3: domutils "^2.8.0" nth-check "^2.0.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" @@ -8294,7 +8356,23 @@ css-tree@^1.1.2, css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-what@^6.0.1: +css-tree@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + +css-what@^6.0.1, css-what@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== @@ -8314,6 +8392,13 @@ cssfilter@0.0.10: resolved "https://registry.yarnpkg.com/cssfilter/-/cssfilter-0.0.10.tgz#c6d2672632a2e5c83e013e6864a42ce8defd20ae" integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw== +csso@5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + csso@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" @@ -8832,12 +8917,21 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + dom-to-image@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/dom-to-image/-/dom-to-image-2.6.0.tgz#8a503608088c87b1c22f9034ae032e1898955867" integrity sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA== -domelementtype@^2.0.1, domelementtype@^2.2.0: +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== @@ -8856,6 +8950,13 @@ domhandler@^4.2.0, domhandler@^4.3.1: dependencies: domelementtype "^2.2.0" +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + dompurify@=3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.6.tgz#925ebd576d54a9531b5d76f0a5bef32548351dae" @@ -8870,6 +8971,15 @@ domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dotenv-cli@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/dotenv-cli/-/dotenv-cli-6.0.0.tgz#8a30cbc59d0a8aaa166b2fee0a9a55e23a1223ab" @@ -8973,6 +9083,11 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@^4.2.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + entities@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" @@ -9842,6 +9957,14 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -10068,6 +10191,17 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.3.10: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -10287,6 +10421,11 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + help-me@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/help-me/-/help-me-4.1.0.tgz#c105e78ba490d6fcaa61a3d0cd06e0054554efab" @@ -10850,6 +10989,15 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jaeger-client@^3.15.0: version "3.19.0" resolved "https://registry.yarnpkg.com/jaeger-client/-/jaeger-client-3.19.0.tgz#9b5bd818ebd24e818616ee0f5cffe1722a53ae6e" @@ -11702,6 +11850,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +"lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + lz-string@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" @@ -11742,6 +11895,16 @@ mdn-data@2.0.14: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -11850,6 +12013,13 @@ minimatch@^7.4.3: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.1.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -11860,6 +12030,11 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + mixpanel-browser@^2.47.0: version "2.47.0" resolved "https://registry.yarnpkg.com/mixpanel-browser/-/mixpanel-browser-2.47.0.tgz#4e7fd3bb660c6f63443efbd169d1cd327db71ed4" @@ -12056,6 +12231,14 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== +node-html-parser@^6.1.11: + version "6.1.11" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-6.1.11.tgz#387378111348c001a5c5fbebb7f478fdf65610aa" + integrity sha512-FAgwwZ6h0DSDWxfD0Iq1tsDcBCxdJB1nXpLPPxX8YyVWzbfCjKWEzaynF4gZZ/8hziUmp7ZSaKylcn0iKhufUQ== + dependencies: + css-select "^5.1.0" + he "1.2.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -12429,6 +12612,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" @@ -13775,6 +13966,11 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -13858,7 +14054,7 @@ sonic-boom@^3.0.0, sonic-boom@^3.1.0: dependencies: atomic-sleep "^1.0.0" -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -13969,7 +14165,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -13978,7 +14174,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.0: +string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -14065,7 +14261,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -14182,6 +14378,20 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-icons-cli@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/svg-icons-cli/-/svg-icons-cli-0.0.5.tgz#501c43f80fe23784e826b47c4fe2e71e7ea5fa67" + integrity sha512-6U7RB1n8qroIuJYjMO/HVk/3OXZS0m48Qu+pFXNGp2oRwhTdkTjMJ2PThbzzAwLNzBNmQ5qMfzQq5vqvp4Ocdg== + dependencies: + "@clack/prompts" "^0.7.0" + clsx "^2.0.0" + glob "^10.3.10" + node-html-parser "^6.1.11" + svgo "^3.0.4" + tailwind-merge "^2.0.0" + tiny-parse-argv "^2.2.0" + typescript "^5.2.2" + svg-parser@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" @@ -14200,6 +14410,19 @@ svgo@^2.8.0: picocolors "^1.0.0" stable "^0.1.8" +svgo@^3.0.4: + version "3.1.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.1.0.tgz#7e63855c8da73297d5d5765e968f9679a0f8d24a" + integrity sha512-R5SnNA89w1dYgNv570591F66v34b3eQShpIBcQtZtM5trJwm1VvxbIoMpRYY3ybTAutcKTLEmTsdnaknOHbiQA== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.2.1" + css-what "^6.1.0" + csso "5.0.5" + picocolors "^1.0.0" + swagger-client@^3.22.3: version "3.23.1" resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.23.1.tgz#22364b76b6f61b7c69f8846563fad59f28891380" @@ -14279,6 +14502,13 @@ tabbable@^4.0.0: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261" integrity sha512-H1XoH1URcBOa/rZZWxLxHCtOdVUEev+9vo5YdYhC9tCY4wnybX+VQrCYuy9ubkg69fCBxCONJOSLGfw0DWMffQ== +tailwind-merge@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.1.0.tgz#541b407e0ec255651e92571d96b685e48f01999c" + integrity sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ== + dependencies: + "@babel/runtime" "^7.23.5" + tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" @@ -14379,6 +14609,11 @@ tiny-invariant@^1.0.6: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tiny-parse-argv@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tiny-parse-argv/-/tiny-parse-argv-2.4.0.tgz#8612163a88104a5af9a64e4775cd1e091d4fa265" + integrity sha512-WTEsnmeHNr99hLQIDA+gnsS+fDsCDITlqgI+zEhx9M6ErPt0heoNZ1PGvql6wcf95sIx40J0MLYXaPveGwtpoA== + tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -14615,6 +14850,11 @@ typescript@^5.1.0: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@^5.2.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + ua-parser-js@^1.0.33: version "1.0.35" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz#c4ef44343bc3db0a3cbefdf21822f1b1fc1ab011" @@ -15013,6 +15253,15 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -15022,14 +15271,14 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" wrappy@1: version "1.0.2" From 694c866bb0ad030d8b4157a29f8d71e902846f1a Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 20 Dec 2023 11:30:24 +0400 Subject: [PATCH 04/15] add sprite to pw tests and migrate entities components --- playwright/index.html | 1 + tools/scripts/pw.sh | 2 ++ ui/shared/IconSvg.tsx | 2 ++ ui/shared/entities/address/AddressEntity.tsx | 9 +++------ ui/shared/entities/base/components.tsx | 11 ++++++----- ui/shared/entities/block/BlockEntity.tsx | 8 +++----- ui/shared/entities/block/BlockEntityL2.tsx | 3 +-- ui/shared/entities/block/ZkEvmBatchEntityL2.tsx | 3 +-- ui/shared/entities/nft/NftEntity.tsx | 6 ++---- ui/shared/entities/token/TokenEntity.tsx | 3 +-- ui/shared/entities/tx/TxEntity.tsx | 8 +++----- 11 files changed, 25 insertions(+), 31 deletions(-) diff --git a/playwright/index.html b/playwright/index.html index 8e124e4903..f902263094 100644 --- a/playwright/index.html +++ b/playwright/index.html @@ -9,5 +9,6 @@
+ diff --git a/tools/scripts/pw.sh b/tools/scripts/pw.sh index d99eebca94..22aee344a2 100755 --- a/tools/scripts/pw.sh +++ b/tools/scripts/pw.sh @@ -8,6 +8,8 @@ dotenv \ -e $config_file \ -- bash -c './deploy/scripts/make_envs_script.sh ./playwright/envs.js' +yarn svg:build-sprite + dotenv \ -v NODE_OPTIONS=\"--max-old-space-size=4096\" \ -e $config_file \ diff --git a/ui/shared/IconSvg.tsx b/ui/shared/IconSvg.tsx index 32c0909ff1..e4ee730386 100644 --- a/ui/shared/IconSvg.tsx +++ b/ui/shared/IconSvg.tsx @@ -4,6 +4,8 @@ import React from 'react'; export const href = '/icons/sprite.svg'; +export { IconName }; + interface Props { name: IconName; isLoading?: boolean; diff --git a/ui/shared/entities/address/AddressEntity.tsx b/ui/shared/entities/address/AddressEntity.tsx index 5eabca3825..fb46d80a94 100644 --- a/ui/shared/entities/address/AddressEntity.tsx +++ b/ui/shared/entities/address/AddressEntity.tsx @@ -7,9 +7,6 @@ import type { AddressParam } from 'types/api/addressParams'; import { route } from 'nextjs-routes'; -import iconSafe from 'icons/brands/safe.svg'; -import iconContractVerified from 'icons/contract_verified.svg'; -import iconContract from 'icons/contract.svg'; import * as EntityBase from 'ui/shared/entities/base/components'; import { getIconProps } from '../base/utils'; @@ -53,7 +50,7 @@ const Icon = (props: IconProps) => { return ( ); } @@ -64,7 +61,7 @@ const Icon = (props: IconProps) => { @@ -78,7 +75,7 @@ const Icon = (props: IconProps) => { diff --git a/ui/shared/entities/base/components.tsx b/ui/shared/entities/base/components.tsx index a53a8447b0..ec85e0ca35 100644 --- a/ui/shared/entities/base/components.tsx +++ b/ui/shared/entities/base/components.tsx @@ -2,11 +2,12 @@ import { Box, chakra, Flex, Skeleton, useColorModeValue } from '@chakra-ui/react import type { As, IconProps } from '@chakra-ui/react'; import React from 'react'; -import IconBase from 'ui/shared/chakra/Icon'; import type { Props as CopyToClipboardProps } from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; import LinkExternal from 'ui/shared/LinkExternal'; import LinkInternal from 'ui/shared/LinkInternal'; @@ -76,12 +77,12 @@ const Link = chakra(({ isLoading, children, isExternal, onClick, href, noLink }: }); export interface IconBaseProps extends Pick { - asProp: As; + name: IconName; color?: IconProps['color']; borderRadius?: IconProps['borderRadius']; } -const Icon = ({ isLoading, iconSize, noIcon, asProp, color, borderRadius }: IconBaseProps) => { +const Icon = ({ isLoading, iconSize, noIcon, name, color, borderRadius }: IconBaseProps) => { const defaultColor = useColorModeValue('gray.500', 'gray.400'); if (noIcon) { @@ -91,8 +92,8 @@ const Icon = ({ isLoading, iconSize, noIcon, asProp, color, borderRadius }: Icon const styles = getIconProps(iconSize); return ( - ; @@ -24,15 +22,15 @@ const Link = chakra((props: LinkProps) => { ); }); -type IconProps = Omit & { - asProp?: As; +type IconProps = Omit & { + name?: EntityBase.IconBaseProps['name']; }; const Icon = (props: IconProps) => { return ( ); }; diff --git a/ui/shared/entities/block/BlockEntityL2.tsx b/ui/shared/entities/block/BlockEntityL2.tsx index aa11730764..b1722d53fa 100644 --- a/ui/shared/entities/block/BlockEntityL2.tsx +++ b/ui/shared/entities/block/BlockEntityL2.tsx @@ -3,7 +3,6 @@ import _omit from 'lodash/omit'; import React from 'react'; import config from 'configs/app'; -import txBatchIcon from 'icons/txn_batches_slim.svg'; import * as BlockEntity from './BlockEntity'; @@ -19,7 +18,7 @@ const BlockEntityL2 = (props: BlockEntity.EntityProps) => { return ( - + diff --git a/ui/shared/entities/block/ZkEvmBatchEntityL2.tsx b/ui/shared/entities/block/ZkEvmBatchEntityL2.tsx index 5ad926c1da..b9edddaeba 100644 --- a/ui/shared/entities/block/ZkEvmBatchEntityL2.tsx +++ b/ui/shared/entities/block/ZkEvmBatchEntityL2.tsx @@ -5,7 +5,6 @@ import React from 'react'; import { route } from 'nextjs-routes'; import config from 'configs/app'; -import txBatchIcon from 'icons/txn_batches_slim.svg'; import * as BlockEntity from './BlockEntity'; @@ -21,7 +20,7 @@ const ZkEvmBatchEntityL2 = (props: BlockEntity.EntityProps) => { return ( - + & { - asProp?: As; + name?: EntityBase.IconBaseProps['name']; }; const Icon = (props: IconProps) => { @@ -24,7 +22,7 @@ const Icon = (props: IconProps) => { ); }; diff --git a/ui/shared/entities/token/TokenEntity.tsx b/ui/shared/entities/token/TokenEntity.tsx index 53ff91f289..6cb07331d4 100644 --- a/ui/shared/entities/token/TokenEntity.tsx +++ b/ui/shared/entities/token/TokenEntity.tsx @@ -1,4 +1,4 @@ -import type { As, ChakraProps } from '@chakra-ui/react'; +import type { ChakraProps } from '@chakra-ui/react'; import { Image, Skeleton, chakra } from '@chakra-ui/react'; import _omit from 'lodash/omit'; import React from 'react'; @@ -29,7 +29,6 @@ const Link = chakra((props: LinkProps) => { }); type IconProps = Pick & { - asProp?: As; marginRight?: ChakraProps['marginRight']; boxSize?: ChakraProps['boxSize']; }; diff --git a/ui/shared/entities/tx/TxEntity.tsx b/ui/shared/entities/tx/TxEntity.tsx index 54cd8eb85a..796d305ded 100644 --- a/ui/shared/entities/tx/TxEntity.tsx +++ b/ui/shared/entities/tx/TxEntity.tsx @@ -1,11 +1,9 @@ -import type { As } from '@chakra-ui/react'; import { chakra } from '@chakra-ui/react'; import _omit from 'lodash/omit'; import React from 'react'; import { route } from 'nextjs-routes'; -import transactionIcon from 'icons/transactions_slim.svg'; import * as EntityBase from 'ui/shared/entities/base/components'; type LinkProps = EntityBase.LinkBaseProps & Pick; @@ -23,15 +21,15 @@ const Link = chakra((props: LinkProps) => { ); }); -type IconProps = Omit & { - asProp?: As; +type IconProps = Omit & { + name?: EntityBase.IconBaseProps['name']; }; const Icon = (props: IconProps) => { return ( ); }; From 17d71792836199c2f9bc17ea045eca9bb68a139c Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 20 Dec 2023 12:37:30 +0400 Subject: [PATCH 05/15] migrate snippets --- lib/hooks/useNavItems.tsx | 98 ++++++++----------- types/client/navigation-items.ts | 4 +- ui/shared/IconSvg.tsx | 10 +- ui/snippets/footer/Footer.tsx | 21 ++-- ui/snippets/footer/FooterLinkItem.tsx | 9 +- ui/snippets/footer/IntTxsIndexingStatus.tsx | 6 +- ui/snippets/header/Burger.tsx | 11 +-- ui/snippets/navigation/NavLink.tsx | 6 +- .../navigation/NavLinkGroupDesktop.tsx | 7 +- ui/snippets/navigation/NavLinkGroupMobile.tsx | 5 +- ui/snippets/navigation/NavLinkIcon.tsx | 7 +- ui/snippets/navigation/NavigationDesktop.tsx | 11 +-- ui/snippets/navigation/NavigationMobile.tsx | 6 +- ui/snippets/networkMenu/NetworkLogo.tsx | 9 +- ui/snippets/networkMenu/NetworkMenuButton.tsx | 8 +- ui/snippets/networkMenu/NetworkMenuLink.tsx | 13 ++- ui/snippets/searchBar/SearchBarInput.tsx | 6 +- .../SearchBarSuggest/SearchBarSuggestApp.tsx | 8 +- .../SearchBarSuggestLabel.tsx | 9 +- .../SearchBarSuggestToken.tsx | 9 +- ui/snippets/topBar/ColorModeSwitch.tsx | 4 +- ui/snippets/topBar/ColorModeSwitchTheme.tsx | 5 +- ui/snippets/topBar/utils.ts | 10 +- ui/snippets/walletMenu/WalletMenuMobile.tsx | 6 +- 24 files changed, 133 insertions(+), 155 deletions(-) diff --git a/lib/hooks/useNavItems.tsx b/lib/hooks/useNavItems.tsx index a8d8e15482..9952830479 100644 --- a/lib/hooks/useNavItems.tsx +++ b/lib/hooks/useNavItems.tsx @@ -4,28 +4,6 @@ import React from 'react'; import type { NavItemInternal, NavItem, NavGroupItem } from 'types/client/navigation-items'; import config from 'configs/app'; -import abiIcon from 'icons/ABI.svg'; -import apiKeysIcon from 'icons/API.svg'; -import appsIcon from 'icons/apps.svg'; -import withdrawalsIcon from 'icons/arrows/north-east.svg'; -import depositsIcon from 'icons/arrows/south-east.svg'; -import blocksIcon from 'icons/block.svg'; -import gearIcon from 'icons/gear.svg'; -import globeIcon from 'icons/globe-b.svg'; -import graphQLIcon from 'icons/graphQL.svg'; -import outputRootsIcon from 'icons/output_roots.svg'; -import privateTagIcon from 'icons/privattags.svg'; -import publicTagIcon from 'icons/publictags.svg'; -import apiDocsIcon from 'icons/restAPI.svg'; -import rpcIcon from 'icons/RPC.svg'; -import statsIcon from 'icons/stats.svg'; -import tokensIcon from 'icons/token.svg'; -import topAccountsIcon from 'icons/top-accounts.svg'; -import transactionsIcon from 'icons/transactions.svg'; -import txnBatchIcon from 'icons/txn_batches.svg'; -import verifiedIcon from 'icons/verified.svg'; -import verifyContractIcon from 'icons/verify-contract.svg'; -import watchlistIcon from 'icons/watchlist.svg'; import { rightLineArrow } from 'lib/html-entities'; import UserAvatar from 'ui/shared/UserAvatar'; @@ -50,35 +28,43 @@ export default function useNavItems(): ReturnType { return React.useMemo(() => { let blockchainNavItems: Array | Array> = []; - const topAccounts = !config.UI.views.address.hiddenViews?.top_accounts ? { + const topAccounts: NavItem | null = !config.UI.views.address.hiddenViews?.top_accounts ? { text: 'Top accounts', nextRoute: { pathname: '/accounts' as const }, - icon: topAccountsIcon, + icon: 'top-accounts', isActive: pathname === '/accounts', } : null; - const blocks = { + const blocks: NavItem | null = { text: 'Blocks', nextRoute: { pathname: '/blocks' as const }, - icon: blocksIcon, + icon: 'block', isActive: pathname === '/blocks' || pathname === '/block/[height_or_hash]', }; - const txs = { + const txs: NavItem | null = { text: 'Transactions', nextRoute: { pathname: '/txs' as const }, - icon: transactionsIcon, + icon: 'transactions', isActive: pathname === '/txs' || pathname === '/tx/[hash]', }; - const verifiedContracts = - // eslint-disable-next-line max-len - { text: 'Verified contracts', nextRoute: { pathname: '/verified-contracts' as const }, icon: verifiedIcon, isActive: pathname === '/verified-contracts' }; + const verifiedContracts: NavItem | null = + { + text: 'Verified contracts', + nextRoute: { pathname: '/verified-contracts' as const }, + icon: 'verified', + isActive: pathname === '/verified-contracts', + }; if (config.features.zkEvmRollup.isEnabled) { blockchainNavItems = [ [ txs, blocks, - // eslint-disable-next-line max-len - { text: 'Txn batches', nextRoute: { pathname: '/zkevm-l2-txn-batches' as const }, icon: txnBatchIcon, isActive: pathname === '/zkevm-l2-txn-batches' || pathname === '/zkevm-l2-txn-batch/[number]' }, + { + text: 'Txn batches', + nextRoute: { pathname: '/zkevm-l2-txn-batches' as const }, + icon: 'txn_batches', + isActive: pathname === '/zkevm-l2-txn-batches' || pathname === '/zkevm-l2-txn-batch/[number]', + }, ], [ topAccounts, @@ -90,16 +76,16 @@ export default function useNavItems(): ReturnType { [ txs, // eslint-disable-next-line max-len - { text: `Deposits (L1${ rightLineArrow }L2)`, nextRoute: { pathname: '/l2-deposits' as const }, icon: depositsIcon, isActive: pathname === '/l2-deposits' }, + { text: `Deposits (L1${ rightLineArrow }L2)`, nextRoute: { pathname: '/l2-deposits' as const }, icon: 'arrows/south-east', isActive: pathname === '/l2-deposits' }, // eslint-disable-next-line max-len - { text: `Withdrawals (L2${ rightLineArrow }L1)`, nextRoute: { pathname: '/l2-withdrawals' as const }, icon: withdrawalsIcon, isActive: pathname === '/l2-withdrawals' }, + { text: `Withdrawals (L2${ rightLineArrow }L1)`, nextRoute: { pathname: '/l2-withdrawals' as const }, icon: 'arrows/north-east', isActive: pathname === '/l2-withdrawals' }, ], [ blocks, // eslint-disable-next-line max-len - { text: 'Txn batches', nextRoute: { pathname: '/l2-txn-batches' as const }, icon: txnBatchIcon, isActive: pathname === '/l2-txn-batches' }, + { text: 'Txn batches', nextRoute: { pathname: '/l2-txn-batches' as const }, icon: 'txn_batches', isActive: pathname === '/l2-txn-batches' }, // eslint-disable-next-line max-len - { text: 'Output roots', nextRoute: { pathname: '/l2-output-roots' as const }, icon: outputRootsIcon, isActive: pathname === '/l2-output-roots' }, + { text: 'Output roots', nextRoute: { pathname: '/l2-output-roots' as const }, icon: 'output_roots', isActive: pathname === '/l2-output-roots' }, ], [ topAccounts, @@ -115,7 +101,7 @@ export default function useNavItems(): ReturnType { config.features.beaconChain.isEnabled && { text: 'Withdrawals', nextRoute: { pathname: '/withdrawals' as const }, - icon: withdrawalsIcon, + icon: 'arrow/north-east', isActive: pathname === '/withdrawals', }, ].filter(Boolean); @@ -125,23 +111,23 @@ export default function useNavItems(): ReturnType { config.features.restApiDocs.isEnabled ? { text: 'REST API', nextRoute: { pathname: '/api-docs' as const }, - icon: apiDocsIcon, + icon: 'restAPI', isActive: pathname === '/api-docs', } : null, config.features.graphqlApiDocs.isEnabled ? { text: 'GraphQL', nextRoute: { pathname: '/graphiql' as const }, - icon: graphQLIcon, + icon: 'graphQL', isActive: pathname === '/graphiql', } : null, !config.UI.sidebar.hiddenLinks?.rpc_api && { text: 'RPC API', - icon: rpcIcon, + icon: 'RPC', url: 'https://docs.blockscout.com/for-users/api/rpc-endpoints', }, !config.UI.sidebar.hiddenLinks?.eth_rpc_api && { text: 'Eth RPC API', - icon: rpcIcon, + icon: 'RPC', url: ' https://docs.blockscout.com/for-users/api/eth-rpc', }, ].filter(Boolean); @@ -149,42 +135,42 @@ export default function useNavItems(): ReturnType { const mainNavItems: ReturnType['mainNavItems'] = [ { text: 'Blockchain', - icon: globeIcon, + icon: 'globe-b', isActive: blockchainNavItems.flat().some(item => isInternalItem(item) && item.isActive), subItems: blockchainNavItems, }, { text: 'Tokens', nextRoute: { pathname: '/tokens' as const }, - icon: tokensIcon, + icon: 'token', isActive: pathname.startsWith('/token'), }, config.features.marketplace.isEnabled ? { text: 'Apps', nextRoute: { pathname: '/apps' as const }, - icon: appsIcon, + icon: 'apps', isActive: pathname.startsWith('/app'), } : null, config.features.stats.isEnabled ? { text: 'Charts & stats', nextRoute: { pathname: '/stats' as const }, - icon: statsIcon, + icon: 'stats', isActive: pathname === '/stats', } : null, apiNavItems.length > 0 && { text: 'API', - icon: apiDocsIcon, + icon: 'restAPI', isActive: apiNavItems.some(item => isInternalItem(item) && item.isActive), subItems: apiNavItems, }, { text: 'Other', - icon: gearIcon, + icon: 'gear', subItems: [ { text: 'Verify contract', nextRoute: { pathname: '/contract-verification' as const }, - icon: verifyContractIcon, + icon: 'verify-contract', isActive: pathname.startsWith('/contract-verification'), }, ...config.UI.sidebar.otherLinks, @@ -196,35 +182,37 @@ export default function useNavItems(): ReturnType { { text: 'Watch list', nextRoute: { pathname: '/account/watchlist' as const }, - icon: watchlistIcon, + icon: 'watchlist', isActive: pathname === '/account/watchlist', }, { text: 'Private tags', nextRoute: { pathname: '/account/tag-address' as const }, - icon: privateTagIcon, + icon: 'privattags', isActive: pathname === '/account/tag-address', }, { text: 'Public tags', nextRoute: { pathname: '/account/public-tags-request' as const }, - icon: publicTagIcon, isActive: pathname === '/account/public-tags-request', + icon: 'publictags', + isActive: pathname === '/account/public-tags-request', }, { text: 'API keys', nextRoute: { pathname: '/account/api-key' as const }, - icon: apiKeysIcon, isActive: pathname === '/account/api-key', + icon: 'API', + isActive: pathname === '/account/api-key', }, { text: 'Custom ABI', nextRoute: { pathname: '/account/custom-abi' as const }, - icon: abiIcon, + icon: 'ABI', isActive: pathname === '/account/custom-abi', }, config.features.addressVerification.isEnabled && { text: 'Verified addrs', nextRoute: { pathname: '/account/verified-addresses' as const }, - icon: verifiedIcon, + icon: 'verified', isActive: pathname === '/account/verified-addresses', }, ].filter(Boolean); diff --git a/types/client/navigation-items.ts b/types/client/navigation-items.ts index 6393a1e957..862b1cec84 100644 --- a/types/client/navigation-items.ts +++ b/types/client/navigation-items.ts @@ -2,8 +2,10 @@ import type React from 'react'; import type { Route } from 'nextjs-routes'; +import type { IconName } from 'ui/shared/IconSvg'; + type NavIconOrComponent = { - icon?: React.FunctionComponent>; + icon?: IconName; } | { iconComponent?: React.FC<{size?: number}>; }; diff --git a/ui/shared/IconSvg.tsx b/ui/shared/IconSvg.tsx index e4ee730386..fb30c5e8cd 100644 --- a/ui/shared/IconSvg.tsx +++ b/ui/shared/IconSvg.tsx @@ -1,3 +1,4 @@ +import type { HTMLChakraProps } from '@chakra-ui/react'; import { Skeleton, chakra } from '@chakra-ui/react'; import { type IconName } from 'public/icons/name'; import React from 'react'; @@ -6,15 +7,14 @@ export const href = '/icons/sprite.svg'; export { IconName }; -interface Props { +interface Props extends HTMLChakraProps<'div'> { name: IconName; isLoading?: boolean; - className?: string; } -const IconSvg = ({ name, isLoading, className }: Props) => { +const IconSvg = ({ name, isLoading, ...props }: Props) => { return ( - + @@ -22,4 +22,4 @@ const IconSvg = ({ name, isLoading, className }: Props) => { ); }; -export default chakra(IconSvg); +export default IconSvg; diff --git a/ui/snippets/footer/Footer.tsx b/ui/snippets/footer/Footer.tsx index 6ab1a08fe6..4c982f40ca 100644 --- a/ui/snippets/footer/Footer.tsx +++ b/ui/snippets/footer/Footer.tsx @@ -6,13 +6,6 @@ import React from 'react'; import type { CustomLinksGroup } from 'types/footerLinks'; import config from 'configs/app'; -import discussionsIcon from 'icons/discussions.svg'; -import donateIcon from 'icons/donate.svg'; -import editIcon from 'icons/edit.svg'; -import cannyIcon from 'icons/social/canny.svg'; -import discordIcon from 'icons/social/discord.svg'; -import gitIcon from 'icons/social/git.svg'; -import twitterIcon from 'icons/social/tweet.svg'; import type { ResourceError } from 'lib/api/resources'; import useApiQuery from 'lib/api/useApiQuery'; import useFetch from 'lib/hooks/useFetch'; @@ -39,43 +32,43 @@ const Footer = () => { const issueUrl = useIssueUrl(backendVersionData?.backend_version); const BLOCKSCOUT_LINKS = [ { - icon: editIcon, + icon: 'edit' as const, iconSize: '16px', text: 'Submit an issue', url: issueUrl, }, { - icon: cannyIcon, + icon: 'social/canny' as const, iconSize: '20px', text: 'Feature request', url: 'https://blockscout.canny.io/feature-requests', }, { - icon: gitIcon, + icon: 'social/git' as const, iconSize: '18px', text: 'Contribute', url: 'https://github.com/blockscout/blockscout', }, { - icon: twitterIcon, + icon: 'social/tweet' as const, iconSize: '18px', text: 'Twitter', url: 'https://www.twitter.com/blockscoutcom', }, { - icon: discordIcon, + icon: 'social/discord' as const, iconSize: '24px', text: 'Discord', url: 'https://discord.gg/blockscout', }, { - icon: discussionsIcon, + icon: 'discussions' as const, iconSize: '20px', text: 'Discussions', url: 'https://github.com/orgs/blockscout/discussions', }, { - icon: donateIcon, + icon: 'donate' as const, iconSize: '20px', text: 'Donate', url: 'https://github.com/sponsors/blockscout', diff --git a/ui/snippets/footer/FooterLinkItem.tsx b/ui/snippets/footer/FooterLinkItem.tsx index e0dfc26a00..9d334a42d0 100644 --- a/ui/snippets/footer/FooterLinkItem.tsx +++ b/ui/snippets/footer/FooterLinkItem.tsx @@ -1,8 +1,11 @@ -import { Center, Icon, Link, Skeleton } from '@chakra-ui/react'; +import { Center, Link, Skeleton } from '@chakra-ui/react'; import React from 'react'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; + type Props = { - icon?: React.FC>; + icon?: IconName; iconSize?: string; text: string; url: string; @@ -18,7 +21,7 @@ const FooterLinkItem = ({ icon, iconSize, text, url, isLoading }: Props) => { { icon && (
- +
) } { text } diff --git a/ui/snippets/footer/IntTxsIndexingStatus.tsx b/ui/snippets/footer/IntTxsIndexingStatus.tsx index 3e0753b0bc..fbf533f968 100644 --- a/ui/snippets/footer/IntTxsIndexingStatus.tsx +++ b/ui/snippets/footer/IntTxsIndexingStatus.tsx @@ -1,15 +1,15 @@ -import { IconButton, Icon, Popover, PopoverTrigger, PopoverContent, PopoverBody, Flex, Text, useColorModeValue } from '@chakra-ui/react'; +import { IconButton, Popover, PopoverTrigger, PopoverContent, PopoverBody, Flex, Text, useColorModeValue } from '@chakra-ui/react'; import { useQueryClient } from '@tanstack/react-query'; import React from 'react'; import type { SocketMessage } from 'lib/socket/types'; import type { IndexingStatus } from 'types/api/indexingStatus'; -import infoIcon from 'icons/info.svg'; import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery'; import { apos, nbsp, ndash } from 'lib/html-entities'; import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketMessage from 'lib/socket/useSocketMessage'; +import IconSvg from 'ui/shared/IconSvg'; const IntTxsIndexingStatus = () => { @@ -72,7 +72,7 @@ const IntTxsIndexingStatus = () => { } + icon={ } boxSize={ 6 } variant="simple" /> diff --git a/ui/snippets/header/Burger.tsx b/ui/snippets/header/Burger.tsx index 9b41bd6335..8d97220ec5 100644 --- a/ui/snippets/header/Burger.tsx +++ b/ui/snippets/header/Burger.tsx @@ -1,9 +1,8 @@ -import { Icon, Box, Flex, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useColorModeValue, useDisclosure } from '@chakra-ui/react'; +import { Box, Flex, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useColorModeValue, useDisclosure } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; -import burgerIcon from 'icons/burger.svg'; -import testnetIcon from 'icons/testnet.svg'; +import IconSvg from 'ui/shared/IconSvg'; import NavigationMobile from 'ui/snippets/navigation/NavigationMobile'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkMenuButton from 'ui/snippets/networkMenu/NetworkMenuButton'; @@ -31,8 +30,8 @@ const Burger = ({ isMarketplaceAppPage }: Props) => { return ( <> - { - { config.chain.isTestnet && } + { config.chain.isTestnet && } { config.UI.sidebar.featuredNetworks ? ( diff --git a/ui/snippets/navigation/NavLink.tsx b/ui/snippets/navigation/NavLink.tsx index 9a789a9fae..67dbbe1f6f 100644 --- a/ui/snippets/navigation/NavLink.tsx +++ b/ui/snippets/navigation/NavLink.tsx @@ -1,4 +1,4 @@ -import { Link, Text, HStack, Tooltip, Box, useBreakpointValue, chakra, shouldForwardProp, Icon } from '@chakra-ui/react'; +import { Link, Text, HStack, Tooltip, Box, useBreakpointValue, chakra, shouldForwardProp } from '@chakra-ui/react'; import NextLink from 'next/link'; import React from 'react'; @@ -6,9 +6,9 @@ import type { NavItem } from 'types/client/navigation-items'; import { route } from 'nextjs-routes'; -import arrowIcon from 'icons/arrows/north-east.svg'; import useIsMobile from 'lib/hooks/useIsMobile'; import { isInternalItem } from 'lib/hooks/useNavItems'; +import IconSvg from 'ui/shared/IconSvg'; import NavLinkIcon from './NavLinkIcon'; import useColors from './useColors'; @@ -63,7 +63,7 @@ const NavLink = ({ item, isCollapsed, px, className, onClick }: Props) => { { item.text } - { !isInternalLink && } + { !isInternalLink && } diff --git a/ui/snippets/navigation/NavLinkGroupDesktop.tsx b/ui/snippets/navigation/NavLinkGroupDesktop.tsx index f5b6ee88a2..00677576d9 100644 --- a/ui/snippets/navigation/NavLinkGroupDesktop.tsx +++ b/ui/snippets/navigation/NavLinkGroupDesktop.tsx @@ -1,5 +1,4 @@ import { - Icon, Text, HStack, Box, @@ -14,7 +13,7 @@ import React from 'react'; import type { NavGroupItem } from 'types/client/navigation-items'; -import chevronIcon from 'icons/arrows/east-mini.svg'; +import IconSvg from 'ui/shared/IconSvg'; import NavLink from './NavLink'; import NavLinkIcon from './NavLinkIcon'; @@ -53,8 +52,8 @@ const NavLinkGroupDesktop = ({ item, isCollapsed }: Props) => { > { item.text } - { { item.text } - +
diff --git a/ui/snippets/navigation/NavLinkIcon.tsx b/ui/snippets/navigation/NavLinkIcon.tsx index fb1816ca67..6509d92584 100644 --- a/ui/snippets/navigation/NavLinkIcon.tsx +++ b/ui/snippets/navigation/NavLinkIcon.tsx @@ -1,11 +1,12 @@ -import { Icon } from '@chakra-ui/react'; import React from 'react'; import type { NavItem, NavGroupItem } from 'types/client/navigation-items'; +import IconSvg from 'ui/shared/IconSvg'; + const NavLinkIcon = ({ item }: { item: NavItem | NavGroupItem}) => { - if ('icon' in item) { - return ; + if ('icon' in item && item.icon) { + return ; } if ('iconComponent' in item && item.iconComponent) { const IconComponent = item.iconComponent; diff --git a/ui/snippets/navigation/NavigationDesktop.tsx b/ui/snippets/navigation/NavigationDesktop.tsx index 81f5872b62..7f04ce8c87 100644 --- a/ui/snippets/navigation/NavigationDesktop.tsx +++ b/ui/snippets/navigation/NavigationDesktop.tsx @@ -1,14 +1,13 @@ -import { Flex, Box, VStack, Icon, useColorModeValue } from '@chakra-ui/react'; +import { Flex, Box, VStack, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; -import chevronIcon from 'icons/arrows/east-mini.svg'; -import testnetIcon from 'icons/testnet.svg'; import { useAppContext } from 'lib/contexts/app'; import * as cookies from 'lib/cookies'; import useHasAccount from 'lib/hooks/useHasAccount'; import useNavItems, { isGroupItem } from 'lib/hooks/useNavItems'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; +import IconSvg from 'ui/shared/IconSvg'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkMenu from 'ui/snippets/networkMenu/NetworkMenu'; @@ -65,7 +64,7 @@ const NavigationDesktop = () => { }, }} > - { config.chain.isTestnet && } + { config.chain.isTestnet && } { ) } - { key="sub" > - + { mainNavItems[openedGroupIndex].text } - ) : ( - @@ -54,8 +53,8 @@ const NetworkMenuLink = ({ title, icon, isActive, isMobile, url, invertIconInDar { title } { isActive && ( - diff --git a/ui/snippets/searchBar/SearchBarInput.tsx b/ui/snippets/searchBar/SearchBarInput.tsx index 2491e8783c..a7ea26d2e7 100644 --- a/ui/snippets/searchBar/SearchBarInput.tsx +++ b/ui/snippets/searchBar/SearchBarInput.tsx @@ -1,12 +1,12 @@ -import { InputGroup, Input, InputLeftElement, Icon, chakra, useColorModeValue, forwardRef, InputRightElement } from '@chakra-ui/react'; +import { InputGroup, Input, InputLeftElement, chakra, useColorModeValue, forwardRef, InputRightElement } from '@chakra-ui/react'; import throttle from 'lodash/throttle'; import React from 'react'; import type { ChangeEvent, FormEvent, FocusEvent } from 'react'; -import searchIcon from 'icons/search.svg'; import { useScrollDirection } from 'lib/contexts/scrollDirection'; import useIsMobile from 'lib/hooks/useIsMobile'; import ClearButton from 'ui/shared/ClearButton'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { onChange: (value: string) => void; @@ -86,7 +86,7 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid > - + > - { data.external && } + { data.external && } > { data.description } - { data.external && } + { data.external && } ); })(); diff --git a/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestLabel.tsx b/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestLabel.tsx index 9821781595..b7905becf5 100644 --- a/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestLabel.tsx +++ b/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestLabel.tsx @@ -1,12 +1,11 @@ -import { Grid, Text, Flex, Icon } from '@chakra-ui/react'; +import { Grid, Text, Flex } from '@chakra-ui/react'; import React from 'react'; import type { SearchResultLabel } from 'types/api/search'; -import labelIcon from 'icons/publictags_slim.svg'; -import iconSuccess from 'icons/status/success.svg'; import highlightText from 'lib/highlightText'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { data: SearchResultLabel; @@ -15,7 +14,7 @@ interface Props { } const SearchBarSuggestLabel = ({ data, isMobile, searchTerm }: Props) => { - const icon = ; + const icon = ; const name = ( { ); - const isContractVerified = data.is_smart_contract_verified && ; + const isContractVerified = data.is_smart_contract_verified && ; if (isMobile) { return ( diff --git a/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestToken.tsx b/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestToken.tsx index 951bc9923c..e5bba9baef 100644 --- a/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestToken.tsx +++ b/ui/snippets/searchBar/SearchBarSuggest/SearchBarSuggestToken.tsx @@ -1,13 +1,12 @@ -import { Grid, Text, Flex, Icon } from '@chakra-ui/react'; +import { Grid, Text, Flex } from '@chakra-ui/react'; import React from 'react'; import type { SearchResultToken } from 'types/api/search'; -import iconSuccess from 'icons/status/success.svg'; -import verifiedToken from 'icons/verified_token.svg'; import highlightText from 'lib/highlightText'; import * as TokenEntity from 'ui/shared/entities/token/TokenEntity'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { data: SearchResultToken; @@ -17,7 +16,7 @@ interface Props { const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => { const icon = ; - const verifiedIcon = ; + const verifiedIcon = ; const name = ( { ); - const contractVerifiedIcon = data.is_smart_contract_verified && ; + const contractVerifiedIcon = data.is_smart_contract_verified && ; const additionalInfo = ( { data.token_type === 'ERC-20' && data.exchange_rate && `$${ Number(data.exchange_rate).toLocaleString() }` } diff --git a/ui/snippets/topBar/ColorModeSwitch.tsx b/ui/snippets/topBar/ColorModeSwitch.tsx index 37d054bed6..35fffea85a 100644 --- a/ui/snippets/topBar/ColorModeSwitch.tsx +++ b/ui/snippets/topBar/ColorModeSwitch.tsx @@ -1,6 +1,5 @@ import { IconButton, - Icon, Popover, PopoverTrigger, PopoverContent, @@ -12,6 +11,7 @@ import { import React from 'react'; import * as cookies from 'lib/cookies'; +import IconSvg from 'ui/shared/IconSvg'; import ColorModeSwitchTheme from './ColorModeSwitchTheme'; import { COLOR_THEMES } from './utils'; @@ -79,7 +79,7 @@ const ColorModeSwitch = () => { variant="simple" colorScheme="blue" aria-label="color mode switch" - icon={ } + icon={ } boxSize={ 5 } onClick={ onToggle } /> diff --git a/ui/snippets/topBar/ColorModeSwitchTheme.tsx b/ui/snippets/topBar/ColorModeSwitchTheme.tsx index 3a0d46363c..d69608ed79 100644 --- a/ui/snippets/topBar/ColorModeSwitchTheme.tsx +++ b/ui/snippets/topBar/ColorModeSwitchTheme.tsx @@ -1,11 +1,12 @@ import { - Icon, Flex, useColorModeValue, useToken, } from '@chakra-ui/react'; import React from 'react'; +import IconSvg from 'ui/shared/IconSvg'; + import ColorModeSwitchSample from './ColorModeSwitchSample'; import type { ColorTheme } from './utils'; @@ -43,7 +44,7 @@ const ColorModeSwitchTheme = ({ icon, name, colors, onClick, activeHex }: Props) fontWeight={ 500 } borderRadius="base" > - + { name } { colors.map((sample) => ) } diff --git a/ui/snippets/topBar/utils.ts b/ui/snippets/topBar/utils.ts index 9eddc1ad9e..0644fcc9b2 100644 --- a/ui/snippets/topBar/utils.ts +++ b/ui/snippets/topBar/utils.ts @@ -1,12 +1,10 @@ -import moonWithStarIcon from 'icons/moon-with-star.svg'; -import moonIcon from 'icons/moon.svg'; -import sunIcon from 'icons/sun.svg'; +import type { IconName } from 'ui/shared/IconSvg'; export const COLOR_THEMES = [ { name: 'Light', colorMode: 'light', - icon: sunIcon, + icon: 'sun' as IconName, colors: [ { hex: '#FFFFFF', sampleBg: 'linear-gradient(154deg, #EFEFEF 50%, rgba(255, 255, 255, 0.00) 330.86%)' }, ], @@ -14,7 +12,7 @@ export const COLOR_THEMES = [ { name: 'Dim', colorMode: 'dark', - icon: moonWithStarIcon, + icon: 'moon-with-star' as IconName, colors: [ { hex: '#232B37', sampleBg: 'linear-gradient(152deg, #232B37 50%, rgba(255, 255, 255, 0.00) 290.71%)' }, { hex: '#1B2E48', sampleBg: 'linear-gradient(150deg, #1B2E48 50%, rgba(255, 255, 255, 0.00) 312.75%)' }, @@ -23,7 +21,7 @@ export const COLOR_THEMES = [ { name: 'Dark', colorMode: 'dark', - icon: moonIcon, + icon: 'moon' as IconName, colors: [ { hex: '#101112', sampleBg: 'linear-gradient(161deg, #000 9.37%, #383838 92.52%)' }, ], diff --git a/ui/snippets/walletMenu/WalletMenuMobile.tsx b/ui/snippets/walletMenu/WalletMenuMobile.tsx index 57b0145cc4..22b79723cb 100644 --- a/ui/snippets/walletMenu/WalletMenuMobile.tsx +++ b/ui/snippets/walletMenu/WalletMenuMobile.tsx @@ -1,8 +1,8 @@ -import { Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, IconButton, Icon } from '@chakra-ui/react'; +import { Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, IconButton } from '@chakra-ui/react'; import React from 'react'; -import walletIcon from 'icons/wallet.svg'; import AddressIdenticon from 'ui/shared/entities/address/AddressIdenticon'; +import IconSvg from 'ui/shared/IconSvg'; import useWallet from 'ui/snippets/walletMenu/useWallet'; import WalletMenuContent from 'ui/snippets/walletMenu/WalletMenuContent'; @@ -21,7 +21,7 @@ const WalletMenuMobile = () => { aria-label="wallet menu" icon={ isWalletConnected ? : - + } variant={ isWalletConnected ? 'subtle' : 'outline' } colorScheme="gray" From 1cbb8cd95ec782bfd81792b30ad51bfa2a3eaf46 Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 20 Dec 2023 13:26:42 +0400 Subject: [PATCH 06/15] migrate address, block and tx pages --- ui/address/AddressCsvExportLink.tsx | 6 +++--- ui/address/AddressTokens.tsx | 6 ++---- ui/address/SolidityscanReport.tsx | 8 +++----- ui/address/contract/ContractExternalLibraries.tsx | 8 +++----- ui/address/contract/ContractMethodCallable.tsx | 6 +++--- ui/address/contract/ContractMethodFieldZeroes.tsx | 8 +++----- .../contract/ContractMethodsAccordionItem.tsx | 6 +++--- ui/address/details/AddressFavoriteButton.tsx | 7 +++---- ui/address/details/AddressQrCode.tsx | 5 ++--- ui/address/internals/AddressIntTxsListItem.tsx | 5 ++--- ui/address/internals/AddressIntTxsTableItem.tsx | 5 ++--- ui/address/tokenSelect/TokenSelect.tsx | 6 +++--- ui/address/tokenSelect/TokenSelectButton.tsx | 9 ++++----- ui/address/tokenSelect/TokenSelectMenu.tsx | 9 ++++----- ui/address/tokens/TokenBalancesItem.tsx | 6 +++--- ui/block/BlockDetails.tsx | 8 +++----- ui/blocks/BlocksListItem.tsx | 5 ++--- ui/blocks/BlocksTableItem.tsx | 5 ++--- ui/shared/radioButtonGroup/RadioButtonGroup.tsx | 13 ++++++++----- ui/tx/TxDetails.tsx | 15 +++++---------- ui/tx/details/TxDetailsAction.tsx | 6 +++--- ui/tx/details/TxDetailsTokenTransfer.tsx | 6 +++--- ui/tx/details/TxDetailsTokenTransfers.tsx | 6 +++--- ui/tx/internals/TxInternalsListItem.tsx | 5 ++--- ui/tx/internals/TxInternalsTable.tsx | 8 ++++---- ui/tx/internals/TxInternalsTableItem.tsx | 5 ++--- ui/txs/TxsListItem.tsx | 7 +++---- ui/txs/TxsTable.tsx | 12 ++++++------ ui/txs/TxsTableItem.tsx | 9 ++++----- 29 files changed, 93 insertions(+), 117 deletions(-) diff --git a/ui/address/AddressCsvExportLink.tsx b/ui/address/AddressCsvExportLink.tsx index 0bbcfa7497..6ef1d2dd0a 100644 --- a/ui/address/AddressCsvExportLink.tsx +++ b/ui/address/AddressCsvExportLink.tsx @@ -1,4 +1,4 @@ -import { chakra, Icon, Tooltip, Hide, Skeleton, Flex } from '@chakra-ui/react'; +import { chakra, Tooltip, Hide, Skeleton, Flex } from '@chakra-ui/react'; import React from 'react'; import type { CsvExportParams } from 'types/client/address'; @@ -6,9 +6,9 @@ import type { CsvExportParams } from 'types/client/address'; import { route } from 'nextjs-routes'; import config from 'configs/app'; -import svgFileIcon from 'icons/files/csv.svg'; import useIsInitialLoading from 'lib/hooks/useIsInitialLoading'; import useIsMobile from 'lib/hooks/useIsMobile'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; interface Props { @@ -47,7 +47,7 @@ const AddressCsvExportLink = ({ className, address, params, isLoading }: Props) href={ route({ pathname: '/csv-export', query: { ...params, address } }) } flexShrink={ 0 } > - + Download CSV diff --git a/ui/address/AddressTokens.tsx b/ui/address/AddressTokens.tsx index 6aae805c47..0e27a73f7d 100644 --- a/ui/address/AddressTokens.tsx +++ b/ui/address/AddressTokens.tsx @@ -5,8 +5,6 @@ import React from 'react'; import type { NFTTokenType } from 'types/api/token'; import type { PaginationParams } from 'ui/shared/pagination/types'; -import listIcon from 'icons/apps.svg'; -import collectionIcon from 'icons/collection.svg'; import { useAppContext } from 'lib/contexts/app'; import * as cookies from 'lib/cookies'; import getFilterValuesFromQuery from 'lib/getFilterValuesFromQuery'; @@ -125,8 +123,8 @@ const AddressTokens = () => { defaultValue={ nftDisplayType } name="type" options={ [ - { title: 'By collection', value: 'collection', icon: collectionIcon, onlyIcon: isMobile }, - { title: 'List', value: 'list', icon: listIcon, onlyIcon: isMobile }, + { title: 'By collection', value: 'collection', icon: 'collection', onlyIcon: isMobile }, + { title: 'List', value: 'list', icon: 'apps', onlyIcon: isMobile }, ] } /> ); diff --git a/ui/address/SolidityscanReport.tsx b/ui/address/SolidityscanReport.tsx index f5596b8016..6b6d6200cb 100644 --- a/ui/address/SolidityscanReport.tsx +++ b/ui/address/SolidityscanReport.tsx @@ -4,7 +4,6 @@ import { Text, Grid, Button, - Icon, chakra, Popover, PopoverTrigger, @@ -19,10 +18,9 @@ import React from 'react'; import { SolidityscanReport } from 'types/api/contract'; -import scoreNotOkIcon from 'icons/score/score-not-ok.svg'; -import scoreOkIcon from 'icons/score/score-ok.svg'; import useApiQuery from 'lib/api/useApiQuery'; import { SOLIDITYSCAN_REPORT } from 'stubs/contract'; +import IconSvg from 'ui/shared/IconSvg'; import LinkExternal from 'ui/shared/LinkExternal'; type DistributionItem = { @@ -125,7 +123,7 @@ const SolidityscanReport = ({ className, hash }: Props) => { h="32px" flexShrink={ 0 } > - + { score } @@ -143,7 +141,7 @@ const SolidityscanReport = ({ className, hash }: Props) => { mr={ 3 } >
- +
diff --git a/ui/address/contract/ContractExternalLibraries.tsx b/ui/address/contract/ContractExternalLibraries.tsx index 0da60de207..4c89b5af69 100644 --- a/ui/address/contract/ContractExternalLibraries.tsx +++ b/ui/address/contract/ContractExternalLibraries.tsx @@ -4,7 +4,6 @@ import { Button, Flex, Heading, - Icon, Modal, ModalCloseButton, ModalContent, @@ -20,11 +19,10 @@ import React from 'react'; import type { SmartContractExternalLibrary } from 'types/api/contract'; -import arrowIcon from 'icons/arrows/east-mini.svg'; -import iconWarning from 'icons/status/warning.svg'; import useIsMobile from 'lib/hooks/useIsMobile'; import { apos } from 'lib/html-entities'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { className?: string; @@ -66,8 +64,8 @@ const ContractExternalLibraries = ({ className, data }: Props) => { aria-label="View external libraries" > { data.length } { data.length > 1 ? 'Libraries' : 'Library' } - - + + ); diff --git a/ui/address/contract/ContractMethodCallable.tsx b/ui/address/contract/ContractMethodCallable.tsx index f08a908088..3f32a7a20a 100644 --- a/ui/address/contract/ContractMethodCallable.tsx +++ b/ui/address/contract/ContractMethodCallable.tsx @@ -1,4 +1,4 @@ -import { Box, Button, chakra, Flex, Icon, Text } from '@chakra-ui/react'; +import { Box, Button, chakra, Flex, Text } from '@chakra-ui/react'; import _fromPairs from 'lodash/fromPairs'; import React from 'react'; import type { SubmitHandler } from 'react-hook-form'; @@ -7,8 +7,8 @@ import { useForm } from 'react-hook-form'; import type { MethodFormFields, ContractMethodCallResult } from './types'; import type { SmartContractMethodInput, SmartContractMethod } from 'types/api/contract'; -import arrowIcon from 'icons/arrows/down-right.svg'; import * as mixpanel from 'lib/mixpanel/index'; +import IconSvg from 'ui/shared/IconSvg'; import ContractMethodField from './ContractMethodField'; @@ -157,7 +157,7 @@ const ContractMethodCallable = ({ data, onSubmit,
{ 'outputs' in data && !isWrite && data.outputs.length > 0 && ( - + { data.outputs.map(({ type }) => type).join(', ') } ) } diff --git a/ui/address/contract/ContractMethodFieldZeroes.tsx b/ui/address/contract/ContractMethodFieldZeroes.tsx index bf078260f8..1c0bfc9852 100644 --- a/ui/address/contract/ContractMethodFieldZeroes.tsx +++ b/ui/address/contract/ContractMethodFieldZeroes.tsx @@ -8,15 +8,13 @@ import { Button, List, ListItem, - Icon, useDisclosure, Input, } from '@chakra-ui/react'; import React from 'react'; -import iconEastMini from 'icons/arrows/east-mini.svg'; -import iconCheck from 'icons/check.svg'; import { times } from 'lib/html-entities'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { onClick: (power: number) => void; @@ -80,7 +78,7 @@ const ContractMethodFieldZeroes = ({ onClick, isDisabled }: Props) => { onClick={ onToggle } isDisabled={ isDisabled } > - + @@ -99,7 +97,7 @@ const ContractMethodFieldZeroes = ({ onClick, isDisabled }: Props) => { cursor="pointer" > 10*{ id } - { selectedOption === id && } + { selectedOption === id && } )) } { data: T; @@ -57,7 +57,7 @@ const ContractMethodsAccordionItem = ({ data, ind onMouseEnter={ onOpen } onMouseLeave={ onClose } > - + ) } diff --git a/ui/address/details/AddressFavoriteButton.tsx b/ui/address/details/AddressFavoriteButton.tsx index b3c3c7cdad..8ce50e6c56 100644 --- a/ui/address/details/AddressFavoriteButton.tsx +++ b/ui/address/details/AddressFavoriteButton.tsx @@ -1,15 +1,14 @@ -import { Icon, chakra, Tooltip, IconButton, useDisclosure } from '@chakra-ui/react'; +import { chakra, Tooltip, IconButton, useDisclosure } from '@chakra-ui/react'; import { useQueryClient } from '@tanstack/react-query'; import { useRouter } from 'next/router'; import React from 'react'; import config from 'configs/app'; -import starFilledIcon from 'icons/star_filled.svg'; -import starOutlineIcon from 'icons/star_outline.svg'; import { getResourceKey } from 'lib/api/useApiQuery'; import useIsAccountActionAllowed from 'lib/hooks/useIsAccountActionAllowed'; import usePreventFocusAfterModalClosing from 'lib/hooks/usePreventFocusAfterModalClosing'; import * as mixpanel from 'lib/mixpanel/index'; +import IconSvg from 'ui/shared/IconSvg'; import WatchlistAddModal from 'ui/watchlist/AddressModal/AddressModal'; import DeleteAddressModal from 'ui/watchlist/DeleteAddressModal'; @@ -73,7 +72,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => { pr="6px" flexShrink={ 0 } onClick={ handleClick } - icon={ } + icon={ } onFocusCapture={ onFocusCapture } /> diff --git a/ui/address/details/AddressQrCode.tsx b/ui/address/details/AddressQrCode.tsx index 62552f3a84..f3f58e546c 100644 --- a/ui/address/details/AddressQrCode.tsx +++ b/ui/address/details/AddressQrCode.tsx @@ -1,7 +1,6 @@ import { chakra, Alert, - Icon, Modal, ModalBody, ModalContent, @@ -22,10 +21,10 @@ import React from 'react'; import type { Address as AddressType } from 'types/api/address'; -import qrCodeIcon from 'icons/qr_code.svg'; import getPageType from 'lib/mixpanel/getPageType'; import * as mixpanel from 'lib/mixpanel/index'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; +import IconSvg from 'ui/shared/IconSvg'; const SVG_OPTIONS = { margin: 0, @@ -78,7 +77,7 @@ const AddressQrCode = ({ address, className, isLoading }: Props) => { pl="6px" pr="6px" onClick={ onOpen } - icon={ } + icon={ } flexShrink={ 0 } /> diff --git a/ui/address/internals/AddressIntTxsListItem.tsx b/ui/address/internals/AddressIntTxsListItem.tsx index 98284c78e5..463a7a053c 100644 --- a/ui/address/internals/AddressIntTxsListItem.tsx +++ b/ui/address/internals/AddressIntTxsListItem.tsx @@ -5,13 +5,12 @@ import React from 'react'; import type { InternalTransaction } from 'types/api/internalTransaction'; import config from 'configs/app'; -import eastArrowIcon from 'icons/arrows/east.svg'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import Tag from 'ui/shared/chakra/Tag'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity'; +import IconSvg from 'ui/shared/IconSvg'; import InOutTag from 'ui/shared/InOutTag'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import TxStatus from 'ui/shared/statusTag/TxStatus'; @@ -76,7 +75,7 @@ const TxInternalsListItem = ({ /> { (isIn || isOut) ? : - + } { toData && ( { (isIn || isOut) ? : - + } diff --git a/ui/address/tokenSelect/TokenSelect.tsx b/ui/address/tokenSelect/TokenSelect.tsx index ca03f06879..3cada7e253 100644 --- a/ui/address/tokenSelect/TokenSelect.tsx +++ b/ui/address/tokenSelect/TokenSelect.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, Icon, IconButton, Skeleton, Tooltip } from '@chakra-ui/react'; +import { Box, Flex, IconButton, Skeleton, Tooltip } from '@chakra-ui/react'; import { useQueryClient, useIsFetching } from '@tanstack/react-query'; import _sumBy from 'lodash/sumBy'; import NextLink from 'next/link'; @@ -7,11 +7,11 @@ import React from 'react'; import type { Address } from 'types/api/address'; -import walletIcon from 'icons/wallet.svg'; import { getResourceKey } from 'lib/api/useApiQuery'; import useIsMobile from 'lib/hooks/useIsMobile'; import * as mixpanel from 'lib/mixpanel/index'; import getQueryParamString from 'lib/router/getQueryParamString'; +import IconSvg from 'ui/shared/IconSvg'; import useFetchTokens from '../utils/useFetchTokens'; import TokenSelectDesktop from './TokenSelectDesktop'; @@ -69,7 +69,7 @@ const TokenSelect = ({ onClick }: Props) => { size="sm" pl="6px" pr="6px" - icon={ } + icon={ } as="a" onClick={ handleIconButtonClick } /> diff --git a/ui/address/tokenSelect/TokenSelectButton.tsx b/ui/address/tokenSelect/TokenSelectButton.tsx index 03976be637..d58fdacea3 100644 --- a/ui/address/tokenSelect/TokenSelectButton.tsx +++ b/ui/address/tokenSelect/TokenSelectButton.tsx @@ -1,11 +1,10 @@ -import { Box, Button, Icon, Skeleton, Text, useColorModeValue } from '@chakra-ui/react'; +import { Box, Button, Skeleton, Text, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; import type { FormattedData } from './types'; -import arrowIcon from 'icons/arrows/east-mini.svg'; -import tokensIcon from 'icons/tokens.svg'; import * as mixpanel from 'lib/mixpanel/index'; +import IconSvg from 'ui/shared/IconSvg'; import { getTokensTotalInfo } from '../utils/tokenUtils'; @@ -41,10 +40,10 @@ const TokenSelectButton = ({ isOpen, isLoading, onClick, data }: Props, ref: Rea onClick={ handleClick } aria-label="Token select" > - + { prefix }{ num } ({ prefix }${ usd.toFormat(2) }) - + { isLoading && !isOpen && } diff --git a/ui/address/tokenSelect/TokenSelectMenu.tsx b/ui/address/tokenSelect/TokenSelectMenu.tsx index 44699e711b..d247a0e3cd 100644 --- a/ui/address/tokenSelect/TokenSelectMenu.tsx +++ b/ui/address/tokenSelect/TokenSelectMenu.tsx @@ -1,4 +1,4 @@ -import { Icon, Text, Box, Input, InputGroup, InputLeftElement, useColorModeValue, Flex, Link } from '@chakra-ui/react'; +import { Text, Box, Input, InputGroup, InputLeftElement, useColorModeValue, Flex, Link } from '@chakra-ui/react'; import _sumBy from 'lodash/sumBy'; import type { ChangeEvent } from 'react'; import React from 'react'; @@ -6,8 +6,7 @@ import React from 'react'; import type { FormattedData } from './types'; import type { TokenType } from 'types/api/token'; -import arrowIcon from 'icons/arrows/east.svg'; -import searchIcon from 'icons/search.svg'; +import IconSvg from 'ui/shared/IconSvg'; import type { Sort } from '../utils/tokenUtils'; import { sortTokenGroups, sortingFns } from '../utils/tokenUtils'; @@ -32,7 +31,7 @@ const TokenSelectMenu = ({ erc20sort, erc1155sort, filteredData, onInputChange, <> - + { type } tokens ({ numPrefix }{ tokenInfo.items.length }) { hasSort && ( - + ) } diff --git a/ui/address/tokens/TokenBalancesItem.tsx b/ui/address/tokens/TokenBalancesItem.tsx index 5d5918851d..7bf61d1860 100644 --- a/ui/address/tokens/TokenBalancesItem.tsx +++ b/ui/address/tokens/TokenBalancesItem.tsx @@ -1,7 +1,7 @@ -import { Box, Flex, Icon, Skeleton, Text, useColorModeValue } from '@chakra-ui/react'; +import { Box, Flex, Skeleton, Text, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; -import walletIcon from 'icons/wallet.svg'; +import IconSvg from 'ui/shared/IconSvg'; const TokenBalancesItem = ({ name, value, isLoading }: {name: string; value: string; isLoading: boolean }) => { @@ -9,7 +9,7 @@ const TokenBalancesItem = ({ name, value, isLoading }: {name: string; value: str return ( - + { name } { value } diff --git a/ui/block/BlockDetails.tsx b/ui/block/BlockDetails.tsx index f173687b8b..af4fe1b3ff 100644 --- a/ui/block/BlockDetails.tsx +++ b/ui/block/BlockDetails.tsx @@ -11,8 +11,6 @@ import type { Block } from 'types/api/block'; import { route } from 'nextjs-routes'; import config from 'configs/app'; -import clockIcon from 'icons/clock.svg'; -import flameIcon from 'icons/flame.svg'; import type { ResourceError } from 'lib/api/resources'; import getBlockReward from 'lib/block/getBlockReward'; import { GWEI, WEI, WEI_IN_GWEI, ZERO } from 'lib/consts'; @@ -20,7 +18,6 @@ import dayjs from 'lib/date/dayjs'; import { space } from 'lib/html-entities'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getQueryParamString from 'lib/router/getQueryParamString'; -import Icon from 'ui/shared/chakra/Icon'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; @@ -28,6 +25,7 @@ import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; import PrevNext from 'ui/shared/PrevNext'; import RawDataSnippet from 'ui/shared/RawDataSnippet'; @@ -169,7 +167,7 @@ const BlockDetails = ({ query }: Props) => { hint="Date & time at which block was produced." isLoading={ isPlaceholderData } > - + { dayjs(data.timestamp).fromNow() } @@ -318,7 +316,7 @@ const BlockDetails = ({ query }: Props) => { } isLoading={ isPlaceholderData } > - + { burntFees.dividedBy(WEI).toFixed() } { config.chain.currency.symbol } diff --git a/ui/blocks/BlocksListItem.tsx b/ui/blocks/BlocksListItem.tsx index 629ba6f0cd..8b5bcb6c2e 100644 --- a/ui/blocks/BlocksListItem.tsx +++ b/ui/blocks/BlocksListItem.tsx @@ -8,15 +8,14 @@ import type { Block } from 'types/api/block'; import { route } from 'nextjs-routes'; import config from 'configs/app'; -import flameIcon from 'icons/flame.svg'; import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import { WEI } from 'lib/consts'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import BlockTimestamp from 'ui/blocks/BlockTimestamp'; -import Icon from 'ui/shared/chakra/Icon'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import TextSeparator from 'ui/shared/TextSeparator'; @@ -106,7 +105,7 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => { Burnt fees - + { burntFees.div(WEI).toFixed() } diff --git a/ui/blocks/BlocksTableItem.tsx b/ui/blocks/BlocksTableItem.tsx index 4dc20cb04b..2081d416dd 100644 --- a/ui/blocks/BlocksTableItem.tsx +++ b/ui/blocks/BlocksTableItem.tsx @@ -8,14 +8,13 @@ import type { Block } from 'types/api/block'; import { route } from 'nextjs-routes'; import config from 'configs/app'; -import flameIcon from 'icons/flame.svg'; import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import { WEI } from 'lib/consts'; import BlockTimestamp from 'ui/blocks/BlockTimestamp'; -import Icon from 'ui/shared/chakra/Icon'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; import TextSeparator from 'ui/shared/TextSeparator'; import Utilization from 'ui/shared/Utilization/Utilization'; @@ -116,7 +115,7 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => { { !isRollup && !config.UI.views.block.hiddenFields?.burnt_fees && ( - + { burntFees.dividedBy(WEI).toFixed(8) } diff --git a/ui/shared/radioButtonGroup/RadioButtonGroup.tsx b/ui/shared/radioButtonGroup/RadioButtonGroup.tsx index 27a8d70fa3..e4eb0b2358 100644 --- a/ui/shared/radioButtonGroup/RadioButtonGroup.tsx +++ b/ui/shared/radioButtonGroup/RadioButtonGroup.tsx @@ -1,14 +1,17 @@ -import { ButtonGroup, Button, Flex, Icon, useRadio, useRadioGroup, useColorModeValue } from '@chakra-ui/react'; +import { ButtonGroup, Button, Flex, useRadio, useRadioGroup, useColorModeValue } from '@chakra-ui/react'; import type { UseRadioProps } from '@chakra-ui/react'; import React from 'react'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; + type RadioItemProps = { title: string; - icon?: React.FC>; + icon?: IconName; onlyIcon: false | undefined; } | { title: string; - icon: React.FC>; + icon: IconName; onlyIcon: true; } @@ -50,7 +53,7 @@ const RadioButton = (props: RadioButtonProps) => { - + ); @@ -59,7 +62,7 @@ const RadioButton = (props: RadioButtonProps) => { return ( ); diff --git a/ui/shared/address/AddressAddToWallet.tsx b/ui/shared/address/AddressAddToWallet.tsx index a9c640b300..119b4419ec 100644 --- a/ui/shared/address/AddressAddToWallet.tsx +++ b/ui/shared/address/AddressAddToWallet.tsx @@ -1,4 +1,4 @@ -import { Box, chakra, Icon, IconButton, Skeleton, Tooltip } from '@chakra-ui/react'; +import { Box, chakra, IconButton, Skeleton, Tooltip } from '@chakra-ui/react'; import React from 'react'; import type { TokenInfo } from 'types/api/token'; @@ -9,6 +9,7 @@ import * as mixpanel from 'lib/mixpanel/index'; import useAddOrSwitchChain from 'lib/web3/useAddOrSwitchChain'; import useProvider from 'lib/web3/useProvider'; import { WALLETS_INFO } from 'lib/web3/wallets'; +import IconSvg from 'ui/shared/IconSvg'; const feature = config.features.web3Wallet; @@ -97,7 +98,7 @@ const AddressAddToWallet = ({ className, token, isLoading, variant = 'icon', ico size="sm" px="6px" onClick={ handleClick } - icon={ } + icon={ } flexShrink={ 0 } /> @@ -107,7 +108,7 @@ const AddressAddToWallet = ({ className, token, isLoading, variant = 'icon', ico return ( - + ); diff --git a/ui/shared/verificationSteps/VerificationStep.tsx b/ui/shared/verificationSteps/VerificationStep.tsx index c3b50a9819..38d78462fb 100644 --- a/ui/shared/verificationSteps/VerificationStep.tsx +++ b/ui/shared/verificationSteps/VerificationStep.tsx @@ -1,11 +1,9 @@ -import { Text, Icon, HStack } from '@chakra-ui/react'; +import { Text, HStack } from '@chakra-ui/react'; import React from 'react'; import type { Step } from './types'; -import arrowIcon from 'icons/arrows/east.svg'; -import finalizedIcon from 'icons/finalized.svg'; -import unfinalizedIcon from 'icons/unfinalized.svg'; +import IconSvg from 'ui/shared/IconSvg'; type Props = { step: Step; @@ -18,9 +16,9 @@ const VerificationStep = ({ step, isLast, isPassed }: Props) => { return ( - + { typeof step === 'string' ? step : step.content } - { !isLast && } + { !isLast && } ); }; diff --git a/ui/stats/StatsDropdownMenu.tsx b/ui/stats/StatsDropdownMenu.tsx index 6f9edbf581..7ab89f9ebe 100644 --- a/ui/stats/StatsDropdownMenu.tsx +++ b/ui/stats/StatsDropdownMenu.tsx @@ -1,7 +1,7 @@ -import { Box, Button, Icon, Menu, MenuButton, MenuItemOption, MenuList, MenuOptionGroup, Text } from '@chakra-ui/react'; +import { Box, Button, Menu, MenuButton, MenuItemOption, MenuList, MenuOptionGroup, Text } from '@chakra-ui/react'; import React, { useCallback } from 'react'; -import eastMiniArrowIcon from 'icons/arrows/east-mini.svg'; +import IconSvg from 'ui/shared/IconSvg'; type Props = { items: Array<{id: T; title: string}>; @@ -39,7 +39,7 @@ export function StatsDropdownMenu({ items, selectedId, onSelec > { selectedCategory?.title } - + diff --git a/ui/token/TokenProjectInfo/Content.tsx b/ui/token/TokenProjectInfo/Content.tsx index 0ff58572da..91a7d80704 100644 --- a/ui/token/TokenProjectInfo/Content.tsx +++ b/ui/token/TokenProjectInfo/Content.tsx @@ -3,20 +3,6 @@ import React from 'react'; import type { TokenVerifiedInfo } from 'types/api/token'; -import iconCoinGecko from 'icons/social/coingecko.svg'; -import iconCoinMarketCap from 'icons/social/coinmarketcap.svg'; -import iconDefiLlama from 'icons/social/defi_llama.svg'; -import iconDiscord from 'icons/social/discord_filled.svg'; -import iconFacebook from 'icons/social/facebook_filled.svg'; -import iconGithub from 'icons/social/github_filled.svg'; -import iconLinkedIn from 'icons/social/linkedin_filled.svg'; -import iconMedium from 'icons/social/medium_filled.svg'; -import iconOpenSea from 'icons/social/opensea_filled.svg'; -import iconReddit from 'icons/social/reddit_filled.svg'; -import iconSlack from 'icons/social/slack_filled.svg'; -import iconTelegram from 'icons/social/telegram_filled.svg'; -import iconTwitter from 'icons/social/twitter_filled.svg'; - import DocsLink from './DocsLink'; import type { Props as ServiceLinkProps } from './ServiceLink'; import ServiceLink from './ServiceLink'; @@ -27,22 +13,22 @@ interface Props { } const SOCIAL_LINKS: Array> = [ - { field: 'github', icon: iconGithub, title: 'Github' }, - { field: 'twitter', icon: iconTwitter, title: 'Twitter' }, - { field: 'telegram', icon: iconTelegram, title: 'Telegram' }, - { field: 'openSea', icon: iconOpenSea, title: 'OpenSea' }, - { field: 'linkedin', icon: iconLinkedIn, title: 'LinkedIn' }, - { field: 'facebook', icon: iconFacebook, title: 'Facebook' }, - { field: 'discord', icon: iconDiscord, title: 'Discord' }, - { field: 'medium', icon: iconMedium, title: 'Medium' }, - { field: 'slack', icon: iconSlack, title: 'Slack' }, - { field: 'reddit', icon: iconReddit, title: 'Reddit' }, + { field: 'github', icon: 'social/github_filled', title: 'Github' }, + { field: 'twitter', icon: 'social/twitter_filled', title: 'Twitter' }, + { field: 'telegram', icon: 'social/telegram_filled', title: 'Telegram' }, + { field: 'openSea', icon: 'social/opensea_filled', title: 'OpenSea' }, + { field: 'linkedin', icon: 'social/linkedin_filled', title: 'LinkedIn' }, + { field: 'facebook', icon: 'social/facebook_filled', title: 'Facebook' }, + { field: 'discord', icon: 'social/discord_filled', title: 'Discord' }, + { field: 'medium', icon: 'social/medium_filled', title: 'Medium' }, + { field: 'slack', icon: 'social/slack_filled', title: 'Slack' }, + { field: 'reddit', icon: 'social/reddit_filled', title: 'Reddit' }, ]; const PRICE_TICKERS: Array> = [ - { field: 'coinGeckoTicker', icon: iconCoinGecko, title: 'CoinGecko' }, - { field: 'coinMarketCapTicker', icon: iconCoinMarketCap, title: 'CoinMarketCap' }, - { field: 'defiLlamaTicker', icon: iconDefiLlama, title: 'DefiLlama' }, + { field: 'coinGeckoTicker', icon: 'social/coingecko', title: 'CoinGecko' }, + { field: 'coinMarketCapTicker', icon: 'social/coinmarketcap', title: 'CoinMarketCap' }, + { field: 'defiLlamaTicker', icon: 'social/defi_llama', title: 'DefiLlama' }, ]; export function hasContent(data: TokenVerifiedInfo): boolean { diff --git a/ui/token/TokenProjectInfo/DocsLink.tsx b/ui/token/TokenProjectInfo/DocsLink.tsx index ddb721381a..d6493d672b 100644 --- a/ui/token/TokenProjectInfo/DocsLink.tsx +++ b/ui/token/TokenProjectInfo/DocsLink.tsx @@ -1,7 +1,7 @@ -import { Icon, Link } from '@chakra-ui/react'; +import { Link } from '@chakra-ui/react'; import React from 'react'; -import iconDocs from 'icons/docs.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { href: string; @@ -16,7 +16,7 @@ const DocsLink = ({ href }: Props) => { alignItems="center" columnGap={ 1 } > - + Documentation ); diff --git a/ui/token/TokenProjectInfo/ServiceLink.tsx b/ui/token/TokenProjectInfo/ServiceLink.tsx index aa213ebd3e..5c797cb73f 100644 --- a/ui/token/TokenProjectInfo/ServiceLink.tsx +++ b/ui/token/TokenProjectInfo/ServiceLink.tsx @@ -1,11 +1,14 @@ -import { Link, Icon } from '@chakra-ui/react'; +import { Link } from '@chakra-ui/react'; import React from 'react'; import type { TokenVerifiedInfo } from 'types/api/token'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; + export interface Props { field: keyof TokenVerifiedInfo; - icon: React.FunctionComponent>; + icon: IconName; title: string; href?: string; } @@ -20,7 +23,7 @@ const ServiceLink = ({ href, title, icon }: Props) => { display="inline-flex" alignItems="center" > - + { title } ); diff --git a/ui/token/TokenProjectInfo/SupportLink.tsx b/ui/token/TokenProjectInfo/SupportLink.tsx index 3a3d3e2422..083cab35b6 100644 --- a/ui/token/TokenProjectInfo/SupportLink.tsx +++ b/ui/token/TokenProjectInfo/SupportLink.tsx @@ -1,8 +1,7 @@ -import { Icon, Link } from '@chakra-ui/react'; +import { Link } from '@chakra-ui/react'; import React from 'react'; -import iconEmail from 'icons/email.svg'; -import iconLink from 'icons/link.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { url: string; @@ -11,7 +10,6 @@ interface Props { const SupportLink = ({ url }: Props) => { const isEmail = url.includes('@'); const href = isEmail ? `mailto:${ url }` : url; - const icon = isEmail ? iconEmail : iconLink; return ( { alignItems="center" columnGap={ 1 } > - + { url } ); diff --git a/ui/token/TokenProjectInfo/TriggerButton.tsx b/ui/token/TokenProjectInfo/TriggerButton.tsx index e7cbdc7208..fcab97ab21 100644 --- a/ui/token/TokenProjectInfo/TriggerButton.tsx +++ b/ui/token/TokenProjectInfo/TriggerButton.tsx @@ -1,8 +1,7 @@ -import { Button, Icon } from '@chakra-ui/react'; +import { Button } from '@chakra-ui/react'; import React from 'react'; -import arrowIcon from 'icons/arrows/east-mini.svg'; -import rocketIcon from 'icons/rocket.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { onClick: () => void; @@ -22,9 +21,9 @@ const TriggerButton = ({ isOpen, onClick }: Props, ref: React.ForwardedRef - + Info - + ); }; diff --git a/ui/token/TokenTransfer/TokenTransferListItem.tsx b/ui/token/TokenTransfer/TokenTransferListItem.tsx index 1458f0067d..795bc253e9 100644 --- a/ui/token/TokenTransfer/TokenTransferListItem.tsx +++ b/ui/token/TokenTransfer/TokenTransferListItem.tsx @@ -3,14 +3,13 @@ import React from 'react'; import type { TokenTransfer } from 'types/api/tokenTransfer'; -import eastArrowIcon from 'icons/arrows/east.svg'; import getCurrencyValue from 'lib/getCurrencyValue'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; -import Icon from 'ui/shared/chakra/Icon'; import Tag from 'ui/shared/chakra/Tag'; import AddressEntityWithTokenFilter from 'ui/shared/entities/address/AddressEntityWithTokenFilter'; import NftEntity from 'ui/shared/entities/nft/NftEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity'; +import IconSvg from 'ui/shared/IconSvg'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import TruncatedValue from 'ui/shared/TruncatedValue'; @@ -62,7 +61,7 @@ const TokenTransferListItem = ({ width="50%" fontWeight="500" /> - + - + diff --git a/ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx b/ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx index aa60643f84..c0521edf66 100644 --- a/ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx +++ b/ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx @@ -1,39 +1,31 @@ -import { FormControl, Icon, Input, InputRightElement, InputGroup } from '@chakra-ui/react'; +import { FormControl, Input, InputRightElement, InputGroup } from '@chakra-ui/react'; import React from 'react'; import type { Control, ControllerProps } from 'react-hook-form'; import { Controller } from 'react-hook-form'; import type { Fields, SocialLinkFields } from '../types'; -import iconDiscord from 'icons/social/discord_filled.svg'; -import iconFacebook from 'icons/social/facebook_filled.svg'; -import iconGithub from 'icons/social/github_filled.svg'; -import iconLinkedIn from 'icons/social/linkedin_filled.svg'; -import iconMedium from 'icons/social/medium_filled.svg'; -import iconOpenSea from 'icons/social/opensea_filled.svg'; -import iconReddit from 'icons/social/reddit_filled.svg'; -import iconSlack from 'icons/social/slack_filled.svg'; -import iconTelegram from 'icons/social/telegram_filled.svg'; -import iconTwitter from 'icons/social/twitter_filled.svg'; import { validator } from 'lib/validations/url'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; import InputPlaceholder from 'ui/shared/InputPlaceholder'; interface Item { - icon: React.FunctionComponent>; + icon: IconName; label: string; color: string; } const SETTINGS: Record = { - github: { label: 'GitHub', icon: iconGithub, color: 'inherit' }, - telegram: { label: 'Telegram', icon: iconTelegram, color: 'telegram' }, - linkedin: { label: 'LinkedIn', icon: iconLinkedIn, color: 'linkedin' }, - discord: { label: 'Discord', icon: iconDiscord, color: 'discord' }, - slack: { label: 'Slack', icon: iconSlack, color: 'slack' }, - twitter: { label: 'Twitter', icon: iconTwitter, color: 'twitter' }, - opensea: { label: 'OpenSea', icon: iconOpenSea, color: 'opensea' }, - facebook: { label: 'Facebook', icon: iconFacebook, color: 'facebook' }, - medium: { label: 'Medium', icon: iconMedium, color: 'inherit' }, - reddit: { label: 'Reddit', icon: iconReddit, color: 'reddit' }, + github: { label: 'GitHub', icon: 'social/github_filled', color: 'inherit' }, + telegram: { label: 'Telegram', icon: 'social/telegram_filled', color: 'telegram' }, + linkedin: { label: 'LinkedIn', icon: 'social/linkedin_filled', color: 'linkedin' }, + discord: { label: 'Discord', icon: 'social/discord_filled', color: 'discord' }, + slack: { label: 'Slack', icon: 'social/slack_filled', color: 'slack' }, + twitter: { label: 'Twitter', icon: 'social/twitter_filled', color: 'twitter' }, + opensea: { label: 'OpenSea', icon: 'social/opensea_filled', color: 'opensea' }, + facebook: { label: 'Facebook', icon: 'social/facebook_filled', color: 'facebook' }, + medium: { label: 'Medium', icon: 'social/medium_filled', color: 'inherit' }, + reddit: { label: 'Reddit', icon: 'social/reddit_filled', color: 'reddit' }, }; interface Props { @@ -55,7 +47,7 @@ const TokenInfoFieldSocialLink = ({ control, isReadOnly, name }: Props) => { /> - + diff --git a/ui/tokens/TokensTable.tsx b/ui/tokens/TokensTable.tsx index f14de2de2a..0a406175de 100644 --- a/ui/tokens/TokensTable.tsx +++ b/ui/tokens/TokensTable.tsx @@ -1,10 +1,10 @@ -import { Icon, Link, Table, Tbody, Th, Tr } from '@chakra-ui/react'; +import { Link, Table, Tbody, Th, Tr } from '@chakra-ui/react'; import React from 'react'; import type { TokenInfo } from 'types/api/token'; import type { TokensSortingField, TokensSortingValue } from 'types/api/tokens'; -import rightArrowIcon from 'icons/arrows/east.svg'; +import IconSvg from 'ui/shared/IconSvg'; import { default as getNextSortValueShared } from 'ui/shared/sort/getNextSortValue'; import { default as Thead } from 'ui/shared/TheadSticky'; @@ -41,19 +41,19 @@ const TokensTable = ({ items, page, isLoading, sorting, setSorting }: Props) => Token - { sorting?.includes('fiat_value') && } + { sorting?.includes('fiat_value') && } Price - { sorting?.includes('circulating_market_cap') && } + { sorting?.includes('circulating_market_cap') && } On-chain market cap - { sorting?.includes('holder_count') && } + { sorting?.includes('holder_count') && } Holders diff --git a/ui/verifiedAddresses/VerifiedAddressesListItem.tsx b/ui/verifiedAddresses/VerifiedAddressesListItem.tsx index f3706a8209..d4719c5dc4 100644 --- a/ui/verifiedAddresses/VerifiedAddressesListItem.tsx +++ b/ui/verifiedAddresses/VerifiedAddressesListItem.tsx @@ -3,11 +3,10 @@ import React from 'react'; import type { TokenInfoApplication, VerifiedAddress } from 'types/api/account'; -import editIcon from 'icons/edit.svg'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity'; +import IconSvg from 'ui/shared/IconSvg'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import VerifiedAddressesStatus from './VerifiedAddressesStatus'; @@ -71,7 +70,7 @@ const VerifiedAddressesListItem = ({ item, application, onAdd, onEdit, isLoading borderRadius="none" flexShrink={ 0 } onClick={ handleEditClick } - icon={ } + icon={ } /> diff --git a/ui/verifiedAddresses/VerifiedAddressesTableItem.tsx b/ui/verifiedAddresses/VerifiedAddressesTableItem.tsx index 96787d4702..7aec29649b 100644 --- a/ui/verifiedAddresses/VerifiedAddressesTableItem.tsx +++ b/ui/verifiedAddresses/VerifiedAddressesTableItem.tsx @@ -3,11 +3,10 @@ import React from 'react'; import type { TokenInfoApplication, VerifiedAddress } from 'types/api/account'; -import editIcon from 'icons/edit.svg'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import TokenEntity from 'ui/shared/entities/token/TokenEntity'; +import IconSvg from 'ui/shared/IconSvg'; import VerifiedAddressesStatus from './VerifiedAddressesStatus'; @@ -87,7 +86,7 @@ const VerifiedAddressesTableItem = ({ item, application, onAdd, onEdit, isLoadin borderRadius="none" flexShrink={ 0 } onClick={ handleEditClick } - icon={ } + icon={ } /> ) : null } diff --git a/ui/verifiedContracts/VerifiedContractsListItem.tsx b/ui/verifiedContracts/VerifiedContractsListItem.tsx index 28c14c1254..ec8931c286 100644 --- a/ui/verifiedContracts/VerifiedContractsListItem.tsx +++ b/ui/verifiedContracts/VerifiedContractsListItem.tsx @@ -5,14 +5,11 @@ import React from 'react'; import type { VerifiedContract } from 'types/api/contracts'; import config from 'configs/app'; -import iconCheck from 'icons/check.svg'; -import iconCross from 'icons/cross.svg'; -import iconSuccess from 'icons/status/success.svg'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import HashStringShorten from 'ui/shared/HashStringShorten'; +import IconSvg from 'ui/shared/IconSvg'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; interface Props { @@ -61,19 +58,19 @@ const VerifiedContractsListItem = ({ data, isLoading }: Props) => { Optimization { data.optimization_enabled ? - : - } + : + } Constructor args { data.has_constructor_args ? - : - } + : + } Verified - + { dayjs(data.verified_at).fromNow() } diff --git a/ui/verifiedContracts/VerifiedContractsTable.tsx b/ui/verifiedContracts/VerifiedContractsTable.tsx index 81694f193c..8d19f5af6b 100644 --- a/ui/verifiedContracts/VerifiedContractsTable.tsx +++ b/ui/verifiedContracts/VerifiedContractsTable.tsx @@ -1,11 +1,11 @@ -import { Table, Tbody, Tr, Th, Link, Icon } from '@chakra-ui/react'; +import { Table, Tbody, Tr, Th, Link } from '@chakra-ui/react'; import React from 'react'; import type { VerifiedContract } from 'types/api/contracts'; import type { VerifiedContractsSorting, VerifiedContractsSortingField, VerifiedContractsSortingValue } from 'types/api/verifiedContracts'; import config from 'configs/app'; -import arrowIcon from 'icons/arrows/east.svg'; +import IconSvg from 'ui/shared/IconSvg'; import getNextSortValue from 'ui/shared/sort/getNextSortValue'; import { default as Thead } from 'ui/shared/TheadSticky'; import { SORT_SEQUENCE } from 'ui/verifiedContracts/utils'; @@ -34,13 +34,13 @@ const VerifiedContractsTable = ({ data, sort, setSorting, isLoading }: Props) => Contract - { sort?.includes('balance') && } + { sort?.includes('balance') && } Balance { config.chain.currency.symbol } - { sort?.includes('txs_count') && } + { sort?.includes('txs_count') && } Txs diff --git a/ui/verifiedContracts/VerifiedContractsTableItem.tsx b/ui/verifiedContracts/VerifiedContractsTableItem.tsx index 50caee59ec..3a528dd6b9 100644 --- a/ui/verifiedContracts/VerifiedContractsTableItem.tsx +++ b/ui/verifiedContracts/VerifiedContractsTableItem.tsx @@ -5,14 +5,11 @@ import React from 'react'; import type { VerifiedContract } from 'types/api/contracts'; import config from 'configs/app'; -import iconCheck from 'icons/check.svg'; -import iconCross from 'icons/cross.svg'; -import iconSuccess from 'icons/status/success.svg'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import HashStringShorten from 'ui/shared/HashStringShorten'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { data: VerifiedContract; @@ -63,21 +60,21 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => { { data.optimization_enabled ? - : - } + : + } { data.has_constructor_args ? - : - } + : + } - + { dayjs(data.verified_at).fromNow() } diff --git a/ui/watchlist/WatchlistTable/WatchListAddressItem.tsx b/ui/watchlist/WatchlistTable/WatchListAddressItem.tsx index e3e68c130e..b5194082da 100644 --- a/ui/watchlist/WatchlistTable/WatchListAddressItem.tsx +++ b/ui/watchlist/WatchlistTable/WatchListAddressItem.tsx @@ -5,14 +5,12 @@ import React from 'react'; import type { WatchlistAddress } from 'types/api/account'; import config from 'configs/app'; -import TokensIcon from 'icons/tokens.svg'; -import WalletIcon from 'icons/wallet.svg'; import getCurrencyValue from 'lib/getCurrencyValue'; import { nbsp } from 'lib/html-entities'; -import Icon from 'ui/shared/chakra/Icon'; import CurrencyValue from 'ui/shared/CurrencyValue'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import * as TokenEntity from 'ui/shared/entities/token/TokenEntity'; +import IconSvg from 'ui/shared/IconSvg'; const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isLoading?: boolean }) => { const nativeTokenData = React.useMemo(() => ({ @@ -51,7 +49,7 @@ const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isL { item.tokens_count && ( - + { `Tokens:${ nbsp }` + item.tokens_count + (item.tokens_overflow ? '+' : '') } { `${ nbsp }($${ BigNumber(item.tokens_fiat_value).toFormat(2) })` } @@ -60,7 +58,7 @@ const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isL ) } { item.tokens_fiat_value && ( - + { `Net worth:${ nbsp }` } { diff --git a/ui/zkEvmL2TxnBatches/ZkEvmL2TxnBatchDetails.tsx b/ui/zkEvmL2TxnBatches/ZkEvmL2TxnBatchDetails.tsx index 103e9c3fc2..3d2b767863 100644 --- a/ui/zkEvmL2TxnBatches/ZkEvmL2TxnBatchDetails.tsx +++ b/ui/zkEvmL2TxnBatches/ZkEvmL2TxnBatchDetails.tsx @@ -8,16 +8,15 @@ import type { ZkEvmL2TxnBatch } from 'types/api/zkEvmL2TxnBatches'; import { route } from 'nextjs-routes'; -import clockIcon from 'icons/clock.svg'; import type { ResourceError } from 'lib/api/resources'; import dayjs from 'lib/date/dayjs'; -import Icon from 'ui/shared/chakra/Icon'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; import PrevNext from 'ui/shared/PrevNext'; import TextSeparator from 'ui/shared/TextSeparator'; @@ -92,7 +91,7 @@ const ZkEvmL2TxnBatchDetails = ({ query }: Props) => { title="Timestamp" isLoading={ isPlaceholderData } > - + { dayjs(data.timestamp).fromNow() } From 7a436b85b14138f9563deebfb4e81fe40bcd036e Mon Sep 17 00:00:00 2001 From: isstuev Date: Tue, 19 Dec 2023 18:50:30 +0100 Subject: [PATCH 08/15] search bar fixes --- ui/snippets/searchBar/SearchBar.tsx | 93 ++++++++++++------------ ui/snippets/searchBar/SearchBarInput.tsx | 6 +- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/ui/snippets/searchBar/SearchBar.tsx b/ui/snippets/searchBar/SearchBar.tsx index 1e1dfadb35..f8b07afe1e 100644 --- a/ui/snippets/searchBar/SearchBar.tsx +++ b/ui/snippets/searchBar/SearchBar.tsx @@ -1,7 +1,7 @@ -import { Box, Popover, PopoverTrigger, PopoverContent, PopoverBody, useDisclosure, PopoverFooter } from '@chakra-ui/react'; +import { Box, Portal, Popover, PopoverTrigger, PopoverContent, PopoverBody, useDisclosure, PopoverFooter, useOutsideClick } from '@chakra-ui/react'; import _debounce from 'lodash/debounce'; import { useRouter } from 'next/router'; -import type { FormEvent, FocusEvent } from 'react'; +import type { FormEvent } from 'react'; import React from 'react'; import { Element } from 'react-scroll'; @@ -59,13 +59,15 @@ const SearchBar = ({ isHomepage }: Props) => { inputRef.current?.querySelector('input')?.blur(); }, [ onClose ]); - const handleBlur = React.useCallback((event: FocusEvent) => { - const isFocusInMenu = menuRef.current?.contains(event.relatedTarget); - const isFocusInInput = inputRef.current?.contains(event.relatedTarget); - if (!isFocusInMenu && !isFocusInInput) { - onClose(); + const handleOutsideClick = React.useCallback((event: Event) => { + const isFocusInInput = inputRef.current?.contains(event.target as Node); + + if (!isFocusInInput) { + handelHide(); } - }, [ onClose ]); + }, [ handelHide ]); + + useOutsideClick({ ref: menuRef, handler: handleOutsideClick }); const handleClear = React.useCallback(() => { handleSearchTermChange(''); @@ -118,53 +120,54 @@ const SearchBar = ({ isHomepage }: Props) => { onChange={ handleSearchTermChange } onSubmit={ handleSubmit } onFocus={ handleFocus } - onBlur={ handleBlur } onHide={ handelHide } onClear={ handleClear } isHomepage={ isHomepage } value={ searchTerm } /> - - + - - { searchTerm.trim().length === 0 && recentSearchKeywords.length > 0 && ( - - ) } - { searchTerm.trim().length > 0 && ( - - ) } - - - { searchTerm.trim().length > 0 && query.data && query.data.length >= 50 && ( - - + { searchTerm.trim().length === 0 && recentSearchKeywords.length > 0 && ( + + ) } + { searchTerm.trim().length > 0 && ( + + ) } + + + { searchTerm.trim().length > 0 && query.data && query.data.length >= 50 && ( + + View all results - - - ) } - + + + ) } + + ); }; diff --git a/ui/snippets/searchBar/SearchBarInput.tsx b/ui/snippets/searchBar/SearchBarInput.tsx index 5d3a51bae2..06c0272dd4 100644 --- a/ui/snippets/searchBar/SearchBarInput.tsx +++ b/ui/snippets/searchBar/SearchBarInput.tsx @@ -21,7 +21,7 @@ interface Props { const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHide, onClear, value }: Props, ref: React.ForwardedRef) => { const innerRef = React.useRef(null); - React.useImperativeHandle(ref, () => innerRef.current!, []); + React.useImperativeHandle(ref, () => innerRef.current as HTMLFormElement, []); const [ isSticky, setIsSticky ] = React.useState(false); const scrollDirection = useScrollDirection(); const isMobile = useIsMobile(); @@ -56,9 +56,7 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid return () => { window.removeEventListener('scroll', throttledHandleScroll); }; - // replicate componentDidMount - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ isMobile ]); + }, [ isMobile, handleScroll ]); const bgColor = useColorModeValue('white', 'black'); const transformMobile = scrollDirection !== 'down' ? 'translateY(0)' : 'translateY(-100%)'; From 136edb64b247f5e38dd645b226b1d534225997f9 Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 20 Dec 2023 14:40:52 +0400 Subject: [PATCH 09/15] last part of migratin and eslint rule --- .eslintrc.js | 3 ++ .../AccountActionsMenu/AccountActionsMenu.tsx | 6 ++-- .../items/PrivateTagMenuItem.tsx | 6 ++-- .../items/PublicTagMenuItem.tsx | 6 ++-- .../items/TokenInfoMenuItem.tsx | 6 ++-- ui/shared/AdditionalInfoButton.tsx | 7 ++--- ui/shared/ApiKeySnippet.tsx | 5 ++-- ui/shared/AppError/AppErrorIcon.tsx | 19 ++++++------- .../AppError/custom/AppErrorInvalidTxHash.tsx | 6 ++-- ui/shared/ClearButton.tsx | 6 ++-- ui/shared/CopyToClipboard.tsx | 4 +-- ui/shared/EmptySearchResult.tsx | 8 +++--- ui/shared/Hint.tsx | 4 +-- ui/shared/LinkExternal.tsx | 6 ++-- ui/shared/NetworkExplorers.tsx | 9 +++--- ui/shared/Page/PageTitle.tsx | 6 ++-- ui/shared/Page/specs/DefaultView.tsx | 5 ++-- ui/shared/Page/specs/LongNameAndManyTags.tsx | 5 ++-- ui/shared/PrevNext.tsx | 8 +++--- ui/shared/ResetIconButton.tsx | 8 +++--- ui/shared/TableItemActionButtons.tsx | 7 ++--- ui/shared/TokenLogoPlaceholder.tsx | 8 +++--- .../TokenTransfer/TokenTransferListItem.tsx | 5 ++-- ui/shared/UserAvatar.tsx | 6 ++-- ui/shared/chart/ChartWidget.tsx | 17 ++++------- ui/shared/chart/FullscreenChartModal.tsx | 6 ++-- ui/shared/filters/FilterButton.tsx | 6 ++-- ui/shared/filters/FilterInput.tsx | 6 ++-- ui/shared/forms/FileSnippet.tsx | 28 ++++++++----------- .../monaco/CodeEditorMainFileIndicator.tsx | 6 ++-- ui/shared/nft/NftFallback.tsx | 8 +++--- ui/shared/pagination/Pagination.tsx | 8 +++--- .../specs/RadioButtonGroupTest.tsx | 13 ++------- ui/shared/sort/SortButton.tsx | 6 ++-- ui/shared/statusTag/StatusTag.tsx | 17 ++++++----- 35 files changed, 127 insertions(+), 153 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 31bfd03078..20881d308f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,9 @@ const RESTRICTED_MODULES = { { name: '@metamask/providers', message: 'Please lazy-load @metamask/providers or use useProvider hook instead' }, { name: '@metamask/post-message-stream', message: 'Please lazy-load @metamask/post-message-stream or use useProvider hook instead' }, ], + patterns: [ + 'icons/*', + ], }; module.exports = { diff --git a/ui/shared/AccountActionsMenu/AccountActionsMenu.tsx b/ui/shared/AccountActionsMenu/AccountActionsMenu.tsx index b8fdb8fac2..a74da37045 100644 --- a/ui/shared/AccountActionsMenu/AccountActionsMenu.tsx +++ b/ui/shared/AccountActionsMenu/AccountActionsMenu.tsx @@ -1,12 +1,12 @@ -import { Button, Menu, MenuButton, MenuList, Icon, Flex, Skeleton, chakra } from '@chakra-ui/react'; +import { Button, Menu, MenuButton, MenuList, Flex, Skeleton, chakra } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import React from 'react'; import config from 'configs/app'; -import iconArrow from 'icons/arrows/east-mini.svg'; import useIsAccountActionAllowed from 'lib/hooks/useIsAccountActionAllowed'; import * as mixpanel from 'lib/mixpanel/index'; import getQueryParamString from 'lib/router/getQueryParamString'; +import IconSvg from 'ui/shared/IconSvg'; import PrivateTagMenuItem from './items/PrivateTagMenuItem'; import PublicTagMenuItem from './items/PublicTagMenuItem'; @@ -44,7 +44,7 @@ const AccountActionsMenu = ({ isLoading, className }: Props) => { > More - + diff --git a/ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx b/ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx index 4450dcd2b1..941434c390 100644 --- a/ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx +++ b/ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx @@ -1,4 +1,4 @@ -import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react'; +import { MenuItem, chakra, useDisclosure } from '@chakra-ui/react'; import { useQueryClient } from '@tanstack/react-query'; import { useRouter } from 'next/router'; import React from 'react'; @@ -6,11 +6,11 @@ import React from 'react'; import type { Address } from 'types/api/address'; import type { Transaction } from 'types/api/transaction'; -import iconPrivateTags from 'icons/privattags.svg'; import { getResourceKey } from 'lib/api/useApiQuery'; import getPageType from 'lib/mixpanel/getPageType'; import AddressModal from 'ui/privateTags/AddressModal/AddressModal'; import TransactionModal from 'ui/privateTags/TransactionModal/TransactionModal'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { className?: string; @@ -61,7 +61,7 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, type = 'address' } return ( <> - + Add private tag { type === 'tx' ? diff --git a/ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx b/ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx index 2f3c0c0e32..25de85da97 100644 --- a/ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx +++ b/ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx @@ -1,8 +1,8 @@ -import { MenuItem, Icon, chakra } from '@chakra-ui/react'; +import { MenuItem, chakra } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import React from 'react'; -import iconPublicTags from 'icons/publictags.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { className?: string; @@ -23,7 +23,7 @@ const PublicTagMenuItem = ({ className, hash, onBeforeClick }: Props) => { return ( - + Add public tag ); diff --git a/ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx b/ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx index 06950e9e82..b7e5f3d337 100644 --- a/ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx +++ b/ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx @@ -1,15 +1,15 @@ -import { MenuItem, Icon, chakra, useDisclosure } from '@chakra-ui/react'; +import { MenuItem, chakra, useDisclosure } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import React from 'react'; import type { Route } from 'nextjs-routes'; import config from 'configs/app'; -import iconEdit from 'icons/edit.svg'; import useApiQuery from 'lib/api/useApiQuery'; import useHasAccount from 'lib/hooks/useHasAccount'; import { PAGE_TYPE_DICT } from 'lib/mixpanel/getPageType'; import AddressVerificationModal from 'ui/addressVerification/AddressVerificationModal'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { className?: string; @@ -61,7 +61,7 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick }: Props) => { router.push({ pathname: '/account/verified-addresses' }); }, [ router ]); - const icon = ; + const icon = ; const content = (() => { if (!verifiedAddressesQuery.data?.verifiedAddresses.find(({ contractAddress }) => contractAddress.toLowerCase() === hash.toLowerCase())) { diff --git a/ui/shared/AdditionalInfoButton.tsx b/ui/shared/AdditionalInfoButton.tsx index 39352cd502..5b1002bfeb 100644 --- a/ui/shared/AdditionalInfoButton.tsx +++ b/ui/shared/AdditionalInfoButton.tsx @@ -1,5 +1,4 @@ import { - Icon, useColorModeValue, chakra, Button, @@ -7,7 +6,7 @@ import { } from '@chakra-ui/react'; import React from 'react'; -import infoIcon from 'icons/info.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { isOpen?: boolean; @@ -39,8 +38,8 @@ const AdditionalInfoButton = ({ isOpen, onClick, className, isLoading }: Props, cursor="pointer" flexShrink={ 0 } > - { return ( - + diff --git a/ui/shared/AppError/AppErrorIcon.tsx b/ui/shared/AppError/AppErrorIcon.tsx index 35f6afe3ca..1fa64aadcc 100644 --- a/ui/shared/AppError/AppErrorIcon.tsx +++ b/ui/shared/AppError/AppErrorIcon.tsx @@ -1,16 +1,13 @@ -import { Icon } from '@chakra-ui/react'; import React from 'react'; -import icon404 from 'icons/error-pages/404.svg'; -import icon422 from 'icons/error-pages/422.svg'; -import icon429 from 'icons/error-pages/429.svg'; -import icon500 from 'icons/error-pages/500.svg'; +import type { IconName } from 'ui/shared/IconSvg'; +import IconSvg from 'ui/shared/IconSvg'; -const ICONS: Record> > = { - '404': icon404, - '422': icon422, - '429': icon429, - '500': icon500, +const ICONS: Record = { + '404': 'error-pages/404', + '422': 'error-pages/422', + '429': 'error-pages/429', + '500': 'error-pages/500', }; interface Props { @@ -18,7 +15,7 @@ interface Props { } const AppErrorIcon = ({ statusCode }: Props) => { - return ; + return ; }; export default AppErrorIcon; diff --git a/ui/shared/AppError/custom/AppErrorInvalidTxHash.tsx b/ui/shared/AppError/custom/AppErrorInvalidTxHash.tsx index 48b5f28841..a6da98596f 100644 --- a/ui/shared/AppError/custom/AppErrorInvalidTxHash.tsx +++ b/ui/shared/AppError/custom/AppErrorInvalidTxHash.tsx @@ -1,8 +1,8 @@ /* eslint-disable max-len */ -import { Box, OrderedList, ListItem, Icon, useColorModeValue, Flex } from '@chakra-ui/react'; +import { Box, OrderedList, ListItem, useColorModeValue, Flex } from '@chakra-ui/react'; import React from 'react'; -import txIcon from 'icons/transactions.svg'; +import IconSvg from 'ui/shared/IconSvg'; import AppErrorTitle from '../AppErrorTitle'; @@ -18,7 +18,7 @@ const AppErrorInvalidTxHash = () => { <> - + diff --git a/ui/shared/ClearButton.tsx b/ui/shared/ClearButton.tsx index 614b3620a4..f2a12592b0 100644 --- a/ui/shared/ClearButton.tsx +++ b/ui/shared/ClearButton.tsx @@ -1,7 +1,7 @@ -import { chakra, Icon, IconButton, useColorModeValue } from '@chakra-ui/react'; +import { chakra, IconButton, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; -import errorIcon from 'icons/status/error.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { onClick: (e: React.SyntheticEvent) => void; @@ -21,7 +21,7 @@ const ClearButton = ({ onClick, isDisabled, className }: Props) => { aria-label="Clear input" title="Clear input" boxSize={ 6 } - icon={ } + icon={ } size="sm" onClick={ onClick } /> diff --git a/ui/shared/CopyToClipboard.tsx b/ui/shared/CopyToClipboard.tsx index 00359599c0..be20647990 100644 --- a/ui/shared/CopyToClipboard.tsx +++ b/ui/shared/CopyToClipboard.tsx @@ -1,7 +1,7 @@ import { IconButton, Tooltip, useClipboard, chakra, useDisclosure, Skeleton } from '@chakra-ui/react'; import React, { useEffect, useState } from 'react'; -import CopyIcon from 'icons/copy.svg'; +import IconSvg from 'ui/shared/IconSvg'; export interface Props { text: string; @@ -31,7 +31,7 @@ const CopyToClipboard = ({ text, className, isLoading }: Props) => { } + icon={ } w="20px" h="20px" color="gray.400" diff --git a/ui/shared/EmptySearchResult.tsx b/ui/shared/EmptySearchResult.tsx index 5e7ca7d900..9c5b7b3720 100644 --- a/ui/shared/EmptySearchResult.tsx +++ b/ui/shared/EmptySearchResult.tsx @@ -1,7 +1,7 @@ -import { Box, Heading, Icon, Text } from '@chakra-ui/react'; +import { Box, Heading, Text } from '@chakra-ui/react'; import React from 'react'; -import emptyIcon from 'icons/empty_search_result.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { text: string; @@ -14,8 +14,8 @@ const EmptySearchResult = ({ text }: Props) => { flexDirection="column" alignItems="center" > - diff --git a/ui/shared/Hint.tsx b/ui/shared/Hint.tsx index 7a4908f8c6..a818e27ec2 100644 --- a/ui/shared/Hint.tsx +++ b/ui/shared/Hint.tsx @@ -2,7 +2,7 @@ import type { TooltipProps } from '@chakra-ui/react'; import { chakra, IconButton, Tooltip, useDisclosure, Skeleton } from '@chakra-ui/react'; import React from 'react'; -import InfoIcon from 'icons/info.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { label: string | React.ReactNode; @@ -35,7 +35,7 @@ const Hint = ({ label, className, tooltipProps, isLoading }: Props) => { } + icon={ } boxSize={ 5 } variant="simple" display="inline-block" diff --git a/ui/shared/LinkExternal.tsx b/ui/shared/LinkExternal.tsx index 64401dab4a..efc5efc561 100644 --- a/ui/shared/LinkExternal.tsx +++ b/ui/shared/LinkExternal.tsx @@ -1,8 +1,8 @@ import type { ChakraProps } from '@chakra-ui/react'; -import { Link, Icon, chakra, Box, Skeleton, useColorModeValue } from '@chakra-ui/react'; +import { Link, chakra, Box, Skeleton, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; -import arrowIcon from 'icons/arrows/north-east.svg'; +import IconSvg from 'ui/shared/IconSvg'; interface Props { href: string; @@ -59,7 +59,7 @@ const LinkExternal = ({ href, children, className, isLoading, variant }: Props) return ( { children } - + ); }; diff --git a/ui/shared/NetworkExplorers.tsx b/ui/shared/NetworkExplorers.tsx index 1475375511..d0cefc98d0 100644 --- a/ui/shared/NetworkExplorers.tsx +++ b/ui/shared/NetworkExplorers.tsx @@ -1,12 +1,11 @@ -import { Flex, Button, Icon, chakra, Popover, PopoverTrigger, PopoverBody, PopoverContent, useDisclosure } from '@chakra-ui/react'; +import { Flex, Button, chakra, Popover, PopoverTrigger, PopoverBody, PopoverContent, useDisclosure } from '@chakra-ui/react'; import React from 'react'; import type { NetworkExplorer as TNetworkExplorer } from 'types/networks'; import config from 'configs/app'; -import arrowIcon from 'icons/arrows/east-mini.svg'; -import explorerIcon from 'icons/explorer.svg'; import stripTrailingSlash from 'lib/stripTrailingSlash'; +import IconSvg from 'ui/shared/IconSvg'; import LinkExternal from 'ui/shared/LinkExternal'; interface Props { @@ -46,8 +45,8 @@ const NetworkExplorers = ({ className, type, pathParam }: Props) => { h="32px" flexShrink={ 0 } > - - + + diff --git a/ui/shared/Page/PageTitle.tsx b/ui/shared/Page/PageTitle.tsx index 9167e7e87e..d531921cc4 100644 --- a/ui/shared/Page/PageTitle.tsx +++ b/ui/shared/Page/PageTitle.tsx @@ -1,10 +1,10 @@ -import { Heading, Flex, Tooltip, Icon, Link, chakra, Skeleton, useDisclosure } from '@chakra-ui/react'; +import { Heading, Flex, Tooltip, Link, chakra, Skeleton, useDisclosure } from '@chakra-ui/react'; import _debounce from 'lodash/debounce'; import React from 'react'; -import eastArrowIcon from 'icons/arrows/east.svg'; import useIsMobile from 'lib/hooks/useIsMobile'; import TextAd from 'ui/shared/ad/TextAd'; +import IconSvg from 'ui/shared/IconSvg'; import LinkInternal from 'ui/shared/LinkInternal'; type BackLinkProp = { label: string; url: string } | { label: string; onClick: () => void }; @@ -32,7 +32,7 @@ const BackLink = (props: BackLinkProp & { isLoading?: boolean }) => { return ; } - const icon = ; + const icon = ; if ('url' in props) { return ( diff --git a/ui/shared/Page/specs/DefaultView.tsx b/ui/shared/Page/specs/DefaultView.tsx index 23db4033fd..0c924f55e0 100644 --- a/ui/shared/Page/specs/DefaultView.tsx +++ b/ui/shared/Page/specs/DefaultView.tsx @@ -1,13 +1,12 @@ -import { Icon } from '@chakra-ui/react'; import React from 'react'; import type { TokenInfo } from 'types/api/token'; -import iconVerifiedToken from 'icons/verified_token.svg'; import * as addressMock from 'mocks/address/address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import * as TokenEntity from 'ui/shared/entities/token/TokenEntity'; import EntityTags from 'ui/shared/EntityTags'; +import IconSvg from 'ui/shared/IconSvg'; import NetworkExplorers from 'ui/shared/NetworkExplorers'; import PageTitle from '../PageTitle'; @@ -33,7 +32,7 @@ const DefaultView = () => { const contentAfter = ( <> - + { const contentAfter = ( <> - + } + icon={ } h={ 6 } borderRadius="sm" variant="subtle" @@ -48,7 +48,7 @@ const PrevNext = ({ className, onClick, prevLabel, nextLabel, isPrevDisabled, is } + icon={ } h={ 6 } borderRadius="sm" variant="subtle" diff --git a/ui/shared/ResetIconButton.tsx b/ui/shared/ResetIconButton.tsx index 53519eb1d1..0b80918219 100644 --- a/ui/shared/ResetIconButton.tsx +++ b/ui/shared/ResetIconButton.tsx @@ -1,7 +1,7 @@ -import { Tooltip, Flex, Icon, useColorModeValue } from '@chakra-ui/react'; +import { Tooltip, Flex, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; -import crossIcon from 'icons/cross.svg'; +import IconSvg from 'ui/shared/IconSvg'; type Props = { onClick: () => void; @@ -14,8 +14,8 @@ const ResetIconButton = ({ onClick }: Props) => { return ( - void; @@ -31,7 +30,7 @@ const TableItemActionButtons = ({ onEditClick, onDeleteClick, isLoading }: Props variant="simple" boxSize={ 5 } onClick={ onEditClick } - icon={ } + icon={ } onFocusCapture={ onFocusCapture } display="inline-block" flexShrink={ 0 } @@ -44,7 +43,7 @@ const TableItemActionButtons = ({ onEditClick, onDeleteClick, isLoading }: Props variant="simple" boxSize={ 5 } onClick={ onDeleteClick } - icon={ } + icon={ } onFocusCapture={ onFocusCapture } display="inline-block" flexShrink={ 0 } diff --git a/ui/shared/TokenLogoPlaceholder.tsx b/ui/shared/TokenLogoPlaceholder.tsx index 5f50d27b7a..343df209f2 100644 --- a/ui/shared/TokenLogoPlaceholder.tsx +++ b/ui/shared/TokenLogoPlaceholder.tsx @@ -1,20 +1,20 @@ -import { chakra, Icon, useColorModeValue } from '@chakra-ui/react'; +import { chakra, useColorModeValue } from '@chakra-ui/react'; import React from 'react'; -import tokenPlaceholderIcon from 'icons/token-placeholder.svg'; +import IconSvg from 'ui/shared/IconSvg'; const TokenLogoPlaceholder = ({ className }: { className?: string }) => { const bgColor = useColorModeValue('gray.200', 'gray.600'); const color = useColorModeValue('gray.400', 'gray.200'); return ( - ) : - + } { boxSize={ `${ size }px` } borderRadius="full" overflow="hidden" - fallback={ isImageLoadError || !data?.avatar ? : undefined } + fallback={ isImageLoadError || !data?.avatar ? : undefined } onError={ handleImageLoadError } /> ); diff --git a/ui/shared/chart/ChartWidget.tsx b/ui/shared/chart/ChartWidget.tsx index 93d1e5c0ae..b613b8f7a4 100644 --- a/ui/shared/chart/ChartWidget.tsx +++ b/ui/shared/chart/ChartWidget.tsx @@ -3,7 +3,6 @@ import { Center, chakra, Flex, - Icon, IconButton, Link, Menu, MenuButton, @@ -20,14 +19,10 @@ import React, { useRef, useCallback, useState } from 'react'; import type { TimeChartItem } from './types'; -import svgFileIcon from 'icons/files/csv.svg'; -import imageIcon from 'icons/files/image.svg'; -import repeatArrowIcon from 'icons/repeat_arrow.svg'; -import scopeIcon from 'icons/scope.svg'; -import dotsIcon from 'icons/vertical_dots.svg'; import dayjs from 'lib/date/dayjs'; import { apos } from 'lib/html-entities'; import saveAsCSV from 'lib/saveAsCSV'; +import IconSvg from 'ui/shared/IconSvg'; import ChartWidgetGraph from './ChartWidgetGraph'; import FullscreenChartModal from './FullscreenChartModal'; @@ -202,7 +197,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError, size="sm" variant="outline" onClick={ handleZoomResetClick } - icon={ } + icon={ } /> @@ -212,7 +207,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError, } + icon={ } colorScheme="gray" variant="ghost" as={ IconButton } @@ -228,7 +223,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError, alignItems="center" onClick={ showChartFullscreen } > - + View fullscreen @@ -237,7 +232,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError, alignItems="center" onClick={ handleFileSaveClick } > - + Save as PNG @@ -246,7 +241,7 @@ const ChartWidget = ({ items, title, description, isLoading, className, isError, alignItems="center" onClick={ handleSVGSavingClick } > - + Save as CSV diff --git a/ui/shared/chart/FullscreenChartModal.tsx b/ui/shared/chart/FullscreenChartModal.tsx index 8752e11ce7..d7a3b1c692 100644 --- a/ui/shared/chart/FullscreenChartModal.tsx +++ b/ui/shared/chart/FullscreenChartModal.tsx @@ -1,9 +1,9 @@ -import { Box, Button, Grid, Heading, Icon, Modal, ModalBody, ModalCloseButton, ModalContent, ModalOverlay, Text } from '@chakra-ui/react'; +import { Box, Button, Grid, Heading, Modal, ModalBody, ModalCloseButton, ModalContent, ModalOverlay, Text } from '@chakra-ui/react'; import React, { useCallback } from 'react'; import type { TimeChartItem } from './types'; -import repeatArrow from 'icons/repeat_arrow.svg'; +import IconSvg from 'ui/shared/IconSvg'; import ChartWidgetGraph from './ChartWidgetGraph'; @@ -71,7 +71,7 @@ const FullscreenChartModal = ({ { !isZoomResetInitial && (