diff --git a/.changeset/align-key-value-columns.md b/.changeset/align-key-value-columns.md new file mode 100644 index 0000000000..440bfcc313 --- /dev/null +++ b/.changeset/align-key-value-columns.md @@ -0,0 +1,5 @@ +--- +'@iota/apps-ui-kit': minor +--- + +Fix `KeyValueInfo` key text overflowing into the value column when it doesn't fit its column width, slightly increase the gap between the key and value columns, and add an optional `keyColumnWidth` prop (`KeyColumnWidth.Default` | `KeyColumnWidth.Wide`) to widen the key column relative to the value column. diff --git a/apps/explorer/src/pages/transaction-result/TransactionOverview.tsx b/apps/explorer/src/pages/transaction-result/TransactionOverview.tsx index 372d575e37..ca4b013ad1 100644 --- a/apps/explorer/src/pages/transaction-result/TransactionOverview.tsx +++ b/apps/explorer/src/pages/transaction-result/TransactionOverview.tsx @@ -2,7 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 import { useState } from 'react'; -import { Badge, BadgeType, ButtonUnstyled, Divider, KeyValueInfo } from '@iota/apps-ui-kit'; +import { + Badge, + BadgeType, + ButtonUnstyled, + Divider, + KeyColumnWidth, + KeyValueInfo, +} from '@iota/apps-ui-kit'; import { CoinFiatValue, TransactionAction, @@ -21,15 +28,37 @@ import { EpochLink, ObjectLink, } from '~/components'; -import { useBreakpoint, useDeserializedSignatures, type SignaturePubkeyPair } from '~/hooks'; +import { useDeserializedSignatures, type SignaturePubkeyPair } from '~/hooks'; import { getSendRecipientAddress, onCopySuccess } from '~/lib/utils'; +// A fixed-width, invisible spacer passed as `KeyValueInfo`'s `keyIcon` to indent the key +// text without changing the row's width (which would misalign the value column). +const INDENT_SPACER = ; + +// Draws a single continuous vertical rule alongside indented rows, instead of each +// row drawing its own border (which leaves visible gaps between rows). +function IndentGuide({ children }: { children: React.ReactNode }): JSX.Element { + return ( +
+
+ {children} +
+ ); +} + function SignatureBreakdown({ signature: data }: { signature: SignaturePubkeyPair }): JSX.Element { const { signature, signatureScheme } = data; return ( -
- + + {'publicKey' in data ? ( ) : null} -
+ ); } @@ -104,7 +137,6 @@ export function TransactionOverview({ const [showAllGasPayment, setShowAllGasPayment] = useState(false); const [showGasFeeBreakdown, setShowGasFeeBreakdown] = useState(false); const [showFullSignatures, setShowFullSignatures] = useState(false); - const isMediumOrAbove = useBreakpoint('md'); const { userSignatures, sponsorSignature } = useDeserializedSignatures(transaction); const transactionKindName = transaction.transaction?.data.transaction?.kind; @@ -136,25 +168,26 @@ export function TransactionOverview({
{transactionKindName && (
} - fullwidth={!isMediumOrAbove} /> )} {transaction.checkpoint && ( @@ -163,22 +196,22 @@ export function TransactionOverview({ } copyText={transaction.checkpoint} onCopySuccess={onCopySuccess} - fullwidth={!isMediumOrAbove} /> )} {transaction.effects?.executedEpoch && ( {transaction.effects.executedEpoch} } - fullwidth={!isMediumOrAbove} /> )} {transaction.timestampMs && ( } - fullwidth={!isMediumOrAbove} /> )} {sender && ( @@ -199,11 +232,11 @@ export function TransactionOverview({ value={} copyText={sender} onCopySuccess={onCopySuccess} - fullwidth={!isMediumOrAbove} /> )} {recipient && ( @@ -211,17 +244,21 @@ export function TransactionOverview({ value={} copyText={recipient} onCopySuccess={onCopySuccess} - fullwidth={!isMediumOrAbove} /> )} {isProgrammableTransaction && totalGas && (
- + value={ +
+
+ + {formattedTotalGas} {totalGasSymbol} + + +
{gasUsed && ( } - fullwidth={!isMediumOrAbove} />
)} {isProgrammableTransaction && showGasFeeBreakdown && gasUsed && ( -
+ {gasPrice && ( } - fullwidth={!isMediumOrAbove} /> )} {gasUsed.computationCost && ( } - fullwidth={!isMediumOrAbove} /> )} {gasUsed.storageCost && ( } - fullwidth={!isMediumOrAbove} /> )} {gasUsed.storageRebate && ( } - fullwidth={!isMediumOrAbove} /> )} -
+ )} {isProgrammableTransaction && gasBudget && ( )} {isProgrammableTransaction && !!gasPayment?.length && ( @@ -313,53 +354,49 @@ export function TransactionOverview({ )}
} - fullwidth={!isMediumOrAbove} /> )} {isProgrammableTransaction && gasOwner && ( } copyText={gasOwner} onCopySuccess={onCopySuccess} - fullwidth={!isMediumOrAbove} /> )} {!!signatures?.length && ( 1 ? 'User Signatures' : 'User Signature'} value={ -
- setShowFullSignatures(!showFullSignatures)} - > - {showFullSignatures ? 'Show Less' : 'Show More'} - - - {showFullSignatures && ( -
- {[ - ...userSignatures, - ...(sponsorSignature ? [sponsorSignature] : []), - ].map((signature, index) => ( -
- {index > 0 && } - -
- ))} -
- )} -
+ setShowFullSignatures(!showFullSignatures)} + > + {showFullSignatures ? 'Show Less' : 'Show More'} + + } - fullwidth={!isMediumOrAbove} /> )} + {showFullSignatures && ( +
+ {[...userSignatures, ...(sponsorSignature ? [sponsorSignature] : [])].map( + (signature, index) => ( +
+ {index > 0 && } + +
+ ), + )} +
+ )}
); } diff --git a/apps/explorer/src/pages/transaction-result/transaction-summary/BalanceChanges.tsx b/apps/explorer/src/pages/transaction-result/transaction-summary/BalanceChanges.tsx index 9d65c23221..b2664fcb25 100644 --- a/apps/explorer/src/pages/transaction-result/transaction-summary/BalanceChanges.tsx +++ b/apps/explorer/src/pages/transaction-result/transaction-summary/BalanceChanges.tsx @@ -35,25 +35,27 @@ export function BalanceChanges({ changes }: BalanceChangesProps): JSX.Element | return (
- <TableCard - data={pageData} - columns={columns} - paginationOptions={paginationOptions} - totalLabel={supportingLabel} - pageSizeSelector={ - paginationOptions && ( - <Select - value={limit.toString()} - options={PAGE_SIZES_RANGE_10_50.map((size) => ({ - label: `${size} / page`, - id: size.toString(), - }))} - size={SelectSize.Small} - onValueChange={(value) => setLimit(Number(value))} - /> - ) - } - /> + <div className="px-md--rs"> + <TableCard + data={pageData} + columns={columns} + paginationOptions={paginationOptions} + totalLabel={supportingLabel} + pageSizeSelector={ + paginationOptions && ( + <Select + value={limit.toString()} + options={PAGE_SIZES_RANGE_10_50.map((size) => ({ + label: `${size} / page`, + id: size.toString(), + }))} + size={SelectSize.Small} + onValueChange={(value) => setLimit(Number(value))} + /> + ) + } + /> + </div> </div> ); } diff --git a/apps/explorer/src/pages/transaction-result/transaction-summary/ObjectChanges.tsx b/apps/explorer/src/pages/transaction-result/transaction-summary/ObjectChanges.tsx index e7c0734b8b..f11abbbe66 100644 --- a/apps/explorer/src/pages/transaction-result/transaction-summary/ObjectChanges.tsx +++ b/apps/explorer/src/pages/transaction-result/transaction-summary/ObjectChanges.tsx @@ -51,25 +51,27 @@ export function ObjectChanges({ objectSummary }: ObjectChangesProps): JSX.Elemen return ( <div className="flex flex-col gap-xs"> <Title title="Object Change" /> - <TableCard - data={pageData} - columns={columns} - paginationOptions={paginationOptions} - totalLabel={supportingLabel} - pageSizeSelector={ - paginationOptions && ( - <Select - value={limit.toString()} - options={PAGE_SIZES_RANGE_10_50.map((size) => ({ - label: `${size} / page`, - id: size.toString(), - }))} - size={SelectSize.Small} - onValueChange={(value) => setLimit(Number(value))} - /> - ) - } - /> + <div className="px-md--rs"> + <TableCard + data={pageData} + columns={columns} + paginationOptions={paginationOptions} + totalLabel={supportingLabel} + pageSizeSelector={ + paginationOptions && ( + <Select + value={limit.toString()} + options={PAGE_SIZES_RANGE_10_50.map((size) => ({ + label: `${size} / page`, + id: size.toString(), + }))} + size={SelectSize.Small} + onValueChange={(value) => setLimit(Number(value))} + /> + ) + } + /> + </div> </div> ); } diff --git a/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx b/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx index 58e0f72aa2..7b9b22126b 100644 --- a/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx +++ b/apps/explorer/src/pages/transaction-result/transaction-summary/index.tsx @@ -26,7 +26,7 @@ export function TransactionSummary({ transaction }: TransactionChangesProps): JS return ( <div className="flex flex-col gap-sm"> <CollapsibleCard title="Changes" hideBorder rawData={{ balanceChanges, objectSummary }}> - <div className="flex flex-col gap-lg px-md--rs pb-lg pt-xs"> + <div className="flex flex-col gap-lg pb-lg pt-xs"> {transactionKindName === 'ProgrammableTransaction' && ( <BalanceChanges changes={balanceChanges ?? null} /> )} diff --git a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx index a9fe9a2554..52fe0bbb85 100644 --- a/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx +++ b/apps/ui-kit/src/lib/components/atoms/key-value-info/KeyValueInfo.tsx @@ -4,7 +4,7 @@ import type { ReactNode } from 'react'; import cx from 'classnames'; import { Copy, Info } from '@iota/apps-ui-icons'; -import { ValueSize } from './keyValue.enums'; +import { KeyColumnWidth, ValueSize } from './keyValue.enums'; import type { TooltipPosition } from '../tooltip'; import { Tooltip } from '../tooltip'; import { ButtonUnstyled } from '../button'; @@ -66,6 +66,10 @@ interface KeyValueProps { * Text shown on value hover. */ valueHoverTitle?: string; + /** + * The width of the key column, relative to the value column (optional). + */ + keyColumnWidth?: KeyColumnWidth; } export function KeyValueInfo({ @@ -83,6 +87,7 @@ export function KeyValueInfo({ fullwidth, isReverse = false, valueHoverTitle, + keyColumnWidth = KeyColumnWidth.Default, }: KeyValueProps): React.JSX.Element { const flexDirectionClass = isReverse ? 'flex-row-reverse' : 'flex-row'; async function handleCopyClick(event: React.MouseEvent<HTMLButtonElement>) { @@ -104,7 +109,7 @@ export function KeyValueInfo({ return ( <div className={cx( - 'flex w-full items-baseline gap-xs py-xxs font-inter', + 'flex w-full items-baseline gap-sm py-xxs font-inter', flexDirectionClass, { 'flex-wrap justify-between': fullwidth, @@ -112,12 +117,13 @@ export function KeyValueInfo({ )} > <div - className={cx('flex shrink-0 flex-row items-center gap-x-0.5', { - 'w-1/4': !fullwidth, + className={cx('flex min-w-0 shrink-0 flex-row items-center gap-x-0.5', { + 'w-1/4': !fullwidth && keyColumnWidth === KeyColumnWidth.Default, + 'w-2/5': !fullwidth && keyColumnWidth === KeyColumnWidth.Wide, })} > {keyIcon} - <span className="key-value-key-text-color break-normal text-body-md"> + <span className="key-value-key-text-color min-w-0 break-normal break-words text-body-md"> {keyText} </span> {tooltipText && ( @@ -128,7 +134,8 @@ export function KeyValueInfo({ </div> <div className={cx('flex min-w-0 flex-row items-baseline gap-1 break-all', { - 'w-3/4': !fullwidth, + 'w-3/4': !fullwidth && keyColumnWidth === KeyColumnWidth.Default, + 'w-3/5': !fullwidth && keyColumnWidth === KeyColumnWidth.Wide, 'flex-wrap': fullwidth, truncate: isTruncated, })} diff --git a/apps/ui-kit/src/lib/components/atoms/key-value-info/keyValue.enums.ts b/apps/ui-kit/src/lib/components/atoms/key-value-info/keyValue.enums.ts index 523a7de2a2..bcb7670f57 100644 --- a/apps/ui-kit/src/lib/components/atoms/key-value-info/keyValue.enums.ts +++ b/apps/ui-kit/src/lib/components/atoms/key-value-info/keyValue.enums.ts @@ -5,3 +5,8 @@ export enum ValueSize { Small = 'small', Medium = 'medium', } + +export enum KeyColumnWidth { + Default = 'default', + Wide = 'wide', +}