diff --git a/apps/explorer/src/components/error-boundary/ErrorBoundary.tsx b/apps/explorer/src/components/error-boundary/ErrorBoundary.tsx index 1319556bb76..f62bd7fd95c 100644 --- a/apps/explorer/src/components/error-boundary/ErrorBoundary.tsx +++ b/apps/explorer/src/components/error-boundary/ErrorBoundary.tsx @@ -4,17 +4,20 @@ import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'; import { useLocation } from 'react-router-dom'; - -import { Banner } from '~/components/ui'; - import type { ReactNode } from 'react'; import type { FallbackProps } from 'react-error-boundary'; +import { InfoBox, InfoBoxType, InfoBoxStyle } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; function Fallback({ error }: FallbackProps): JSX.Element { return ( - - {error.message} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ); } diff --git a/apps/explorer/src/components/layout/PageLayout.tsx b/apps/explorer/src/components/layout/PageLayout.tsx index 77ca33f4367..ec4f1a34853 100644 --- a/apps/explorer/src/components/layout/PageLayout.tsx +++ b/apps/explorer/src/components/layout/PageLayout.tsx @@ -10,8 +10,8 @@ import { type ReactNode, useRef } from 'react'; import Footer from '../footer/Footer'; import Header from '../header/Header'; import { useNetworkContext } from '~/contexts'; -import { Banner } from '~/components/ui'; -import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, LoadingIndicator } from '@iota/apps-ui-kit'; +import { Info } from '@iota/ui-icons'; type PageLayoutProps = { content: ReactNode; @@ -47,9 +47,12 @@ export function PageLayout({ content, loading }: PageLayoutProps): JSX.Element {
{renderNetworkDegradeBanner && ( - -
{networkDegradeBannerCopy}
-
+ } + type={InfoBoxType.Default} + style={InfoBoxStyle.Elevated} + /> )}
diff --git a/apps/explorer/src/components/module/module-functions-interaction/FunctionExecutionResult.tsx b/apps/explorer/src/components/module/module-functions-interaction/FunctionExecutionResult.tsx index 5af84bcb125..ef2bbb9a238 100644 --- a/apps/explorer/src/components/module/module-functions-interaction/FunctionExecutionResult.tsx +++ b/apps/explorer/src/components/module/module-functions-interaction/FunctionExecutionResult.tsx @@ -3,9 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 import { LinkGroup } from './LinkGroup'; -import { Banner } from '~/components/ui'; - import type { IotaTransactionBlockResponse, OwnedObjectRef } from '@iota/iota-sdk/client'; +import { Close } from '@iota/ui-icons'; interface ToObjectLink { text: string; @@ -27,10 +26,9 @@ type FunctionExecutionResultProps = { export function FunctionExecutionResult({ error, result, onClear }: FunctionExecutionResultProps) { const adjError = error || (result && result.effects?.status.error) || null; - const variant = adjError ? 'error' : 'message'; return ( - -
+
+
+
+ +
- +
); } diff --git a/apps/explorer/src/components/object/ObjectFieldsCard.tsx b/apps/explorer/src/components/object/ObjectFieldsCard.tsx index ce35bae8e0b..c6e2e8213bf 100644 --- a/apps/explorer/src/components/object/ObjectFieldsCard.tsx +++ b/apps/explorer/src/components/object/ObjectFieldsCard.tsx @@ -5,7 +5,6 @@ import { type IotaMoveNormalizedStruct, type IotaObjectResponse } from '@iota/iota-sdk/client'; import clsx from 'clsx'; import { useCallback, useEffect, useState } from 'react'; -import { Banner } from '~/components/ui'; import { getFieldTypeValue } from '~/lib/ui'; import { FieldItem } from './FieldItem'; import { ScrollToViewCard } from './ScrollToViewCard'; @@ -21,7 +20,11 @@ import { LoadingIndicator, Search, ListItem, + InfoBox, + InfoBoxStyle, + InfoBoxType, } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; const DEFAULT_OPEN_FIELDS = 3; const DEFAULT_FIELDS_COUNT_TO_SHOW_SEARCH = 10; @@ -90,9 +93,13 @@ export function ObjectFieldsCard({ } if (error) { return ( - - Failed to get field data for {id} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ); } diff --git a/apps/explorer/src/components/object/UnderlyingObjectCard.tsx b/apps/explorer/src/components/object/UnderlyingObjectCard.tsx index fd1f8224d43..7d4ce9061e9 100644 --- a/apps/explorer/src/components/object/UnderlyingObjectCard.tsx +++ b/apps/explorer/src/components/object/UnderlyingObjectCard.tsx @@ -4,10 +4,9 @@ import { useIotaClientQuery } from '@iota/dapp-kit'; import { FieldItem } from './FieldItem'; -import { Banner } from '~/components/ui'; - import type { DynamicFieldName } from '@iota/iota-sdk/client'; -import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, LoadingIndicator } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; interface UnderlyingObjectCardProps { parentId: string; @@ -53,9 +52,13 @@ export function UnderlyingObjectCard({ (!normalizedStruct && normalizedStructFetched)) ) { return ( - - Failed to get field data for {parentId} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ); } diff --git a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx index 609080b513f..e2fc0f7f0a8 100644 --- a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx +++ b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx @@ -3,11 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 import { useIotaClientQuery } from '@iota/dapp-kit'; - -import { Banner, PlaceholderTable, TableCard } from '~/components/ui'; +import { PlaceholderTable, TableCard } from '~/components/ui'; import { generateValidatorsTableColumns } from '~/lib/ui'; -import { Panel, Title } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, Panel, Title } from '@iota/apps-ui-kit'; import { ErrorBoundary } from '../error-boundary/ErrorBoundary'; +import { Warning } from '@iota/ui-icons'; const NUMBER_OF_VALIDATORS = 10; @@ -30,9 +30,13 @@ export function TopValidatorsCard({ limit, showIcon }: TopValidatorsCardProps): if (isError || (!isPending && !data.activeValidators.length)) { return ( - - Validator data could not be loaded - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ); } diff --git a/apps/explorer/src/components/transactions/TransactionsForAddress.tsx b/apps/explorer/src/components/transactions/TransactionsForAddress.tsx index 89f2d42cb4e..e3547919a9b 100644 --- a/apps/explorer/src/components/transactions/TransactionsForAddress.tsx +++ b/apps/explorer/src/components/transactions/TransactionsForAddress.tsx @@ -2,11 +2,12 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, LoadingIndicator } from '@iota/apps-ui-kit'; import { useIotaClient } from '@iota/dapp-kit'; import { type IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; +import { Warning } from '@iota/ui-icons'; import { useQuery } from '@tanstack/react-query'; -import { Banner, TableCard } from '~/components/ui'; +import { TableCard } from '~/components/ui'; import { generateTransactionsTableColumns } from '~/lib/ui'; interface TransactionsForAddressProps { @@ -37,9 +38,13 @@ export function TransactionsForAddressTable({ if (isError) { return ( - - Transactions could not be extracted on the following specified address: {address} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ); } diff --git a/apps/explorer/src/components/ui/Banner.tsx b/apps/explorer/src/components/ui/Banner.tsx deleted file mode 100644 index 8c3a2a1dd84..00000000000 --- a/apps/explorer/src/components/ui/Banner.tsx +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -import { cva, type VariantProps } from 'class-variance-authority'; -import { type ReactNode } from 'react'; -import { Close, Info } from '@iota/ui-icons'; - -const bannerStyles = cva( - 'inline-flex text-pBodySmall font-medium overflow-hidden gap-2 items-center flex-nowrap relative', - { - variants: { - variant: { - positive: 'bg-success-light text-success-dark', - warning: 'bg-warning-light text-warning-dark', - error: 'bg-issue-light text-issue-dark', - message: 'bg-iota-light text-hero', - neutralGrey: 'bg-steel text-white', - neutralWhite: 'bg-white/80 text-steel-darker', - }, - align: { - left: 'justify-start', - center: 'justify-center', - }, - fullWidth: { - true: 'w-full', - }, - spacing: { - sm: 'px-1.5 py-0.5', - md: 'px-3 py-2', - lg: 'p-5', - }, - shadow: { - true: 'shadow-md', - }, - border: { - true: '', - }, - rounded: { - none: 'rounded-none', - '2xl': 'rounded-2xl', - }, - }, - defaultVariants: { - variant: 'message', - spacing: 'md', - rounded: '2xl', - }, - compoundVariants: [ - { - variant: 'positive', - border: true, - class: 'border border-success/30', - }, - { - variant: 'warning', - border: true, - class: 'border border-warning-dark/30', - }, - { - variant: 'error', - border: true, - class: 'border border-issue-dark/30', - }, - { - variant: 'message', - border: true, - class: 'border border-iota/30', - }, - { - variant: 'neutralGrey', - border: true, - class: 'border border-steel', - }, - { - variant: 'neutralWhite', - border: true, - class: 'border border-gray-45', - }, - ], - }, -); - -export interface BannerProps extends VariantProps { - icon?: ReactNode | null; - title?: ReactNode | string; - children: ReactNode; - onDismiss?: () => void; -} - -export function Banner({ - icon = , - title, - children, - variant, - align, - fullWidth, - spacing, - border, - shadow, - rounded, - onDismiss, -}: BannerProps): JSX.Element { - return ( -
- {icon &&
{icon}
} -
- {title && {title}} -
{children}
-
- {onDismiss ? ( -
- -
- ) : null} -
- ); -} diff --git a/apps/explorer/src/components/ui/index.ts b/apps/explorer/src/components/ui/index.ts index 84c5615073b..2d5858084eb 100644 --- a/apps/explorer/src/components/ui/index.ts +++ b/apps/explorer/src/components/ui/index.ts @@ -6,7 +6,6 @@ export * from './header'; export * from './image'; export * from './modal'; -export * from './Banner'; export * from './ButtonOrLink'; export * from './Card'; export * from './Divider'; diff --git a/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx b/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx index 9bd00c50321..7b23c9054b1 100644 --- a/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx +++ b/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx @@ -5,11 +5,14 @@ import { useIotaClient } from '@iota/dapp-kit'; import { useQuery } from '@tanstack/react-query'; import { useParams } from 'react-router-dom'; -import { PageLayout, Banner, PageHeader } from '~/components'; +import { PageLayout, PageHeader } from '~/components'; import { CheckpointTransactionBlocks } from './CheckpointTransactionBlocks'; import { ButtonSegment, ButtonSegmentType, + InfoBox, + InfoBoxStyle, + InfoBoxType, LabelText, LabelTextSize, LoadingIndicator, @@ -21,6 +24,7 @@ import { import { useState } from 'react'; import { useFormatCoin } from '@iota/core'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; +import { Warning } from '@iota/ui-icons'; enum FeesTabs { GasAndStorageFees = 'gas-and-storage-fees', @@ -64,9 +68,13 @@ export default function CheckpointDetail(): JSX.Element { - There was an issue retrieving data for checkpoint: {id} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ) : isPending ? ( ) : ( diff --git a/apps/explorer/src/pages/epochs/EpochDetail.tsx b/apps/explorer/src/pages/epochs/EpochDetail.tsx index 64e564976fa..be17ede1df1 100644 --- a/apps/explorer/src/pages/epochs/EpochDetail.tsx +++ b/apps/explorer/src/pages/epochs/EpochDetail.tsx @@ -9,13 +9,16 @@ import { useParams } from 'react-router-dom'; import { ButtonSegment, ButtonSegmentType, + InfoBox, + InfoBoxStyle, + InfoBoxType, LoadingIndicator, SegmentedButton, SegmentedButtonType, } from '@iota/apps-ui-kit'; import { CheckpointsTable, PageLayout } from '~/components'; -import { Banner, TableCard } from '~/components/ui'; +import { TableCard } from '~/components/ui'; import { useEnhancedRpcClient } from '~/hooks/useEnhancedRpc'; import { EpochStats, EpochStatsGrid } from './stats/EpochStats'; import { ValidatorStatus } from './stats/ValidatorStatus'; @@ -24,6 +27,7 @@ import cx from 'clsx'; import { TokenStats } from './stats/TokenStats'; import { EpochTopStats } from './stats/EpochTopStats'; import { getEpochStorageFundFlow } from '~/lib/utils'; +import { Warning } from '@iota/ui-icons'; enum EpochTabs { Checkpoints = 'checkpoints', @@ -79,9 +83,13 @@ export default function EpochDetail() { return ( - {`There was an issue retrieving data for epoch ${id}.`} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> } /> ); diff --git a/apps/explorer/src/pages/object-result/ObjectResult.tsx b/apps/explorer/src/pages/object-result/ObjectResult.tsx index 0bec83b88e2..147ba0fc4d5 100644 --- a/apps/explorer/src/pages/object-result/ObjectResult.tsx +++ b/apps/explorer/src/pages/object-result/ObjectResult.tsx @@ -5,12 +5,13 @@ import { useGetObject } from '@iota/core'; import { useParams } from 'react-router-dom'; import { ErrorBoundary, PageLayout } from '~/components'; -import { Banner, PageHeader } from '~/components/ui'; +import { PageHeader } from '~/components/ui'; import { ObjectView } from '~/pages/object-result/views/ObjectView'; import { translate, type DataType } from './ObjectResultType'; import PkgView from './views/PkgView'; import { TokenView } from './views/TokenView'; -import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, LoadingIndicator } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; const PACKAGE_TYPE_NAME = 'Move Package'; @@ -46,10 +47,13 @@ export function ObjectResult(): JSX.Element {
)} {isPageError || !data || !resp ? ( - - Data could not be extracted on the following specified object ID:{' '} - {objID} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ) : ( <> {isPackage && } diff --git a/apps/explorer/src/pages/transaction-result/TransactionResult.tsx b/apps/explorer/src/pages/transaction-result/TransactionResult.tsx index a184da79407..2abdd1770a9 100644 --- a/apps/explorer/src/pages/transaction-result/TransactionResult.tsx +++ b/apps/explorer/src/pages/transaction-result/TransactionResult.tsx @@ -5,10 +5,11 @@ import { useGetTransaction } from '@iota/core'; import { type IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; import { useParams } from 'react-router-dom'; - import { PageLayout } from '~/components'; -import { Banner, PageHeader } from '~/components/ui'; +import { PageHeader } from '~/components/ui'; import { TransactionView } from './TransactionView'; +import { InfoBox, InfoBoxType, InfoBoxStyle } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; interface TransactionResultPageHeaderProps { transaction?: IotaTransactionBlockResponse; @@ -62,11 +63,17 @@ export default function TransactionResult(): JSX.Element { loading={isPending} /> {getTxnErrorBool || !data ? ( - - {!id - ? "Can't search for a transaction without a digest" - : `Data could not be extracted for the following specified transaction ID: ${id}`} - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ) : ( )} diff --git a/apps/explorer/src/pages/validator/ValidatorDetails.tsx b/apps/explorer/src/pages/validator/ValidatorDetails.tsx index b2271c8491d..a8ea8c7ae60 100644 --- a/apps/explorer/src/pages/validator/ValidatorDetails.tsx +++ b/apps/explorer/src/pages/validator/ValidatorDetails.tsx @@ -10,8 +10,8 @@ import { useParams } from 'react-router-dom'; import { PageLayout, ValidatorMeta, ValidatorStats } from '~/components'; import { VALIDATOR_LOW_STAKE_GRACE_PERIOD } from '~/lib/constants'; import { getValidatorMoveEvent } from '~/lib/utils'; -import { Banner } from '~/components/ui'; -import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { InfoBox, InfoBoxStyle, InfoBoxType, LoadingIndicator } from '@iota/apps-ui-kit'; +import { Warning } from '@iota/ui-icons'; const getAtRiskRemainingEpochs = ( data: IotaSystemStateSummary | undefined, @@ -62,10 +62,14 @@ function ValidatorDetails(): JSX.Element { return ( - - No validator data found for {id} - +
+ } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + />
} /> @@ -94,25 +98,16 @@ function ValidatorDetails(): JSX.Element { tallyingScore={tallyingScore} /> {atRiskRemainingEpochs !== null && ( -
- - At risk of being removed as a validator after{' '} - {atRiskRemainingEpochs} epoch - {atRiskRemainingEpochs > 1 ? 's' : ''} - - } - > - - Staked IOTA is below the minimum IOTA stake threshold to remain - a validator. - - -
+ 1 ? 's' : '' + }`} + supportingText="Staked IOTA is below the minimum IOTA stake threshold to remain + a validator." + icon={} + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> )}
} diff --git a/apps/explorer/src/pages/validators/Validators.tsx b/apps/explorer/src/pages/validators/Validators.tsx index 47a29bf3e37..bb70f5d0899 100644 --- a/apps/explorer/src/pages/validators/Validators.tsx +++ b/apps/explorer/src/pages/validators/Validators.tsx @@ -8,13 +8,17 @@ import { DisplayStats, DisplayStatsSize, DisplayStatsType, + InfoBox, + InfoBoxStyle, + InfoBoxType, TableHeader, TooltipPosition, } from '@iota/apps-ui-kit'; import { useIotaClientQuery } from '@iota/dapp-kit'; import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils'; -import { ErrorBoundary, PageLayout, Banner, PlaceholderTable, TableCard } from '~/components'; +import { ErrorBoundary, PageLayout, PlaceholderTable, TableCard } from '~/components'; import { generateValidatorsTableColumns } from '~/lib/ui'; +import { Warning } from '@iota/ui-icons'; function ValidatorPageResult(): JSX.Element { const { data, isPending, isSuccess, isError } = useIotaClientQuery('getLatestIotaSystemState'); @@ -127,9 +131,13 @@ function ValidatorPageResult(): JSX.Element { - Validator data could not be loaded - + } + type={InfoBoxType.Error} + style={InfoBoxStyle.Elevated} + /> ) : (
Validators