From d3fd07186b8bf4212b20223b84b3099d93949221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20K=C5=82os?= <114915819+wklos-iohk@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:28:21 +0100 Subject: [PATCH 01/14] text(extension): maintenance 15 Feb 2024 (#893) * test(extension): remove wallet details logging * test(extension): fix assertion for selected pools text * test(extension): stabilise test for collateral --- .../src/assert/multidelegation/PortfolioBarAssert.ts | 2 +- .../src/assert/settings/CollateralDrawerAssert.ts | 1 + .../src/fixture/browserStorageInitializer.ts | 11 +++++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/e2e-tests/src/assert/multidelegation/PortfolioBarAssert.ts b/packages/e2e-tests/src/assert/multidelegation/PortfolioBarAssert.ts index dc1d08cb8..2c373409b 100644 --- a/packages/e2e-tests/src/assert/multidelegation/PortfolioBarAssert.ts +++ b/packages/e2e-tests/src/assert/multidelegation/PortfolioBarAssert.ts @@ -6,7 +6,7 @@ class PortfolioBarAssert { assertSeePortfolioBar = async (selectedPools: string) => { await PortfolioBar.container.waitForDisplayed(); await PortfolioBar.selectedPoolsCounter.waitForDisplayed(); - expect(await PortfolioBar.selectedPoolsCounter.getText()).to.equal( + expect(await PortfolioBar.selectedPoolsCounter.getText()).to.startWith( (await t('portfolioBar.selectedPools', 'staking')).replace('{{selectedPoolsCount}}', selectedPools) ); await PortfolioBar.maxPoolsCounter.waitForDisplayed(); diff --git a/packages/e2e-tests/src/assert/settings/CollateralDrawerAssert.ts b/packages/e2e-tests/src/assert/settings/CollateralDrawerAssert.ts index 7c06c8e14..e8e98f604 100644 --- a/packages/e2e-tests/src/assert/settings/CollateralDrawerAssert.ts +++ b/packages/e2e-tests/src/assert/settings/CollateralDrawerAssert.ts @@ -45,6 +45,7 @@ class CollateralDrawerAssert { } async assertSeeCollateralNotEnoughAdaDrawer() { + await CollateralDrawer.collateralButton.waitForClickable(); await CollateralDrawer.passwordInputContainer.waitForClickable({ reverse: true }); diff --git a/packages/e2e-tests/src/fixture/browserStorageInitializer.ts b/packages/e2e-tests/src/fixture/browserStorageInitializer.ts index 628e7b514..b70c5c4a2 100644 --- a/packages/e2e-tests/src/fixture/browserStorageInitializer.ts +++ b/packages/e2e-tests/src/fixture/browserStorageInitializer.ts @@ -2,6 +2,7 @@ import { WalletConfig } from '../support/walletConfiguration'; import { setBackgroundStorage, setMigrationState } from '../utils/browserStorage'; import { Logger } from '../support/logger'; import { switchToWindowWithLace } from '../utils/window'; +import { browser } from '@wdio/globals'; export const initializeBrowserStorage = async (wallet: WalletConfig): Promise => { try { @@ -36,9 +37,9 @@ export const getNumWalletsInRepository = async (): Promise => `); export const clearWalletRepository = async (): Promise => { - Logger.log('Removing wallets'); - await switchToWindowWithLace(0); - const removedWallets = await browser.execute(` + try { + await switchToWindowWithLace(0); + await browser.execute(` return (async () => { await window.walletManager.deactivate(); const wallets = await window.firstValueFrom(window.walletRepository.wallets$); @@ -48,5 +49,7 @@ export const clearWalletRepository = async (): Promise => { return JSON.stringify(wallets); })() `); - Logger.log(`Removed wallets: ${removedWallets}`); + } catch (error) { + Logger.log(`Failed to clear wallet repository: ${error}`); + } }; From 2d7b410f9c9bbf917f6304fa9d2d879296affc4e Mon Sep 17 00:00:00 2001 From: Renan Valentin Date: Mon, 19 Feb 2024 09:21:53 -0300 Subject: [PATCH 02/14] feat(extension): LW-9669 show collateral on dapp dialogue (#864) * feat(extension): add utility function to calculate the tx collateral * feat(core): add collateral component * feat(core,cardano): show collateral on dapp dialogue * refactor(extension): extract tx collateral computation to a hook * refactor(extension): use the SDK get collateral implementation * feat(ui): add tooltip property to amount tx summary * refactor(core): use ui toolkit amount component * refactor(core): remove eslint comment * refactor(extension): remove max-statements comment * refactor(extension): add return type annotation * refactor(extension): cache tx to avoid creating new object references * refactor(core): remove magic numbers comment * refactor(core): extract amount transformer * fix(core): add test id for tx fee * refactor(extension): use wallet state * fix(ui): use relative imports * refactor(core,ui): add back tx fee test id * refactor(core): add test id to transaction details --- .../dapp/components/ConfirmTransaction.tsx | 23 ++-- .../src/hooks/useComputeTxCollateral.ts | 32 +++++ .../src/lib/translations/en.json | 4 +- packages/cardano/src/wallet/types.ts | 1 + .../components/ActivityDetail/Collateral.tsx | 21 ++++ .../ActivityDetail/TransactionDetails.tsx | 2 +- .../ActivityDetail/TransactionFee.module.scss | 109 ------------------ .../ActivityDetail/TransactionFee.tsx | 36 ++---- .../src/ui/components/ActivityDetail/index.ts | 1 + .../DappTransaction/DappTransaction.tsx | 25 +++- .../dappConnector/confirmTransactionPage.ts | 8 +- .../src/elements/transactionDetails.ts | 4 +- .../table/table-header.component.tsx | 3 +- .../table/table-row.component.tsx | 4 +- .../transaction-summary-amount.component.tsx | 48 +++++++- .../transaction-summary.css.ts | 15 +++ .../transaction-summary.stories.tsx | 9 ++ 17 files changed, 177 insertions(+), 168 deletions(-) create mode 100644 apps/browser-extension-wallet/src/hooks/useComputeTxCollateral.ts create mode 100644 packages/core/src/ui/components/ActivityDetail/Collateral.tsx delete mode 100644 packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss diff --git a/apps/browser-extension-wallet/src/features/dapp/components/ConfirmTransaction.tsx b/apps/browser-extension-wallet/src/features/dapp/components/ConfirmTransaction.tsx index 7696cfb23..006298b5b 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/ConfirmTransaction.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/ConfirmTransaction.tsx @@ -31,6 +31,7 @@ import { TX_CREATION_TYPE_KEY, TxCreationType } from '@providers/AnalyticsProvid import { txSubmitted$ } from '@providers/AnalyticsProvider/onChain'; import { signingCoordinator } from '@lib/wallet-api-ui'; import { senderToDappInfo } from '@src/utils/senderToDappInfo'; +import { useComputeTxCollateral } from '@hooks/useComputeTxCollateral'; const DAPP_TOAST_DURATION = 50; @@ -86,7 +87,8 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement walletType, isHardwareWallet, blockchainProvider: { assetProvider }, - walletUI: { cardanoCoin } + walletUI: { cardanoCoin }, + walletState } = useWalletStore(); const { fiatCurrency } = useCurrencyStore(); const { list: addressList } = useAddressBookContext(); @@ -99,11 +101,12 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement const [isConfirmingTx, setIsConfirmingTx] = useState(); const [assetsInfo, setAssetsInfo] = useState(); const [dappInfo, setDappInfo] = useState(); + const tx = useMemo(() => req?.transaction.toCore(), [req?.transaction]); + const txCollateral = useComputeTxCollateral(walletState, tx); // All assets' ids in the transaction body. Used to fetch their info from cardano services const assetIds = useMemo(() => { - if (!req) return []; - const tx = req.transaction.toCore(); + if (!tx) return []; const uniqueAssetIds = new Set(); // Merge all assets (TokenMaps) from the tx outputs and mint const assetMaps = tx.body?.outputs?.map((output) => output.value.assets) ?? []; @@ -118,7 +121,7 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement } } return [...uniqueAssetIds.values()]; - }, [req]); + }, [tx]); useEffect(() => { if (assetIds?.length > 0) { @@ -190,7 +193,7 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement const assetId = Wallet.Cardano.AssetId.fromParts(asset.policyId, asset.assetName); const assetInfo = assets.get(assetId) || assetsInfo?.get(assetId); // If it's a new asset or the name is being updated we should be getting it from the tx metadata - const metadataName = getAssetNameFromMintMetadata(asset, req.transaction.toCore()?.auxiliaryData?.blob); + const metadataName = getAssetNameFromMintMetadata(asset, tx?.auxiliaryData?.blob); return { name: assetInfo?.name.toString() || asset.fingerprint || assetId, ticker: @@ -203,7 +206,7 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement }; }); }, - [assets, assetsInfo, req] + [assets, assetsInfo, tx] ); const createAssetList = useCallback( @@ -231,7 +234,7 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement const [txSummary, setTxSummary] = useState(); useEffect(() => { - if (!req) { + if (!tx) { setTxSummary(void 0); return; } @@ -241,7 +244,6 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement burned: assetsBurnedInspector }); - const tx = req.transaction.toCore(); const { minted, burned } = await inspector(tx as Wallet.Cardano.HydratedTx); const isMintTransaction = minted.length > 0 || burned.length > 0; @@ -274,11 +276,12 @@ export const ConfirmTransaction = withAddressBookContext((): React.ReactElement outputs: txSummaryOutputs, type: txType, mintedAssets: createMintedList(minted), - burnedAssets: createMintedList(burned) + burnedAssets: createMintedList(burned), + collateral: txCollateral ? Wallet.util.lovelacesToAdaString(txCollateral.toString()) : undefined }); }; getTxSummary(); - }, [req, walletInfo.addresses, createAssetList, createMintedList, addressToNameMap, setTxSummary]); + }, [tx, walletInfo.addresses, createAssetList, createMintedList, addressToNameMap, setTxSummary, txCollateral]); const onConfirm = () => { analytics.sendEventToPostHog(PostHogAction.SendTransactionSummaryConfirmClick, { diff --git a/apps/browser-extension-wallet/src/hooks/useComputeTxCollateral.ts b/apps/browser-extension-wallet/src/hooks/useComputeTxCollateral.ts new file mode 100644 index 000000000..38000c03c --- /dev/null +++ b/apps/browser-extension-wallet/src/hooks/useComputeTxCollateral.ts @@ -0,0 +1,32 @@ +import { Wallet } from '@lace/cardano'; +import { createHistoricalOwnInputResolver } from '@src/utils/own-input-resolver'; +import { useState, useEffect } from 'react'; +import { getCollateral } from '@cardano-sdk/core'; +import { ObservableWalletState } from './useWalletState'; + +export const useComputeTxCollateral = (wallet: ObservableWalletState, tx?: Wallet.Cardano.Tx): bigint | undefined => { + const [txCollateral, setTxCollateral] = useState(); + + useEffect(() => { + if (!tx) return; + + const computeCollateral = async () => { + const inputResolver = createHistoricalOwnInputResolver({ + addresses: wallet.addresses, + transactions: wallet.transactions + }); + + const collateral = await getCollateral( + tx, + inputResolver, + wallet.addresses.map((addr) => addr.address) + ); + + setTxCollateral(collateral); + }; + + computeCollateral(); + }, [tx, wallet]); + + return txCollateral; +}; diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index 56f43e42e..f239404b5 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -56,7 +56,9 @@ "to": "To", "multipleAddresses": "Multiple addresses", "pools": "Pool(s)", - "epoch": "Epoch" + "epoch": "Epoch", + "collateral": "Collateral", + "collateralInfo": "Amount set as collateral to cover contract execution failure. In case of no failure collateral remains unspent." }, "walletNameAndPasswordSetupStep": { "title": "Let's set up your new wallet", diff --git a/packages/cardano/src/wallet/types.ts b/packages/cardano/src/wallet/types.ts index 5d1cf1519..946b0e338 100644 --- a/packages/cardano/src/wallet/types.ts +++ b/packages/cardano/src/wallet/types.ts @@ -38,6 +38,7 @@ export type Cip30SignTxSummary = { type: 'Send' | 'Mint'; mintedAssets?: Cip30SignTxAssetItem[]; burnedAssets?: Cip30SignTxAssetItem[]; + collateral?: string; }; export type Cip30SignTxAssetItem = { diff --git a/packages/core/src/ui/components/ActivityDetail/Collateral.tsx b/packages/core/src/ui/components/ActivityDetail/Collateral.tsx new file mode 100644 index 000000000..4b3159a2b --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/Collateral.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { useTranslate } from '@src/ui/hooks'; +import { TransactionSummary } from '@lace/ui'; + +export interface Props { + collateral: string; + amountTransformer: (amount: string) => string; + coinSymbol: string; +} +export const Collateral = ({ collateral, amountTransformer, coinSymbol }: Props): React.ReactElement => { + const { t } = useTranslate(); + + return ( + + ); +}; diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index bc40229b6..1fa563df5 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -265,7 +265,7 @@ export const TransactionDetails = ({ {fee && fee !== '-' && ( - + )} diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss deleted file mode 100644 index 7ba475863..000000000 --- a/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss +++ /dev/null @@ -1,109 +0,0 @@ -@import '../../styles/theme.scss'; -@import '../../../../../common/src/ui/styles/abstracts/typography'; - -.txFeeContainer { - display: flex; - align-items: center; - justify-content: center; - gap: size_unit(1); -} - -.txfee { - color: var(--text-color-primary); - font-size: var(--body, 16px); - font-weight: 600; - line-height: size_unit(3); -} - -.details { - color: var(--text-color-primary, #ffffff); - display: flex; - justify-content: space-between; - align-items: flex-start; - width: 100%; - - .title { - display: flex; - flex: 0 0 50%; - align-self: baseline; - color: var(--text-color-primary, #ffffff); - @include text-body-semi-bold; - } - - .detail { - align-items: end; - display: flex; - flex-direction: column; - gap: size_unit(2); - color: var(--text-color-primary, #ffffff); - text-align: right; - word-break: break-all; - @include text-body-medium; - - @media (max-width: $breakpoint-popup) { - flex-direction: column; - } - - &.hash { - @include text-address; - font-weight: 500; - text-align: right; - cursor: pointer; - } - &.txLink { - color: var(--text-color-blue, #3489f7); - line-height: 17px; - @media (max-width: $breakpoint-popup) { - flex: 60%; - } - } - &.poolId { - color: var(--text-color-secondary); - font-size: var(--bodySmall); - font-weight: 500; - line-height: 17px; - } - } - - .timestamp { - flex: 0 0 35%; - } - - .amount { - display: flex; - flex-direction: column; - width: 100%; - align-items: flex-end; - - .ada { - color: var(--text-color-primary, #ffffff); - } - - .fiat { - color: var(--text-color-secondary, #878e9e); - } - - .addrName { - margin-bottom: size_unit(1); - } - } - - .addressDetail { - font-size: var(--bodySmall, 14px); - font-weight: 400; - line-height: size_unit(2); - text-align: right; - margin-bottom: size_unit(5); - @media (max-width: $breakpoint-popup) { - margin-bottom: size_unit(6); - } - } - - .metadataLabel { - display: flex; - flex: 0 0 50%; - align-self: baseline; - @include text-bodyLarge-bold; - color: var(--text-color-primary); - } -} diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx index ba4f3fd62..26312ad81 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionFee.tsx @@ -1,10 +1,6 @@ -/* eslint-disable no-magic-numbers */ import React from 'react'; -import { InfoCircleOutlined } from '@ant-design/icons'; -import { Tooltip } from 'antd'; -import styles from './TransactionFee.module.scss'; -import { ReactComponent as Info } from '../../assets/icons/info-icon.component.svg'; import { useTranslate } from '@src/ui/hooks'; +import { TransactionSummary } from '@lace/ui'; export interface TransactionFeeProps { fee: string; @@ -15,28 +11,12 @@ export const TransactionFee = ({ fee, amountTransformer, coinSymbol }: Transacti const { t } = useTranslate(); return ( -
-
-
- {t('package.core.activityDetails.transactionFee')} -
- - {Info ? ( - - ) : ( - - )} - -
- -
-
- {`${fee} ${coinSymbol}`} - - {amountTransformer(fee)} - -
-
-
+ ); }; diff --git a/packages/core/src/ui/components/ActivityDetail/index.ts b/packages/core/src/ui/components/ActivityDetail/index.ts index 7ba95eea8..c2ee72854 100644 --- a/packages/core/src/ui/components/ActivityDetail/index.ts +++ b/packages/core/src/ui/components/ActivityDetail/index.ts @@ -4,3 +4,4 @@ export * from './ActivityTypeIcon'; export * from './TransactionDetailAsset'; export * from './TransactionInputOutput'; export * from './TransactionFee'; +export * from './Collateral'; diff --git a/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx b/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx index 9f5717baa..1bde1147a 100644 --- a/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx +++ b/packages/core/src/ui/components/DappTransaction/DappTransaction.tsx @@ -8,7 +8,7 @@ import { DappTxAsset, DappTxAssetProps } from './DappTxAsset/DappTxAsset'; import { DappTxOutput, DappTxOutputProps } from './DappTxOutput/DappTxOutput'; import styles from './DappTransaction.module.scss'; import { useTranslate } from '@src/ui/hooks'; -import { TransactionFee } from '@ui/components/ActivityDetail'; +import { TransactionFee, Collateral } from '@ui/components/ActivityDetail'; type TransactionDetails = { fee: string; @@ -16,8 +16,12 @@ type TransactionDetails = { type: 'Send' | 'Mint'; mintedAssets?: DappTxAssetProps[]; burnedAssets?: DappTxAssetProps[]; + collateral?: string; }; +const amountTransformer = (fiat: { price: number; code: string }) => (ada: string) => + `${Wallet.util.convertAdaToFiat({ ada, fiat: fiat.price })} ${fiat.code}`; + export interface DappTransactionProps { /** Transaction details such as type, amount, fee and address */ transaction: TransactionDetails; @@ -31,7 +35,7 @@ export interface DappTransactionProps { } export const DappTransaction = ({ - transaction: { type, outputs, fee, mintedAssets, burnedAssets }, + transaction: { type, outputs, fee, mintedAssets, burnedAssets, collateral }, dappInfo, errorMessage, fiatCurrencyCode, @@ -77,12 +81,23 @@ export const DappTransaction = ({ ))} )} + {collateral && ( + + )} {fee && fee !== '-' && ( - `${Wallet.util.convertAdaToFiat({ ada, fiat: fiatCurrencyPrice })} ${fiatCurrencyCode}` - } + amountTransformer={amountTransformer({ + price: fiatCurrencyPrice, + code: fiatCurrencyCode + })} coinSymbol={coinSymbol} /> )} diff --git a/packages/e2e-tests/src/elements/dappConnector/confirmTransactionPage.ts b/packages/e2e-tests/src/elements/dappConnector/confirmTransactionPage.ts index 1472ceed9..772693953 100644 --- a/packages/e2e-tests/src/elements/dappConnector/confirmTransactionPage.ts +++ b/packages/e2e-tests/src/elements/dappConnector/confirmTransactionPage.ts @@ -7,10 +7,10 @@ class ConfirmTransactionPage extends CommonDappPageElements { private TRANSACTION_TYPE = '[data-testid="dapp-transaction-type"]'; private TRANSACTION_AMOUNT_TITLE = '[data-testid="dapp-transaction-amount-title"]'; private TRANSACTION_AMOUNT_VALUE = '[data-testid="dapp-transaction-amount-value"]'; - private TRANSACTION_AMOUNT_FEE_TITLE = '[data-testid="tx-fee-title"]'; - private TRANSACTION_AMOUNT_FEE_TITLE_TOOLTIP_ICON = '[data-testid="tx-fee-tooltip-icon"]'; - private TRANSACTION_AMOUNT_FEE_VALUE_ADA = '[data-testid="tx-fee-ada"]'; - private TRANSACTION_AMOUNT_FEE_VALUE_FIAT = '[data-testid="tx-fee-fiat"]'; + private TRANSACTION_AMOUNT_FEE_TITLE = '[data-testid="tx-amount-fee-label"]'; + private TRANSACTION_AMOUNT_FEE_TITLE_TOOLTIP_ICON = '[data-testid="tx-amount-fee-tooltip-icon"]'; + private TRANSACTION_AMOUNT_FEE_VALUE_ADA = '[data-testid="tx-amount-fee-amount"]'; + private TRANSACTION_AMOUNT_FEE_VALUE_FIAT = '[data-testid="tx-amount-fee-fiat"]'; private TRANSACTION_AMOUNT_ASSET = '[data-testid="dapp-transaction-asset"]'; private TRANSACTION_RECIPIENT_TITLE = '[data-testid="dapp-transaction-recipient-title"]'; private TRANSACTION_RECIPIENT_ADDRESS_TITLE = '[data-testid="dapp-transaction-recipient-address-title"]'; diff --git a/packages/e2e-tests/src/elements/transactionDetails.ts b/packages/e2e-tests/src/elements/transactionDetails.ts index eb3fd6cfb..61a541b8d 100644 --- a/packages/e2e-tests/src/elements/transactionDetails.ts +++ b/packages/e2e-tests/src/elements/transactionDetails.ts @@ -18,8 +18,8 @@ class ActivityDetailsPage extends CommonDrawerElements { private TRANSACTION_DETAILS_TO_ADDRESS = '[data-testid="tx-to-detail"]'; private TRANSACTION_DETAILS_STATUS = '[data-testid="tx-status"]'; private TRANSACTION_DETAILS_TIMESTAMP = '[data-testid="tx-timestamp"]'; - private TRANSACTION_DETAILS_FEE_ADA = '[data-testid="tx-fee-ada"]'; - private TRANSACTION_DETAILS_FEE_FIAT = '[data-testid="tx-fee-fiat"]'; + private TRANSACTION_DETAILS_FEE_ADA = '[data-testid="tx-amount-fee-amount"]'; + private TRANSACTION_DETAILS_FEE_FIAT = '[data-testid="tx-amount-fee-fiat"]'; private TRANSACTION_DETAILS_INPUTS_SECTION = '[data-testid="tx-inputs"]'; private TRANSACTION_DETAILS_OUTPUTS_SECTION = '[data-testid="tx-outputs"]'; private TRANSACTION_DETAILS_DROPDOWN = '[data-testid="tx-addr-list_toggle"]'; diff --git a/packages/ui/src/design-system/table/table-header.component.tsx b/packages/ui/src/design-system/table/table-header.component.tsx index e693a48c6..e150cbb11 100644 --- a/packages/ui/src/design-system/table/table-header.component.tsx +++ b/packages/ui/src/design-system/table/table-header.component.tsx @@ -1,9 +1,10 @@ import React from 'react'; -import { IconButton } from '@lace/ui'; import { Tooltip } from 'antd'; import cn from 'classnames'; +import * as IconButton from '../icon-buttons'; + import * as cx from './table.css'; export interface Headers { diff --git a/packages/ui/src/design-system/table/table-row.component.tsx b/packages/ui/src/design-system/table/table-row.component.tsx index b1c060d8a..3db0bce39 100644 --- a/packages/ui/src/design-system/table/table-row.component.tsx +++ b/packages/ui/src/design-system/table/table-row.component.tsx @@ -1,9 +1,11 @@ /* eslint-disable react/no-multi-comp */ import React from 'react'; -import { Checkbox, Tooltip } from '@lace/ui'; import cn from 'classnames'; +import { Checkbox } from '../checkbox'; +import { Tooltip } from '../tooltip'; + import * as cx from './table.css'; export interface RowProps< diff --git a/packages/ui/src/design-system/transaction-summary/transaction-summary-amount.component.tsx b/packages/ui/src/design-system/transaction-summary/transaction-summary-amount.component.tsx index 7baef80ac..d6bc56c3d 100644 --- a/packages/ui/src/design-system/transaction-summary/transaction-summary-amount.component.tsx +++ b/packages/ui/src/design-system/transaction-summary/transaction-summary-amount.component.tsx @@ -1,7 +1,11 @@ import React from 'react'; +import { ReactComponent as InfoIcon } from '@lace/icons/dist/InfoComponent'; + +import { Box } from '../box'; import { Flex } from '../flex'; import { Grid, Cell } from '../grid'; +import { Tooltip } from '../tooltip'; import * as Typography from '../typography'; import * as cx from './transaction-summary.css'; @@ -10,29 +14,61 @@ import type { OmitClassName } from '../../types'; type Props = OmitClassName<'div'> & { label?: string; + tooltip?: string; amount: string; fiatPrice: string; + 'data-testid'?: string; +}; + +const makeTestId = (namespace = '', path = ''): string | undefined => { + return namespace === '' ? undefined : `tx-amount-${namespace}-${path}`; }; export const Amount = ({ label, amount, fiatPrice, + tooltip, ...props }: Readonly): JSX.Element => { + const testId = props['data-testid']; + return ( - + - - {label} - + + + {label} + + {tooltip !== undefined && ( + + +
+ +
+
+
+ )} +
- + {amount} - + {fiatPrice} diff --git a/packages/ui/src/design-system/transaction-summary/transaction-summary.css.ts b/packages/ui/src/design-system/transaction-summary/transaction-summary.css.ts index 502aa1294..995421544 100644 --- a/packages/ui/src/design-system/transaction-summary/transaction-summary.css.ts +++ b/packages/ui/src/design-system/transaction-summary/transaction-summary.css.ts @@ -24,3 +24,18 @@ export const secondaryText = style([ wordBreak: 'break-all', }, ]); + +export const tooltip = style([ + sx({ + color: '$transaction_summary_secondary_label_color', + width: '$24', + height: '$24', + fontSize: '$25', + }), +]); + +export const tooltipText = style([ + sx({ + display: 'flex', + }), +]); diff --git a/packages/ui/src/design-system/transaction-summary/transaction-summary.stories.tsx b/packages/ui/src/design-system/transaction-summary/transaction-summary.stories.tsx index 25d82548d..46b4c49d8 100644 --- a/packages/ui/src/design-system/transaction-summary/transaction-summary.stories.tsx +++ b/packages/ui/src/design-system/transaction-summary/transaction-summary.stories.tsx @@ -58,6 +58,15 @@ const Example = (): JSX.Element => ( + + +
From 152ff439f127f3e50c9f19aa9ac0140928c453c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20K=C5=82os?= <114915819+wklos-iohk@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:35:42 +0100 Subject: [PATCH 03/14] test(extension): apply workaround for smoke tests (#897) --- .github/workflows/smoke-tests.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/smoke-tests.yml b/.github/workflows/smoke-tests.yml index 24d88d4a4..b68ef3e74 100644 --- a/.github/workflows/smoke-tests.yml +++ b/.github/workflows/smoke-tests.yml @@ -22,6 +22,11 @@ jobs: run: ./decrypt_secret.sh env: WALLET_1_PASSWORD: ${{ secrets.WALLET_PASSWORD_TESTNET }} + - name: Downgrade chrome + run: | + wget -q -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_120.0.6099.216-1_amd64.deb \ + && sudo apt install -y --allow-downgrades /tmp/chrome.deb \ + && rm /tmp/chrome.deb - name: Build dist version of Lace uses: ./.github/shared/build with: @@ -29,10 +34,14 @@ jobs: - name: Start XVFB run: | Xvfb :99 & + - name: setup chromedriver + uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: '120.0.6099.216' - name: Start Chrome driver run: | if [ ${BROWSER} == "chrome" ]; then - ${CHROMEWEBDRIVER}/chromedriver -port=4444 & + chromedriver -port=4444 & else echo "Skipping start of ChromeDriver" fi From 79e30bea247a2c2c096f2333085fe53f4a5d053f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20K=C5=82os?= <114915819+wklos-iohk@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:24:07 +0100 Subject: [PATCH 04/14] test(extension): remove unnecessary hook (#900) --- packages/e2e-tests/wdio.conf.base.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/e2e-tests/wdio.conf.base.ts b/packages/e2e-tests/wdio.conf.base.ts index cfc8dfe5e..c2722eb25 100755 --- a/packages/e2e-tests/wdio.conf.base.ts +++ b/packages/e2e-tests/wdio.conf.base.ts @@ -1,6 +1,5 @@ /* eslint-disable no-undef */ -import * as dns from 'dns'; import extensionUtils from './src/utils/utils'; export const config: WebdriverIO.Config = { @@ -59,8 +58,5 @@ export const config: WebdriverIO.Config = { tagsInTitle: true, timeout: 200_000, retry: 1 - } as WebdriverIO.CucumberOpts, - async beforeSession() { - await dns.setDefaultResultOrder('ipv4first'); - } + } as WebdriverIO.CucumberOpts }; From f18d5643150a1cc669d743b3419f0e365fdbdff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20W=C5=82odek?= Date: Tue, 20 Feb 2024 10:10:32 +0100 Subject: [PATCH 05/14] chore(staking): mock @lace/cardano for storybook in Staking (#898) --- .../staking/.storybook/__mocks__/cardano.ts | 6 +++ packages/staking/.storybook/main.ts | 9 ++++ .../DelegationCard/DelegationCard.stories.tsx | 34 +++++++------- .../PoolDetailsCard.stories.tsx | 46 +++++++++---------- 4 files changed, 55 insertions(+), 40 deletions(-) create mode 100644 packages/staking/.storybook/__mocks__/cardano.ts diff --git a/packages/staking/.storybook/__mocks__/cardano.ts b/packages/staking/.storybook/__mocks__/cardano.ts new file mode 100644 index 000000000..a0f841264 --- /dev/null +++ b/packages/staking/.storybook/__mocks__/cardano.ts @@ -0,0 +1,6 @@ +import { Cardano, util } from '@cardano-sdk/core'; + +export const Wallet = { + util, + Cardano, +}; diff --git a/packages/staking/.storybook/main.ts b/packages/staking/.storybook/main.ts index 3476b7786..d6dea7dc8 100644 --- a/packages/staking/.storybook/main.ts +++ b/packages/staking/.storybook/main.ts @@ -6,6 +6,7 @@ import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'; import svgrPlugin from 'vite-plugin-svgr'; import tsconfigPaths from 'vite-tsconfig-paths'; import { nodePolyfills } from 'vite-plugin-node-polyfills'; +// TODO to be removed when @lace/icons properly supports ESM import commonjs from 'vite-plugin-commonjs'; /** @@ -44,6 +45,14 @@ const config: StorybookConfig = { }), tsconfigPaths(), ], + resolve: { + alias: [ + { + find: '@lace/cardano', + replacement: require.resolve('./__mocks__/cardano.ts'), + }, + ], + }, }; return mergeConfig(baseConfig, userConfig); diff --git a/packages/staking/src/features/DelegationCard/DelegationCard.stories.tsx b/packages/staking/src/features/DelegationCard/DelegationCard.stories.tsx index d6515f477..0e87f7b73 100644 --- a/packages/staking/src/features/DelegationCard/DelegationCard.stories.tsx +++ b/packages/staking/src/features/DelegationCard/DelegationCard.stories.tsx @@ -1,6 +1,6 @@ -// import { PieChartGradientColor } from '@lace/ui'; +import { PieChartGradientColor } from '@lace/ui'; import type { Meta } from '@storybook/react'; -// import { DelegationCard } from './DelegationCard'; +import { DelegationCard } from './DelegationCard'; export default { title: 'DelegationCard', @@ -9,20 +9,20 @@ export default { // TODO https://input-output.atlassian.net/browse/LW-9492 export const Overview = () => ( <> - {/* */} - {/*
*/} - {/* */} + +
+ ); diff --git a/packages/staking/src/features/Drawer/preferences/PoolDetailsCard/PoolDetailsCard.stories.tsx b/packages/staking/src/features/Drawer/preferences/PoolDetailsCard/PoolDetailsCard.stories.tsx index d79ac0f84..9a7cf157c 100644 --- a/packages/staking/src/features/Drawer/preferences/PoolDetailsCard/PoolDetailsCard.stories.tsx +++ b/packages/staking/src/features/Drawer/preferences/PoolDetailsCard/PoolDetailsCard.stories.tsx @@ -1,6 +1,6 @@ import { Flex } from '@lace/ui'; import type { Meta } from '@storybook/react'; -// import { PoolDetailsCard } from './'; +import { PoolDetailsCard } from './'; export default { title: 'Drawer/PoolDetailsCard', @@ -9,27 +9,27 @@ export default { // TODO https://input-output.atlassian.net/browse/LW-9492 export const Overview = () => ( - {/* void 0}*/} - {/* stakeValue="10,000.00"*/} - {/* cardanoCoinSymbol="ADA"*/} - {/* savedPercentage={30}*/} - {/* targetPercentage={30}*/} - {/* onPercentageChange={(nextValue) => console.info('changed 1:', nextValue)}*/} - {/* defaultExpand*/} - {/* />*/} - {/* void 0}*/} - {/* stakeValue="4,000.00"*/} - {/* targetPercentage={10}*/} - {/* cardanoCoinSymbol="ADA"*/} - {/* onPercentageChange={(nextValue) => console.info('changed 2:', nextValue)}*/} - {/* />*/} + void 0} + stakeValue="10,000.00" + cardanoCoinSymbol="ADA" + savedPercentage={30} + targetPercentage={30} + onPercentageChange={(nextValue) => console.info('changed 1:', nextValue)} + defaultExpand + /> + void 0} + stakeValue="4,000.00" + targetPercentage={10} + cardanoCoinSymbol="ADA" + onPercentageChange={(nextValue) => console.info('changed 2:', nextValue)} + /> ); From 91036582cce8d465488b5a95ac00455679548d72 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Tue, 20 Feb 2024 17:21:21 +0200 Subject: [PATCH 06/14] feat(extension): add missing tooltips for new stake pool table headers (#895) * feat(extension): add missing tooltips for new stake pool table headers * fix(extension): resolve pr comments * fix(extension): resolve pr comments --- .../src/lib/translations/en.json | 15 ++++++++++++--- .../StakePoolsTable/StakePoolsTable.tsx | 13 ++++++++----- .../src/features/BrowsePools/BrowsePools.tsx | 4 ++-- .../staking/src/features/i18n/translations/en.ts | 9 +++++++-- packages/staking/src/features/i18n/types.ts | 11 +++++++++-- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index f239404b5..2596248f3 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -1082,8 +1082,14 @@ }, "stakePoolTableBrowser": { "tableHeader": { - "ticker": "Ticker", - "cost": "Cost", + "ticker": { + "title": "Ticker", + "tooltip": "Refers to the unique identifier of a staking pool" + }, + "cost": { + "title": "Cost", + "tooltip": "The cost is not directly paid by the delegator; they are deducted from a pool's rewards, consisting of a fixed cost and a variable cost, which fund the pool's operational costs" + }, "ros": { "title": "ROS", "tooltip": "Estimated 'Return On Stake' based on previous pool performance" @@ -1104,7 +1110,10 @@ "title": "Pledge", "tooltip": "An amount of self‐bonded assets intended to remain staked to the pool for as long as it operates" }, - "liveStake": "Live Stake" + "liveStake": { + "title": "Live Stake", + "tooltip": "Refers to the total amount of a cryptocurrency that is currently being staked in a particular staking pool" + } } }, "stakingConfirmationInfo": { diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolsTable/StakePoolsTable.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolsTable/StakePoolsTable.tsx index 22252421b..575748599 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolsTable/StakePoolsTable.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/staking/components/StakePoolsTable/StakePoolsTable.tsx @@ -62,21 +62,24 @@ export const StakePoolsTable = ({ scrollableTargetId }: stakePoolsTableProps): R } = useWalletStore(); const tableHeaderTranslations: TranslationsFor = { - ticker: t('cardano.stakePoolTableBrowser.tableHeader.ticker'), + ticker: t('cardano.stakePoolTableBrowser.tableHeader.ticker.title'), apy: t('cardano.stakePoolTableBrowser.tableHeader.ros.title'), - cost: t('cardano.stakePoolTableBrowser.tableHeader.cost'), + cost: t('cardano.stakePoolTableBrowser.tableHeader.cost.title'), saturation: t('cardano.stakePoolTableBrowser.tableHeader.saturation.title'), margin: t('cardano.stakePoolTableBrowser.tableHeader.margin.title'), blocks: t('cardano.stakePoolTableBrowser.tableHeader.blocks.title'), pledge: t('cardano.stakePoolTableBrowser.tableHeader.pledge.title'), - liveStake: t('cardano.stakePoolTableBrowser.tableHeader.liveStake') + liveStake: t('cardano.stakePoolTableBrowser.tableHeader.liveStake.title') }; - const tableHeaderTooltipsTranslations: Partial> = { + const tableHeaderTooltipsTranslations: TranslationsFor = { + ticker: t('cardano.stakePoolTableBrowser.tableHeader.ticker.tooltip'), apy: t('cardano.stakePoolTableBrowser.tableHeader.ros.tooltip'), + cost: t('cardano.stakePoolTableBrowser.tableHeader.cost.tooltip'), saturation: t('cardano.stakePoolTableBrowser.tableHeader.saturation.tooltip'), margin: t('cardano.stakePoolTableBrowser.tableHeader.margin.tooltip'), blocks: t('cardano.stakePoolTableBrowser.tableHeader.blocks.tooltip'), - pledge: t('cardano.stakePoolTableBrowser.tableHeader.pledge.tooltip') + pledge: t('cardano.stakePoolTableBrowser.tableHeader.pledge.tooltip'), + liveStake: t('cardano.stakePoolTableBrowser.tableHeader.liveStake.tooltip') }; const debouncedSearch = useMemo(() => debounce(fetchStakePools, searchDebounce), [fetchStakePools]); diff --git a/packages/staking/src/features/BrowsePools/BrowsePools.tsx b/packages/staking/src/features/BrowsePools/BrowsePools.tsx index 1f92d367b..7ebc04fe9 100644 --- a/packages/staking/src/features/BrowsePools/BrowsePools.tsx +++ b/packages/staking/src/features/BrowsePools/BrowsePools.tsx @@ -47,12 +47,12 @@ export const BrowsePools = () => { const tableHeaderTranslations = { apy: t('browsePools.stakePoolTableBrowser.tableHeader.ros.title'), blocks: t('browsePools.stakePoolTableBrowser.tableHeader.blocks.title'), - cost: t('browsePools.stakePoolTableBrowser.tableHeader.cost'), + cost: t('browsePools.stakePoolTableBrowser.tableHeader.cost.title'), liveStake: t('browsePools.stakePoolTableBrowser.tableHeader.liveStake.title'), margin: t('browsePools.stakePoolTableBrowser.tableHeader.margin.title'), pledge: t('browsePools.stakePoolTableBrowser.tableHeader.pledge.title'), saturation: t('browsePools.stakePoolTableBrowser.tableHeader.saturation.title'), - ticker: t('browsePools.stakePoolTableBrowser.tableHeader.ticker'), + ticker: t('browsePools.stakePoolTableBrowser.tableHeader.ticker.title'), }; const debouncedSearch = useMemo(() => debounce(fetchStakePools, SEARCH_DEBOUNCE), [fetchStakePools]); diff --git a/packages/staking/src/features/i18n/translations/en.ts b/packages/staking/src/features/i18n/translations/en.ts index 4d1dbae9a..807c8294f 100644 --- a/packages/staking/src/features/i18n/translations/en.ts +++ b/packages/staking/src/features/i18n/translations/en.ts @@ -19,8 +19,12 @@ export const en: Translations = { 'browsePools.stakePoolTableBrowser.stake': 'Stake', 'browsePools.stakePoolTableBrowser.tableHeader.blocks.title': 'Blocks', 'browsePools.stakePoolTableBrowser.tableHeader.blocks.tooltip': 'Total blocks created by the pool.', - 'browsePools.stakePoolTableBrowser.tableHeader.cost': 'Cost', + 'browsePools.stakePoolTableBrowser.tableHeader.cost.title': 'Cost', + 'browsePools.stakePoolTableBrowser.tableHeader.cost.tooltip': + "The cost is not directly paid by the delegator; they are deducted from a pool's rewards, consisting of a fixed cost and a variable cost, which fund the pool's operational costs", 'browsePools.stakePoolTableBrowser.tableHeader.liveStake.title': 'Live Stake', + 'browsePools.stakePoolTableBrowser.tableHeader.liveStake.tooltip': + 'Refers to the total amount of a cryptocurrency that is currently being staked in a particular staking pool', 'browsePools.stakePoolTableBrowser.tableHeader.margin.title': 'Margin', 'browsePools.stakePoolTableBrowser.tableHeader.margin.tooltip': 'The percentage of rewards taken by the stake pool operator after the fixed cost but before rewards are distributed', @@ -33,7 +37,8 @@ export const en: Translations = { 'browsePools.stakePoolTableBrowser.tableHeader.saturation.title': 'Saturation', 'browsePools.stakePoolTableBrowser.tableHeader.saturation.tooltip': 'Once a pool reaches the point of saturation, it will offer diminishing rewards', - 'browsePools.stakePoolTableBrowser.tableHeader.ticker': 'Ticker', + 'browsePools.stakePoolTableBrowser.tableHeader.ticker.title': 'Ticker', + 'browsePools.stakePoolTableBrowser.tableHeader.ticker.tooltip': 'Refers to the unique identifier of a staking pool', 'browsePools.stakePoolTableBrowser.unselect': 'Unselect', 'drawer.confirmation.button.confirm': 'Next', 'drawer.confirmation.button.confirmWithDevice': 'Confirm with {{hardwareWallet}}', diff --git a/packages/staking/src/features/i18n/types.ts b/packages/staking/src/features/i18n/types.ts index 77eb9500e..53d5ac3b3 100644 --- a/packages/staking/src/features/i18n/types.ts +++ b/packages/staking/src/features/i18n/types.ts @@ -40,12 +40,18 @@ type KeysStructure = { stakePoolTableBrowser: { searchInputPlaceholder: ''; tableHeader: { - ticker: ''; + ticker: { + title: ''; + tooltip: ''; + }; ros: { title: ''; tooltip: ''; }; - cost: ''; + cost: { + title: ''; + tooltip: ''; + }; saturation: { title: ''; tooltip: ''; @@ -64,6 +70,7 @@ type KeysStructure = { }; liveStake: { title: ''; + tooltip: ''; }; }; emptyMessage: ''; From 546ecff628e07048fa7cd9a680d97fe820c40975 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Wed, 21 Feb 2024 10:45:59 +0200 Subject: [PATCH 07/14] fix(extension): fix focus and click on label for radio button (#894) * fix(extension): fix focus and click on label for radio button * fix(extension): resolve pr comments * fix(extension): resolve pr comments * fix(extension): resolve pr comments * fix(extension): resolve sdet comments * fix(extension): resolve sdet comments --- .../WalletSetup/WalletSetupRegisterStep.tsx | 1 + .../radio-button/radio-button.component.tsx | 24 ++- .../radio-button/radio-button.css.ts | 81 +++++--- .../radio-button/radio-button.stories.css.ts | 5 - .../radio-button/radio-button.stories.tsx | 184 ++++++++---------- packages/ui/src/design-tokens/colors.data.ts | 2 + .../src/design-tokens/theme/dark-theme.css.ts | 8 +- .../design-tokens/theme/light-theme.css.ts | 2 + 8 files changed, 167 insertions(+), 140 deletions(-) delete mode 100644 packages/ui/src/design-system/radio-button/radio-button.stories.css.ts diff --git a/packages/core/src/ui/components/WalletSetup/WalletSetupRegisterStep.tsx b/packages/core/src/ui/components/WalletSetup/WalletSetupRegisterStep.tsx index 64fbcc115..cc9cd0b6e 100644 --- a/packages/core/src/ui/components/WalletSetup/WalletSetupRegisterStep.tsx +++ b/packages/core/src/ui/components/WalletSetup/WalletSetupRegisterStep.tsx @@ -65,6 +65,7 @@ export const WalletSetupRegisterStep = ({ label={translations.walletName} onChange={(e) => handleOnChange(e.target.value)} maxLength={WALLET_NAME_INPUT_MAX_LENGTH} + autoFocus /> {shouldShowErrorMessage && (

{options.map(({ value, label, icon, onIconClick }) => ( - + {label && ( -

+ + + + + + + + + + + + + + + + + + + + + + +
+ +); diff --git a/packages/staking/src/features/BrowsePools/SortAndFilter/SortAndFilter.tsx b/packages/staking/src/features/BrowsePools/SortAndFilter/SortAndFilter.tsx new file mode 100644 index 000000000..dffa3c229 --- /dev/null +++ b/packages/staking/src/features/BrowsePools/SortAndFilter/SortAndFilter.tsx @@ -0,0 +1,244 @@ +import { ReactComponent as SortDirectionAscIcon } from '@lace/icons/dist/SortDirectionAscComponent'; +import { ReactComponent as SortDirectionDescIcon } from '@lace/icons/dist/SortDirectionDescComponent'; +import { + Card, + Flex, + RadioButtonGroup, + RadioButtonGroupOption, + SelectGroup, + Text, + TextBox, + ToggleButtonGroup, +} from '@lace/ui'; +import cn from 'classnames'; +import { MetricType, SortDirection, SortField, StakePoolSortOptions } from 'features/BrowsePools'; +import debounce from 'lodash/debounce'; +import { useCallback, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import * as styles from './SortAndFilter.css'; +import { FilterOption, FilterValues, PoolsFilter, SelectOption, SortAndFilterTab } from './types'; + +export interface SortAndFilterProps { + activeTab: SortAndFilterTab; + sort: StakePoolSortOptions; + filter: FilterValues; + onSortChange: (value: StakePoolSortOptions) => void; + onFilterChange: (filters: FilterValues) => void; + onTabChange: (section: SortAndFilterTab) => void; +} + +// TODO consider moving this kind of responsibility to the parent component +const ON_CHANGE_DEBOUNCE = 400; + +export const SortAndFilter = ({ + activeTab, + filter, + sort, + onFilterChange, + onTabChange, + onSortChange, +}: SortAndFilterProps) => { + const { t } = useTranslation(); + const [localFilters, setLocalFilters] = useState(filter); + const { field: sortBy, order: direction } = sort; + + const debouncedFilterChange = useMemo(() => debounce(onFilterChange, ON_CHANGE_DEBOUNCE), [onFilterChange]); + const handleFilterChange = useCallback( + (key: PoolsFilter, optIndex: number, value: string) => { + const newFilters = { + ...localFilters, + }; + newFilters[key][optIndex] = value; + setLocalFilters(newFilters); + debouncedFilterChange(newFilters); + }, + [debouncedFilterChange, localFilters] + ); + + const handleIconClick = useCallback(() => { + const newSort: StakePoolSortOptions = { + field: sortBy, + order: direction === SortDirection.desc ? SortDirection.asc : SortDirection.desc, + }; + onSortChange(newSort); + }, [direction, onSortChange, sortBy]); + + const handleSortChange = useCallback( + (field: string) => + onSortChange({ + field: field as unknown as SortField, + order: direction, + }), + [direction, onSortChange] + ); + + const getFilters = (filterOption: FilterOption) => { + if (filterOption.type === 'input') { + return ( + + {(filterOption.opts as string[]).map((opt, idx) => ( + 1 && { + [styles.textBoxLeft]: idx === 0, + [styles.textBoxRight]: idx === filterOption.opts.length - 1, + } + )} + label={opt} + value={localFilters[filterOption.key][idx]} + onChange={(e) => handleFilterChange(filterOption.key, idx, e.target.value)} + /> + ))} + + ); + } + + const selectedValue = + (filterOption.opts as SelectOption[]).find((opt) => opt.value === localFilters[filterOption.key][0])?.value ?? ''; + + return ( + handleFilterChange(filterOption.key, 0, value)} + showArrow + withOutline + className={styles.selectGroup} + placeholder={t('browsePools.stakePoolTableBrowser.sortAndFilter.input.select')} + options={filterOption.opts as SelectOption[]} + selectedValue={selectedValue} + /> + ); + }; + + const sortingOptions: RadioButtonGroupOption[] = useMemo(() => { + const icon = direction === SortDirection.asc ? SortDirectionAscIcon : SortDirectionDescIcon; + return [ + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.ticker'), + onIconClick: handleIconClick, + value: MetricType.ticker, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.saturation'), + onIconClick: handleIconClick, + value: MetricType.saturation, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.ros.title'), + onIconClick: handleIconClick, + value: MetricType.apy, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.cost'), + onIconClick: handleIconClick, + value: MetricType.cost, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.margin'), + onIconClick: handleIconClick, + value: MetricType.margin, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.blocks'), + onIconClick: handleIconClick, + value: MetricType.blocks, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.pledge'), + onIconClick: handleIconClick, + value: MetricType.pledge, + }, + { + icon, + label: t('browsePools.stakePoolTableBrowser.sortByTitle.livestake'), + onIconClick: handleIconClick, + value: MetricType.liveStake, + }, + ]; + }, [direction, handleIconClick, t]); + + const filterOptions: FilterOption[] = useMemo(() => { + const fromLabel = t('browsePools.stakePoolTableBrowser.sortAndFilter.input.from'); + const toLabel = t('browsePools.stakePoolTableBrowser.sortAndFilter.input.to'); + + return [ + { + key: PoolsFilter.Saturation, + opts: [fromLabel, toLabel], + title: t('browsePools.stakePoolTableBrowser.sortByTitle.saturation'), + type: 'input', + }, + { + key: PoolsFilter.ProfitMargin, + opts: [fromLabel, toLabel], + title: t('browsePools.stakePoolTableBrowser.sortByTitle.profitMargin'), + type: 'input', + }, + { + key: PoolsFilter.Performance, + opts: [fromLabel, toLabel], + title: t('browsePools.stakePoolTableBrowser.sortByTitle.performance'), + type: 'input', + }, + { + key: PoolsFilter.Ros, + opts: [ + { + label: t('browsePools.stakePoolTableBrowser.sortByTitle.ros.lastEpoch'), + selected: localFilters[PoolsFilter.Ros][0] === 'lastepoch', + value: 'lastepoch', + }, + { + label: t('browsePools.stakePoolTableBrowser.sortByTitle.ros.other'), + selected: localFilters[PoolsFilter.Ros][0] === 'lastepoch', + value: 'other', + }, + ], + title: t('browsePools.stakePoolTableBrowser.sortByTitle.ros.title'), + type: 'select', + }, + ]; + }, [localFilters, t]); + + return ( + + + + {t('browsePools.stakePoolTableBrowser.sortAndFilter.headers.moreOptions')} + + onTabChange(value as SortAndFilterTab)}> + + {t('browsePools.stakePoolTableBrowser.sortAndFilter.headers.sorting')} + + + {t('browsePools.stakePoolTableBrowser.sortAndFilter.headers.filters')} + + + {activeTab === SortAndFilterTab.sort ? ( + + ) : ( + + {filterOptions.map((filterOption) => ( + + {filterOption.title} + {getFilters(filterOption)} + + ))} + + )} + + + ); +}; diff --git a/packages/staking/src/features/BrowsePools/SortAndFilter/index.ts b/packages/staking/src/features/BrowsePools/SortAndFilter/index.ts new file mode 100644 index 000000000..bdfe32b60 --- /dev/null +++ b/packages/staking/src/features/BrowsePools/SortAndFilter/index.ts @@ -0,0 +1 @@ +export { SortAndFilter } from './SortAndFilter'; diff --git a/packages/staking/src/features/BrowsePools/SortAndFilter/types.ts b/packages/staking/src/features/BrowsePools/SortAndFilter/types.ts new file mode 100644 index 000000000..c5221aacc --- /dev/null +++ b/packages/staking/src/features/BrowsePools/SortAndFilter/types.ts @@ -0,0 +1,27 @@ +export enum PoolsFilter { + Saturation = 'SATURATION', + ProfitMargin = 'PROFIT_MARGIN', + Performance = 'PERFORMANCE', + Ros = 'ROS', +} + +export type SelectOption = { label: string; value: string; selected: boolean }; + +export type FilterOption = { + key: PoolsFilter; + title: string; + type: 'input' | 'select'; + opts: string[] | SelectOption[]; +}; + +export interface FilterValues { + [PoolsFilter.Saturation]: string[]; + [PoolsFilter.ProfitMargin]: string[]; + [PoolsFilter.Performance]: string[]; + [PoolsFilter.Ros]: string[]; +} + +export enum SortAndFilterTab { + sort = 'sort', + filter = 'filter', +} diff --git a/packages/staking/src/features/BrowsePools/index.ts b/packages/staking/src/features/BrowsePools/index.ts index 3cbfdacfb..02afb59c3 100644 --- a/packages/staking/src/features/BrowsePools/index.ts +++ b/packages/staking/src/features/BrowsePools/index.ts @@ -1,4 +1,5 @@ export { BrowsePools } from './BrowsePools'; +export { SortAndFilter } from './SortAndFilter'; // TODO: remove once multi delegaion feature is GA'd export type { StakePoolSortOptions, TranslationsFor } from './types'; export { MetricType, SortField, SortDirection } from './types'; diff --git a/packages/staking/src/features/i18n/translations/en.ts b/packages/staking/src/features/i18n/translations/en.ts index 807c8294f..a49d7db21 100644 --- a/packages/staking/src/features/i18n/translations/en.ts +++ b/packages/staking/src/features/i18n/translations/en.ts @@ -16,6 +16,24 @@ export const en: Translations = { 'browsePools.stakePoolTableBrowser.disabledTooltip': 'Maximum number of pools selected', 'browsePools.stakePoolTableBrowser.emptyMessage': 'No results matching your search', 'browsePools.stakePoolTableBrowser.searchInputPlaceholder': 'Search by pool name, ticker, or ID', + 'browsePools.stakePoolTableBrowser.sortAndFilter.headers.filters': 'Filters', + 'browsePools.stakePoolTableBrowser.sortAndFilter.headers.moreOptions': 'More options', + 'browsePools.stakePoolTableBrowser.sortAndFilter.headers.sorting': 'Sorting', + 'browsePools.stakePoolTableBrowser.sortAndFilter.input.from': 'From', + 'browsePools.stakePoolTableBrowser.sortAndFilter.input.select': 'Select', + 'browsePools.stakePoolTableBrowser.sortAndFilter.input.to': 'To', + 'browsePools.stakePoolTableBrowser.sortByTitle.blocks': 'Blocks produced', + 'browsePools.stakePoolTableBrowser.sortByTitle.cost': 'Cost', + 'browsePools.stakePoolTableBrowser.sortByTitle.livestake': 'Live stake', + 'browsePools.stakePoolTableBrowser.sortByTitle.margin': 'Margin', + 'browsePools.stakePoolTableBrowser.sortByTitle.performance': 'Performance', + 'browsePools.stakePoolTableBrowser.sortByTitle.pledge': 'Pledge', + 'browsePools.stakePoolTableBrowser.sortByTitle.profitMargin': 'Profit Margin', + 'browsePools.stakePoolTableBrowser.sortByTitle.ros.lastEpoch': 'Last epoch', + 'browsePools.stakePoolTableBrowser.sortByTitle.ros.other': 'other', + 'browsePools.stakePoolTableBrowser.sortByTitle.ros.title': 'ROS', + 'browsePools.stakePoolTableBrowser.sortByTitle.saturation': 'Saturation', + 'browsePools.stakePoolTableBrowser.sortByTitle.ticker': 'Ticker name', 'browsePools.stakePoolTableBrowser.stake': 'Stake', 'browsePools.stakePoolTableBrowser.tableHeader.blocks.title': 'Blocks', 'browsePools.stakePoolTableBrowser.tableHeader.blocks.tooltip': 'Total blocks created by the pool.', diff --git a/packages/staking/src/features/i18n/types.ts b/packages/staking/src/features/i18n/types.ts index 53d5ac3b3..6c1e397ca 100644 --- a/packages/staking/src/features/i18n/types.ts +++ b/packages/staking/src/features/i18n/types.ts @@ -38,6 +38,34 @@ type KeysStructure = { notAvailable: ''; }; stakePoolTableBrowser: { + sortAndFilter: { + input: { + from: ''; + to: ''; + select: ''; + }; + headers: { + sorting: ''; + filters: ''; + moreOptions: ''; + }; + }; + sortByTitle: { + ticker: ''; + saturation: ''; + ros: { + title: ''; + lastEpoch: ''; + other: ''; + }; + cost: ''; + margin: ''; + blocks: ''; + pledge: ''; + livestake: ''; + profitMargin: ''; + performance: ''; + }; searchInputPlaceholder: ''; tableHeader: { ticker: { diff --git a/packages/staking/src/features/theme/colors.ts b/packages/staking/src/features/theme/colors.ts index f2505ee16..272909c34 100644 --- a/packages/staking/src/features/theme/colors.ts +++ b/packages/staking/src/features/theme/colors.ts @@ -4,6 +4,7 @@ export const colorsContract = { $activityNoActivityTextColor: '', $bannerBellIconColor: '', $bannerInfoIconColor: '', + $browsePoolsFilterInputRightBorderColor: '', $dataGreenGradient: '', $dataOrangeGradient: '', $dataPinkGradient: '', @@ -45,6 +46,7 @@ export const lightThemeColors: typeof colorsContract = { $activityNoActivityTextColor: lightColorScheme.$primary_dark_grey, $bannerBellIconColor: lightColorScheme.$primary_accent_purple, $bannerInfoIconColor: lightColorScheme.$primary_accent_purple, + $browsePoolsFilterInputRightBorderColor: lightColorScheme.$primary_light_grey_plus, $dataGreenGradient: `linear-gradient(to right, ${vars.colors.$data_green}, ${vars.colors.$data_green})`, $dataOrangeGradient: `linear-gradient(to right, ${vars.colors.$data_orange}, ${vars.colors.$data_orange})`, $dataPinkGradient: `linear-gradient(to right, ${vars.colors.$data_pink}, ${vars.colors.$data_pink})`, @@ -86,6 +88,7 @@ export const darkThemeColors: typeof colorsContract = { $activityNoActivityTextColor: darkColorScheme.$primary_light_grey, $bannerBellIconColor: darkColorScheme.$primary_accent_purple, $bannerInfoIconColor: darkColorScheme.$primary_accent_purple, + $browsePoolsFilterInputRightBorderColor: darkColorScheme.$primary_grey, $dataGreenGradient: `linear-gradient(to right, ${vars.colors.$data_green}, ${vars.colors.$data_green})`, $dataOrangeGradient: `linear-gradient(to right, ${vars.colors.$data_orange}, ${vars.colors.$data_orange})`, $dataPinkGradient: `linear-gradient(to right, ${vars.colors.$data_pink}, ${vars.colors.$data_pink})`, diff --git a/packages/ui/src/design-system/index.ts b/packages/ui/src/design-system/index.ts index 3e190eb8c..3205c4f4b 100644 --- a/packages/ui/src/design-system/index.ts +++ b/packages/ui/src/design-system/index.ts @@ -39,6 +39,10 @@ export type { ToggleButtonGroupItemProps, } from './toggle-button-group'; export { RadioButtonGroup } from './radio-button'; +export type { + RadioButtonGroupProps, + RadioButtonGroupOption, +} from './radio-button'; export { SelectGroup } from './select'; export { ActionCard } from './action-card'; export { Loader } from './loader'; diff --git a/packages/ui/src/design-system/radio-button/index.tsx b/packages/ui/src/design-system/radio-button/index.tsx index 0f0926372..c1e223efd 100644 --- a/packages/ui/src/design-system/radio-button/index.tsx +++ b/packages/ui/src/design-system/radio-button/index.tsx @@ -1 +1,5 @@ export { RadioButtonGroup } from './radio-button.component'; +export type { + RadioButtonGroupProps, + RadioButtonGroupOption, +} from './radio-button.component'; diff --git a/packages/ui/src/design-system/radio-button/radio-button.component.tsx b/packages/ui/src/design-system/radio-button/radio-button.component.tsx index 88addf3c9..7d9fc82ce 100644 --- a/packages/ui/src/design-system/radio-button/radio-button.component.tsx +++ b/packages/ui/src/design-system/radio-button/radio-button.component.tsx @@ -8,21 +8,20 @@ import { Flex } from '../flex'; import * as cx from './radio-button.css'; -export type Props = Readonly<{ +export interface RadioButtonGroupOption { + value: string; + label: string; + icon?: React.ComponentType>; + onIconClick?: () => void; +} + +export interface RadioButtonGroupProps { disabled?: boolean; className?: string; selectedValue?: string; - - options: { - value: string; - label: string; - icon?: React.ComponentType>; - - onIconClick?: () => void; - }[]; - + options: RadioButtonGroupOption[]; onValueChange: (value: string) => void; -}>; +} export const RadioButtonGroup = ({ disabled = false, @@ -31,55 +30,59 @@ export const RadioButtonGroup = ({ selectedValue, options, ...props -}: Props): JSX.Element => ( - - - {options.map(({ value, label, icon, onIconClick }) => ( - - ): JSX.Element => { + const hasIcon = options.some(({ icon }) => Boolean(icon)); + + return ( + + + {options.map(({ value, label, icon: Icon, onIconClick }) => ( + - - - {label && ( - - )} - {icon !== undefined && value === selectedValue && ( - -
- {React.createElement(icon)} -
-
- )} -
- ))} -
-
-); + + {label} + + + )} + {Icon !== undefined && value === selectedValue && ( + +
+ +
+
+ )} + + ))} + +
+ ); +}; diff --git a/packages/ui/src/design-system/radio-button/radio-button.css.ts b/packages/ui/src/design-system/radio-button/radio-button.css.ts index 507d267cf..9189dd7d0 100644 --- a/packages/ui/src/design-system/radio-button/radio-button.css.ts +++ b/packages/ui/src/design-system/radio-button/radio-button.css.ts @@ -1,20 +1,34 @@ +import { styleVariants } from '@vanilla-extract/css'; + import { style, sx, vars } from '../../design-tokens'; -export const radioGroupRoot = style([ +const radioGroupRootBase = style([ sx({ display: 'flex', flexDirection: 'column', - gap: '$20', - margin: '$0', + gap: '$16', }), { fontFamily: vars.fontFamily.$nova, fontWeight: vars.fontWeights.$semibold, + flexGrow: 1, }, ]); +export const radioGroupRootWithIcon = styleVariants({ + default: [radioGroupRootBase], + withIcon: [ + radioGroupRootBase, + { + gap: 0, + }, + ], +}); + export const radioGroupItemWrapperSelector = style([]); +export const withIcon = style([{ minHeight: 36 }]); + export const radioGroupItem = style([ { width: vars.spacing.$16, @@ -106,6 +120,17 @@ export const radioGroupIndicator = style([ }, ]); +export const iconWrapper = style([ + sx({ + marginLeft: '$18', + width: '$32', + height: '$32', + }), + { + flexGrow: 1, + }, +]); + export const icon = style([ sx({ borderRadius: '$small', @@ -135,7 +160,7 @@ export const icon = style([ export const root = style([ sx({ alignItems: 'center', - justifyContent: 'center', + justifyContent: 'stretch', borderRadius: '$small', }), { @@ -143,10 +168,6 @@ export const root = style([ }, ]); -export const withLabel = style({ - padding: `${vars.spacing.$2} ${vars.spacing.$8}`, -}); - export const label = style({ fontSize: '15px', lineHeight: '1', diff --git a/packages/ui/src/design-system/radio-button/radio-button.stories.tsx b/packages/ui/src/design-system/radio-button/radio-button.stories.tsx index 8bc700f02..adc2ce079 100644 --- a/packages/ui/src/design-system/radio-button/radio-button.stories.tsx +++ b/packages/ui/src/design-system/radio-button/radio-button.stories.tsx @@ -38,7 +38,7 @@ const getOptionsWithIcon = (): { onIconClick: () => void; }[] => [ { - value: `option-${uuid()}`, + value: 'option', label: 'Label', icon: DocumentDownload, onIconClick: (): void => void 0, diff --git a/packages/ui/src/design-system/text-box/text-box.component.tsx b/packages/ui/src/design-system/text-box/text-box.component.tsx index 668aca731..caf1efd02 100644 --- a/packages/ui/src/design-system/text-box/text-box.component.tsx +++ b/packages/ui/src/design-system/text-box/text-box.component.tsx @@ -48,9 +48,7 @@ export const TextBox = ({ diff --git a/packages/ui/src/design-system/text-box/text-box.css.ts b/packages/ui/src/design-system/text-box/text-box.css.ts index 96b2f937b..9b7feef14 100644 --- a/packages/ui/src/design-system/text-box/text-box.css.ts +++ b/packages/ui/src/design-system/text-box/text-box.css.ts @@ -57,8 +57,10 @@ globalStyle(`${container}:has(${input}:disabled)`, { globalStyle(`${container}:has(${input}:hover:not(:disabled))`, { outline: `2px solid ${vars.colors.$input_container_hover_outline_color}`, + outlineOffset: -2, }); globalStyle(`${container}:has(${input}:focus)`, { outline: `3px solid ${vars.colors.$input_container_focused_outline_color}`, + outlineOffset: -3, }); diff --git a/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.component.tsx b/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.component.tsx index 4be0f2e43..57d75a951 100644 --- a/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.component.tsx +++ b/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.component.tsx @@ -2,6 +2,8 @@ import React, { forwardRef } from 'react'; import * as ToggleGroup from '@radix-ui/react-toggle-group'; +import * as Typography from '../typography'; + import * as cx from './toggle-button-group-item.css'; import type { ToggleGroupItemProps } from '@radix-ui/react-toggle-group'; @@ -20,7 +22,9 @@ export const Item = forwardRef( ): JSX.Element => ( {IconComponent && } - {children} + {Boolean(children) && ( + {children} + )} ), ); diff --git a/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.css.ts b/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.css.ts index fdae3f746..a3c7332a3 100644 --- a/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.css.ts +++ b/packages/ui/src/design-system/toggle-button-group/toggle-button-group-item.css.ts @@ -5,7 +5,6 @@ import * as toggleButtonGroupRootCn from './toggle-button-group-root.css'; export const root = style([ sx({ padding: '$8', - fontSize: '$16', color: '$toggle_button_group_item_label_color', backgroundColor: '$toggle_button_group_item_bgColor', borderRadius: '$small', diff --git a/packages/ui/src/design-tokens/sx.css.ts b/packages/ui/src/design-tokens/sx.css.ts index 1e2dab22e..10b3a91b9 100644 --- a/packages/ui/src/design-tokens/sx.css.ts +++ b/packages/ui/src/design-tokens/sx.css.ts @@ -111,6 +111,10 @@ const colorProperties = defineProperties({ const radiusProperties = defineProperties({ properties: { borderRadius: vars.radius, + borderTopLeftRadius: vars.radius, + borderTopRightRadius: vars.radius, + borderBottomRightRadius: vars.radius, + borderBottomLeftRadius: vars.radius, }, }); From 6516722024494584fd3bb81196a345d5895f43db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20K=C5=82os?= <114915819+wklos-iohk@users.noreply.github.com> Date: Thu, 22 Feb 2024 13:56:38 +0100 Subject: [PATCH 11/14] test(extension): enable test for LW-9634 (#907) --- .../assert/multidelegation/MultidelegationPageAssert.ts | 3 +++ .../src/elements/multidelegation/MultidelegationPage.ts | 6 +++--- .../src/features/MultiDelegationPageExtended.feature | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/e2e-tests/src/assert/multidelegation/MultidelegationPageAssert.ts b/packages/e2e-tests/src/assert/multidelegation/MultidelegationPageAssert.ts index 7f8275bf4..313e4bf44 100644 --- a/packages/e2e-tests/src/assert/multidelegation/MultidelegationPageAssert.ts +++ b/packages/e2e-tests/src/assert/multidelegation/MultidelegationPageAssert.ts @@ -188,6 +188,9 @@ class MultidelegationPageAssert { await MultidelegationPage.tooltip.waitForDisplayed(); let expectedTooltipText; switch (columnName) { + case 'Ticker': + expectedTooltipText = await t('browsePools.stakePoolTableBrowser.tableHeader.ticker.tooltip', 'staking'); + break; case 'Saturation': expectedTooltipText = await t('browsePools.stakePoolTableBrowser.tableHeader.saturation.tooltip', 'staking'); break; diff --git a/packages/e2e-tests/src/elements/multidelegation/MultidelegationPage.ts b/packages/e2e-tests/src/elements/multidelegation/MultidelegationPage.ts index 36653e78e..69ba727e7 100644 --- a/packages/e2e-tests/src/elements/multidelegation/MultidelegationPage.ts +++ b/packages/e2e-tests/src/elements/multidelegation/MultidelegationPage.ts @@ -336,16 +336,16 @@ class MultidelegationPage { async hoverOverColumnWithName(columnName: StakePoolListColumnType) { switch (columnName) { case 'Ticker': - await this.columnHeaderTicker.moveTo(); + await this.columnHeaderTicker.moveTo({ xOffset: 1, yOffset: 1 }); break; case 'Saturation': await this.columnHeaderSaturation.moveTo(); break; case 'ROS': - await this.columnHeaderROS.moveTo(); + await this.columnHeaderROS.moveTo({ xOffset: 1, yOffset: 1 }); break; case 'Cost': - await this.columnHeaderCost.moveTo(); + await this.columnHeaderCost.moveTo({ xOffset: 1, yOffset: 1 }); break; case 'Margin': await this.columnHeaderMargin.moveTo({ xOffset: 1, yOffset: 1 }); diff --git a/packages/e2e-tests/src/features/MultiDelegationPageExtended.feature b/packages/e2e-tests/src/features/MultiDelegationPageExtended.feature index 7ef9c6f50..ceab385c5 100644 --- a/packages/e2e-tests/src/features/MultiDelegationPageExtended.feature +++ b/packages/e2e-tests/src/features/MultiDelegationPageExtended.feature @@ -92,14 +92,14 @@ Feature: Staking Page - Extended View Then tooltip for "" column is displayed Examples: | column_name | + | Ticker | | Saturation | -# TODO: Update when LW-9634 is completed -# | ROS | -# | Cost | +# | ROS | #TODO: Uncomment when LW-9827 is resolved + | Cost | | Margin | | Blocks | | Pledge | -# | Live stake | + | Live stake | @LW-8637 @Testnet @Mainnet Scenario: Extended View - Staking password screen details From 4dd914cbdefd7b6177b3f3b0afe397dfbdd35046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojtek=20K=C5=82os?= <114915819+wklos-iohk@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:12:03 +0100 Subject: [PATCH 12/14] test(extension): update WebdriverIO to v8.32.3 (#911) * test(extension): update WebdriverIO to v8.32.3 * test(extension): adjust import statement * test(extension): change default chromedriver execution --- .github/workflows/e2e-tests-linux.yml | 23 - .github/workflows/e2e-tests-win.yml | 14 - .github/workflows/smoke-tests.yml | 16 - packages/e2e-tests/README.md | 4 +- packages/e2e-tests/package.json | 21 +- .../src/elements/transactionDetails.ts | 4 +- .../e2e-tests/src/utils/consoleManager.ts | 2 +- .../e2e-tests/src/utils/networkManager.ts | 2 +- packages/e2e-tests/wdio.conf.chrome.ts | 9 +- packages/e2e-tests/wdio.conf.edge.ts | 9 +- yarn.lock | 1203 +++++++---------- 11 files changed, 542 insertions(+), 765 deletions(-) diff --git a/.github/workflows/e2e-tests-linux.yml b/.github/workflows/e2e-tests-linux.yml index 5482a9f7c..f07432413 100644 --- a/.github/workflows/e2e-tests-linux.yml +++ b/.github/workflows/e2e-tests-linux.yml @@ -46,11 +46,6 @@ jobs: run: ./decrypt_secret.sh env: WALLET_1_PASSWORD: ${{ secrets.WALLET_PASSWORD_TESTNET }} - - name: Downgrade chrome - run: | - wget -q -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_120.0.6099.216-1_amd64.deb \ - && sudo apt install -y --allow-downgrades /tmp/chrome.deb \ - && rm /tmp/chrome.deb - name: Build dist version of Lace uses: ./.github/shared/build with: @@ -58,24 +53,6 @@ jobs: - name: Start XVFB run: | Xvfb :99 & - - name: setup chromedriver - uses: nanasess/setup-chromedriver@v2 - with: - chromedriver-version: '120.0.6099.216' - - name: Start Chrome driver - run: | - if [ ${BROWSER} == "chrome" ]; then - chromedriver -port=4444 & - else - echo "Skipping start of ChromeDriver" - fi - - name: Start Edge driver - run: | - if [ ${BROWSER} == "edge" ]; then - ${EDGEWEBDRIVER}/msedgedriver -port=4444 & - else - echo "Skipping start of EdgeDriver" - fi - name: Execute E2E tests id: e2e-tests working-directory: ./packages/e2e-tests diff --git a/.github/workflows/e2e-tests-win.yml b/.github/workflows/e2e-tests-win.yml index 39dfd33aa..adbdaf16f 100644 --- a/.github/workflows/e2e-tests-win.yml +++ b/.github/workflows/e2e-tests-win.yml @@ -99,20 +99,6 @@ jobs: - name: Install dependencies working-directory: ./packages/e2e-tests run: yarn config set httpTimeout 300000 && yarn install --check-cache --immutable - - name: Start Chrome driver - run: | - if [ ${BROWSER} == "chrome" ]; then - ${CHROMEWEBDRIVER}\chromedriver.exe -port=4444 & - else - echo "Skipping start of ChromeDriver" - fi - - name: Start Edge driver - run: | - if [ ${BROWSER} == "edge" ]; then - ${EDGEWEBDRIVER}\msedgedriver.exe -port=4444 & - else - echo "Skipping start of EdgeDriver" - fi - name: Execute E2E tests working-directory: ./packages/e2e-tests id: e2e-tests diff --git a/.github/workflows/smoke-tests.yml b/.github/workflows/smoke-tests.yml index b68ef3e74..4f4d1638c 100644 --- a/.github/workflows/smoke-tests.yml +++ b/.github/workflows/smoke-tests.yml @@ -22,11 +22,6 @@ jobs: run: ./decrypt_secret.sh env: WALLET_1_PASSWORD: ${{ secrets.WALLET_PASSWORD_TESTNET }} - - name: Downgrade chrome - run: | - wget -q -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_120.0.6099.216-1_amd64.deb \ - && sudo apt install -y --allow-downgrades /tmp/chrome.deb \ - && rm /tmp/chrome.deb - name: Build dist version of Lace uses: ./.github/shared/build with: @@ -34,17 +29,6 @@ jobs: - name: Start XVFB run: | Xvfb :99 & - - name: setup chromedriver - uses: nanasess/setup-chromedriver@v2 - with: - chromedriver-version: '120.0.6099.216' - - name: Start Chrome driver - run: | - if [ ${BROWSER} == "chrome" ]; then - chromedriver -port=4444 & - else - echo "Skipping start of ChromeDriver" - fi - name: Execute E2E tests id: e2e-tests working-directory: ./packages/e2e-tests diff --git a/packages/e2e-tests/README.md b/packages/e2e-tests/README.md index d4331e871..0940b1209 100755 --- a/packages/e2e-tests/README.md +++ b/packages/e2e-tests/README.md @@ -46,7 +46,7 @@ UI-mapped gherkin tests for the Lace browser extension ## Supported params -- `CI=true|false` default = false (optional) +- `STANDALONE_DRIVER=true|false` default = false (optional) - true = use already running chromedriver on port 4444 - false = use webdriver manager - `ENV=(mainnet|preprod|preview)`default = preprod (optional) @@ -59,7 +59,7 @@ UI-mapped gherkin tests for the Lace browser extension ## Run single feature file with params -- `CI=true ENV=preprod WALLET_1_PASSWORD='' yarn wdio run wdio.conf..ts --spec SendTransactionSimpleExtended.feature` +- `ENV=preprod WALLET_1_PASSWORD='' yarn wdio run wdio.conf..ts --spec SendTransactionSimpleExtended.feature` ## Updating walletConfiguration.ts (for development) diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json index 55746c84a..c0b8624df 100755 --- a/packages/e2e-tests/package.json +++ b/packages/e2e-tests/package.json @@ -32,27 +32,28 @@ "devDependencies": { "@rpii/wdio-report-events": "8.0.2", "@types/flat": "5.0.2", + "@types/puppeteer": "7.0.4", "@typescript-eslint/eslint-plugin": "6.0.0", "@typescript-eslint/parser": "6.0.0", - "@wdio/allure-reporter": "8.20.0", - "@wdio/cli": "8.20.0", - "@wdio/config": "8.20.0", - "@wdio/cucumber-framework": "8.20.0", - "@wdio/devtools-service": "8.20.0", - "@wdio/local-runner": "8.20.0", - "@wdio/spec-reporter": "8.20.0", - "@wdio/types": "8.20.0", + "@wdio/allure-reporter": "8.32.2", + "@wdio/cli": "8.32.3", + "@wdio/config": "8.32.3", + "@wdio/cucumber-framework": "8.32.3", + "@wdio/devtools-service": "8.32.3", + "@wdio/local-runner": "8.32.3", + "@wdio/spec-reporter": "8.32.2", + "@wdio/types": "8.32.2", "allure-commandline": "2.24.1", "clipboardy": "2.3.0", "eslint": "8.38.0", "eslint-config-airbnb-base": "15.0.0", "eslint-plugin-import": "2.27.5", - "eslint-plugin-wdio": "8.20.0", + "eslint-plugin-wdio": "8.24.12", "flat": "5.0.2", "npm-run-all": "4.1.5", "ts-node": "10.9.1", "typescript": "4.9.5", "wdio-intercept-service": "4.4.0", - "webdriverio": "8.20.0" + "webdriverio": "8.32.3" } } diff --git a/packages/e2e-tests/src/elements/transactionDetails.ts b/packages/e2e-tests/src/elements/transactionDetails.ts index 61a541b8d..aa8faa16c 100644 --- a/packages/e2e-tests/src/elements/transactionDetails.ts +++ b/packages/e2e-tests/src/elements/transactionDetails.ts @@ -163,12 +163,12 @@ class ActivityDetailsPage extends CommonDrawerElements { async getTransactionSentTokensForBundle(index = 0): Promise { const array = await this.transactionSentTokensForBundle(index); - return Promise.all(array.map(async (element) => await element.getText())); + return Promise.all(await array.map(async (element) => await element.getText())); } async getTransactionSentTokensWithoutDuplicates(): Promise { const array = await this.transactionSentTokens(); - const arr = Promise.all(array.map(async (element) => (await element.getText()).split(' ').pop())); + const arr = Promise.all(await array.map(async (element) => (await element.getText()).split(' ').pop())); return [...new Set(await arr)]; } diff --git a/packages/e2e-tests/src/utils/consoleManager.ts b/packages/e2e-tests/src/utils/consoleManager.ts index 5879ea8f5..577d7a9e6 100644 --- a/packages/e2e-tests/src/utils/consoleManager.ts +++ b/packages/e2e-tests/src/utils/consoleManager.ts @@ -1,4 +1,4 @@ -import { CDPSession } from 'puppeteer-core/lib/esm/puppeteer/common/Connection'; +import { CDPSession } from 'puppeteer'; import { browser } from '@wdio/globals'; export interface ConsoleLogEntry { diff --git a/packages/e2e-tests/src/utils/networkManager.ts b/packages/e2e-tests/src/utils/networkManager.ts index d13fddf30..18c96a2f3 100644 --- a/packages/e2e-tests/src/utils/networkManager.ts +++ b/packages/e2e-tests/src/utils/networkManager.ts @@ -2,7 +2,7 @@ import { ChainablePromiseElement } from 'webdriverio'; import { Logger } from '../support/logger'; import allure from '@wdio/allure-reporter'; -import { CDPSession } from 'puppeteer-core/lib/esm/puppeteer/common/Connection'; +import { CDPSession } from 'puppeteer'; import { browser } from '@wdio/globals'; export class NetworkManager { diff --git a/packages/e2e-tests/wdio.conf.chrome.ts b/packages/e2e-tests/wdio.conf.chrome.ts index 11c1fb857..ea5ff45f2 100755 --- a/packages/e2e-tests/wdio.conf.chrome.ts +++ b/packages/e2e-tests/wdio.conf.chrome.ts @@ -3,13 +3,14 @@ import { config as baseConfig } from './wdio.conf.base'; -const chromeConfig: WebdriverIO.Config = { +const chromeConfig = { capabilities: [ { maxInstances: 1, browserName: 'chrome', - ...(process.env.CI && { hostname: 'localhost' }), - ...(process.env.CI && { port: 4444 }), + browserVersion: 'stable', + ...(String(process.env.STANDALONE_DRIVER) === 'true' && { hostname: 'localhost' }), + ...(String(process.env.STANDALONE_DRIVER) === 'true' && { port: 4444 }), 'goog:chromeOptions': { args: [ '--no-sandbox', @@ -35,7 +36,7 @@ const chromeConfig: WebdriverIO.Config = { services: ['devtools', 'intercept'] }; -if (process.env.CI) { +if (String(process.env.STANDALONE_DRIVER) === 'true') { fetch('http://127.0.0.1:4444/wd/hub').catch(() => { throw new Error("chromedriver doesn't seem to be running, please start it first"); }); diff --git a/packages/e2e-tests/wdio.conf.edge.ts b/packages/e2e-tests/wdio.conf.edge.ts index a00eb5983..8ab1c4a74 100755 --- a/packages/e2e-tests/wdio.conf.edge.ts +++ b/packages/e2e-tests/wdio.conf.edge.ts @@ -2,13 +2,14 @@ import { config as baseConfig } from './wdio.conf.base'; -const edgeConfig: WebdriverIO.Config = { +const edgeConfig = { capabilities: [ { maxInstances: 1, browserName: 'MicrosoftEdge', - ...(process.env.CI && { hostname: 'localhost' }), - ...(process.env.CI && { port: 4444 }), + browserVersion: 'stable', + ...(String(process.env.STANDALONE_DRIVER) === 'true' && { hostname: 'localhost' }), + ...(String(process.env.STANDALONE_DRIVER) === 'true' && { port: 4444 }), 'ms:edgeOptions': { args: [ '--disable-gpu', @@ -33,7 +34,7 @@ const edgeConfig: WebdriverIO.Config = { services: ['devtools', 'intercept'] }; -if (process.env.CI) { +if (String(process.env.STANDALONE_DRIVER) === 'true') { fetch('http://127.0.0.1:4444/wd/hub').catch(() => { throw new Error("chromedriver doesn't seem to be running, please start it first or use CI=false"); }); diff --git a/yarn.lock b/yarn.lock index 2e566e3a0..2113deea5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8344,12 +8344,12 @@ __metadata: languageName: node linkType: hard -"@cucumber/gherkin@npm:27.0.0": - version: 27.0.0 - resolution: "@cucumber/gherkin@npm:27.0.0" +"@cucumber/gherkin@npm:28.0.0": + version: 28.0.0 + resolution: "@cucumber/gherkin@npm:28.0.0" dependencies: - "@cucumber/messages": ">=19.1.4 <=22" - checksum: e951304648ef9385935bf1e8bdca562f6fd66d5da27b7b840d7ee0f42992b0c86842f418f54c15ee6ce2c44bb5c3409af46ec75066fc9a4dcf3bc59ca3af64c1 + "@cucumber/messages": ">=19.1.4 <=24" + checksum: de0681fbbf4532b7529cd037d2c91faa2490d2b973c5bddad0f07bedc1b3130006b7e551286034cf21a4fa74072354bd49bbe59a2bdf7206bc7a357ab43fbd69 languageName: node linkType: hard @@ -8392,6 +8392,18 @@ __metadata: languageName: node linkType: hard +"@cucumber/messages@npm:24.0.1, @cucumber/messages@npm:>=19.1.4 <=24": + version: 24.0.1 + resolution: "@cucumber/messages@npm:24.0.1" + dependencies: + "@types/uuid": 9.0.7 + class-transformer: 0.5.1 + reflect-metadata: 0.2.1 + uuid: 9.0.1 + checksum: 65ee49ed1019d822bb36a50f8fbb46c33dc8b37d0a54dca44fecc3988e763348927a755e1ba8e05804b4cc9540e3a5dc71174f8fb1c3e1ced60b73466c1672dd + languageName: node + linkType: hard + "@cucumber/messages@npm:^19.1.4": version: 19.1.4 resolution: "@cucumber/messages@npm:19.1.4" @@ -9969,15 +9981,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect-utils@npm:^29.6.1": - version: 29.6.1 - resolution: "@jest/expect-utils@npm:29.6.1" - dependencies: - jest-get-type: ^29.4.3 - checksum: 037ee017eca62f7b45e1465fb5c6f9e92d5709a9ac716b8bff0bd294240a54de734e8f968fb69309cc4aef6c83b9552d5a821f3b18371af394bf04783859d706 - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -10160,15 +10163,6 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^29.6.0": - version: 29.6.0 - resolution: "@jest/schemas@npm:29.6.0" - dependencies: - "@sinclair/typebox": ^0.27.8 - checksum: c00511c69cf89138a7d974404d3a5060af375b5a52b9c87215d91873129b382ca11c1ff25bd6d605951404bb381ddce5f8091004a61e76457da35db1f5c51365 - languageName: node - linkType: hard - "@jest/schemas@npm:^29.6.3": version: 29.6.3 resolution: "@jest/schemas@npm:29.6.3" @@ -10421,20 +10415,6 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^29.6.1": - version: 29.6.1 - resolution: "@jest/types@npm:29.6.1" - dependencies: - "@jest/schemas": ^29.6.0 - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^3.0.0 - "@types/node": "*" - "@types/yargs": ^17.0.8 - chalk: ^4.0.0 - checksum: 89fc1ccf71a84fe0da643e0675b1cfe6a6f19ea72e935b2ab1dbdb56ec547e94433fb59b3536d3832a6e156c077865b7176fe9dae707dab9c3d2f9405ba6233c - languageName: node - linkType: hard - "@jest/types@npm:^29.6.3": version: 29.6.3 resolution: "@jest/types@npm:29.6.3" @@ -10799,16 +10779,17 @@ __metadata: "@types/chai-sorted": 0.2.3 "@types/chai-string": 1.4.5 "@types/flat": 5.0.2 + "@types/puppeteer": 7.0.4 "@typescript-eslint/eslint-plugin": 6.0.0 "@typescript-eslint/parser": 6.0.0 - "@wdio/allure-reporter": 8.20.0 - "@wdio/cli": 8.20.0 - "@wdio/config": 8.20.0 - "@wdio/cucumber-framework": 8.20.0 - "@wdio/devtools-service": 8.20.0 - "@wdio/local-runner": 8.20.0 - "@wdio/spec-reporter": 8.20.0 - "@wdio/types": 8.20.0 + "@wdio/allure-reporter": 8.32.2 + "@wdio/cli": 8.32.3 + "@wdio/config": 8.32.3 + "@wdio/cucumber-framework": 8.32.3 + "@wdio/devtools-service": 8.32.3 + "@wdio/local-runner": 8.32.3 + "@wdio/spec-reporter": 8.32.2 + "@wdio/types": 8.32.2 allure-commandline: 2.24.1 chai: 4.3.10 chai-sorted: 0.2.0 @@ -10817,13 +10798,13 @@ __metadata: eslint: 8.38.0 eslint-config-airbnb-base: 15.0.0 eslint-plugin-import: 2.27.5 - eslint-plugin-wdio: 8.20.0 + eslint-plugin-wdio: 8.24.12 flat: 5.0.2 npm-run-all: 4.1.5 ts-node: 10.9.1 typescript: 4.9.5 wdio-intercept-service: 4.4.0 - webdriverio: 8.20.0 + webdriverio: 8.32.3 languageName: unknown linkType: soft @@ -11087,10 +11068,12 @@ __metadata: languageName: node linkType: hard -"@ljharb/through@npm:^2.3.9": - version: 2.3.9 - resolution: "@ljharb/through@npm:2.3.9" - checksum: a47ffed12ef4b08d07458db8bff5f7a13a7030fddf7dbfa947a765581a634d42ee90f7b8c249315aad122c21ad061e97a74f65aef3c03d2c09291d11312f0bfb +"@ljharb/through@npm:^2.3.11": + version: 2.3.12 + resolution: "@ljharb/through@npm:2.3.12" + dependencies: + call-bind: ^1.0.5 + checksum: d5a78568cd3025c03264a9f9c61b30511d27cb9611fae7575cb1339a1baa1a263b6af03e28505b821324f3c6285086ee5add612b8b0155d1f253ed5159cd3f56 languageName: node linkType: hard @@ -11636,6 +11619,24 @@ __metadata: languageName: node linkType: hard +"@puppeteer/browsers@npm:2.1.0": + version: 2.1.0 + resolution: "@puppeteer/browsers@npm:2.1.0" + dependencies: + debug: 4.3.4 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.4.0 + semver: 7.6.0 + tar-fs: 3.0.5 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + bin: + browsers: lib/cjs/main-cli.js + checksum: 318740056fc716cf26179f053eb47e119bc01658f59382a19fb7d39e5b9232a7ad7d82e33445e0519683c13e22b328193fc9952c99d09cdc09f6539391d4749c + languageName: node + linkType: hard + "@puppeteer/browsers@npm:^1.6.0": version: 1.7.1 resolution: "@puppeteer/browsers@npm:1.7.1" @@ -19704,6 +19705,15 @@ __metadata: languageName: node linkType: hard +"@types/puppeteer@npm:7.0.4": + version: 7.0.4 + resolution: "@types/puppeteer@npm:7.0.4" + dependencies: + puppeteer: "*" + checksum: c84a44b054454c13935a9cf0f8983166e238532397af4f321c918d89b43a91f854460e3d0dda122f72c258b444dbcdc04ada950e35adc1938ff3b7831c6fd7a4 + languageName: node + linkType: hard + "@types/qs@npm:*, @types/qs@npm:^6.9.5": version: 6.9.7 resolution: "@types/qs@npm:6.9.7" @@ -20018,7 +20028,7 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^9.0.1": +"@types/uuid@npm:9.0.7, @types/uuid@npm:^9.0.1": version: 9.0.7 resolution: "@types/uuid@npm:9.0.7" checksum: c7321194aeba9ea173efd1e721403bdf4e7ae6945f8f8cdbc87c791f4b505ccf3dbc4a8883d90b394ef13b7c2dc778045792b05dbb23b3c746f8ea347804d448 @@ -20899,6 +20909,17 @@ __metadata: languageName: node linkType: hard +"@vitest/snapshot@npm:^1.2.1, @vitest/snapshot@npm:^1.2.2": + version: 1.3.1 + resolution: "@vitest/snapshot@npm:1.3.1" + dependencies: + magic-string: ^0.30.5 + pathe: ^1.1.1 + pretty-format: ^29.7.0 + checksum: 5feb485bce446316594fff955a32dff68294f24dbcaeeea3a04175306d9319e62419a63c038d580db412c308c529c3fbaa5ea21365e9a3c4f1ed7e774e58de75 + languageName: node + linkType: hard + "@vitest/spy@npm:0.31.0": version: 0.31.0 resolution: "@vitest/spy@npm:0.31.0" @@ -20939,31 +20960,32 @@ __metadata: languageName: node linkType: hard -"@wdio/allure-reporter@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/allure-reporter@npm:8.20.0" +"@wdio/allure-reporter@npm:8.32.2": + version: 8.32.2 + resolution: "@wdio/allure-reporter@npm:8.32.2" dependencies: "@types/node": ^20.1.0 - "@wdio/reporter": 8.20.0 - "@wdio/types": 8.20.0 + "@wdio/reporter": 8.32.2 + "@wdio/types": 8.32.2 allure-js-commons: ^2.5.0 csv-stringify: ^6.0.4 strip-ansi: ^7.1.0 - checksum: ea1187dc516369f72fa91e372a89877ed382aec5c464d1d1f93361086cc40231ff3a036f16df8a706b368bc42bebe56b4f1d3c4a0d9c971dbb7edfc2f8390001 + checksum: a0ef63804c934d33d21ff008448c85f0ce7a55c771f4906904b7db6865052975ace3ce162320d33d472789ca522f7a4001c70501058e85f99689f461810d63d2 languageName: node linkType: hard -"@wdio/cli@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/cli@npm:8.20.0" +"@wdio/cli@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/cli@npm:8.32.3" dependencies: "@types/node": ^20.1.1 - "@wdio/config": 8.20.0 - "@wdio/globals": 8.20.0 - "@wdio/logger": 8.16.17 - "@wdio/protocols": 8.18.0 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 + "@vitest/snapshot": ^1.2.1 + "@wdio/config": 8.32.3 + "@wdio/globals": 8.32.3 + "@wdio/logger": 8.28.0 + "@wdio/protocols": 8.32.0 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 async-exit-hook: ^2.0.1 chalk: ^5.2.0 chokidar: ^3.5.3 @@ -20971,281 +20993,218 @@ __metadata: dotenv: ^16.3.1 ejs: ^3.1.9 execa: ^8.0.1 - import-meta-resolve: ^3.0.0 - inquirer: 9.2.11 + import-meta-resolve: ^4.0.0 + inquirer: 9.2.12 lodash.flattendeep: ^4.4.0 lodash.pickby: ^4.6.0 lodash.union: ^4.6.0 - read-pkg-up: 10.1.0 + read-pkg-up: 10.0.0 recursive-readdir: ^2.2.3 - webdriverio: 8.20.0 + webdriverio: 8.32.3 yargs: ^17.7.2 bin: wdio: bin/wdio.js - checksum: 2e39de390ffd1a40efbbc17342743b577b590dbca325c376b286a67819e28aeebce90be34d8d26a667f6b0309ec939858057adb9d637325c1d2e0c0ca03b27ec + checksum: 816dbfb35ed44b2f99006cc6f599015bd7612b239728ac9d221d7b57e3dfe3ab3016c5232f4e71ed851e5704c89fdbe8b3a7f8717d360b16adde5e32ecfceb8d languageName: node linkType: hard -"@wdio/config@npm:8.12.1": - version: 8.12.1 - resolution: "@wdio/config@npm:8.12.1" +"@wdio/config@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/config@npm:8.32.3" dependencies: - "@wdio/logger": 8.11.0 - "@wdio/types": 8.10.4 - "@wdio/utils": 8.12.1 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 decamelize: ^6.0.0 deepmerge-ts: ^5.0.0 glob: ^10.2.2 - import-meta-resolve: ^3.0.0 - read-pkg-up: ^9.1.0 - checksum: 8843450d9219ff71800b8699abd7e9291e37eb87275b22a51e4c925b3d2728148913728cb673285982ad02205ad2029e0af7ab98b38b1a53a830408d78affc20 + import-meta-resolve: ^4.0.0 + checksum: ff3ed91d829eb262ab53276f8aeeb0530c5979003d4665bef4f2511fc2ba4f0bae0ec49194f0480f5676eb347c0a811bf83b88216ba66773b979978f47aa60db languageName: node linkType: hard -"@wdio/config@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/config@npm:8.20.0" - dependencies: - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 - decamelize: ^6.0.0 - deepmerge-ts: ^5.0.0 - glob: ^10.2.2 - import-meta-resolve: ^3.0.0 - read-pkg-up: ^10.0.0 - checksum: 25e56a396fd2970aed1c00eae86c2db83e1ee4215a15202a4477f1838c1a913e7033c1db4aee1644fcbf6c6fe744795c52c34f6db9d156422230276b9c44ea74 - languageName: node - linkType: hard - -"@wdio/cucumber-framework@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/cucumber-framework@npm:8.20.0" +"@wdio/cucumber-framework@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/cucumber-framework@npm:8.32.3" dependencies: "@cucumber/cucumber": 9.5.1 - "@cucumber/gherkin": 27.0.0 - "@cucumber/messages": 22.0.0 + "@cucumber/gherkin": 28.0.0 + "@cucumber/messages": 24.0.1 "@types/node": ^20.1.0 - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 glob: ^10.2.2 - got: ^13.0.0 + got: ^12.6.1 is-glob: ^4.0.0 - checksum: d9fd34ee3945d5f61df6519283912c76511d516ecec9f1dc1cb2f094c6869b54a58b42ae01d9d48f3948bea2e7c8a2485e53d2ff139617859786b59a460ea009 + checksum: 789a2434bf8982ea597297651f57b6c2f5ad2f18535034b6c566adaff47225333b1a7ad77ecd7eac485c2d59ef8acb64df18589cb1d599ff532df6cee518428a languageName: node linkType: hard -"@wdio/devtools-service@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/devtools-service@npm:8.20.0" +"@wdio/devtools-service@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/devtools-service@npm:8.32.3" dependencies: "@babel/core": ^7.18.0 "@tracerbench/trace-event": ^8.0.0 "@types/node": ^20.1.0 - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 babel-plugin-istanbul: ^6.1.1 - devtools-protocol: ^0.0.1209236 + devtools-protocol: ^0.0.1262051 istanbul-lib-coverage: ^3.2.0 istanbul-lib-report: ^3.0.0 istanbul-reports: ^3.1.4 lighthouse: 8.6.0 puppeteer-core: 20.3.0 - speedline: ^1.4.3 - stable: ^0.1.8 - webdriverio: 8.20.0 - checksum: 7badaa54dcca22695190bf859acfc6828e6357b4d6d0ba7f00d308469c4c1a562ced2ad664e324ea87f0ab6767cd528c69d1dba745772fc8530f700f43b1c3ac - languageName: node - linkType: hard - -"@wdio/globals@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/globals@npm:8.20.0" - dependencies: - expect-webdriverio: ^4.2.5 - webdriverio: 8.20.0 - dependenciesMeta: - expect-webdriverio: - optional: true - webdriverio: - optional: true - checksum: f32c6853001533540f06c1a1bc5d56898d7ae045baca814754ca7b70eb9c344e10a247b95ebd00c004a4a2f95b8a26cf1d7104e28b12d60ff3416ebce659f60e + webdriverio: 8.32.3 + checksum: 680e3238cd3a308c88f90f9b227c32b1d429f7c5534dbfe1cf326348ae18cd0c5deb682a00dbd0d2a9c41a3a9ee66a721231f1a9c815c55e0d6caec7877b4747 languageName: node linkType: hard -"@wdio/globals@npm:^8.13.1": - version: 8.13.4 - resolution: "@wdio/globals@npm:8.13.4" +"@wdio/globals@npm:8.32.3, @wdio/globals@npm:^8.29.3": + version: 8.32.3 + resolution: "@wdio/globals@npm:8.32.3" dependencies: - expect-webdriverio: ^4.2.5 - webdriverio: 8.13.4 + expect-webdriverio: ^4.11.2 + webdriverio: 8.32.3 dependenciesMeta: expect-webdriverio: optional: true webdriverio: optional: true - checksum: 2a56fc49460c3118d5c100cd3611b43d7256122929aabf0a5bd59f4f6c36073753f2dcc772a28cd02e58916a6ae77741f28b5612f10ec962c560607e6df665ee + checksum: 219d4f782562f065b1be2de5f10aa949eacd38ed4e7b0367994fae7b6f9b303a6e341d94b8a723be44a181677cd76bd4075b1d8df0dc549b6aff86cdea80d722 languageName: node linkType: hard -"@wdio/local-runner@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/local-runner@npm:8.20.0" +"@wdio/local-runner@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/local-runner@npm:8.32.3" dependencies: "@types/node": ^20.1.0 - "@wdio/logger": 8.16.17 - "@wdio/repl": 8.10.1 - "@wdio/runner": 8.20.0 - "@wdio/types": 8.20.0 + "@wdio/logger": 8.28.0 + "@wdio/repl": 8.24.12 + "@wdio/runner": 8.32.3 + "@wdio/types": 8.32.2 async-exit-hook: ^2.0.1 split2: ^4.1.0 stream-buffers: ^3.0.2 - checksum: 505249930713aebd90be67fcd80609abb88c38db9ccb635d5d667142ff4c2a7ca7e9277c0933f03f9e1fa448543c2681bb44ef1a4f571f85b07b004e0afcde68 + checksum: ad354a9bfc30204497d4f5f0b531773fc42e11f642d61534ac2476f6c18679a034f376e1364cb3a4626c46bf9916ea982d20236e4feb38ed82687f62d0c28335 languageName: node linkType: hard -"@wdio/logger@npm:8.11.0, @wdio/logger@npm:^8.11.0": - version: 8.11.0 - resolution: "@wdio/logger@npm:8.11.0" +"@wdio/logger@npm:8.28.0, @wdio/logger@npm:^8.28.0": + version: 8.28.0 + resolution: "@wdio/logger@npm:8.28.0" dependencies: chalk: ^5.1.2 loglevel: ^1.6.0 loglevel-plugin-prefix: ^0.8.4 strip-ansi: ^7.1.0 - checksum: b62d0db074240a993c72d95793606d4fa7890fcbebdff5e344bf5c7be90f8189e94432056c1fbb5e636a74b0f036a8a1d88af6c04e4c01e436e9dfab7048f638 + checksum: d7fe9d1d0b58fa73f1d34b2d1ab54993cfc535564a108e6488df30882bdf9c03602cf3010f2790c162352cea0771c1b44051d01d468dc1cd5c3e6b77afa4e76f languageName: node linkType: hard -"@wdio/logger@npm:8.16.17": - version: 8.16.17 - resolution: "@wdio/logger@npm:8.16.17" +"@wdio/logger@npm:^8.11.0": + version: 8.11.0 + resolution: "@wdio/logger@npm:8.11.0" dependencies: chalk: ^5.1.2 loglevel: ^1.6.0 loglevel-plugin-prefix: ^0.8.4 strip-ansi: ^7.1.0 - checksum: 162da3205eaf636adca8a2e1a74438a3d87b797c0a62fdcc1decd9d0a818dda195532f728c7f78b80857dd1eac3be6d58fe8079b028872055c428b5d59e96386 - languageName: node - linkType: hard - -"@wdio/protocols@npm:8.11.0": - version: 8.11.0 - resolution: "@wdio/protocols@npm:8.11.0" - checksum: 68dc353c8bfb0585773a12f049d0b70073715399317398a4014cc05adb806aa7fe9649c305a90153da4d7f23338fe22a22ffe8d9c6d2e5ff261f3ec5d729d76d + checksum: b62d0db074240a993c72d95793606d4fa7890fcbebdff5e344bf5c7be90f8189e94432056c1fbb5e636a74b0f036a8a1d88af6c04e4c01e436e9dfab7048f638 languageName: node linkType: hard -"@wdio/protocols@npm:8.18.0": - version: 8.18.0 - resolution: "@wdio/protocols@npm:8.18.0" - checksum: 290ba962644131039102c6ba73ab2326d1bd3d94669bf41f5242b4e44bbf306e992221f054b33cce895a40eff01046c8bc81ad289f07bdbeab3bf8d84dc640bb +"@wdio/protocols@npm:8.32.0": + version: 8.32.0 + resolution: "@wdio/protocols@npm:8.32.0" + checksum: 19481090b7de1428f0c1c048ee72ad6136cf136ee7ecbe1bebdedd4362998e184f1dcb26d5dd51880ffbe1f216c5d57a2d5338f81b343c1cd9a1bb15ce48f2da languageName: node linkType: hard -"@wdio/repl@npm:8.10.1": - version: 8.10.1 - resolution: "@wdio/repl@npm:8.10.1" +"@wdio/repl@npm:8.24.12": + version: 8.24.12 + resolution: "@wdio/repl@npm:8.24.12" dependencies: "@types/node": ^20.1.0 - checksum: 7c770769e3db82f743f2dc9f604da8200f6eb7dfe4a708ed0b30e9c9b5c9c627342455991917c884d76448e4cc31054b85f9f843ba09c166faa32de9934571b3 + checksum: 4deb2bc7b5b64a3280c881ebd3a2d582834c406d1e7cd02e3f32dfca17e7178a38316c9398f745c442005050ae0eee1952c5ed62afdb156699e9fef6082c116d languageName: node linkType: hard -"@wdio/reporter@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/reporter@npm:8.20.0" +"@wdio/reporter@npm:8.32.2": + version: 8.32.2 + resolution: "@wdio/reporter@npm:8.32.2" dependencies: "@types/node": ^20.1.0 - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 diff: ^5.0.0 object-inspect: ^1.12.0 - checksum: 67ce0056357db17bbffc7363b79fad66c55be244c9ac23a2c46d1368295ed7d3f50f6160f7d604ffdb07ef5600f996a8e8cd36d1f72fa2538c5b566424d8e912 + checksum: 209922f4ede5672a164376e458e94873f2c919963a5a60db33f1db9b5985139848338726ac888bce091e01f613d5dfa1b8956087e55008cf784ca993e11d4720 languageName: node linkType: hard -"@wdio/runner@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/runner@npm:8.20.0" +"@wdio/runner@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/runner@npm:8.32.3" dependencies: "@types/node": ^20.1.0 - "@wdio/config": 8.20.0 - "@wdio/globals": 8.20.0 - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 + "@wdio/config": 8.32.3 + "@wdio/globals": 8.32.3 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 deepmerge-ts: ^5.0.0 - expect-webdriverio: ^4.2.5 + expect-webdriverio: ^4.11.2 gaze: ^1.1.2 - webdriver: 8.20.0 - webdriverio: 8.20.0 - checksum: 375f87b5a5cda3456aef346b0e849f7b6ac78834370715f84b817d64310e004683200c50d9a8dbd06a86a276b60214e553afd6ea06970c2123ec66b7c615a461 + webdriver: 8.32.3 + webdriverio: 8.32.3 + checksum: 8d1cf3e531d95da7397a83e7da65156a47676ffd6033cc45604d20fa2efd9373b3a6fa4d26fed5a0ff85e05168ee9a7de442c219f8d4e1693ff54647500ba6fc languageName: node linkType: hard -"@wdio/spec-reporter@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/spec-reporter@npm:8.20.0" +"@wdio/spec-reporter@npm:8.32.2": + version: 8.32.2 + resolution: "@wdio/spec-reporter@npm:8.32.2" dependencies: - "@wdio/reporter": 8.20.0 - "@wdio/types": 8.20.0 + "@wdio/reporter": 8.32.2 + "@wdio/types": 8.32.2 chalk: ^5.1.2 easy-table: ^1.2.0 pretty-ms: ^7.0.0 - checksum: 5114da5703d841c19dca6c77924744260fd1ee605addb2ccdc683669910f7a17cf19ca5cb3bb056c4b7b3d545f2a771a224547ebca643c9ebbb51e0e626c5b35 - languageName: node - linkType: hard - -"@wdio/types@npm:8.10.4": - version: 8.10.4 - resolution: "@wdio/types@npm:8.10.4" - dependencies: - "@types/node": ^20.1.0 - checksum: 57c9e1513627453643d008ec9d0dd365e8342ade7a58516672d149ddde5a142f9e09e9224944e712956b6f27ac478ed17fadb4f0a9d1d498e8cba356e3dd976c + checksum: 52f93a241d58094702c5e76aff324515d95f0cf57525054610060b97d5dfbec698107e2e69bab4d84ee9b5c96379a5fbf40fed1cf7df2036dc06f42f58fa2e6f languageName: node linkType: hard -"@wdio/types@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/types@npm:8.20.0" +"@wdio/types@npm:8.32.2": + version: 8.32.2 + resolution: "@wdio/types@npm:8.32.2" dependencies: "@types/node": ^20.1.0 - checksum: c3239b165b7f8dd3fa90f9b6a16375ad2bb5660b36eea74ab7bf50f974ce9b3d3b2e9c72a64bad7662dba04ec88bd88a9ed70c2ae0367aaf9513061e1d560f10 + checksum: d44c11a13a5c7a69a97f42963c2576dc4e7fe46a44b10df5b0d5b45f5ea1a472bca34ab4b0b3b80a227c43cea7aac075efb1fe75595059812315460b54c3d33a languageName: node linkType: hard -"@wdio/utils@npm:8.12.1": - version: 8.12.1 - resolution: "@wdio/utils@npm:8.12.1" - dependencies: - "@wdio/logger": 8.11.0 - "@wdio/types": 8.10.4 - import-meta-resolve: ^3.0.0 - p-iteration: ^1.1.8 - checksum: f5e4ffc5097b59bee6e913c6369a7c7e7e99700a7392ff400eddfffd82a2f2f70b148fff4d866bab39a530eac441f683921a38b2fff0d427b4b720b840ee6aa7 - languageName: node - linkType: hard - -"@wdio/utils@npm:8.20.0": - version: 8.20.0 - resolution: "@wdio/utils@npm:8.20.0" +"@wdio/utils@npm:8.32.3": + version: 8.32.3 + resolution: "@wdio/utils@npm:8.32.3" dependencies: "@puppeteer/browsers": ^1.6.0 - "@wdio/logger": 8.16.17 - "@wdio/types": 8.20.0 + "@wdio/logger": 8.28.0 + "@wdio/types": 8.32.2 decamelize: ^6.0.0 deepmerge-ts: ^5.1.0 edgedriver: ^5.3.5 - geckodriver: ^4.2.0 + geckodriver: ^4.3.1 get-port: ^7.0.0 - got: ^13.0.0 - import-meta-resolve: ^3.0.0 + import-meta-resolve: ^4.0.0 locate-app: ^2.1.0 safaridriver: ^0.1.0 split2: ^4.2.0 wait-port: ^1.0.4 - checksum: cbaa3b5e177e246ebde6e610724ab0076ed854ec081b5d64a1c06b9fcf7d7ee543c2db1f23af5299a2d0d307e8af387529ce2ef697ee96ba2d8247f910c42295 + checksum: 874fa3d194812a477ba6c9a5882703f824324a6be97d4a01cd98054603288f308ccb0ecd77b28330cd7dd82411b01b084d02dd5c0e7875d1ffaa8513176637d9 languageName: node linkType: hard @@ -22525,24 +22484,6 @@ __metadata: languageName: node linkType: hard -"archiver-utils@npm:^2.1.0": - version: 2.1.0 - resolution: "archiver-utils@npm:2.1.0" - dependencies: - glob: ^7.1.4 - graceful-fs: ^4.2.0 - lazystream: ^1.0.0 - lodash.defaults: ^4.2.0 - lodash.difference: ^4.5.0 - lodash.flatten: ^4.4.0 - lodash.isplainobject: ^4.0.6 - lodash.union: ^4.6.0 - normalize-path: ^3.0.0 - readable-stream: ^2.0.0 - checksum: 5665f40bde87ee82cb638177bdccca8cc6e55edea1b94338f7e6b56a1d9367b0d9a39e42b47866eaf84b8c67669a7d250900a226207ecc30fa163b52aae859a5 - languageName: node - linkType: hard - "archiver-utils@npm:^4.0.1": version: 4.0.1 resolution: "archiver-utils@npm:4.0.1" @@ -22557,21 +22498,6 @@ __metadata: languageName: node linkType: hard -"archiver@npm:^5.0.0": - version: 5.3.1 - resolution: "archiver@npm:5.3.1" - dependencies: - archiver-utils: ^2.1.0 - async: ^3.2.3 - buffer-crc32: ^0.2.1 - readable-stream: ^3.6.0 - readdir-glob: ^1.0.0 - tar-stream: ^2.2.0 - zip-stream: ^4.1.0 - checksum: 905b198ed04d26c951b80545d45c7f2e0432ef89977a93af8a762501d659886e39dda0fbffb0d517ff3fa450a3d09a29146e4273c2170624e1988f889fb5302c - languageName: node - linkType: hard - "archiver@npm:^6.0.0": version: 6.0.1 resolution: "archiver@npm:6.0.1" @@ -23203,15 +23129,6 @@ __metadata: languageName: node linkType: hard -"babar@npm:0.2.0": - version: 0.2.0 - resolution: "babar@npm:0.2.0" - dependencies: - colors: ~0.6.2 - checksum: ccfb91822c4cd564c8b6d3078e9a53b1f092fa83babacf11af2ee5d45b011fe2650b104c47dd2af7af6df5e97379013ac22ced8320eff650f378245095a730d0 - languageName: node - linkType: hard - "babel-core@npm:^7.0.0-bridge.0": version: 7.0.0-bridge.0 resolution: "babel-core@npm:7.0.0-bridge.0" @@ -23746,6 +23663,41 @@ __metadata: languageName: node linkType: hard +"bare-events@npm:^2.0.0, bare-events@npm:^2.2.0": + version: 2.2.0 + resolution: "bare-events@npm:2.2.0" + checksum: b3001d61cbb7e6c91c7e47ed1d5701512f94c68955a88c1fe368ff313ba68f372fd701f422d1604fd6ac6e2237024d99373aa14e43a92696755a1f7ae46a8626 + languageName: node + linkType: hard + +"bare-fs@npm:^2.1.1": + version: 2.1.5 + resolution: "bare-fs@npm:2.1.5" + dependencies: + bare-events: ^2.0.0 + bare-os: ^2.0.0 + bare-path: ^2.0.0 + streamx: ^2.13.0 + checksum: 268bc03dd97c2e039f3396d79993640a10bbb5ad30bc7a3a2d406ceb538333b0f79eab33f1db288bcf55fde52c767fa1f25332ac606c27555cc62951c236d346 + languageName: node + linkType: hard + +"bare-os@npm:^2.0.0, bare-os@npm:^2.1.0": + version: 2.2.0 + resolution: "bare-os@npm:2.2.0" + checksum: ed78e2f3ea498e35c7565532ae3aa3b85a7e5e223ab6353de64864823cadff02a2a8b7722e9a6c1a0ff56cb9f21f23ada8e88a085cc0a5d38a7c1bcf65e8f7fd + languageName: node + linkType: hard + +"bare-path@npm:^2.0.0, bare-path@npm:^2.1.0": + version: 2.1.0 + resolution: "bare-path@npm:2.1.0" + dependencies: + bare-os: ^2.1.0 + checksum: 03f260e72bd0ae0df4cd712322a2d3c8c16701ffaa55cf2d517ae62b7f78c64b7ec5bba81ec579367f966472481f5160db282e6663bd0fc8cfb09ebe272d8bba + languageName: node + linkType: hard + "base-x@npm:3.0.9, base-x@npm:^3.0.2, base-x@npm:^3.0.5": version: 3.0.9 resolution: "base-x@npm:3.0.9" @@ -24554,7 +24506,7 @@ __metadata: languageName: node linkType: hard -"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:^0.2.13, buffer-crc32@npm:~0.2.3": +"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:~0.2.3": version: 0.2.13 resolution: "buffer-crc32@npm:0.2.13" checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c @@ -25428,20 +25380,6 @@ __metadata: languageName: node linkType: hard -"chrome-launcher@npm:^0.15.0": - version: 0.15.1 - resolution: "chrome-launcher@npm:0.15.1" - dependencies: - "@types/node": "*" - escape-string-regexp: ^4.0.0 - is-wsl: ^2.2.0 - lighthouse-logger: ^1.0.0 - bin: - print-chrome-path: bin/print-chrome-path.js - checksum: b534221b831afc59a0058a1f8406a77d7b4a592342785418e2ef97099b073609b0ca0e4be39d1ed842aa2b64b02ab5ccb45166eada9a37b775c757fb201d7fa5 - languageName: node - linkType: hard - "chrome-trace-event@npm:^1.0.2": version: 1.0.3 resolution: "chrome-trace-event@npm:1.0.3" @@ -25471,6 +25409,18 @@ __metadata: languageName: node linkType: hard +"chromium-bidi@npm:0.5.9": + version: 0.5.9 + resolution: "chromium-bidi@npm:0.5.9" + dependencies: + mitt: 3.0.1 + urlpattern-polyfill: 10.0.0 + peerDependencies: + devtools-protocol: "*" + checksum: 5885a5ab93ddccc2b64ec6fe5455258c440e235daf7c9fb55e1de32ad95b514b721fae8bb7ddaee48d5c7745b57bdcf8a7114f012a41af3ea34b5fe6f1c22646 + languageName: node + linkType: hard + "ci-info@npm:^2.0.0": version: 2.0.0 resolution: "ci-info@npm:2.0.0" @@ -25928,13 +25878,6 @@ __metadata: languageName: node linkType: hard -"colors@npm:~0.6.2": - version: 0.6.2 - resolution: "colors@npm:0.6.2" - checksum: 3f48cadb26ef1809847f3c0ff1e1dc4b2e2af4ace54dd9cd7491bfcaafef3abaac7cb063cb91f98f305bba8a6fa74720a8856610629f9c889b1eb4cd84a120a3 - languageName: node - linkType: hard - "columnify@npm:^1.6.0": version: 1.6.0 resolution: "columnify@npm:1.6.0" @@ -26083,18 +26026,6 @@ __metadata: languageName: node linkType: hard -"compress-commons@npm:^4.1.0": - version: 4.1.1 - resolution: "compress-commons@npm:4.1.1" - dependencies: - buffer-crc32: ^0.2.13 - crc32-stream: ^4.0.2 - normalize-path: ^3.0.0 - readable-stream: ^3.6.0 - checksum: 0176483211a7304a4a8aa52dbcc149a4c9181ac8a04bfbcc3d1a379174bf5fa56c3b15cec19e5ae3d31f1b1ce35ebb275b792b867000c77bac7162ce4e0ca268 - languageName: node - linkType: hard - "compress-commons@npm:^5.0.1": version: 5.0.1 resolution: "compress-commons@npm:5.0.1" @@ -26758,6 +26689,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:9.0.0": + version: 9.0.0 + resolution: "cosmiconfig@npm:9.0.0" + dependencies: + env-paths: ^2.2.1 + import-fresh: ^3.3.0 + js-yaml: ^4.1.0 + parse-json: ^5.2.0 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: a30c424b53d442ea0bdd24cb1b3d0d8687c8dda4a17ab6afcdc439f8964438801619cdb66e8e79f63b9caa3e6586b60d8bab9ce203e72df6c5e80179b971fe8f + languageName: node + linkType: hard + "cosmiconfig@npm:^6.0.0": version: 6.0.0 resolution: "cosmiconfig@npm:6.0.0" @@ -26875,16 +26823,6 @@ __metadata: languageName: node linkType: hard -"crc32-stream@npm:^4.0.2": - version: 4.0.2 - resolution: "crc32-stream@npm:4.0.2" - dependencies: - crc-32: ^1.2.0 - readable-stream: ^3.4.0 - checksum: 1099559283b86e8a55390228b57ff4d57a74cac6aa8086aa4730f84317c9f93e914aeece115352f2d706a9df7ed75327ffacd86cfe23f040aef821231b528e76 - languageName: node - linkType: hard - "crc32-stream@npm:^5.0.0": version: 5.0.0 resolution: "crc32-stream@npm:5.0.0" @@ -28177,39 +28115,17 @@ __metadata: languageName: node linkType: hard -"devtools-protocol@npm:^0.0.1170846": - version: 0.0.1170846 - resolution: "devtools-protocol@npm:0.0.1170846" - checksum: e2945ad0a0e3a4f978abc43edf3c1c4c1a7897a5950fa8692c0ef6147dc444177dbb6b0edd991710d2c9bb94326aba66f9a7a6c8324ef6cd48c514c05d18336f +"devtools-protocol@npm:0.0.1249869": + version: 0.0.1249869 + resolution: "devtools-protocol@npm:0.0.1249869" + checksum: 549dda02f6d778741930e5abdde3f8e5d39e16fdbe8af38597a974e9c239798dd464250bd7ab4360d77e3d059620e95be7cf05150142473bf9b661ed28a616ed languageName: node linkType: hard -"devtools-protocol@npm:^0.0.1209236": - version: 0.0.1209236 - resolution: "devtools-protocol@npm:0.0.1209236" - checksum: f50157153417e1909ac4ad708df3b67570a64766c9a187c57b104ac8472b90b91f6d2b75715c65ffff68715f8756e52614d2e4305cda208dcdda0b76b6e0e82c - languageName: node - linkType: hard - -"devtools@npm:8.12.1": - version: 8.12.1 - resolution: "devtools@npm:8.12.1" - dependencies: - "@types/node": ^20.1.0 - "@wdio/config": 8.12.1 - "@wdio/logger": 8.11.0 - "@wdio/protocols": 8.11.0 - "@wdio/types": 8.10.4 - "@wdio/utils": 8.12.1 - chrome-launcher: ^0.15.0 - edge-paths: ^3.0.5 - import-meta-resolve: ^3.0.0 - puppeteer-core: 20.3.0 - query-selector-shadow-dom: ^1.0.0 - ua-parser-js: ^1.0.1 - uuid: ^9.0.0 - which: ^3.0.0 - checksum: dd980d79dd88d7ec7d1dc3bb99541f43ae65e5c75533a520706ec0590b74619d59717180a2b950d96a5475eed6c6f70d3780d5866dd72fad3c3a4f38cbc05428 +"devtools-protocol@npm:^0.0.1262051": + version: 0.0.1262051 + resolution: "devtools-protocol@npm:0.0.1262051" + checksum: beaad00059964a661ab056d5e993492742c612c0370c6f08acd91490181c4d4ecf57d316eedb5a37fb6bb59321901d09ce50762f79ea09a50751d86f601b8f8e languageName: node linkType: hard @@ -29059,7 +28975,7 @@ __metadata: languageName: node linkType: hard -"env-paths@npm:^2.2.0": +"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e @@ -30303,10 +30219,10 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-wdio@npm:8.20.0": - version: 8.20.0 - resolution: "eslint-plugin-wdio@npm:8.20.0" - checksum: 4c6333cb4b414c82e3d282e0118f5dda9f72b988afa7632ccf24eb2b4063d7f196039fd4db2aeab1e18e9262096921bec638d1df99cc0c6907521c6d8df54d9f +"eslint-plugin-wdio@npm:8.24.12": + version: 8.24.12 + resolution: "eslint-plugin-wdio@npm:8.24.12" + checksum: b0d0baa71555bc36df30f5654263b7efba2b1990b74637e555688b2d68cb88b3492104451e9135b9985fa50d8510e34c4610734135e7020a91977b63988cd7fd languageName: node linkType: hard @@ -30872,20 +30788,25 @@ __metadata: languageName: node linkType: hard -"expect-webdriverio@npm:^4.2.5": - version: 4.2.7 - resolution: "expect-webdriverio@npm:4.2.7" +"expect-webdriverio@npm:^4.11.2": + version: 4.11.9 + resolution: "expect-webdriverio@npm:4.11.9" dependencies: - "@wdio/globals": ^8.13.1 - expect: ^29.6.1 - jest-matcher-utils: ^29.6.1 - webdriverio: ^8.13.1 + "@vitest/snapshot": ^1.2.2 + "@wdio/globals": ^8.29.3 + "@wdio/logger": ^8.28.0 + expect: ^29.7.0 + jest-matcher-utils: ^29.7.0 + lodash.isequal: ^4.5.0 + webdriverio: ^8.29.3 dependenciesMeta: "@wdio/globals": optional: true + "@wdio/logger": + optional: true webdriverio: optional: true - checksum: 0b1bb7284ad691e8e050904511829533753aa5dd8a1f680f4729fbb94326b93e016bb609e915e019e3ba155830f19313c6c5804849bb0f1fdb4c5724058246ec + checksum: 13331c164cbd6d48cd98c2d1452e1916e8ebf0da09f477adfaf2b578f8e47c7c6425b054a92746b7189bef6d6ef95bc6004bcaf56ecff8e91612caf5bad29f1e languageName: node linkType: hard @@ -30915,20 +30836,6 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.6.1": - version: 29.6.1 - resolution: "expect@npm:29.6.1" - dependencies: - "@jest/expect-utils": ^29.6.1 - "@types/node": "*" - jest-get-type: ^29.4.3 - jest-matcher-utils: ^29.6.1 - jest-message-util: ^29.6.1 - jest-util: ^29.6.1 - checksum: 4e712e52c90f6c54e748fd2876be33c43ada6a59088ddf6a1acb08b18b3b97b3a672124684abe32599986d2f2a438d5afad148837ee06ea386d2a4bf0348de78 - languageName: node - linkType: hard - "expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" @@ -32199,21 +32106,21 @@ __metadata: languageName: node linkType: hard -"geckodriver@npm:^4.2.0": - version: 4.2.1 - resolution: "geckodriver@npm:4.2.1" +"geckodriver@npm:^4.3.1": + version: 4.3.3 + resolution: "geckodriver@npm:4.3.3" dependencies: - "@wdio/logger": ^8.11.0 + "@wdio/logger": ^8.28.0 decamelize: ^6.0.0 - http-proxy-agent: ^7.0.0 - https-proxy-agent: ^7.0.1 - node-fetch: ^3.3.1 - tar-fs: ^3.0.4 + http-proxy-agent: ^7.0.2 + https-proxy-agent: ^7.0.4 + node-fetch: ^3.3.2 + tar-fs: ^3.0.5 unzipper: ^0.10.14 which: ^4.0.0 bin: geckodriver: bin/geckodriver.js - checksum: 9773cd8c6002cdee49cad8dddd6908ff4bc00fe0eda01e47be1ea1c1a744ea265c4b81e30f4b3dafb9dc7386ed948ed4efb8e6b55be74e82b04079a482fd1f57 + checksum: 554eb3bf81a7b96b49fa019c15a548d7510d36c6952f1c58ac90336576ecc9d5fb5d229d0d5023d58f80aae7ad7d60df7a05f14c1a97e3bc35d0fce8d683b46f languageName: node linkType: hard @@ -33802,6 +33709,16 @@ __metadata: languageName: node linkType: hard +"http-proxy-agent@npm:^7.0.1, http-proxy-agent@npm:^7.0.2": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + "http-proxy-middleware@npm:^2.0.3": version: 2.0.6 resolution: "http-proxy-middleware@npm:2.0.6" @@ -33912,7 +33829,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": +"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "https-proxy-agent@npm:7.0.2" dependencies: @@ -33922,6 +33839,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^7.0.3, https-proxy-agent@npm:^7.0.4": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: ^7.0.2 + debug: 4 + checksum: daaab857a967a2519ddc724f91edbbd388d766ff141b9025b629f92b9408fc83cee8a27e11a907aede392938e9c398e240d643e178408a59e4073539cde8cfe9 + languageName: node + linkType: hard + "human-signals@npm:^2.1.0": version: 2.1.0 resolution: "human-signals@npm:2.1.0" @@ -34162,10 +34089,10 @@ __metadata: languageName: node linkType: hard -"import-meta-resolve@npm:^3.0.0": - version: 3.0.0 - resolution: "import-meta-resolve@npm:3.0.0" - checksum: d0428cd14915ee0093b995dc5bbc70bd01cc668822f52b62af98f728e5d6a08724f07e6aa9f5fae002d5eecbf6ec2cdcd379bf4869dd1b353bd080693f91e394 +"import-meta-resolve@npm:^4.0.0": + version: 4.0.0 + resolution: "import-meta-resolve@npm:4.0.0" + checksum: 51c50115fd38e9ba21736f8d7543a58446b92d2cb5f38c9b5ec72426afeb2fb790f82051560a0f16323f44dd73d8d37c07eab5f8dc4635bcdb401daa36727b1a languageName: node linkType: hard @@ -34301,11 +34228,11 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:9.2.11": - version: 9.2.11 - resolution: "inquirer@npm:9.2.11" +"inquirer@npm:9.2.12": + version: 9.2.12 + resolution: "inquirer@npm:9.2.12" dependencies: - "@ljharb/through": ^2.3.9 + "@ljharb/through": ^2.3.11 ansi-escapes: ^4.3.2 chalk: ^5.3.0 cli-cursor: ^3.1.0 @@ -34320,7 +34247,7 @@ __metadata: string-width: ^4.2.3 strip-ansi: ^6.0.1 wrap-ansi: ^6.2.0 - checksum: af59b422eb6005dac90f6c5e8295013d0611ac5471ff4fbf4ad3e228136e0f41db73af2d5a68e36770f9e31ac203ae1589d35c3e970acbc6110bb5df905928f9 + checksum: 8c372832367f5adb4bb08a0c3ee3b8b16e83202c125d1a681ece2c0ef2f00a5d7d6589a501fd58a0249b4ad49a8013584ac58ae12a20d29b1c24a0ec450927a5 languageName: node linkType: hard @@ -34622,7 +34549,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:2.11.0, is-core-module@npm:^2.11.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": +"is-core-module@npm:2.11.0, is-core-module@npm:^2.11.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": version: 2.11.0 resolution: "is-core-module@npm:2.11.0" dependencies: @@ -35878,18 +35805,6 @@ __metadata: languageName: node linkType: hard -"jest-diff@npm:^29.6.1": - version: 29.6.1 - resolution: "jest-diff@npm:29.6.1" - dependencies: - chalk: ^4.0.0 - diff-sequences: ^29.4.3 - jest-get-type: ^29.4.3 - pretty-format: ^29.6.1 - checksum: c6350178ca27d92c7fd879790fb2525470c1ff1c5d29b1834a240fecd26c6904fb470ebddb98dc96dd85389c56c3b50e6965a1f5203e9236d213886ed9806219 - languageName: node - linkType: hard - "jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" @@ -36018,13 +35933,6 @@ __metadata: languageName: node linkType: hard -"jest-get-type@npm:^29.4.3": - version: 29.4.3 - resolution: "jest-get-type@npm:29.4.3" - checksum: 6ac7f2dde1c65e292e4355b6c63b3a4897d7e92cb4c8afcf6d397f2682f8080e094c8b0b68205a74d269882ec06bf696a9de6cd3e1b7333531e5ed7b112605ce - languageName: node - linkType: hard - "jest-get-type@npm:^29.6.3": version: 29.6.3 resolution: "jest-get-type@npm:29.6.3" @@ -36190,18 +36098,6 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^29.6.1": - version: 29.6.1 - resolution: "jest-matcher-utils@npm:29.6.1" - dependencies: - chalk: ^4.0.0 - jest-diff: ^29.6.1 - jest-get-type: ^29.4.3 - pretty-format: ^29.6.1 - checksum: d2efa6aed6e4820758b732b9fefd315c7fa4508ee690da656e1c5ac4c1a0f4cee5b04c9719ee1fda9aeb883b4209186c145089ced521e715b9fa70afdfa4a9c6 - languageName: node - linkType: hard - "jest-matcher-utils@npm:^29.7.0": version: 29.7.0 resolution: "jest-matcher-utils@npm:29.7.0" @@ -36265,23 +36161,6 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^29.6.1": - version: 29.6.1 - resolution: "jest-message-util@npm:29.6.1" - dependencies: - "@babel/code-frame": ^7.12.13 - "@jest/types": ^29.6.1 - "@types/stack-utils": ^2.0.0 - chalk: ^4.0.0 - graceful-fs: ^4.2.9 - micromatch: ^4.0.4 - pretty-format: ^29.6.1 - slash: ^3.0.0 - stack-utils: ^2.0.3 - checksum: 3e7cb2ff087fe72255292e151d24e4fbb4cd6134885c0a67a4b302f233fe4110bf7580b176f427f05ad7550eb878ed94237209785d09d659a7d171ffa59c068f - languageName: node - linkType: hard - "jest-message-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-message-util@npm:29.7.0" @@ -36772,20 +36651,6 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^29.6.1": - version: 29.6.1 - resolution: "jest-util@npm:29.6.1" - dependencies: - "@jest/types": ^29.6.1 - "@types/node": "*" - chalk: ^4.0.0 - ci-info: ^3.2.0 - graceful-fs: ^4.2.9 - picomatch: ^2.2.3 - checksum: fc553556c1350c443449cadaba5fb9d604628e8b5ceb6ceaf4e7e08975b24277d0a14bf2e0f956024e03c23e556fcb074659423422a06fbedf2ab52978697ac7 - languageName: node - linkType: hard - "jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" @@ -38428,27 +38293,6 @@ __metadata: languageName: node linkType: hard -"lodash.defaults@npm:^4.2.0": - version: 4.2.0 - resolution: "lodash.defaults@npm:4.2.0" - checksum: 84923258235592c8886e29de5491946ff8c2ae5c82a7ac5cddd2e3cb697e6fbdfbbb6efcca015795c86eec2bb953a5a2ee4016e3735a3f02720428a40efbb8f1 - languageName: node - linkType: hard - -"lodash.difference@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.difference@npm:4.5.0" - checksum: ecee276aa578f300e79350805a14a51be8d1f12b3c1389a19996d8ab516f814211a5f65c68331571ecdad96522b863ccc484b55504ce8c9947212a29f8857d5a - languageName: node - linkType: hard - -"lodash.flatten@npm:^4.4.0": - version: 4.4.0 - resolution: "lodash.flatten@npm:4.4.0" - checksum: 0ac34a393d4b795d4b7421153d27c13ae67e08786c9cbb60ff5b732210d46f833598eee3fb3844bb10070e8488efe390ea53bb567377e0cb47e9e630bf0811cb - languageName: node - linkType: hard - "lodash.flattendeep@npm:^4.4.0": version: 4.4.0 resolution: "lodash.flattendeep@npm:4.4.0" @@ -38687,7 +38531,7 @@ __metadata: languageName: node linkType: hard -"loud-rejection@npm:^1.0.0, loud-rejection@npm:^1.6.0": +"loud-rejection@npm:^1.0.0": version: 1.6.0 resolution: "loud-rejection@npm:1.6.0" dependencies: @@ -38865,6 +38709,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.5": + version: 0.30.7 + resolution: "magic-string@npm:0.30.7" + dependencies: + "@jridgewell/sourcemap-codec": ^1.4.15 + checksum: bdf102e36a44d1728ec61b69d655caba3f66ca58898e292f6debe57dc30896bd37908bfe3464a7464a435831a9e44aa905cebd681e21c2f44bbe4dddf225619f + languageName: node + linkType: hard + "make-dir@npm:^2.0.0, make-dir@npm:^2.1.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" @@ -39339,7 +39192,7 @@ __metadata: languageName: node linkType: hard -"meow@npm:^3.1.0, meow@npm:^3.7.0": +"meow@npm:^3.1.0": version: 3.7.0 resolution: "meow@npm:3.7.0" dependencies: @@ -39904,6 +39757,13 @@ __metadata: languageName: node linkType: hard +"mitt@npm:3.0.1": + version: 3.0.1 + resolution: "mitt@npm:3.0.1" + checksum: b55a489ac9c2949ab166b7f060601d3b6d893a852515ae9eca4e11df01c013876df777ea109317622b5c1c60e8aae252558e33c8c94e14124db38f64a39614b1 + languageName: node + linkType: hard + "mixin-deep@npm:^1.2.0": version: 1.3.2 resolution: "mixin-deep@npm:1.3.2" @@ -40652,18 +40512,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^3.0.2": - version: 3.0.3 - resolution: "normalize-package-data@npm:3.0.3" - dependencies: - hosted-git-info: ^4.0.1 - is-core-module: ^2.5.0 - semver: ^7.3.4 - validate-npm-package-license: ^3.0.1 - checksum: bbcee00339e7c26fdbc760f9b66d429258e2ceca41a5df41f5df06cc7652de8d82e8679ff188ca095cad8eff2b6118d7d866af2b68400f74602fbcbce39c160a - languageName: node - linkType: hard - "normalize-package-data@npm:^5.0.0": version: 5.0.0 resolution: "normalize-package-data@npm:5.0.0" @@ -41512,13 +41360,6 @@ __metadata: languageName: node linkType: hard -"p-iteration@npm:^1.1.8": - version: 1.1.8 - resolution: "p-iteration@npm:1.1.8" - checksum: 3eb8d8affc2ef947c076807e5c57030949abad0ff81759ebc54fc43823e30ce918e69b035bf1884991c61b7885c77efaf32c0de7ac01110a2c874f6aa81e0d7f - languageName: node - linkType: hard - "p-limit@npm:^1.1.0": version: 1.3.0 resolution: "p-limit@npm:1.3.0" @@ -42104,6 +41945,13 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.1": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: ec5f778d9790e7b9ffc3e4c1df39a5bb1ce94657a4e3ad830c1276491ca9d79f189f47609884671db173400256b005f4955f7952f52a2aeb5834ad5fb4faf134 + languageName: node + linkType: hard + "pathval@npm:^1.1.1": version: 1.1.1 resolution: "pathval@npm:1.1.1" @@ -43346,17 +43194,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.6.1": - version: 29.6.1 - resolution: "pretty-format@npm:29.6.1" - dependencies: - "@jest/schemas": ^29.6.0 - ansi-styles: ^5.0.0 - react-is: ^18.0.0 - checksum: 6f923a2379a37a425241dc223d76f671c73c4f37dba158050575a54095867d565c068b441843afdf3d7c37bed9df4bbadf46297976e60d4149972b779474203a - languageName: node - linkType: hard - "pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" @@ -43634,6 +43471,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:6.4.0": + version: 6.4.0 + resolution: "proxy-agent@npm:6.4.0" + dependencies: + agent-base: ^7.0.2 + debug: ^4.3.4 + http-proxy-agent: ^7.0.1 + https-proxy-agent: ^7.0.3 + lru-cache: ^7.14.1 + pac-proxy-agent: ^7.0.1 + proxy-from-env: ^1.1.0 + socks-proxy-agent: ^8.0.2 + checksum: 4d3794ad5e07486298902f0a7f250d0f869fa0e92d790767ca3f793a81374ce0ab6c605f8ab8e791c4d754da96656b48d1c24cb7094bfd310a15867e4a0841d7 + languageName: node + linkType: hard + "proxy-from-env@npm:1.1.0, proxy-from-env@npm:^1.0.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -43763,6 +43616,20 @@ __metadata: languageName: node linkType: hard +"puppeteer-core@npm:22.2.0": + version: 22.2.0 + resolution: "puppeteer-core@npm:22.2.0" + dependencies: + "@puppeteer/browsers": 2.1.0 + chromium-bidi: 0.5.9 + cross-fetch: 4.0.0 + debug: 4.3.4 + devtools-protocol: 0.0.1249869 + ws: 8.16.0 + checksum: 270d765169224d1ef8864cb0e8519e1c99cc979ba56c05c2b207fdf5862322c6c3e817885e12af6996d3ce21e9a2d62ff73ab531872febd1d2b3fccc0f86fab1 + languageName: node + linkType: hard + "puppeteer-core@npm:^2.1.1": version: 2.1.1 resolution: "puppeteer-core@npm:2.1.1" @@ -43800,6 +43667,19 @@ __metadata: languageName: node linkType: hard +"puppeteer@npm:*": + version: 22.2.0 + resolution: "puppeteer@npm:22.2.0" + dependencies: + "@puppeteer/browsers": 2.1.0 + cosmiconfig: 9.0.0 + puppeteer-core: 22.2.0 + bin: + puppeteer: lib/esm/puppeteer/node/cli.js + checksum: a5d604367f9b6432b5d6318b60d1b789b4af53e658bd423c1f5e3e35d85dc10bde6536450b1a04cb2f0af2c5485c38a99466eed8917d31ea840ce23c9fdec5c0 + languageName: node + linkType: hard + "pure-rand@npm:^6.0.0": version: 6.0.4 resolution: "pure-rand@npm:6.0.4" @@ -45620,14 +45500,14 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:10.1.0, read-pkg-up@npm:^10.0.0": - version: 10.1.0 - resolution: "read-pkg-up@npm:10.1.0" +"read-pkg-up@npm:10.0.0": + version: 10.0.0 + resolution: "read-pkg-up@npm:10.0.0" dependencies: find-up: ^6.3.0 - read-pkg: ^8.1.0 - type-fest: ^4.2.0 - checksum: 554470d7ff54026b561f6c851c35470f5bc95a47bfb8645dc13c447d83c42c78b42d47fffdc8f86bffe731215406dab498f75cb27494e1fb3eca7fa8d00fb501 + read-pkg: ^8.0.0 + type-fest: ^3.12.0 + checksum: af179c3c5d3808bfef112b004267074d64b2a67b9aeab1e7f8259d0cd77ae39b260695a2b6dd247d10cb9fb25074d964bcc8f6e42c09f20d58403404b1a50b9d languageName: node linkType: hard @@ -45662,17 +45542,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^9.1.0": - version: 9.1.0 - resolution: "read-pkg-up@npm:9.1.0" - dependencies: - find-up: ^6.3.0 - read-pkg: ^7.1.0 - type-fest: ^2.5.0 - checksum: 41b8ba4bdb7c1e914aa6ce2d36a7c1651e9086938977fa12f058f6fca51ee15315634af648ca4ef70dd074e575e854616b39032ad0b376e9e97d61a9d0867afe - languageName: node - linkType: hard - "read-pkg@npm:^1.0.0": version: 1.1.0 resolution: "read-pkg@npm:1.1.0" @@ -45707,19 +45576,7 @@ __metadata: languageName: node linkType: hard -"read-pkg@npm:^7.1.0": - version: 7.1.0 - resolution: "read-pkg@npm:7.1.0" - dependencies: - "@types/normalize-package-data": ^2.4.1 - normalize-package-data: ^3.0.2 - parse-json: ^5.2.0 - type-fest: ^2.0.0 - checksum: 20d11c59be3ae1fc79d4b9c8594dabeaec58105f9dfd710570ef9690ec2ac929247006e79ca114257683228663199735d60f149948dbc5f34fcd2d28883ab5f7 - languageName: node - linkType: hard - -"read-pkg@npm:^8.1.0": +"read-pkg@npm:^8.0.0": version: 8.1.0 resolution: "read-pkg@npm:8.1.0" dependencies: @@ -45797,15 +45654,6 @@ __metadata: languageName: node linkType: hard -"readdir-glob@npm:^1.0.0": - version: 1.1.2 - resolution: "readdir-glob@npm:1.1.2" - dependencies: - minimatch: ^5.1.0 - checksum: 1e5f701d3c94af5653e1736dfef99e991869c6e1c87bf08835d8c641f767e73ae25b829d3d1f8504fab8cad49b70b718ef960d3afee5be45cd779ccaeb264ed4 - languageName: node - linkType: hard - "readdir-glob@npm:^1.1.2": version: 1.1.3 resolution: "readdir-glob@npm:1.1.3" @@ -45999,6 +45847,13 @@ __metadata: languageName: node linkType: hard +"reflect-metadata@npm:0.2.1": + version: 0.2.1 + resolution: "reflect-metadata@npm:0.2.1" + checksum: 772f552a544e04b999c1bf2c868225fef10032274e9d9e315bc3e7a687a504b8b115fa71966665b9619acfd323123a941f892b593250140da809330d41564181 + languageName: node + linkType: hard + "refractor@npm:^3.1.0": version: 3.6.0 resolution: "refractor@npm:3.6.0" @@ -47501,6 +47356,17 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.6.0": + version: 7.6.0 + resolution: "semver@npm:7.6.0" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c + languageName: node + linkType: hard + "semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0": version: 6.3.0 resolution: "semver@npm:6.3.0" @@ -47581,7 +47447,7 @@ __metadata: languageName: node linkType: hard -"serialize-error@npm:^8, serialize-error@npm:^8.0.0": +"serialize-error@npm:^8": version: 8.1.0 resolution: "serialize-error@npm:8.1.0" dependencies: @@ -48382,22 +48248,6 @@ __metadata: languageName: node linkType: hard -"speedline@npm:^1.4.3": - version: 1.4.3 - resolution: "speedline@npm:1.4.3" - dependencies: - "@types/node": "*" - babar: 0.2.0 - image-ssim: ^0.2.0 - jpeg-js: ^0.4.1 - loud-rejection: ^1.6.0 - meow: ^3.7.0 - bin: - speedline: cli.js - checksum: 0dfe8c9629d32e9d5faadea2c01c2466538561b5a46d376381aa6000cd539784b7b9b1e8f5d5882174341509efe80cb4dfa542f22ddeff748195e6d3de4c4431 - languageName: node - linkType: hard - "split-ca@npm:^1.0.1": version: 1.0.1 resolution: "split-ca@npm:1.0.1" @@ -48865,6 +48715,20 @@ __metadata: languageName: node linkType: hard +"streamx@npm:^2.13.0": + version: 2.16.1 + resolution: "streamx@npm:2.16.1" + dependencies: + bare-events: ^2.2.0 + fast-fifo: ^1.1.0 + queue-tick: ^1.0.1 + dependenciesMeta: + bare-events: + optional: true + checksum: 6bbb4c38c0ab6ddbe0857d55e72f71288f308f2a9f4413b7b07391cdf9f94232ffc2bbe40a1212d2e09634ecdbd5052b444c73cc8d67ae1c97e2b7e553dad559 + languageName: node + linkType: hard + "streamx@npm:^2.15.0": version: 2.15.1 resolution: "streamx@npm:2.15.1" @@ -49751,7 +49615,7 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:3.0.4, tar-fs@npm:^3.0.4": +"tar-fs@npm:3.0.4": version: 3.0.4 resolution: "tar-fs@npm:3.0.4" dependencies: @@ -49762,6 +49626,23 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:3.0.5, tar-fs@npm:^3.0.5": + version: 3.0.5 + resolution: "tar-fs@npm:3.0.5" + dependencies: + bare-fs: ^2.1.1 + bare-path: ^2.1.0 + pump: ^3.0.0 + tar-stream: ^3.1.5 + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: e31c7e3e525fec0afecdec1cac58071809e396187725f2eba442f08a4c5649c8cd6b7ce25982f9a91bb0f055628df47c08177dd2ea4f5dafd3c22f42f8da8f00 + languageName: node + linkType: hard + "tar-fs@npm:~2.0.1": version: 2.0.1 resolution: "tar-fs@npm:2.0.1" @@ -49774,7 +49655,7 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^2.0.0, tar-stream@npm:^2.1.4, tar-stream@npm:^2.2.0": +"tar-stream@npm:^2.0.0, tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" dependencies: @@ -50882,7 +50763,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^2.0.0, type-fest@npm:^2.12.2, type-fest@npm:^2.19.0, type-fest@npm:^2.5.0, type-fest@npm:~2.19": +"type-fest@npm:^2.12.2, type-fest@npm:^2.19.0, type-fest@npm:~2.19": version: 2.19.0 resolution: "type-fest@npm:2.19.0" checksum: a4ef07ece297c9fba78fc1bd6d85dff4472fe043ede98bd4710d2615d15776902b595abf62bd78339ed6278f021235fb28a96361f8be86ed754f778973a0d278 @@ -50896,7 +50777,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^3.8.0": +"type-fest@npm:^3.12.0, type-fest@npm:^3.8.0": version: 3.13.1 resolution: "type-fest@npm:3.13.1" checksum: c06b0901d54391dc46de3802375f5579868949d71f93b425ce564e19a428a0d411ae8d8cb0e300d330071d86152c3ea86e744c3f2860a42a79585b6ec2fdae8e @@ -51101,13 +50982,6 @@ __metadata: languageName: node linkType: hard -"ua-parser-js@npm:^1.0.1": - version: 1.0.33 - resolution: "ua-parser-js@npm:1.0.33" - checksum: 460adef51235267345b221842979b6b167543725d03f7c9c4f9ca6af4da835a71d016390da139d2b32828063c4730dcfae6e53b9dce815f4000be4e1fe1c7737 - languageName: node - linkType: hard - "ua-parser-js@npm:^1.0.37": version: 1.0.37 resolution: "ua-parser-js@npm:1.0.37" @@ -51648,6 +51522,13 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:10.0.0": + version: 10.0.0 + resolution: "urlpattern-polyfill@npm:10.0.0" + checksum: 61d890f151ea4ecf34a3dcab32c65ad1f3cda857c9d154af198260c6e5b2ad96d024593409baaa6d4428dd1ab206c14799bf37fe011117ac93a6a44913ac5aa4 + languageName: node + linkType: hard + "usb@npm:^2.11.0": version: 2.11.0 resolution: "usb@npm:2.11.0" @@ -51881,6 +51762,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:9.0.1": + version: 9.0.1 + resolution: "uuid@npm:9.0.1" + bin: + uuid: dist/bin/uuid + checksum: 39931f6da74e307f51c0fb463dc2462807531dc80760a9bff1e35af4316131b4fc3203d16da60ae33f07fdca5b56f3f1dd662da0c99fea9aaeab2004780cc5f4 + languageName: node + linkType: hard + "uuid@npm:^3.3.2": version: 3.4.0 resolution: "uuid@npm:3.4.0" @@ -52570,95 +52460,43 @@ __metadata: languageName: node linkType: hard -"webdriver@npm:8.13.1": - version: 8.13.1 - resolution: "webdriver@npm:8.13.1" +"webdriver@npm:8.32.3": + version: 8.32.3 + resolution: "webdriver@npm:8.32.3" dependencies: "@types/node": ^20.1.0 "@types/ws": ^8.5.3 - "@wdio/config": 8.12.1 - "@wdio/logger": 8.11.0 - "@wdio/protocols": 8.11.0 - "@wdio/types": 8.10.4 - "@wdio/utils": 8.12.1 - deepmerge-ts: ^5.0.0 - got: ^ 12.6.1 - ky: ^0.33.0 - ws: ^8.8.0 - checksum: 7efde3c47504a3842bb30ef66d789ed2271a7d62e7034dada5e7d6bb2eb272f9602fab6db0d71db960fc0cdfd2cb55e294dd1a59d24d75b560f4cc92a7fd54f7 - languageName: node - linkType: hard - -"webdriver@npm:8.20.0": - version: 8.20.0 - resolution: "webdriver@npm:8.20.0" - dependencies: - "@types/node": ^20.1.0 - "@types/ws": ^8.5.3 - "@wdio/config": 8.20.0 - "@wdio/logger": 8.16.17 - "@wdio/protocols": 8.18.0 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 + "@wdio/config": 8.32.3 + "@wdio/logger": 8.28.0 + "@wdio/protocols": 8.32.0 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 deepmerge-ts: ^5.1.0 - got: ^ 12.6.1 + got: ^12.6.1 ky: ^0.33.0 ws: ^8.8.0 - checksum: bc14cc9aabc406fbb02cf2451adbba901f134535c36b69173451552c10297629f52f3d9e8120d425b10490a95b5ac1bace88d5ed1af75db39cc2664ff45b9292 - languageName: node - linkType: hard - -"webdriverio@npm:8.13.4, webdriverio@npm:^8.13.1": - version: 8.13.4 - resolution: "webdriverio@npm:8.13.4" - dependencies: - "@types/node": ^20.1.0 - "@wdio/config": 8.12.1 - "@wdio/logger": 8.11.0 - "@wdio/protocols": 8.11.0 - "@wdio/repl": 8.10.1 - "@wdio/types": 8.10.4 - "@wdio/utils": 8.12.1 - archiver: ^5.0.0 - aria-query: ^5.0.0 - css-shorthand-properties: ^1.1.1 - css-value: ^0.0.1 - devtools: 8.12.1 - devtools-protocol: ^0.0.1170846 - grapheme-splitter: ^1.0.2 - import-meta-resolve: ^3.0.0 - is-plain-obj: ^4.1.0 - lodash.clonedeep: ^4.5.0 - lodash.zip: ^4.2.0 - minimatch: ^9.0.0 - puppeteer-core: 20.3.0 - query-selector-shadow-dom: ^1.0.0 - resq: ^1.9.1 - rgb2hex: 0.2.5 - serialize-error: ^8.0.0 - webdriver: 8.13.1 - checksum: 60b8cd3d1b6e7eef06d6b14c090564cd3a5094002bc487f18bfbd3bf3020468d3044bf097983476196bf347c52487802d38477dab3235f2ed4a8f5a552c0a67e + checksum: f50325361eaa734c362aacea6d234b6c8a6ff99297c5ad34ed76f0421d3956ec71867163390a5ccca0f66bf400088dc850b1e2c87412193f133cdecddde771a5 languageName: node linkType: hard -"webdriverio@npm:8.20.0": - version: 8.20.0 - resolution: "webdriverio@npm:8.20.0" +"webdriverio@npm:8.32.3, webdriverio@npm:^8.29.3": + version: 8.32.3 + resolution: "webdriverio@npm:8.32.3" dependencies: "@types/node": ^20.1.0 - "@wdio/config": 8.20.0 - "@wdio/logger": 8.16.17 - "@wdio/protocols": 8.18.0 - "@wdio/repl": 8.10.1 - "@wdio/types": 8.20.0 - "@wdio/utils": 8.20.0 + "@wdio/config": 8.32.3 + "@wdio/logger": 8.28.0 + "@wdio/protocols": 8.32.0 + "@wdio/repl": 8.24.12 + "@wdio/types": 8.32.2 + "@wdio/utils": 8.32.3 archiver: ^6.0.0 aria-query: ^5.0.0 css-shorthand-properties: ^1.1.1 css-value: ^0.0.1 - devtools-protocol: ^0.0.1209236 + devtools-protocol: ^0.0.1262051 grapheme-splitter: ^1.0.2 - import-meta-resolve: ^3.0.0 + import-meta-resolve: ^4.0.0 is-plain-obj: ^4.1.0 lodash.clonedeep: ^4.5.0 lodash.zip: ^4.2.0 @@ -52668,13 +52506,13 @@ __metadata: resq: ^1.9.1 rgb2hex: 0.2.5 serialize-error: ^11.0.1 - webdriver: 8.20.0 + webdriver: 8.32.3 peerDependencies: devtools: ^8.14.0 peerDependenciesMeta: devtools: optional: true - checksum: 9e36a9abaa704f6e6a7af9e5048a3ab9d44bd19a86998d7a1c427cdfc48eccd4ce54f7be761c2298cac84affc6c62e103ed0b4a8a80d48459fdb82216246c367 + checksum: 8964c0c8a06ae932b3521dce609b3493b4a6b35c432c836c031700aa53dfbbc007accfc0e264a0faf7e48ff2ad037bcd58bd00d22529b947da38e6016d26375e languageName: node linkType: hard @@ -53624,6 +53462,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.16.0, ws@npm:^8.5.0": + version: 8.16.0 + resolution: "ws@npm:8.16.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: feb3eecd2bae82fa8a8beef800290ce437d8b8063bdc69712725f21aef77c49cb2ff45c6e5e7fce622248f9c7abaee506bae0a9064067ffd6935460c7357321b + languageName: node + linkType: hard + "ws@npm:^6.1.0": version: 6.2.2 resolution: "ws@npm:6.2.2" @@ -53663,21 +53516,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.5.0": - version: 8.16.0 - resolution: "ws@npm:8.16.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: feb3eecd2bae82fa8a8beef800290ce437d8b8063bdc69712725f21aef77c49cb2ff45c6e5e7fce622248f9c7abaee506bae0a9064067ffd6935460c7357321b - languageName: node - linkType: hard - "ws@npm:^8.8.0": version: 8.12.0 resolution: "ws@npm:8.12.0" @@ -53898,6 +53736,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:17.7.2, yargs@npm:^17.7.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: ^8.0.1 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.1.1 + checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a + languageName: node + linkType: hard + "yargs@npm:^13.0.0": version: 13.3.2 resolution: "yargs@npm:13.3.2" @@ -54014,21 +53867,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.7.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" - dependencies: - cliui: ^8.0.1 - escalade: ^3.1.1 - get-caller-file: ^2.0.5 - require-directory: ^2.1.1 - string-width: ^4.2.3 - y18n: ^5.0.5 - yargs-parser: ^21.1.1 - checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a - languageName: node - linkType: hard - "yauzl@npm:^2.10.0": version: 2.10.0 resolution: "yauzl@npm:2.10.0" @@ -54072,17 +53910,6 @@ __metadata: languageName: node linkType: hard -"zip-stream@npm:^4.1.0": - version: 4.1.0 - resolution: "zip-stream@npm:4.1.0" - dependencies: - archiver-utils: ^2.1.0 - compress-commons: ^4.1.0 - readable-stream: ^3.6.0 - checksum: 4a73da856738b0634700b52f4ab3fe0bf0a532bea6820ad962d0bda0163d2d5525df4859f89a7238e204a378384e12551985049790c1894c3ac191866e85887f - languageName: node - linkType: hard - "zip-stream@npm:^5.0.1": version: 5.0.1 resolution: "zip-stream@npm:5.0.1" From d8cc55a5e09711d4c665730c28695baa76ba9c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Mon, 26 Feb 2024 12:11:59 +0100 Subject: [PATCH 13/14] fix(extension): fix trezor integration and DApp tx signing with Trezor (#905) --- apps/browser-extension-wallet/src/hooks/useWalletManager.ts | 2 +- apps/browser-extension-wallet/src/lib/wallet-api-ui.ts | 2 +- packages/cardano/src/wallet/index.ts | 2 +- packages/cardano/src/wallet/lib/hardware-wallet.ts | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/browser-extension-wallet/src/hooks/useWalletManager.ts b/apps/browser-extension-wallet/src/hooks/useWalletManager.ts index 70b4920c2..c71d60162 100644 --- a/apps/browser-extension-wallet/src/hooks/useWalletManager.ts +++ b/apps/browser-extension-wallet/src/hooks/useWalletManager.ts @@ -171,7 +171,7 @@ const createHardwareWallet = async ({ const addWalletProps: AddWalletProps = { metadata: { name }, - type: WalletType.Ledger, + type: connectedDevice, accounts: [ { extendedAccountPublicKey: keyAgent.extendedAccountPublicKey, diff --git a/apps/browser-extension-wallet/src/lib/wallet-api-ui.ts b/apps/browser-extension-wallet/src/lib/wallet-api-ui.ts index 1e736fc68..114f03142 100644 --- a/apps/browser-extension-wallet/src/lib/wallet-api-ui.ts +++ b/apps/browser-extension-wallet/src/lib/wallet-api-ui.ts @@ -11,7 +11,7 @@ import { walletManagerChannel, walletManagerProperties, walletRepositoryProperties -} from '@cardano-sdk/web-extension'; +} from '../../../../node_modules/@cardano-sdk/web-extension/dist/cjs'; import { Wallet } from '@lace/cardano'; import { firstValueFrom } from 'rxjs'; import { runtime } from 'webextension-polyfill'; diff --git a/packages/cardano/src/wallet/index.ts b/packages/cardano/src/wallet/index.ts index 822411e2b..ee6756ea6 100644 --- a/packages/cardano/src/wallet/index.ts +++ b/packages/cardano/src/wallet/index.ts @@ -49,7 +49,7 @@ export { export * as KeyManagement from '@cardano-sdk/key-management'; export * as Ledger from '@cardano-sdk/hardware-ledger'; -export * as Trezor from '@cardano-sdk/hardware-trezor'; +export * as Trezor from '../../../../node_modules/@cardano-sdk/hardware-trezor/dist/cjs'; export { HexBlob, Percent, BigIntMath } from '@cardano-sdk/util'; export * as Crypto from '@cardano-sdk/crypto'; diff --git a/packages/cardano/src/wallet/lib/hardware-wallet.ts b/packages/cardano/src/wallet/lib/hardware-wallet.ts index 64c4d8601..85d8e0b48 100644 --- a/packages/cardano/src/wallet/lib/hardware-wallet.ts +++ b/packages/cardano/src/wallet/lib/hardware-wallet.ts @@ -2,7 +2,7 @@ import * as KeyManagement from '@cardano-sdk/key-management'; import { DeviceConnection, HardwareWallets } from '../types'; import * as HardwareLedger from '../../../../../node_modules/@cardano-sdk/hardware-ledger/dist/cjs'; -import * as HardwareTrezor from '../../../../../node_modules/@cardano-sdk/hardware-trezor/dist/cjs'; +import { TrezorKeyAgent } from '../../../../../node_modules/@cardano-sdk/hardware-trezor/dist/cjs'; import { WalletType } from '@cardano-sdk/web-extension'; // Using nodejs CML version to satisfy the tests requirements, but this gets replaced by webpack to the browser version in the build @@ -25,13 +25,13 @@ const connectDevices: Record Promise> = await HardwareLedger.LedgerKeyAgent.checkDeviceConnection(DEFAULT_COMMUNICATION_TYPE), ...(AVAILABLE_WALLETS.includes(WalletType.Trezor) && { [WalletType.Trezor]: async () => { - const isTrezorInitialized = await HardwareTrezor.TrezorKeyAgent.initializeTrezorTransport({ + const isTrezorInitialized = await TrezorKeyAgent.initializeTrezorTransport({ manifest, communicationType: DEFAULT_COMMUNICATION_TYPE }); // initializeTrezorTransport would still succeed even when device is not connected - await HardwareTrezor.TrezorKeyAgent.checkDeviceConnection(KeyManagement.CommunicationType.Web); + await TrezorKeyAgent.checkDeviceConnection(DEFAULT_COMMUNICATION_TYPE); return isTrezorInitialized; } From ca3561970962c7f5a4877c2272400f010e4c6bea Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 26 Feb 2024 09:40:20 -0300 Subject: [PATCH 14/14] [LW-9406] Add co signers (#869) * feat(ui): add auto suggest box component * feat: add co signers component --- packages/cardano/src/wallet/index.ts | 1 + packages/core/package.json | 2 + .../AddCoSigners/AddCoSignerInput.tsx | 33 ++ .../AddCoSigners/AddCoSigners.module.scss | 34 ++ .../AddCoSigners/AddCoSigners.stories.tsx | 84 +++++ .../AddCoSigners/AddCoSigners.tsx | 127 +++++++ .../SharedWallet/AddCoSigners/hooks.ts | 71 ++++ .../SharedWallet/AddCoSigners/index.ts | 1 + .../SharedWallet/AddCoSigners/type.ts | 7 + packages/icons/raw/book.component.svg | 3 + packages/icons/raw/loading.component.svg | 4 + packages/ui/package.json | 1 + .../auto-suggest-box-button.css.ts | 34 ++ ...uto-suggest-box-close-button.component.tsx | 26 ++ .../auto-suggest-box-icon.component.tsx | 37 ++ .../auto-suggest-box-icon.css.ts | 29 ++ .../auto-suggest-box-input.component.tsx | 52 +++ .../auto-suggest-box-input.css.ts | 35 ++ ...auto-suggest-box-open-button.component.tsx | 26 ++ ...uggest-box-picked-suggestion.component.tsx | 59 ++++ .../auto-suggest-box-picked-suggestion.css.ts | 9 + .../auto-suggest-box-suggestion.component.tsx | 80 +++++ .../auto-suggest-box-suggestion.css.ts | 44 +++ .../auto-suggest-box-types.ts | 20 ++ .../auto-suggest-box.component.tsx | 158 +++++++++ .../auto-suggest-box/auto-suggest-box.css.ts | 83 +++++ .../auto-suggest-box/auto-suggest-box.hook.ts | 86 +++++ .../auto-suggest-box.stories.tsx | 329 ++++++++++++++++++ .../design-system/auto-suggest-box/index.ts | 6 + packages/ui/src/design-system/index.ts | 1 + .../design-system/loader/loader.component.tsx | 15 +- .../scroll-area/scroll-area.component.tsx | 16 +- packages/ui/src/design-tokens/colors.data.ts | 9 + .../src/design-tokens/theme/dark-theme.css.ts | 8 + .../design-tokens/theme/light-theme.css.ts | 9 + yarn.lock | 141 +++++++- 36 files changed, 1672 insertions(+), 8 deletions(-) create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSignerInput.tsx create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.module.scss create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.stories.tsx create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.tsx create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/hooks.ts create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/index.ts create mode 100644 packages/core/src/ui/components/SharedWallet/AddCoSigners/type.ts create mode 100644 packages/icons/raw/book.component.svg create mode 100644 packages/icons/raw/loading.component.svg create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-button.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-close-button.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-open-button.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-types.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.component.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.css.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.hook.ts create mode 100644 packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.stories.tsx create mode 100644 packages/ui/src/design-system/auto-suggest-box/index.ts diff --git a/packages/cardano/src/wallet/index.ts b/packages/cardano/src/wallet/index.ts index ee6756ea6..98bb5e308 100644 --- a/packages/cardano/src/wallet/index.ts +++ b/packages/cardano/src/wallet/index.ts @@ -18,6 +18,7 @@ export { StakeSummary, SortField, EraSummary, + HandleResolution, TxSubmissionError } from '@cardano-sdk/core'; diff --git a/packages/core/package.json b/packages/core/package.json index a9de3d37b..7d989aeea 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -58,6 +58,7 @@ "react-dom": "17.0.2", "react-i18next": "11.11.4", "react-infinite-scroll-component": "^6.1.0", + "uuid": "^9.0.1", "zxcvbn": "^4.4.2" }, "devDependencies": { @@ -79,6 +80,7 @@ "@storybook/testing-library": "^0.0.13", "@types/babel__preset-env": "^7", "@types/debounce-promise": "^3.1.6", + "@types/uuid": "^9", "sass": "^1.68.0", "storybook": "^7.4.3", "typescript": "^4.3.5" diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSignerInput.tsx b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSignerInput.tsx new file mode 100644 index 000000000..45f623e1c --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSignerInput.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import type { SuggestionThreeItemType } from '@lace/ui'; +import { AutoSuggestBox } from '@lace/ui'; +import { ValidateAddress } from './type'; +import { useCoSignerInput } from './hooks'; + +interface Props { + onChange: (address: string, isValid: boolean) => void; + validateAddress: ValidateAddress; + translations: { + label: string; + error: string; + }; + suggestions: SuggestionThreeItemType[]; +} + +export const AddCoSignerInput = ({ translations, suggestions, validateAddress, onChange }: Props): JSX.Element => { + const { errorMessage, validationStatus, onInputChange } = useCoSignerInput({ + validateAddress, + onChange, + errorString: translations.error + }); + + return ( + + ); +}; diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.module.scss b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.module.scss new file mode 100644 index 000000000..fcd17363b --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.module.scss @@ -0,0 +1,34 @@ +.coSigners { + & + & { + margin-top: 16px; + width: 100%; + justify-content: center; + } +} + +.scrollArea { + overflow: visible; +} + +.scrollAreaViewport { + max-height: 250px; + overflow: visible; +} + +.scrollBar { + padding: 0; + right: -25px !important; +} + +.remove { + margin-left: 24px; + background: none; + border: none; + padding: 0; + cursor: pointer; +} + +.removeLabel { + color: var(--primary-default, #7f5af0); + font-size: 12px; +} diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.stories.tsx b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.stories.tsx new file mode 100644 index 000000000..243ab5b30 --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.stories.tsx @@ -0,0 +1,84 @@ +/* eslint-disable no-magic-numbers, promise/avoid-new */ +import React from 'react'; +import type { Meta } from '@storybook/react'; + +import { AddCoSigners } from './AddCoSigners'; +import { Flex } from '@lace/ui'; +import { ValidateAddress } from './type'; +import { Wallet } from '@lace/cardano'; + +const meta: Meta = { + title: 'Shared Wallets/AddCoSigners', + component: AddCoSigners, + parameters: { + layout: 'centered' + } +}; + +export default meta; + +const addressBook = [ + { + name: 'Alice', + address: + 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp' + }, + { + name: 'Bob', + address: + 'addr_test1qp9xn9gwdjkj0w300vc8xgctegvgty2ks4n875zdzjkkzy3qz69wq6z9tpmuj9tutsc7f0s4kx6mvh3mwupmjdjx2fjqf0q2j2' + }, + { + name: 'Charlie', + address: '$lace', + handleResolution: { + cardanoAddress: + 'addr_test1qzrljm7nskakjydxlr450ktsj08zuw6aktvgfkmmyw9semrkrezryq3ydtmkg0e7e2jvzg443h0ffzfwd09wpcxy2fuql9tk0g' + } as Wallet.HandleResolution + } +]; + +const handleResolution = + 'addr_test1qzrljm7nskakjydxlr450ktsj08zuw6aktvgfkmmyw9semrkrezryq3ydtmkg0e7e2jvzg443h0ffzfwd09wpcxy2fuql9tk0g' as Wallet.Cardano.PaymentAddress; +let timeout: NodeJS.Timeout; + +const validateAddress: ValidateAddress = async (address) => { + if (!address) { + return { isValid: false }; + } + if (address.startsWith('$')) { + return new Promise((resolve) => { + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(() => { + clearTimeout(timeout); + resolve(Math.random() < 0.5 ? { isValid: true, handleResolution } : { isValid: false }); + }, 2000); + }); + } + return { + isValid: address.startsWith('addr_test1') + }; +}; + +export const Overview = (): JSX.Element => ( + + void 0} + onNext={() => void 0} + addressBook={addressBook} + /> + +); diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.tsx b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.tsx new file mode 100644 index 000000000..6edb9c4f1 --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/AddCoSigners.tsx @@ -0,0 +1,127 @@ +import React, { useMemo } from 'react'; +import { Box, Flex, Text, Button, ControlButton, SuggestionThreeItemType, ScrollArea, sx } from '@lace/ui'; +import { Wallet } from '@lace/cardano'; +import styles from './AddCoSigners.module.scss'; +import { AddCoSignerInput } from './AddCoSignerInput'; +import { CoSigner, ValidateAddress } from './type'; +import { addEllipsis } from '@lace/common'; +import { useCoSigners } from './hooks'; + +interface Props { + onBack: () => void; + onNext: (coSigner: CoSigner[]) => void; + validateAddress: ValidateAddress; + addressBook: { + name: string; + address: string | Wallet.Cardano.PaymentAddress; + handleResolution?: Wallet.HandleResolution; + }[]; + translations: { + title: string; + subtitle: string; + inputLabel: string; + inputError: string; + addButton: string; + backButton: string; + nextButton: string; + removeButton: string; + }; +} + +const MAX_COSIGNERS = 20; +const HEAD_LENGTH = 10; +const TAIL_LENGTH = 5; + +export const AddCoSigners = ({ addressBook, translations, validateAddress, onBack, onNext }: Props): JSX.Element => { + const { coSigners, updateCoSigner, removeCoSigner, addCoSigner } = useCoSigners(); + + const suggestions: SuggestionThreeItemType[] = useMemo( + () => + addressBook.map((addressEntry) => ({ + description: addEllipsis(addressEntry.address, HEAD_LENGTH, TAIL_LENGTH), + title: addressEntry.name, + value: addressEntry.handleResolution + ? addressEntry.handleResolution.cardanoAddress.toString() + : addressEntry.address + })), + [addressBook] + ); + + return ( + + + {translations.title} + + + {translations.subtitle} + + + + {coSigners.map(({ id }, index) => ( + + { + updateCoSigner(index, { address, isValid, id }); + }} + /> + {index !== 0 && ( + + )} + + ))} + + + {coSigners.length > 1 && ( + + + {coSigners.length}/{MAX_COSIGNERS} + + + )} + + addCoSigner()} + /> + + + + + !isValid)} + label={translations.nextButton} + onClick={() => onNext(coSigners)} + /> + + + ); +}; diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/hooks.ts b/packages/core/src/ui/components/SharedWallet/AddCoSigners/hooks.ts new file mode 100644 index 000000000..fafec223c --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/hooks.ts @@ -0,0 +1,71 @@ +import { useState } from 'react'; +import { ValidationStatus } from '@lace/ui'; +import { CoSigner, ValidateAddress } from './type'; +import { v1 as uuid } from 'uuid'; + +export const useCoSigners = (): { + coSigners: CoSigner[]; + removeCoSigner: (index: number) => void; + updateCoSigner: (index: number, coSigner: CoSigner) => void; + addCoSigner: () => void; +} => { + const [coSigners, setCoSigners] = useState([{ address: '', isValid: true, id: uuid() }]); + + return { + coSigners, + removeCoSigner: (index) => { + setCoSigners([...coSigners.filter((_, i) => i !== index)]); + }, + updateCoSigner: (index: number, coSigner: CoSigner) => { + coSigners[index] = coSigner; + setCoSigners([...coSigners]); + }, + addCoSigner: () => { + setCoSigners([...coSigners, { address: '', isValid: false, id: uuid() }]); + } + }; +}; + +interface UseCoSignerInput { + errorString: string; + onChange: (address: string, isValid: boolean) => void; + validateAddress: ValidateAddress; +} + +export const useCoSignerInput = ({ + errorString, + validateAddress, + onChange +}: UseCoSignerInput): { + errorMessage: string; + validationStatus: ValidationStatus; + onInputChange: (address: string) => Promise; +} => { + const [validationStatus, setValidationStatus] = useState(ValidationStatus.Idle); + const [errorMessage, setErrorMessage] = useState(''); + + return { + errorMessage, + validationStatus, + onInputChange: async (value: string) => { + if (!value) { + onChange(value, false); + setValidationStatus(ValidationStatus.Idle); + setErrorMessage(''); + return; + } + setValidationStatus(ValidationStatus.Validading); + const result = await validateAddress(value); + + if (result.isValid) { + onChange(result.handleResolution || value, true); + setValidationStatus(ValidationStatus.Validated); + setErrorMessage(''); + } else { + onChange(value, false); + setValidationStatus(ValidationStatus.Idle); + setErrorMessage(errorString); + } + } + }; +}; diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/index.ts b/packages/core/src/ui/components/SharedWallet/AddCoSigners/index.ts new file mode 100644 index 000000000..d5d05eeb8 --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/index.ts @@ -0,0 +1 @@ +export { AddCoSigners } from './AddCoSigners'; diff --git a/packages/core/src/ui/components/SharedWallet/AddCoSigners/type.ts b/packages/core/src/ui/components/SharedWallet/AddCoSigners/type.ts new file mode 100644 index 000000000..9e5352c67 --- /dev/null +++ b/packages/core/src/ui/components/SharedWallet/AddCoSigners/type.ts @@ -0,0 +1,7 @@ +import { Wallet } from '@lace/cardano'; + +export type ValidateAddress = ( + address: string +) => Promise<{ isValid: boolean; handleResolution?: Wallet.Cardano.PaymentAddress }>; + +export type CoSigner = { address: string; isValid: boolean; id: string }; diff --git a/packages/icons/raw/book.component.svg b/packages/icons/raw/book.component.svg new file mode 100644 index 000000000..5a181b66c --- /dev/null +++ b/packages/icons/raw/book.component.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/packages/icons/raw/loading.component.svg b/packages/icons/raw/loading.component.svg new file mode 100644 index 000000000..6abd18d15 --- /dev/null +++ b/packages/icons/raw/loading.component.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/packages/ui/package.json b/packages/ui/package.json index 99051012e..b9ce66a8d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -37,6 +37,7 @@ "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-form": "^0.0.3", + "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-scroll-area": "^0.1.3", diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-button.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-button.css.ts new file mode 100644 index 000000000..b4d903b54 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-button.css.ts @@ -0,0 +1,34 @@ +import { style, sx, vars } from '../../design-tokens'; + +export const button = style([ + sx({ + width: '$52', + height: '$52', + borderRadius: '$extraSmall', + mx: '$6', + background: '$input_button_bgColor', + color: '$auto_suggest_address_color', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }), + { + border: 'none', + cursor: 'pointer', + flex: 'none', + ':disabled': { + cursor: 'default', + }, + }, +]); + +export const disabledInputButtonIcon = style({ + opacity: vars.opacities.$0_24, +}); + +export const icon = style([ + sx({ + width: '$24', + height: '$24', + }), +]); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-close-button.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-close-button.component.tsx new file mode 100644 index 000000000..87580f8d7 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-close-button.component.tsx @@ -0,0 +1,26 @@ +import React from 'react'; + +import { ReactComponent as CloseIcon } from '@lace/icons/dist/CloseComponent'; + +import * as cx from './auto-suggest-box-button.css'; + +interface Props { + disabled: boolean; + onClick: (event: Readonly>) => void; +} + +export const CloseButton = ({ + disabled, + onClick, +}: Readonly): JSX.Element => { + return ( + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.component.tsx new file mode 100644 index 000000000..2cb5ada11 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.component.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { ReactComponent as CheckIcon } from '@lace/icons/dist/CheckFileUploadComponent'; +import { ReactComponent as LoadingIcon } from '@lace/icons/dist/LoadingComponent'; +import cn from 'classnames'; + +import { Box } from '../box'; +import { Loader } from '../loader'; + +import * as cx from './auto-suggest-box-icon.css'; +import { ValidationStatus } from './auto-suggest-box-types'; + +export interface Props { + status?: ValidationStatus; +} + +export const Icon = ({ status }: Readonly): JSX.Element => { + const isValidating = status === ValidationStatus.Validading; + const isValidated = status === ValidationStatus.Validated; + + if (status === undefined) { + return <>; + } + + return ( + + {isValidating && } + {isValidated && } + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.css.ts new file mode 100644 index 000000000..9f8648f14 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-icon.css.ts @@ -0,0 +1,29 @@ +import { style, sx } from '../../design-tokens'; + +export const icon = style([ + sx({ + mr: '$16', + w: '$24', + h: '$24', + }), + { + fontSize: '24px', + visibility: 'hidden', + }, +]); + +export const loader = style([ + sx({ + color: '$auto_suggest_loader_color', + }), +]); + +export const check = style([ + sx({ + color: '$auto_suggest_check_color', + }), +]); + +export const visible = style({ + visibility: 'visible', +}); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.component.tsx new file mode 100644 index 000000000..a49145684 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.component.tsx @@ -0,0 +1,52 @@ +/* eslint-disable prefer-arrow-functions/prefer-arrow-functions */ +import React from 'react'; + +import cn from 'classnames'; + +import { Flex } from '../flex'; + +import * as cx from './auto-suggest-box-input.css'; + +export interface Props { + required?: boolean; + disabled?: boolean; + id?: string; + label: string; + name?: string; + value: string; + pickedSuggestion?: React.ReactElement; + onChange: (event: Readonly>) => void; + onKeyDown?: (event: Readonly>) => void; +} + +export const Input = ({ + required = false, + disabled = false, + label, + name, + id, + value, + pickedSuggestion, + onChange, + onKeyDown = (): void => void 0, +}: Readonly): JSX.Element => { + return ( + + {pickedSuggestion ?? ( + + )} + {label} + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.css.ts new file mode 100644 index 000000000..41c1ee8b5 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-input.css.ts @@ -0,0 +1,35 @@ +import { vars, style, globalStyle } from '../../design-tokens'; + +import { pickedSuggesion } from './auto-suggest-box-picked-suggestion.css'; + +export const input = style({ + width: '100%', + boxSizing: 'border-box', + fontSize: vars.fontSizes.$18, + border: 'none', + outline: 'none', + background: 'transparent', + color: vars.colors.$input_value_color, + position: 'relative', + pointerEvents: 'all', + padding: '0', +}); + +export const label = style({ + position: 'absolute', + display: 'block', + left: vars.spacing.$24, + top: vars.spacing.$18, + transitionDuration: '0.2s', + pointerEvents: 'none', + color: vars.colors.$input_label_color, + fontSize: vars.fontSizes.$18, +}); + +globalStyle( + `${input}:focus + ${label},${pickedSuggesion} + ${label}, ${input}:not([value=""]) + ${label}`, + { + top: '8px', + fontSize: vars.fontSizes.$12, + }, +); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-open-button.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-open-button.component.tsx new file mode 100644 index 000000000..952ef7a4e --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-open-button.component.tsx @@ -0,0 +1,26 @@ +import React from 'react'; + +import { ReactComponent as BookIcon } from '@lace/icons/dist/BookComponent'; + +import * as cx from './auto-suggest-box-button.css'; + +interface Props { + disabled: boolean; + onClick: (event: Readonly>) => void; +} + +export const OpenButton = ({ + disabled, + onClick, +}: Readonly): JSX.Element => { + return ( + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.component.tsx new file mode 100644 index 000000000..3264dd1f2 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.component.tsx @@ -0,0 +1,59 @@ +/* eslint-disable react/no-multi-comp */ +import React from 'react'; + +import { Box } from '../box'; +import { Flex } from '../flex'; +import * as Text from '../typography'; + +import * as cx from './auto-suggest-box-picked-suggestion.css'; + +import type { + SuggestionClassicType, + SuggestionThreeItemType, + SuggestionType, +} from './auto-suggest-box-types'; + +const PickedSuggestionClassic = ({ + label, + value, +}: Readonly): JSX.Element => { + return ( +
+ {label ?? value} +
+ ); +}; + +const PickedSuggestionThreeItem = ({ + title, + description, +}: Readonly): JSX.Element => { + return ( +
+ + + {title} + + + {description} + + +
+ ); +}; + +export const PickedSuggestion = ( + props: Readonly, +): JSX.Element => { + if ('title' in props) { + return ; + } + + return ; +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.css.ts new file mode 100644 index 000000000..0e55bede7 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-picked-suggestion.css.ts @@ -0,0 +1,9 @@ +import { style, vars } from '../../design-tokens'; + +export const pickedSuggesion = style({ + cursor: 'not-allowed', +}); + +export const address = style({ + color: vars.colors.$auto_suggest_address_color, +}); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.component.tsx new file mode 100644 index 000000000..ae2d33ee9 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.component.tsx @@ -0,0 +1,80 @@ +/* eslint-disable prefer-arrow-functions/prefer-arrow-functions */ +/* eslint-disable react/no-multi-comp */ +import React, { forwardRef } from 'react'; + +import * as Select from '@radix-ui/react-select'; + +import { Box } from '../box'; +import { Flex } from '../flex'; +import * as Text from '../typography'; + +import * as cx from './auto-suggest-box-suggestion.css'; + +import type { + SuggestionClassicType, + SuggestionThreeItemType, + SuggestionType, +} from './auto-suggest-box-types'; + +export interface SuggestionComponentProps { + suggestion: SuggestionType; + onClick: (value: string) => void; +} + +const getSuggestionComponent = ( + props: Readonly, +): JSX.Element => { + if ('title' in props) { + return ; + } + + return ; +}; + +export const Suggestion = forwardRef( + function Suggestion({ onClick, suggestion }, ref): JSX.Element { + return ( + { + onClick(suggestion.value); + }} + onKeyDown={(event): void => { + if (event.code === 'Enter') { + onClick(suggestion.value); + } + }} + > + {getSuggestionComponent(suggestion)} + + ); + }, +); + +export const SuggestionClassic = ({ + label, + value, +}: Readonly): JSX.Element => { + return {label ?? value}; +}; + +export const SuggestionThreeItem = ({ + title, + description, +}: Readonly): JSX.Element => { + return ( + + + + {title[0]} + + {title} + + {description} + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.css.ts new file mode 100644 index 000000000..1ac97e3fc --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-suggestion.css.ts @@ -0,0 +1,44 @@ +import { vars, style, sx } from '../../design-tokens'; + +export const suggestion = style({ + cursor: 'pointer', + padding: vars.spacing.$16, + ':hover': { + backgroundColor: vars.colors.$auto_suggest_border_color, + borderRadius: vars.radius.$medium, + }, + ':focus': { + backgroundColor: vars.colors.$auto_suggest_border_color, + borderRadius: vars.radius.$medium, + outline: 'none', + }, +}); + +export const title = style({ + flex: '1', + alignItems: 'center', +}); + +export const address = style({ + color: vars.colors.$auto_suggest_address_color, + flex: '1', +}); + +export const initial = style([ + sx({ + height: '$40', + width: '$40', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + borderRadius: '$circle', + background: '$auto_suggest_initial_bgColor', + color: '$auto_suggest_initial_color', + mr: '$16', + }), + { + overflow: 'hidden', + userSelect: 'none', + position: 'relative', + }, +]); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-types.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-types.ts new file mode 100644 index 000000000..95f825679 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box-types.ts @@ -0,0 +1,20 @@ +export enum ValidationStatus { + Idle = 'Idle', + Validading = 'Validading', + Validated = 'Validated', +} + +export interface SuggestionBaseType { + value: string; +} + +export interface SuggestionClassicType extends SuggestionBaseType { + label?: string; +} + +export interface SuggestionThreeItemType extends SuggestionBaseType { + title: string; + description: string; +} + +export type SuggestionType = SuggestionClassicType | SuggestionThreeItemType; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.component.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.component.tsx new file mode 100644 index 000000000..fd7a2da68 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.component.tsx @@ -0,0 +1,158 @@ +import React from 'react'; + +import * as Popover from '@radix-ui/react-popover'; +import * as Select from '@radix-ui/react-select'; +import cn from 'classnames'; + +import { Box } from '../box'; +import { Flex } from '../flex'; +import { ScrollArea } from '../scroll-area'; +import * as Text from '../typography'; + +import { CloseButton } from './auto-suggest-box-close-button.component'; +import { Icon } from './auto-suggest-box-icon.component'; +import { Input } from './auto-suggest-box-input.component'; +import { OpenButton } from './auto-suggest-box-open-button.component'; +import { PickedSuggestion } from './auto-suggest-box-picked-suggestion.component'; +import { Suggestion } from './auto-suggest-box-suggestion.component'; +import * as cx from './auto-suggest-box.css'; +import { useAutoSuggestBox } from './auto-suggest-box.hook'; + +import type { + SuggestionBaseType, + ValidationStatus, +} from './auto-suggest-box-types'; + +export interface Props< + SuggestionType extends SuggestionBaseType = SuggestionBaseType, +> { + required?: boolean; + disabled?: boolean; + id?: string; + label: string; + name?: string; + suggestions?: SuggestionType[]; + errorMessage?: string; + onChange?: (value: string) => void; + initialValue?: string; + validationStatus?: ValidationStatus; +} + +export const AutoSuggestBox = ({ + id, + required = false, + disabled = false, + label, + name, + initialValue, + onChange, + suggestions = [], + errorMessage, + validationStatus, +}: Readonly>): JSX.Element => { + const { + value, + isCloseButton, + isSuggesting, + filteredSuggestions, + pickedSuggestion, + firstSuggestionRef, + closeSuggestions, + onOpenButtonClick, + onCloseButtonClick, + onInputChange, + onSuggestionClick, + } = useAutoSuggestBox({ + initialValue, + onChange, + suggestions, + }); + + return ( + + + + + + + { + if (event.code === 'ArrowDown') { + firstSuggestionRef.current?.focus(); + event.preventDefault(); + } + }} + pickedSuggestion={ + pickedSuggestion && ( + + ) + } + /> + + + + {isCloseButton ? ( + + ) : ( + + )} + + + + { + event.preventDefault(); + }} + > + + + + + {filteredSuggestions.map((suggestion, index) => ( + + ))} + + + + + + {Boolean(errorMessage) && ( + {errorMessage} + )} + + + + ); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.css.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.css.ts new file mode 100644 index 000000000..cec9101ce --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.css.ts @@ -0,0 +1,83 @@ +import { vars, style, globalStyle } from '../../design-tokens'; + +import { input } from './auto-suggest-box-input.css'; + +export const disabledContainer = style({ + ':hover': { + outline: 'none', + }, +}); + +export const container = style({ + boxSizing: 'border-box', + justifyContent: 'center', +}); + +export const inputContainer = style({ + border: '2px solid transparent', + borderRadius: vars.radius.$medium, + boxSizing: 'border-box', + display: 'flex', + justifyContent: 'space-between', + background: vars.colors.$auto_suggest_container_background_color, + height: vars.spacing.$64, + fontWeight: vars.fontWeights.$semibold, + fontFamily: vars.fontFamily.$nova, + position: 'relative', + paddingLeft: vars.spacing.$24, +}); + +export const isSuggesting = style({ + borderRadius: vars.radius.$medium, + borderBottomRightRadius: vars.radius.$sharp, + borderBottomLeftRadius: vars.radius.$sharp, + borderBottom: `2px solid ${vars.colors.$auto_suggest_border_color}`, +}); + +export const idle = style({}); + +export const popoverContent = style({ + zIndex: 1000, +}); + +export const selectContent = style({ + width: 'var(--radix-popper-anchor-width)', +}); + +export const scrollArea = style({ + background: vars.colors.$auto_suggest_container_background_color, + padding: vars.spacing.$6, + boxSizing: 'border-box', + borderBottomRightRadius: vars.radius.$medium, + borderBottomLeftRadius: vars.radius.$medium, +}); + +export const scrollAreaViewport = style({ + maxHeight: '180px', +}); + +export const scrollBar = style({ + padding: 0, +}); + +export const errorMessage = style({ + color: vars.colors.$input_error_message_color, + marginLeft: vars.spacing.$24, + marginTop: vars.spacing.$4, +}); + +globalStyle(`${scrollArea}:has(${scrollBar})`, { + paddingRight: vars.spacing.$16, +}); + +globalStyle(`${inputContainer}:has(${input}:disabled)`, { + opacity: vars.opacities.$0_5, +}); + +globalStyle(`${inputContainer}:has(${input}:hover:not(:disabled))`, { + border: `2px solid ${vars.colors.$auto_suggest_border_color}`, +}); + +globalStyle(`${inputContainer}:has(${input}:focus)`, { + border: `3px solid ${vars.colors.$input_container_focused_outline_color}`, +}); diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.hook.ts b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.hook.ts new file mode 100644 index 000000000..b596f24c7 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.hook.ts @@ -0,0 +1,86 @@ +/* eslint-disable unicorn/no-useless-undefined */ +import type React from 'react'; +import { useEffect, useRef, useState } from 'react'; + +import type { SuggestionBaseType } from './auto-suggest-box-types'; + +interface Props { + onChange?: (value: string) => void; + initialValue?: string; + suggestions?: SuggestionType[]; +} + +interface Context { + value: string; + pickedSuggestion?: SuggestionType; + isSuggesting: boolean; + isCloseButton: boolean; + filteredSuggestions: SuggestionType[]; + firstSuggestionRef: React.MutableRefObject; + closeSuggestions: () => void; + onSuggestionClick: (value: string) => void; + onInputChange: (event: Readonly>) => void; + onOpenButtonClick: () => void; + onCloseButtonClick: () => void; +} + +export const useAutoSuggestBox = ({ + onChange, + initialValue = '', + suggestions = [], +}: Readonly>): Context => { + const firstSuggestionReference = useRef(null); + const [value, setValue] = useState(initialValue); + const [isSuggesting, setIsSuggesting] = useState(false); + const [pickedSuggestion, setPickedSuggestion] = useState< + SuggestionType | undefined + >(); + const filteredSuggestions = suggestions.filter(item => + Object.values(item).some((itemValue: string) => + itemValue.toLowerCase().includes(value.toLowerCase()), + ), + ); + + const isCloseButton = isSuggesting || Boolean(value); + + useEffect(() => { + onChange?.(value); + }, [value]); + + return { + value, + isSuggesting: filteredSuggestions.length > 0 && isSuggesting, + isCloseButton, + filteredSuggestions, + pickedSuggestion, + firstSuggestionRef: firstSuggestionReference, + onSuggestionClick: (value): void => { + setIsSuggesting(false); + setValue(value); + const pickedSuggestion = suggestions.find( + suggestion => suggestion.value === value, + ); + + if (pickedSuggestion) { + setPickedSuggestion(pickedSuggestion); + } + }, + onInputChange: (event): void => { + setValue(event.target.value); + if (event.target.value) { + setIsSuggesting(true); + } + }, + onOpenButtonClick: (): void => { + setIsSuggesting(true); + }, + onCloseButtonClick: (): void => { + setValue(''); + setPickedSuggestion(undefined); + setIsSuggesting(false); + }, + closeSuggestions: (): void => { + setIsSuggesting(false); + }, + }; +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.stories.tsx b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.stories.tsx new file mode 100644 index 000000000..d5be3067a --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/auto-suggest-box.stories.tsx @@ -0,0 +1,329 @@ +/* eslint-disable react/display-name */ +import React from 'react'; + +import { expect } from '@storybook/jest'; +import type { ComponentStory, Meta } from '@storybook/react'; +import { userEvent, within } from '@storybook/testing-library'; + +import { LocalThemeProvider, ThemeColorScheme } from '../../design-tokens'; +import { sleep } from '../../test'; +import { Box } from '../box'; +import { page, Section, Variants } from '../decorators'; +import { Divider } from '../divider'; +import { Flex } from '../flex'; +import { Cell, Grid } from '../grid'; +import * as Text from '../typography'; + +import { ValidationStatus } from './auto-suggest-box-types'; +import { AutoSuggestBox } from './auto-suggest-box.component'; + +import type { + SuggestionClassicType, + SuggestionThreeItemType, +} from './auto-suggest-box-types'; +import type { Props } from './auto-suggest-box.component'; + +const subtitle = 'Input with auto suggestions'; + +const SUGGESTIONS: SuggestionClassicType[] = [ + { value: 'apple', label: 'Apple' }, + { value: 'orange', label: 'Orange' }, + { value: 'grape', label: 'Grape' }, + { value: 'banana', label: 'Banana' }, + { value: 'pear', label: 'Pear' }, +]; + +const ADDRESS_SUGGESTIONS: SuggestionThreeItemType[] = [ + { + title: 'Alice', + description: 'addr1q12ab...0t7a1', + value: 'addr1q12ab0t7a1', + }, + { + title: 'Bob', + description: 'addr1r23de...1u8b2', + value: 'addr1r23de1u8b2', + }, + { + title: 'Charlie', + description: 'addr1s45fg...2v9c3', + value: 'addr1s45fg2v9c3', + }, +]; + +export default { + title: 'Input Fields/Auto Suggest Box', + component: AutoSuggestBox, + decorators: [page({ title: 'Auto Suggest Box', subtitle })], +} as Meta; + +const MainComponents = (): JSX.Element => ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export const Overview = (): JSX.Element => { + return ( + +
+ + + Classic item dropdown + + + + + + + + 3 item dropdown + + + + + + + +
+ +
+ + + + + + + + + + +
+
+ ); +}; + +Overview.parameters = { + pseudo: { + hover: '#hover', + focus: '#focus', + }, +}; + +export const Controls = (props: Readonly): JSX.Element => ( + + + + + +); + +Controls.argTypes = { + label: { + defaultValue: 'Auto suggest box', + }, + suggestions: { + defaultValue: SUGGESTIONS, + }, + validationStatus: { + defaultValue: ValidationStatus.Idle, + }, +}; + +type Interactions = ComponentStory; + +const createInteraction: () => Interactions = () => (): JSX.Element => + ( + + + + + + ); + +export const SuggestAndErase = createInteraction(); +export const SuggestAndPick = createInteraction(); + +SuggestAndErase.play = async ({ canvasElement }): Promise => { + const canvas = within(canvasElement); + + userEvent.click(canvas.getByTestId('auto-suggest-box-button-open')); + + await sleep(); + + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-apple'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-orange'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-grape'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-banana'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-pear'), + ).toBeInTheDocument(); + + userEvent.click(canvas.getByTestId('auto-suggest-box-input')); + + await sleep(); + + await userEvent.type(canvas.getByTestId('auto-suggest-box-input'), 'ra', { + delay: 100, + }); + + await sleep(); + + expect(await canvas.findByTestId('auto-suggest-box-input')).toHaveValue('ra'); + + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-apple'), + ).not.toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-orange'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-grape'), + ).toBeInTheDocument(); + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-banana'), + ).not.toBeInTheDocument(); + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-pear'), + ).not.toBeInTheDocument(); + + userEvent.click(canvas.getByTestId('auto-suggest-box-input')); + + userEvent.click(canvas.getByTestId('auto-suggest-box-button-close')); + + await sleep(); + + expect(await canvas.findByTestId('auto-suggest-box-input')).toHaveValue(''); +}; + +SuggestAndPick.play = async ({ canvasElement }): Promise => { + const canvas = within(canvasElement); + + await sleep(); + + userEvent.click(canvas.getByTestId('auto-suggest-box-button-open')); + + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-apple'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-orange'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-grape'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-banana'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-pear'), + ).toBeInTheDocument(); + + await sleep(); + + userEvent.click(canvas.getByTestId('auto-suggest-box-input')); + + await sleep(); + + await userEvent.type(canvas.getByTestId('auto-suggest-box-input'), 'ra', { + delay: 100, + }); + + expect(await canvas.findByTestId('auto-suggest-box-input')).toHaveValue('ra'); + + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-apple'), + ).not.toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-orange'), + ).toBeInTheDocument(); + expect( + await canvas.findByTestId('auto-suggest-box-suggestion-grape'), + ).toBeInTheDocument(); + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-banana'), + ).not.toBeInTheDocument(); + expect( + canvas.queryByTestId('auto-suggest-box-suggestion-pear'), + ).not.toBeInTheDocument(); + + await sleep(); + + userEvent.click(canvas.getByTestId('auto-suggest-box-suggestion-orange')); + + expect( + await canvas.findByTestId('auto-suggest-box-picked-suggestion'), + ).toHaveTextContent('Orange'); +}; diff --git a/packages/ui/src/design-system/auto-suggest-box/index.ts b/packages/ui/src/design-system/auto-suggest-box/index.ts new file mode 100644 index 000000000..28a96b241 --- /dev/null +++ b/packages/ui/src/design-system/auto-suggest-box/index.ts @@ -0,0 +1,6 @@ +export { AutoSuggestBox } from './auto-suggest-box.component'; +export { ValidationStatus } from './auto-suggest-box-types'; +export type { + SuggestionClassicType, + SuggestionThreeItemType, +} from './auto-suggest-box-types'; diff --git a/packages/ui/src/design-system/index.ts b/packages/ui/src/design-system/index.ts index 3205c4f4b..a26e17f61 100644 --- a/packages/ui/src/design-system/index.ts +++ b/packages/ui/src/design-system/index.ts @@ -46,4 +46,5 @@ export type { export { SelectGroup } from './select'; export { ActionCard } from './action-card'; export { Loader } from './loader'; +export * from './auto-suggest-box'; export * from './table'; diff --git a/packages/ui/src/design-system/loader/loader.component.tsx b/packages/ui/src/design-system/loader/loader.component.tsx index f4e071a53..3acd38048 100644 --- a/packages/ui/src/design-system/loader/loader.component.tsx +++ b/packages/ui/src/design-system/loader/loader.component.tsx @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/strict-boolean-expressions */ +import type { SVGProps } from 'react'; import React from 'react'; import { ReactComponent as LoaderDarkIcon } from '@lace/icons/dist/LoaderDarkGradientComponent'; @@ -11,16 +13,23 @@ import * as cx from './loader.css'; import type { BoxProps } from '../box'; +type Props = Readonly< + BoxProps & { + icon?: (props: Readonly>) => JSX.Element; + } +>; + export const Loader = ({ w = '$148', h = '$148', + icon, ...props -}: Readonly): JSX.Element => { +}: Props): JSX.Element => { const { colorScheme } = useTheme(); - - const LoaderIcon = + const defaultIcon = colorScheme === ThemeColorScheme.Dark ? LoaderDarkIcon : LoaderLightIcon; + const LoaderIcon = icon ?? defaultIcon; return ( ): JSX.Element => ( - - +export const ScrollArea = ({ + children, + classNames, +}: Readonly): JSX.Element => ( + + {children} - +