mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Replace lodash with es-toolkit (#2503)
* first part of migration * second part of migration * bump up es-toolkit version * bump up `es-toolkit` version and remove `lodash` completely * update screenshot
This commit is contained in:
@@ -30,14 +30,9 @@ const RESTRICTED_MODULES = {
|
||||
importNames: [ 'Popover', 'Menu', 'PinInput', 'useToast', 'Skeleton' ],
|
||||
message: 'Please use corresponding component or hook from ui/shared/chakra component instead',
|
||||
},
|
||||
{
|
||||
name: 'lodash',
|
||||
message: 'Please use `import [package] from \'lodash/[package]\'` instead.',
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
'icons/*',
|
||||
'!lodash/*',
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.444 18.315a10 10 0 1 0 11.112-16.63 10 10 0 0 0-11.112 16.63ZM5.3 2.965a8.462 8.462 0 1 1 9.402 14.07 8.462 8.462 0 0 1-9.402-14.07Zm8.637 11.978a.768.768 0 0 0 .295.057.769.769 0 0 0 .546-1.315l-4.008-4V3.846a.769.769 0 1 0-1.538 0V10a.77.77 0 0 0 .223.546l4.23 4.23a.77.77 0 0 0 .252.167Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.444 18.315a10 10 0 1 0 11.112-16.63 10 10 0 0 0-11.112 16.63ZM5.3 2.965a8.462 8.462 0 1 1 9.402 14.07A8.462 8.462 0 0 1 5.3 2.965Zm8.637 11.978a.768.768 0 0 0 .295.057.769.769 0 0 0 .546-1.315l-4.008-4V3.846a.769.769 0 1 0-1.538 0V10a.77.77 0 0 0 .223.546l4.23 4.23a.77.77 0 0 0 .252.167Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 446 B |
@@ -1,6 +1,5 @@
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import _omit from 'lodash/omit';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { omit, pickBy } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { CsrfData } from 'types/client/account';
|
||||
@@ -38,7 +37,7 @@ export default function useApiFetch() {
|
||||
const resource: ApiResource = RESOURCES[resourceName];
|
||||
const url = buildUrl(resourceName, pathParams, queryParams);
|
||||
const withBody = isBodyAllowed(fetchParams?.method);
|
||||
const headers = _pickBy({
|
||||
const headers = pickBy({
|
||||
'x-endpoint': resource.endpoint && isNeedProxy() ? resource.endpoint : undefined,
|
||||
Authorization: resource.endpoint && resource.needAuth ? apiToken : undefined,
|
||||
'x-csrf-token': withBody && csrfToken ? csrfToken : undefined,
|
||||
@@ -55,7 +54,7 @@ export default function useApiFetch() {
|
||||
// change condition here if something is changed
|
||||
credentials: config.features.account.isEnabled ? 'include' : 'same-origin',
|
||||
headers,
|
||||
..._omit(fetchParams, 'headers'),
|
||||
...(fetchParams ? omit(fetchParams, [ 'headers' ]) : {}),
|
||||
},
|
||||
{
|
||||
resource: resource.path,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import clamp from 'lodash/clamp';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { throttle, clamp } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
const ScrollDirectionContext = React.createContext<'up' | 'down' | null>(null);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import type { LegacyRef } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
@@ -19,7 +19,7 @@ export default function useClientRect<E extends Element>(): [ DOMRect | null, Le
|
||||
return;
|
||||
}
|
||||
|
||||
const resizeHandler = _debounce(() => {
|
||||
const resizeHandler = debounce(() => {
|
||||
setRect(nodeRef.current?.getBoundingClientRect() ?? null);
|
||||
}, 100);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import throttle from 'lodash/throttle';
|
||||
import { throttle } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
export default function useIsSticky(ref: React.RefObject<HTMLDivElement>, offset = 0, isEnabled = true) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _clamp from 'lodash/clamp';
|
||||
import { clamp } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function useLazyRenderedList(list: Array<unknown>, isEnabled: boo
|
||||
|
||||
React.useEffect(() => {
|
||||
if (inView) {
|
||||
setRenderedItemsNum((prev) => _clamp(prev + STEP, 0, list.length));
|
||||
setRenderedItemsNum((prev) => clamp(prev + STEP, 0, list.length));
|
||||
}
|
||||
}, [ inView, list.length ]);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
|
||||
export default function getTabName(tab: string) {
|
||||
return tab !== '' ? _capitalize(tab.replaceAll('_', ' ')) : 'Default';
|
||||
return tab !== '' ? capitalize(tab.replaceAll('_', ' ')) : 'Default';
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import type { Config } from 'mixpanel-browser';
|
||||
import mixpanel from 'mixpanel-browser';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -40,12 +40,12 @@ export default function useMixpanelInit() {
|
||||
'Viewport width': window.innerWidth,
|
||||
'Viewport height': window.innerHeight,
|
||||
Language: window.navigator.language,
|
||||
'Device type': _capitalize(deviceType),
|
||||
'Device type': capitalize(deviceType),
|
||||
'User id': userId,
|
||||
});
|
||||
mixpanel.identify(userId);
|
||||
userProfile.set({
|
||||
'Device Type': _capitalize(deviceType),
|
||||
'Device Type': capitalize(deviceType),
|
||||
...(isAuth ? { 'With Account': true } : {}),
|
||||
});
|
||||
userProfile.setOnce({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import _compose from 'lodash/fp/compose';
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
import { mapValues } from 'es-toolkit';
|
||||
|
||||
import type { NetworkExplorer } from 'types/networks';
|
||||
|
||||
@@ -32,7 +31,7 @@ const networkExplorers: Array<NetworkExplorer> = (() => {
|
||||
return config.UI.explorers.items.map((explorer) => ({
|
||||
...explorer,
|
||||
baseUrl: stripTrailingSlash(explorer.baseUrl),
|
||||
paths: _mapValues(explorer.paths, _compose(stripTrailingSlash, addLeadingSlash)),
|
||||
paths: mapValues(explorer.paths, (value) => value ? stripTrailingSlash(addLeadingSlash(value)) : value),
|
||||
}));
|
||||
})();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _uniq from 'lodash/uniq';
|
||||
import { uniq } from 'es-toolkit';
|
||||
|
||||
import isBrowser from './isBrowser';
|
||||
|
||||
@@ -27,7 +27,7 @@ export function saveToRecentKeywords(value: string) {
|
||||
}
|
||||
|
||||
const keywordsArr = getRecentSearchKeywords();
|
||||
const result = _uniq([ value, ...keywordsArr ]).slice(0, MAX_KEYWORDS_NUMBER - 1);
|
||||
const result = uniq([ value, ...keywordsArr ]).slice(0, MAX_KEYWORDS_NUMBER - 1);
|
||||
window.localStorage.setItem(RECENT_KEYWORDS_LS_KEY, JSON.stringify(result));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _upperFirst from 'lodash/upperFirst';
|
||||
import { upperFirst } from 'es-toolkit';
|
||||
|
||||
import type { Metadata, MetadataAttributes } from 'types/client/token';
|
||||
|
||||
@@ -72,7 +72,7 @@ export default function attributesParser(attributes: Array<unknown>): Metadata['
|
||||
|
||||
return {
|
||||
...formatValue(value, display, trait),
|
||||
trait_type: _upperFirst(trait || 'property'),
|
||||
trait_type: upperFirst(trait || 'property'),
|
||||
};
|
||||
})
|
||||
.filter((item) => item?.value)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _get from 'lodash/get';
|
||||
import { get } from 'es-toolkit/compat';
|
||||
import React from 'react';
|
||||
|
||||
import config from 'configs/app';
|
||||
@@ -25,7 +25,7 @@ export default function useAddOrSwitchChain() {
|
||||
|
||||
const errorObj = getErrorObj(error);
|
||||
const code = errorObj && 'code' in errorObj ? errorObj.code : undefined;
|
||||
const originalErrorCode = _get(errorObj, 'data.originalError.code');
|
||||
const originalErrorCode = get(errorObj, 'data.originalError.code');
|
||||
|
||||
// This error code indicates that the chain has not been added to Wallet.
|
||||
if (code === 4902 || originalErrorCode === 4902) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _padStart from 'lodash/padStart';
|
||||
import { padStart } from 'es-toolkit/compat';
|
||||
|
||||
import type { BlockEpoch, BlockEpochElectionRewardDetails, BlockEpochElectionRewardDetailsResponse } from 'types/api/block';
|
||||
|
||||
@@ -42,11 +42,11 @@ function getRewardDetailsItem(index: number): BlockEpochElectionRewardDetails {
|
||||
amount: `${ 100 - index }210001063118670575`,
|
||||
account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x30D060F129817c4DE5fBc1366d53e19f43c8c6${ _padStart(String(index), 2, '0') }`,
|
||||
hash: `0x30D060F129817c4DE5fBc1366d53e19f43c8c6${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
associated_account: {
|
||||
...addressMock.withoutName,
|
||||
hash: `0x456f41406B32c45D59E539e4BBA3D7898c3584${ _padStart(String(index), 2, '0') }`,
|
||||
hash: `0x456f41406B32c45D59E539e4BBA3D7898c3584${ padStart(String(index), 2, '0') }`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
import { mapValues } from 'es-toolkit';
|
||||
|
||||
import type { HomeStats } from 'types/api/stats';
|
||||
|
||||
@@ -51,17 +51,17 @@ export const withBtcLocked: HomeStats = {
|
||||
|
||||
export const withoutFiatPrices: HomeStats = {
|
||||
...base,
|
||||
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, fiat_price: null }) : null),
|
||||
gas_prices: base.gas_prices ? mapValues(base.gas_prices, (price) => price ? ({ ...price, fiat_price: null }) : null) : null,
|
||||
};
|
||||
|
||||
export const withoutGweiPrices: HomeStats = {
|
||||
...base,
|
||||
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null }) : null),
|
||||
gas_prices: base.gas_prices ? mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null }) : null) : null,
|
||||
};
|
||||
|
||||
export const withoutBothPrices: HomeStats = {
|
||||
...base,
|
||||
gas_prices: _mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null, fiat_price: null }) : null),
|
||||
gas_prices: base.gas_prices ? mapValues(base.gas_prices, (price) => price ? ({ ...price, price: null, fiat_price: null }) : null) : null,
|
||||
};
|
||||
|
||||
export const withoutGasInfo: HomeStats = {
|
||||
|
||||
+2
-12
@@ -1,4 +1,5 @@
|
||||
import type CspDev from 'csp-dev';
|
||||
import { uniq } from 'es-toolkit';
|
||||
|
||||
export const KEY_WORDS = {
|
||||
BLOB: 'blob:',
|
||||
@@ -11,17 +12,6 @@ export const KEY_WORDS = {
|
||||
UNSAFE_EVAL: '\'unsafe-eval\'',
|
||||
};
|
||||
|
||||
// we cannot use lodash/uniq and lodash/mergeWith in middleware code since it calls new Set() and it'is causing an error in Next.js
|
||||
// "Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime"
|
||||
export function unique(array: Array<string | undefined>) {
|
||||
const set: Record<string, boolean> = {};
|
||||
for (const item of array) {
|
||||
item && (set[item] = true);
|
||||
}
|
||||
|
||||
return Object.keys(set);
|
||||
}
|
||||
|
||||
export function mergeDescriptors(...descriptors: Array<CspDev.DirectiveDescriptor>) {
|
||||
return descriptors.reduce((result, item) => {
|
||||
for (const _key in item) {
|
||||
@@ -50,7 +40,7 @@ export function makePolicyString(policyDescriptor: CspDev.DirectiveDescriptor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uniqueValues = unique(value);
|
||||
const uniqueValues = uniq(value);
|
||||
return [ key, uniqueValues.join(' ') ].join(' ');
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { pick } from 'es-toolkit';
|
||||
import type { IncomingMessage } from 'http';
|
||||
import _pick from 'lodash/pick';
|
||||
import type { NextApiRequest } from 'next';
|
||||
import type { NextApiRequestCookies } from 'next/dist/server/api-utils';
|
||||
import type { RequestInit, Response } from 'node-fetch';
|
||||
@@ -21,7 +21,7 @@ export default function fetchFactory(
|
||||
accept: _req.headers['accept'] || 'application/json',
|
||||
'content-type': _req.headers['content-type'] || 'application/json',
|
||||
cookie: apiToken ? `${ cookies.NAMES.API_TOKEN }=${ apiToken }` : '',
|
||||
..._pick(_req.headers, [
|
||||
...pick(_req.headers, [
|
||||
'x-csrf-token',
|
||||
'Authorization', // the old value, just in case
|
||||
'authorization', // Node.js automatically lowercases headers
|
||||
|
||||
+1
-1
@@ -80,6 +80,7 @@
|
||||
"dappscout-iframe": "0.2.5",
|
||||
"dayjs": "^1.11.5",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"es-toolkit": "1.31.0",
|
||||
"focus-visible": "^5.2.0",
|
||||
"framer-motion": "^6.5.1",
|
||||
"getit-sdk": "^1.0.4",
|
||||
@@ -88,7 +89,6 @@
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-ws": "^5.11.3",
|
||||
"js-cookie": "^3.0.1",
|
||||
"lodash": "^4.0.0",
|
||||
"magic-bytes.js": "1.8.0",
|
||||
"mixpanel-browser": "^2.47.0",
|
||||
"monaco-editor": "^0.34.1",
|
||||
|
||||
+2
-3
@@ -1,5 +1,4 @@
|
||||
import _pick from 'lodash/pick';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pick, pickBy } from 'es-toolkit';
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import fetchFactory from 'nextjs/utils/fetchProxy';
|
||||
@@ -18,7 +17,7 @@ const handler = async(nextReq: NextApiRequest, nextRes: NextApiResponse) => {
|
||||
);
|
||||
const apiRes = await fetchFactory(nextReq)(
|
||||
url.toString(),
|
||||
_pickBy(_pick(nextReq, [ 'body', 'method' ]), Boolean),
|
||||
pickBy(pick(nextReq, [ 'body', 'method' ]), Boolean),
|
||||
);
|
||||
|
||||
// proxy some headers from API
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { TestFixture, Page } from '@playwright/test';
|
||||
import _isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import { encodeFunctionData, encodeFunctionResult, type AbiFunction } from 'viem';
|
||||
|
||||
import { getEnvValue } from 'configs/app/utils';
|
||||
@@ -43,7 +43,7 @@ const fixture: TestFixture<MockContractReadResponseFixture, { page: Page }> = as
|
||||
value: params?.value,
|
||||
};
|
||||
|
||||
if (_isEqual(params, callParams) && id) {
|
||||
if (isEqual(params, callParams) && id) {
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
json: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { TestFixture, Page } from '@playwright/test';
|
||||
import _isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import type { PublicRpcSchema } from 'viem';
|
||||
|
||||
import { getEnvValue } from 'configs/app/utils';
|
||||
@@ -34,7 +34,7 @@ const fixture: TestFixture<MockRpcResponseFixture, { page: Page }> = async({ pag
|
||||
...(rpcMock.Parameters ? { params: rpcMock.Parameters } : {}),
|
||||
};
|
||||
|
||||
if (_isEqual(json, payload) && id !== undefined) {
|
||||
if (isEqual(json, payload) && id !== undefined) {
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
json: {
|
||||
|
||||
+5
-3
@@ -1,7 +1,6 @@
|
||||
import './fonts.css';
|
||||
import './index.css';
|
||||
import { beforeMount } from '@playwright/experimental-ct-react/hooks';
|
||||
import _defaultsDeep from 'lodash/defaultsDeep';
|
||||
import MockDate from 'mockdate';
|
||||
import * as router from 'next/router';
|
||||
|
||||
@@ -12,12 +11,15 @@ const NEXT_ROUTER_MOCK = {
|
||||
replace: () => Promise.resolve(),
|
||||
};
|
||||
|
||||
beforeMount(async({ hooksConfig }) => {
|
||||
beforeMount(async({ hooksConfig }: { hooksConfig?: { router: typeof router } }) => {
|
||||
// Before mount, redefine useRouter to return mock value from test.
|
||||
|
||||
// @ts-ignore: I really want to redefine this property :)
|
||||
// eslint-disable-next-line no-import-assign
|
||||
router.useRouter = () => _defaultsDeep(hooksConfig?.router, NEXT_ROUTER_MOCK);
|
||||
router.useRouter = () => ({
|
||||
...NEXT_ROUTER_MOCK,
|
||||
...hooksConfig?.router,
|
||||
});
|
||||
|
||||
// set current date
|
||||
MockDate.set('2022-11-11T12:00:00Z');
|
||||
|
||||
+50
-52
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 121 KiB |
@@ -1,4 +1,4 @@
|
||||
import noop from 'lodash/noop';
|
||||
import { noop } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import { test, expect } from 'playwright/lib';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Accordion, Box, Flex, Link } from '@chakra-ui/react';
|
||||
import _range from 'lodash/range';
|
||||
import { range } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { SmartContractMethod } from './types';
|
||||
@@ -39,7 +39,7 @@ const ContractAbi = ({ abi, addressHash, sourceAddress, tab, visibleItems }: Pro
|
||||
}
|
||||
|
||||
if (expandedSections.length < abi.length) {
|
||||
setExpandedSections(_range(0, abi.length));
|
||||
setExpandedSections(range(0, abi.length));
|
||||
} else {
|
||||
setExpandedSections([]);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _set from 'lodash/set';
|
||||
import { set } from 'es-toolkit/compat';
|
||||
|
||||
import type { ContractAbiItemInput } from '../types';
|
||||
|
||||
@@ -78,7 +78,7 @@ export function transformFormDataToMethodArgs(formData: ContractMethodFormFields
|
||||
|
||||
for (const field in formData) {
|
||||
const value = formData[field];
|
||||
_set(result, field.replaceAll(':', '.'), value);
|
||||
set(result, field.replaceAll(':', '.'), value);
|
||||
}
|
||||
|
||||
const filteredResult = filterOutEmptyItems(result);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pickBy } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
@@ -63,7 +63,7 @@ export default function useMethodsFilters({ abi }: Params) {
|
||||
return;
|
||||
}
|
||||
|
||||
const queryForPathname = _pickBy(router.query, (value, key) => router.pathname.includes(`[${ key }]`));
|
||||
const queryForPathname = pickBy(router.query, (value, key) => router.pathname.includes(`[${ key }]`));
|
||||
router.push(
|
||||
{ pathname: router.pathname, query: { ...queryForPathname, tab: nextTab } },
|
||||
undefined,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Image, Tooltip } from '@chakra-ui/react';
|
||||
import _capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { MultichainProviderConfigParsed } from 'types/client/multichainProviderConfig';
|
||||
@@ -25,10 +25,10 @@ const AddressMultichainButton = ({ item, addressHash, onClick, hasSingleProvider
|
||||
const buttonContent = hasSingleProvider ? (
|
||||
<>
|
||||
{ buttonIcon }
|
||||
{ _capitalize(item.name) }
|
||||
{ capitalize(item.name) }
|
||||
</>
|
||||
) : (
|
||||
<Tooltip label={ _capitalize(item.name) }>{ buttonIcon }</Tooltip>
|
||||
<Tooltip label={ capitalize(item.name) }>{ buttonIcon }</Tooltip>
|
||||
);
|
||||
|
||||
const linkProps = {
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
chakra,
|
||||
} from '@chakra-ui/react';
|
||||
import type { UseQueryResult } from '@tanstack/react-query';
|
||||
import _clamp from 'lodash/clamp';
|
||||
import { clamp } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type * as bens from '@blockscout/bens-types';
|
||||
@@ -37,7 +37,7 @@ interface Props {
|
||||
const DomainsGrid = ({ data }: { data: Array<bens.Domain> }) => {
|
||||
return (
|
||||
<Grid
|
||||
templateColumns={{ base: `repeat(${ _clamp(data.length, 1, 2) }, 1fr)`, lg: `repeat(${ _clamp(data.length, 1, 3) }, 1fr)` }}
|
||||
templateColumns={{ base: `repeat(${ clamp(data.length, 1, 2) }, 1fr)`, lg: `repeat(${ clamp(data.length, 1, 3) }, 1fr)` }}
|
||||
columnGap={ 8 }
|
||||
rowGap={ 4 }
|
||||
mt={ 2 }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Flex, IconButton, Tooltip } from '@chakra-ui/react';
|
||||
import { useQueryClient, useIsFetching } from '@tanstack/react-query';
|
||||
import _sumBy from 'lodash/sumBy';
|
||||
import { sumBy } from 'es-toolkit';
|
||||
import NextLink from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
@@ -50,7 +50,7 @@ const TokenSelect = ({ onClick }: Props) => {
|
||||
);
|
||||
}
|
||||
|
||||
const hasTokens = _sumBy(Object.values(data), ({ items }) => items.length) > 0;
|
||||
const hasTokens = sumBy(Object.values(data), ({ items }) => items.length) > 0;
|
||||
if (isError || !hasTokens) {
|
||||
return <Box py="6px">0</Box>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Text, Box, Input, InputGroup, InputLeftElement, useColorModeValue, Flex, Link } from '@chakra-ui/react';
|
||||
import _sumBy from 'lodash/sumBy';
|
||||
import { sumBy } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
@@ -26,7 +26,7 @@ interface Props {
|
||||
const TokenSelectMenu = ({ erc20sort, erc1155sort, erc404sort, filteredData, onInputChange, onSortClick, searchTerm }: Props) => {
|
||||
const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
|
||||
|
||||
const hasFilteredResult = _sumBy(Object.values(filteredData), ({ items }) => items.length) > 0;
|
||||
const hasFilteredResult = sumBy(Object.values(filteredData), ({ items }) => items.length) > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
import { mapValues } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function useTokenSelect(data: FormattedData) {
|
||||
}, []);
|
||||
|
||||
const filteredData = React.useMemo(() => {
|
||||
return _mapValues(data, ({ items, isOverflow }) => ({
|
||||
return mapValues(data, ({ items, isOverflow }) => ({
|
||||
isOverflow,
|
||||
items: items.filter(filterTokens(searchTerm.toLowerCase())),
|
||||
}));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import fpAdd from 'lodash/fp/add';
|
||||
|
||||
import type { AddressTokenBalance } from 'types/api/address';
|
||||
import type { TokenType } from 'types/api/token';
|
||||
@@ -100,7 +99,7 @@ export const getTokensTotalInfo = (data: TokenSelectData) => {
|
||||
|
||||
const num = Object.values(data)
|
||||
.map(({ items }) => items.length)
|
||||
.reduce(fpAdd, 0);
|
||||
.reduce((result, item) => result + item, 0);
|
||||
|
||||
const isOverflow = Object.values(data).some(({ isOverflow }) => isOverflow);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Select, Input, InputGroup, InputRightElement, VStack, IconButton } from '@chakra-ui/react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Input, Text } from '@chakra-ui/react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Input, Tag, Text } from '@chakra-ui/react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex, Checkbox, CheckboxGroup, Text, Spinner, Select } from '@chakra-ui/react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isEqual } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { AdvancedFilterParams } from 'types/api/advancedFilter';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Flex, Checkbox, CheckboxGroup, Spinner, chakra } from '@chakra-ui/react';
|
||||
import differenceBy from 'lodash/differenceBy';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isEqual, differenceBy } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Flex, Checkbox, CheckboxGroup } from '@chakra-ui/react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import without from 'lodash/without';
|
||||
import { isEqual, without } from 'es-toolkit';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import castArray from 'lodash/castArray';
|
||||
import { castArray } from 'es-toolkit/compat';
|
||||
|
||||
import type { AdvancedFilterAge, AdvancedFilterParams } from 'types/api/advancedFilter';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Grid, GridItem, Text, Link, Box, Tooltip } from '@chakra-ui/react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
import { scroller, Element } from 'react-scroll';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _padStart from 'lodash/padStart';
|
||||
import { padStart } from 'es-toolkit/compat';
|
||||
|
||||
export default function splitSecondsInPeriods(value: number) {
|
||||
const seconds = value % 60;
|
||||
@@ -7,9 +7,9 @@ export default function splitSecondsInPeriods(value: number) {
|
||||
const days = (value - seconds - minutes * 60 - hours * 60 * 60) / (60 * 60 * 24);
|
||||
|
||||
return {
|
||||
seconds: _padStart(String(seconds), 2, '0'),
|
||||
minutes: _padStart(String(minutes), 2, '0'),
|
||||
hours: _padStart(String(hours), 2, '0'),
|
||||
days: _padStart(String(days), 2, '0'),
|
||||
seconds: padStart(String(seconds), 2, '0'),
|
||||
minutes: padStart(String(minutes), 2, '0'),
|
||||
hours: padStart(String(hours), 2, '0'),
|
||||
days: padStart(String(days), 2, '0'),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Flex, Text, Box, Tooltip } from '@chakra-ui/react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { Block } from 'types/api/block';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Table, Tbody, Tr, Th } from '@chakra-ui/react';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import React from 'react';
|
||||
|
||||
import type { Block } from 'types/api/block';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _get from 'lodash/get';
|
||||
import { get } from 'es-toolkit/compat';
|
||||
import React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
@@ -43,7 +43,7 @@ const ContractVerificationFieldGitHubRepo = ({ onCommitHashChange }: Props) => {
|
||||
const response = await fetch(`https://api.github.com/repos/${ gitHubData.owner }/${ gitHubData.repo }/commits?per_page=1`);
|
||||
repoErrorRef.current = undefined;
|
||||
trigger('repository_url');
|
||||
onCommitHashChange(_get(response, '[0].sha'));
|
||||
onCommitHashChange(get(response, '[0].sha'));
|
||||
return;
|
||||
} catch (error) {
|
||||
repoErrorRef.current = 'GitHub repository not found';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import type { UseFormReturn } from 'react-hook-form';
|
||||
|
||||
@@ -40,7 +40,7 @@ const CsvExportFormField = ({ formApi, name }: Props) => {
|
||||
name={ name }
|
||||
type="date"
|
||||
max={ dayjs().format('YYYY-MM-DD') }
|
||||
placeholder={ _capitalize(name) }
|
||||
placeholder={ capitalize(name) }
|
||||
isRequired
|
||||
rules={{ validate }}
|
||||
size={{ base: 'md', lg: 'lg' }}
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
HStack,
|
||||
Link,
|
||||
} from '@chakra-ui/react';
|
||||
import omit from 'lodash/omit';
|
||||
import { omit } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { chakra } from '@chakra-ui/react';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
import _inRange from 'lodash/inRange';
|
||||
import { inRange } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
@@ -43,7 +43,7 @@ const UserOp = () => {
|
||||
if (!userOpQuery.data) {
|
||||
return true;
|
||||
} else {
|
||||
if (_inRange(
|
||||
if (inRange(
|
||||
Number(tt.log_index),
|
||||
userOpQuery.data?.user_logs_start_index,
|
||||
userOpQuery.data?.user_logs_start_index + userOpQuery.data?.user_logs_count,
|
||||
@@ -58,7 +58,7 @@ const UserOp = () => {
|
||||
if (!userOpQuery.data) {
|
||||
return true;
|
||||
} else {
|
||||
if (_inRange(log.index, userOpQuery.data?.user_logs_start_index, userOpQuery.data?.user_logs_start_index + userOpQuery.data?.user_logs_count)) {
|
||||
if (inRange(log.index, userOpQuery.data?.user_logs_start_index, userOpQuery.data?.user_logs_start_index + userOpQuery.data?.user_logs_count)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Alert, Box, Button, Flex, Grid, GridItem } from '@chakra-ui/react';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pickBy } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { FormSubmitResult } from './types';
|
||||
@@ -26,7 +26,7 @@ const PublicTagsSubmitResult = ({ data }: Props) => {
|
||||
|
||||
const hasErrors = groupedData.items.some((item) => item.error !== null);
|
||||
const companyWebsite = makePrettyLink(groupedData.companyWebsite);
|
||||
const startOverButtonQuery = hasErrors ? _pickBy({
|
||||
const startOverButtonQuery = hasErrors ? pickBy({
|
||||
requesterName: groupedData.requesterName,
|
||||
requesterEmail: groupedData.requesterEmail,
|
||||
companyName: groupedData.companyName,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { chakra, Flex } from '@chakra-ui/react';
|
||||
import type { GroupBase, SelectComponentsConfig, SingleValueProps } from 'chakra-react-select';
|
||||
import { chakraComponents } from 'chakra-react-select';
|
||||
import _capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
@@ -22,7 +22,7 @@ const PublicTagsSubmitFieldTagType = ({ index, tagTypes }: Props) => {
|
||||
|
||||
const typeOptions = React.useMemo(() => tagTypes?.map((type) => ({
|
||||
value: type.type,
|
||||
label: _capitalize(type.type),
|
||||
label: capitalize(type.type),
|
||||
})) ?? [], [ tagTypes ]);
|
||||
|
||||
const fieldValue = watch(`tags.${ index }.type`).value;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Box, Button, Flex, Grid, GridItem, useColorModeValue } from '@chakra-ui/react';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pickBy } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { FormSubmitResultGrouped } from '../types';
|
||||
@@ -23,7 +23,7 @@ const PublicTagsSubmitResultWithErrors = ({ data }: Props) => {
|
||||
<Flex flexDir="column" rowGap={ 3 }>
|
||||
{ data.items.map((item, index) => {
|
||||
|
||||
const startOverButtonQuery = _pickBy({
|
||||
const startOverButtonQuery = pickBy({
|
||||
addresses: item.addresses,
|
||||
requesterName: data.requesterName,
|
||||
requesterEmail: data.requesterEmail,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import _isEqual from 'lodash/isEqual';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pickBy, isEqual } from 'es-toolkit';
|
||||
|
||||
import type { FormFieldTag, FormFields, FormSubmitResult, FormSubmitResultGrouped, FormSubmitResultItemGrouped, SubmitRequestBody } from './types';
|
||||
import type { UserInfo } from 'types/api/account';
|
||||
@@ -22,7 +21,7 @@ export function convertFormDataToRequestsBody(data: FormFields): Array<SubmitReq
|
||||
name: tag.name,
|
||||
tagType: tag.type.value,
|
||||
description: data.description,
|
||||
meta: _pickBy({
|
||||
meta: pickBy({
|
||||
bgColor: tag.bgColor,
|
||||
textColor: tag.textColor,
|
||||
tagUrl: tag.url,
|
||||
@@ -72,7 +71,7 @@ export function groupSubmitResult(data: FormSubmitResult | undefined): FormSubmi
|
||||
|
||||
// merge items with the same error and tags
|
||||
for (const item of _items) {
|
||||
const existingItem = items.find(({ error, tags }) => error === item.error && _isEqual(tags, item.tags));
|
||||
const existingItem = items.find(({ error, tags }) => error === item.error && isEqual(tags, item.tags));
|
||||
if (existingItem) {
|
||||
existingItem.addresses.push(...item.addresses);
|
||||
continue;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { PopoverTrigger, PopoverContent, PopoverBody, useDisclosure } from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import type { FormEvent, FocusEvent } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
@@ -59,7 +59,7 @@ const SearchResultsInput = ({ searchTerm, handleSubmit, handleSearchTermChange }
|
||||
}
|
||||
calculateMenuWidth();
|
||||
|
||||
const resizeHandler = _debounce(calculateMenuWidth, 200);
|
||||
const resizeHandler = debounce(calculateMenuWidth, 200);
|
||||
const resizeObserver = new ResizeObserver(resizeHandler);
|
||||
resizeObserver.observe(inputRef.current);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Box, useColorModeValue } from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||||
|
||||
const CUT_HEIGHT = 144;
|
||||
@@ -25,7 +25,7 @@ const AccountPageDescription = ({ children, allowCut = true }: { children: React
|
||||
}
|
||||
|
||||
calculateCut();
|
||||
const resizeHandler = _debounce(calculateCut, 300);
|
||||
const resizeHandler = debounce(calculateCut, 300);
|
||||
window.addEventListener('resize', resizeHandler);
|
||||
return function cleanup() {
|
||||
window.removeEventListener('resize', resizeHandler);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
import type { As } from '@chakra-ui/react';
|
||||
import { Tooltip, chakra } from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import type { FontFace } from 'use-font-face-observer';
|
||||
import useFontFaceObserver from 'use-font-face-observer';
|
||||
@@ -81,7 +81,7 @@ const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled,
|
||||
}, [ calculateString, isFontFaceLoaded ]);
|
||||
|
||||
useEffect(() => {
|
||||
const resizeHandler = _debounce(calculateString, 100);
|
||||
const resizeHandler = debounce(calculateString, 100);
|
||||
const resizeObserver = new ResizeObserver(resizeHandler);
|
||||
|
||||
resizeObserver.observe(document.body);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Heading, Flex, Tooltip, Link, chakra, useDisclosure } from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
@@ -94,7 +94,7 @@ const PageTitle = ({ title, contentAfter, withTextAd, backLink, className, isLoa
|
||||
}, [ isLoading, updatedTruncateState ]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleResize = _debounce(updatedTruncateState, 1000);
|
||||
const handleResize = debounce(updatedTruncateState, 1000);
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
return function cleanup() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ChakraProps, ThemingProps } from '@chakra-ui/react';
|
||||
import { chakra } from '@chakra-ui/react';
|
||||
import _pickBy from 'lodash/pickBy';
|
||||
import { pickBy } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
@@ -42,7 +42,7 @@ const RoutedTabs = ({
|
||||
const handleTabChange = React.useCallback((index: number) => {
|
||||
const nextTab = tabs[index];
|
||||
|
||||
const queryForPathname = _pickBy(router.query, (value, key) => router.pathname.includes(`[${ key }]`));
|
||||
const queryForPathname = pickBy(router.query, (value, key) => router.pathname.includes(`[${ key }]`));
|
||||
const tabId = Array.isArray(nextTab.id) ? nextTab.id[0] : nextTab.id;
|
||||
router.push(
|
||||
{ pathname: router.pathname, query: { ...queryForPathname, tab: tabId } },
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
TabPanels,
|
||||
chakra,
|
||||
} from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import type { TabItem } from './types';
|
||||
@@ -69,7 +69,7 @@ const TabsWithScroll = ({
|
||||
}, [ defaultTabIndex ]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const resizeHandler = _debounce(() => {
|
||||
const resizeHandler = debounce(() => {
|
||||
setScreenWidth(window.innerWidth);
|
||||
}, 100);
|
||||
const resizeObserver = new ResizeObserver(resizeHandler);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Thead, useColorModeValue } from '@chakra-ui/react';
|
||||
import type { TableHeadProps, PositionProps } from '@chakra-ui/react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { throttle } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
interface Props extends TableHeadProps {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { PlacementWithLogical } from '@chakra-ui/react';
|
||||
import { Tooltip, useDisclosure } from '@chakra-ui/react';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import useFontFaceObserver from 'use-font-face-observer';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Box, Flex, chakra, useColorModeValue } from '@chakra-ui/react';
|
||||
import clamp from 'lodash/clamp';
|
||||
import { clamp } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import Skeleton from 'ui/shared/chakra/Skeleton';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as d3 from 'd3';
|
||||
import _clamp from 'lodash/clamp';
|
||||
import { clamp } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import { POINT_SIZE } from './utils';
|
||||
@@ -69,33 +69,33 @@ function calculatePosition({ pointX, pointY, canvasWidth, canvasHeight, nodeWidt
|
||||
// right
|
||||
if (pointX + offset + nodeWidth <= canvasWidth) {
|
||||
const x = pointX + offset;
|
||||
const y = _clamp(pointY - nodeHeight / 2, 0, canvasHeight - nodeHeight);
|
||||
const y = clamp(pointY - nodeHeight / 2, 0, canvasHeight - nodeHeight);
|
||||
return [ x, y ];
|
||||
}
|
||||
|
||||
// left
|
||||
if (nodeWidth + offset <= pointX) {
|
||||
const x = pointX - offset - nodeWidth;
|
||||
const y = _clamp(pointY - nodeHeight / 2, 0, canvasHeight - nodeHeight);
|
||||
const y = clamp(pointY - nodeHeight / 2, 0, canvasHeight - nodeHeight);
|
||||
return [ x, y ];
|
||||
}
|
||||
|
||||
// top
|
||||
if (nodeHeight + offset <= pointY) {
|
||||
const x = _clamp(pointX - nodeWidth / 2, 0, canvasWidth - nodeWidth);
|
||||
const x = clamp(pointX - nodeWidth / 2, 0, canvasWidth - nodeWidth);
|
||||
const y = pointY - offset - nodeHeight;
|
||||
return [ x, y ];
|
||||
}
|
||||
|
||||
// bottom
|
||||
if (pointY + offset + nodeHeight <= canvasHeight) {
|
||||
const x = _clamp(pointX - nodeWidth / 2, 0, canvasWidth - nodeWidth);
|
||||
const x = clamp(pointX - nodeWidth / 2, 0, canvasWidth - nodeWidth);
|
||||
const y = pointY + offset;
|
||||
return [ x, y ];
|
||||
}
|
||||
|
||||
const x = _clamp(pointX / 2, 0, canvasWidth - nodeWidth);
|
||||
const y = _clamp(pointY / 2, 0, canvasHeight - nodeHeight);
|
||||
const x = clamp(pointX / 2, 0, canvasWidth - nodeWidth);
|
||||
const y = clamp(pointY / 2, 0, canvasHeight - nodeHeight);
|
||||
|
||||
return [ x, y ];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import _range from 'lodash/range';
|
||||
import { range } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
export default function useChartLegend(dataLength: number) {
|
||||
const [ selectedLines, setSelectedLines ] = React.useState<Array<number>>(_range(dataLength));
|
||||
const [ selectedLines, setSelectedLines ] = React.useState<Array<number>>(range(dataLength));
|
||||
|
||||
const handleLegendItemClick = React.useCallback((index: number) => {
|
||||
const nextSelectedLines = selectedLines.includes(index) ? selectedLines.filter((item) => item !== index) : [ ...selectedLines, index ];
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import * as d3 from 'd3';
|
||||
import _maxBy from 'lodash/maxBy';
|
||||
import _unique from 'lodash/uniq';
|
||||
import { maxBy, uniq } from 'es-toolkit';
|
||||
|
||||
import type { AxesConfig, AxisConfig, TimeChartData } from '../types';
|
||||
|
||||
@@ -88,8 +87,8 @@ function getYLabelFormatParams(ticks: Array<number>, maximumSignificantDigits =
|
||||
notation: 'compact' as const,
|
||||
};
|
||||
|
||||
const uniqTicksStr = _unique(ticks.map((tick) => tick.toLocaleString(undefined, params)));
|
||||
const maxLabelLength = _maxBy(uniqTicksStr, (items) => items.length)?.length ?? DEFAULT_LABEL_LENGTH;
|
||||
const uniqTicksStr = uniq(ticks.map((tick) => tick.toLocaleString(undefined, params)));
|
||||
const maxLabelLength = maxBy(uniqTicksStr, (items) => items.length)?.length ?? DEFAULT_LABEL_LENGTH;
|
||||
|
||||
if (uniqTicksStr.length === ticks.length || maximumSignificantDigits === MAXIMUM_SIGNIFICANT_DIGITS_LIMIT) {
|
||||
return { ...params, maxLabelLength };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _noop from 'lodash/noop';
|
||||
import { noop } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import { test, expect } from 'playwright/lib';
|
||||
@@ -18,7 +18,7 @@ const defaultProps = {
|
||||
isRequired: true,
|
||||
placeholder: 'Compiler',
|
||||
name: 'compiler',
|
||||
onChange: _noop,
|
||||
onChange: noop,
|
||||
};
|
||||
|
||||
[ 'md' as const, 'lg' as const ].forEach((size) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { HTMLChakraProps } from '@chakra-ui/react';
|
||||
import { Box, Tab, TabList, TabPanel, TabPanels, Tabs, useBoolean } from '@chakra-ui/react';
|
||||
import _throttle from 'lodash/throttle';
|
||||
import { throttle } from 'es-toolkit';
|
||||
import type * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import React from 'react';
|
||||
|
||||
@@ -47,7 +47,7 @@ const CodeEditorSideBar = ({ onFileSelect, data, monaco, editor, selectedFile, m
|
||||
letterSpacing: 0.3,
|
||||
};
|
||||
|
||||
const handleScrollThrottled = React.useRef(_throttle((event: React.SyntheticEvent) => {
|
||||
const handleScrollThrottled = React.useRef(throttle((event: React.SyntheticEvent) => {
|
||||
setIsStuck((event.target as HTMLDivElement).scrollTop > 0);
|
||||
}, 100));
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { UseQueryResult } from '@tanstack/react-query';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import omit from 'lodash/omit';
|
||||
import { omit } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useCallback } from 'react';
|
||||
import { animateScroll } from 'react-scroll';
|
||||
@@ -154,7 +154,14 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
|
||||
}, [ queryClient, resourceName, router, scrollToTop ]);
|
||||
|
||||
const onFilterChange = useCallback(<R extends PaginatedResources = Resource>(newFilters: PaginationFilters<R> | undefined) => {
|
||||
const newQuery = omit<typeof router.query>(router.query, 'next_page_params', 'page', 'filterFields' in resource ? resource.filterFields : []);
|
||||
const newQuery: typeof router.query = omit(
|
||||
router.query,
|
||||
[
|
||||
'next_page_params',
|
||||
'page',
|
||||
...('filterFields' in resource ? resource.filterFields : []),
|
||||
],
|
||||
);
|
||||
if (newFilters) {
|
||||
Object.entries(newFilters).forEach(([ key, value ]) => {
|
||||
const isValidValue = typeof value === 'boolean' || (value && value.length);
|
||||
@@ -179,8 +186,8 @@ export default function useQueryWithPages<Resource extends PaginatedResources>({
|
||||
}, [ router, resource, scrollToTop ]);
|
||||
|
||||
const onSortingChange = useCallback((newSorting: PaginationSorting<Resource> | undefined) => {
|
||||
const newQuery = {
|
||||
...omit<typeof router.query>(router.query, 'next_page_params', 'page', SORTING_FIELDS),
|
||||
const newQuery: typeof router.query = {
|
||||
...omit(router.query, [ 'next_page_params', 'page', ...SORTING_FIELDS ]),
|
||||
...newSorting,
|
||||
};
|
||||
scrollToTop();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _noop from 'lodash/noop';
|
||||
import { noop } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import { test, expect } from 'playwright/lib';
|
||||
@@ -12,7 +12,7 @@ test('base view +@dark-mode', async({ render }) => {
|
||||
<TagGroupSelect
|
||||
items={ [ { id: '1', title: 'Option 1' }, { id: '2', title: 'Option 2' }, { id: 'duck', title: 'Cute little duck' } ] }
|
||||
value="duck"
|
||||
onChange={ _noop }
|
||||
onChange={ noop }
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Box, Select, VStack, Flex } from '@chakra-ui/react';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import { capitalize } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { NetworkGroup, FeaturedNetwork } from 'types/networks';
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
useDisclosure,
|
||||
useOutsideClick,
|
||||
} from '@chakra-ui/react';
|
||||
import _debounce from 'lodash/debounce';
|
||||
import { debounce } from 'es-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { FormEvent } from 'react';
|
||||
import React from 'react';
|
||||
@@ -115,7 +115,7 @@ const SearchBar = ({ isHomepage }: Props) => {
|
||||
}
|
||||
calculateMenuWidth();
|
||||
|
||||
const resizeHandler = _debounce(calculateMenuWidth, 200);
|
||||
const resizeHandler = debounce(calculateMenuWidth, 200);
|
||||
const resizeObserver = new ResizeObserver(resizeHandler);
|
||||
resizeObserver.observe(inputRef.current);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { InputGroup, Input, InputLeftElement, chakra, useColorModeValue, forwardRef, InputRightElement, Center } from '@chakra-ui/react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { throttle } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import type { ChangeEvent, FormEvent, FocusEvent } from 'react';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Box, Tab, TabList, Tabs, Text, useColorModeValue } from '@chakra-ui/react';
|
||||
import type { UseQueryResult } from '@tanstack/react-query';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { throttle } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
import { scroller, Element } from 'react-scroll';
|
||||
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 48 KiB |
@@ -1,11 +1,11 @@
|
||||
import _upperFirst from 'lodash/upperFirst';
|
||||
import { upperFirst } from 'es-toolkit';
|
||||
|
||||
export function formatName(_name: string) {
|
||||
const name = _name
|
||||
.replaceAll('_', ' ')
|
||||
.replaceAll(/\burl|nft|id\b/gi, (str) => str.toUpperCase());
|
||||
|
||||
return _upperFirst(name.trim());
|
||||
return upperFirst(name.trim());
|
||||
}
|
||||
|
||||
const PINNED_FIELDS = [ 'name', 'description' ];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Table, Tbody, Tr, Th, Box, Text, Show, Hide } from '@chakra-ui/react';
|
||||
import _chunk from 'lodash/chunk';
|
||||
import { chunk } from 'es-toolkit';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
|
||||
import type { PaginationParams } from 'ui/shared/pagination/types';
|
||||
@@ -34,7 +34,7 @@ export default function TxAssetFlows(props: FlowViewProps) {
|
||||
const [ page, setPage ] = useState<number>(1);
|
||||
|
||||
const ViewData = useMemo(() => (queryData ? generateFlowViewData(queryData) : []), [ queryData ]);
|
||||
const chunkedViewData = _chunk(ViewData, 50);
|
||||
const chunkedViewData = chunk(ViewData, 50);
|
||||
|
||||
const paginationProps: PaginationParams = useMemo(() => ({
|
||||
onNextPageClick: () => setPage(page + 1),
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import _findIndex from 'lodash/findIndex';
|
||||
|
||||
import type { NovesNft, NovesResponseData, NovesSentReceived, NovesToken } from 'types/api/noves';
|
||||
|
||||
export interface NovesAction {
|
||||
@@ -27,7 +25,7 @@ export function generateFlowViewData(data: NovesResponseData): Array<NovesFlowVi
|
||||
|
||||
const txItems = [ ...sent, ...received ];
|
||||
|
||||
const paidGasIndex = _findIndex(txItems, (item) => item.action === 'paidGas');
|
||||
const paidGasIndex = txItems.findIndex((item) => item.action === 'paidGas');
|
||||
if (paidGasIndex >= 0) {
|
||||
const element = txItems.splice(paidGasIndex, 1)[0];
|
||||
element.to.name = 'Validators';
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import _groupBy from 'lodash/groupBy';
|
||||
import _keysIn from 'lodash/keysIn';
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
import { groupBy, mapValues } from 'es-toolkit';
|
||||
|
||||
import type { NovesResponseData } from 'types/api/noves';
|
||||
import type { TokenInfo } from 'types/api/token';
|
||||
@@ -49,28 +47,28 @@ export function getTokensData(data: NovesResponseData): TokensData {
|
||||
});
|
||||
|
||||
// Group tokens by property into arrays
|
||||
const tokensGroupByname = _groupBy(tokens, 'name');
|
||||
const tokensGroupBySymbol = _groupBy(tokens, 'symbol');
|
||||
const tokensGroupById = _groupBy(tokens, 'id');
|
||||
const tokensGroupByName = groupBy(tokens, (item) => item.name || 'null');
|
||||
const tokensGroupBySymbol = groupBy(tokens, (item) => item.symbol || 'null');
|
||||
const tokensGroupById = groupBy(tokens, (item) => item.id || 'null');
|
||||
|
||||
// Map properties to an object and remove duplicates
|
||||
const mappedNames = _mapValues(tokensGroupByname, (i) => {
|
||||
const mappedNames = mapValues(tokensGroupByName, (i) => {
|
||||
return i[0];
|
||||
});
|
||||
|
||||
const mappedSymbols = _mapValues(tokensGroupBySymbol, (i) => {
|
||||
const mappedSymbols = mapValues(tokensGroupBySymbol, (i) => {
|
||||
return i[0];
|
||||
});
|
||||
|
||||
const mappedIds = _mapValues(tokensGroupById, (i) => {
|
||||
const mappedIds = mapValues(tokensGroupById, (i) => {
|
||||
return i[0];
|
||||
});
|
||||
|
||||
const filters = [ 'undefined', 'null' ];
|
||||
// Array of keys to match in string
|
||||
const nameList = _keysIn(mappedNames).filter(i => !filters.includes(i));
|
||||
const symbolList = _keysIn(mappedSymbols).filter(i => !filters.includes(i));
|
||||
const idList = _keysIn(mappedIds).filter(i => !filters.includes(i));
|
||||
const nameList = Object.keys(mappedNames).filter(i => !filters.includes(i));
|
||||
const symbolList = Object.keys(mappedSymbols).filter(i => !filters.includes(i));
|
||||
const idList = Object.keys(mappedIds).filter(i => !filters.includes(i));
|
||||
|
||||
return {
|
||||
nameList,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import _chunk from 'lodash/chunk';
|
||||
import _uniq from 'lodash/uniq';
|
||||
import { uniq, chunk } from 'es-toolkit';
|
||||
import React from 'react';
|
||||
|
||||
import type { NovesDescribeTxsResponse } from 'types/api/noves';
|
||||
@@ -16,8 +15,8 @@ const translateEnabled = feature.isEnabled && feature.provider === 'noves';
|
||||
export default function useDescribeTxs(items: Array<Transaction> | undefined, viewAsAccountAddress: string | undefined, isPlaceholderData: boolean) {
|
||||
const apiFetch = useApiFetch();
|
||||
|
||||
const txsHash = _uniq(items?.map(i => i.hash));
|
||||
const txChunks = _chunk(txsHash, 10);
|
||||
const txsHash = items ? uniq(items.map(i => i.hash)) : [];
|
||||
const txChunks = chunk(txsHash, 10);
|
||||
|
||||
const queryKey = {
|
||||
viewAsAccountAddress,
|
||||
|
||||
@@ -10376,6 +10376,11 @@ es-to-primitive@^1.2.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
[email protected]:
|
||||
version "1.31.0"
|
||||
resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.31.0.tgz#f4fc1382aea09cb239afa38f3c724a5658ff3163"
|
||||
integrity sha512-vwS0lv/tzjM2/t4aZZRAgN9I9TP0MSkWuvt6By+hEXfG/uLs8yg2S1/ayRXH/x3pinbLgVJYT+eppueg3cM6tg==
|
||||
|
||||
esbuild@^0.21.3:
|
||||
version "0.21.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d"
|
||||
@@ -13573,7 +13578,7 @@ lodash.throttle@^4.1.1:
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
|
||||
|
||||
lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.21:
|
||||
lodash@^4.15.0, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
Reference in New Issue
Block a user