diff --git a/apps/minifront/src/components/dashboard/assets-table.tsx b/apps/minifront/src/components/dashboard/assets-table.tsx index 334e532c95..16d0d06304 100644 --- a/apps/minifront/src/components/dashboard/assets-table.tsx +++ b/apps/minifront/src/components/dashboard/assets-table.tsx @@ -33,12 +33,17 @@ export default function AssetsTable() { {data.map((a, index) => (
-
-
+
+
-

Account #{a.index.account}

+

+ Account #{a.index.account} +

+
+ +
+
-
diff --git a/packages/ui/components/ui/address-component.test.tsx b/packages/ui/components/ui/address-component.test.tsx index 6130fd8102..5657611bb6 100644 --- a/packages/ui/components/ui/address-component.test.tsx +++ b/packages/ui/components/ui/address-component.test.tsx @@ -3,28 +3,27 @@ import { describe, expect, test } from 'vitest'; import { render } from '@testing-library/react'; import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb'; import { bech32ToUint8Array } from '@penumbra-zone/types/src/address'; -import { shortenAddress } from '@penumbra-zone/types/src/string'; describe('', () => { const address = 'penumbra1u7dk4qw6fz3vlwyjl88vlj6gqv4hcmz2vesm87t7rm0lvwmgqqkrp3zrdmfg6et86ggv4nwmnc8vy39uxyacwm8g7trk77ad0c8n4qt76ncvuukx6xlj8mskhyjpn4twkpwwl2'; const pbAddress = new Address({ inner: bech32ToUint8Array(address) }); - test('renders the shortened address', () => { + test('renders the address', () => { const { baseElement } = render(); - expect(baseElement).toHaveTextContent(shortenAddress(address)); + expect(baseElement).toHaveTextContent(address); }); test('uses text-muted-foreground for non-ephemeral addresses', () => { const { getByText } = render(); - expect(getByText(shortenAddress(address))).toHaveClass('text-muted-foreground'); + expect(getByText(address)).toHaveClass('text-muted-foreground'); }); test('uses colored text for ephemeral addresses', () => { const { getByText } = render(); - expect(getByText(shortenAddress(address))).toHaveClass('text-[#8D5728]'); + expect(getByText(address)).toHaveClass('text-[#8D5728]'); }); }); diff --git a/packages/ui/components/ui/address-component.tsx b/packages/ui/components/ui/address-component.tsx index bd3c928bdf..321d9f753c 100644 --- a/packages/ui/components/ui/address-component.tsx +++ b/packages/ui/components/ui/address-component.tsx @@ -1,6 +1,5 @@ import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb'; import { bech32Address } from '@penumbra-zone/types/src/address'; -import { shortenAddress } from '@penumbra-zone/types/src/string'; interface AddressComponentProps { address: Address; @@ -15,8 +14,10 @@ export const AddressComponent = ({ address, ephemeral }: AddressComponentProps) const bech32Addr = bech32Address(address); return ( - - {shortenAddress(bech32Addr)} + + {bech32Addr} ); }; diff --git a/packages/ui/components/ui/card.tsx b/packages/ui/components/ui/card.tsx index e8f9b2576e..a6327cfd89 100644 --- a/packages/ui/components/ui/card.tsx +++ b/packages/ui/components/ui/card.tsx @@ -7,7 +7,7 @@ export interface CardProps extends React.HTMLAttributes { const Card = React.forwardRef( ({ className, gradient, children, ...props }, ref) => { - const baseClasses = 'bg-charcoal rounded-lg shadow-sm p-[30px]'; + const baseClasses = 'bg-charcoal rounded-lg shadow-sm p-[30px] overflow-hidden'; return (
{
-
- +
+
+ +
-

+

diff --git a/packages/ui/components/ui/tx/view/action-details.tsx b/packages/ui/components/ui/tx/view/action-details.tsx index d76fa172b8..274ec22c76 100644 --- a/packages/ui/components/ui/tx/view/action-details.tsx +++ b/packages/ui/components/ui/tx/view/action-details.tsx @@ -12,8 +12,14 @@ import { ReactNode } from 'react'; * * ``` */ -export const ActionDetails = ({ children }: { children: ReactNode }) => { - return
{children}
; +export const ActionDetails = ({ children, label }: { children: ReactNode; label?: string }) => { + return ( +
+ {!!label &&
{label}
} + + {children} +
+ ); }; const Separator = () => ( @@ -21,14 +27,26 @@ const Separator = () => (
); -const ActionDetailsRow = ({ label, children }: { label: string; children: ReactNode }) => { +const ActionDetailsRow = ({ + label, + children, + truncate, +}: { + label: string; + children: ReactNode; + /** + * If `children` is a string, passing `truncate` will automatically truncate + * the text if it doesn't fit in a single line. + */ + truncate?: boolean; +}) => { return (
- {label} + {label} - {children} + {truncate ? {children} : children}
); }; diff --git a/packages/ui/components/ui/tx/view/address-view.tsx b/packages/ui/components/ui/tx/view/address-view.tsx index b57c914348..74c473d762 100644 --- a/packages/ui/components/ui/tx/view/address-view.tsx +++ b/packages/ui/components/ui/tx/view/address-view.tsx @@ -28,7 +28,7 @@ export const AddressViewComponent = ({ view, copyable = true }: AddressViewProps copyable = isOneTimeAddress ? false : copyable; return ( -
+
{accountIndex !== undefined ? ( <> diff --git a/packages/ui/components/ui/tx/view/delegate.tsx b/packages/ui/components/ui/tx/view/delegate.tsx index 24b0cf68a8..b3f8a5e76c 100644 --- a/packages/ui/components/ui/tx/view/delegate.tsx +++ b/packages/ui/components/ui/tx/view/delegate.tsx @@ -2,44 +2,38 @@ import { Delegate } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/ import { ViewBox } from './viewbox'; import { joinLoHiAmount } from '@penumbra-zone/types/src/amount'; import { bech32IdentityKey } from '@penumbra-zone/types/src/identity-key'; +import { ActionDetails } from './action-details'; /** * Render a `Delegate` action. - * - * @todo: Make this nicer :) */ export const DelegateComponent = ({ value }: { value: Delegate }) => { return ( -
- Epoch index: {value.epochIndex.toString()} -
+ + {value.epochIndex.toString()} {!!value.delegationAmount && ( -
- Delegation amount:{' '} + {joinLoHiAmount(value.delegationAmount).toString()} -
+ )} {!!value.unbondedAmount && ( -
- Unbonded amount:{' '} + {joinLoHiAmount(value.unbondedAmount).toString()} -
+ )} {/** @todo: Render validator name/etc. after fetching? */} {!!value.validatorIdentity && ( -
- Validator identity:{' '} + {bech32IdentityKey(value.validatorIdentity)} -
+ )} -
+ } /> ); diff --git a/packages/ui/components/ui/tx/view/swap.tsx b/packages/ui/components/ui/tx/view/swap.tsx index f7c9838f29..a36a4ae302 100644 --- a/packages/ui/components/ui/tx/view/swap.tsx +++ b/packages/ui/components/ui/tx/view/swap.tsx @@ -1,56 +1,51 @@ import { ViewBox } from './viewbox'; import { SwapView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/dex/v1/dex_pb'; -import { bech32Address } from '@penumbra-zone/types/src/address'; import { fromBaseUnitAmount, joinLoHiAmount } from '@penumbra-zone/types/src/amount'; import { uint8ArrayToBase64 } from '@penumbra-zone/types/src/base64'; +import { ActionDetails } from './action-details'; +import { AddressView } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb'; +import { AddressViewComponent } from './address-view'; export const SwapViewComponent = ({ value }: { value: SwapView }) => { if (value.swapView.case === 'visible') { const { tradingPair, delta1I, delta2I, claimFee, claimAddress } = value.swapView.value.swapPlaintext!; - const encodedAddress = bech32Address(claimAddress!); + const addressView = new AddressView({ + addressView: { case: 'decoded', value: { address: claimAddress } }, + }); return ( -
- Asset 1: -
- ID: +
+ + {uint8ArrayToBase64(tradingPair!.asset1!.inner)} -
-
- Amount: - {joinLoHiAmount(delta1I!).toString()} -
-
-
- Asset 2: -
- ID: + + + {joinLoHiAmount(delta1I!).toString()} + + + + + {uint8ArrayToBase64(tradingPair!.asset2!.inner)} -
-
- Amount: - {joinLoHiAmount(delta2I!).toString()} -
-
-
- Claim: -
- Address: - {encodedAddress} -
-
- Fee: - - {fromBaseUnitAmount(claimFee!.amount!, 0).toFormat()} upenumbra - -
-
+ + + {joinLoHiAmount(delta2I!).toString()} + + + + + + + + + {fromBaseUnitAmount(claimFee!.amount!, 0).toFormat()} upenumbra + +
} /> diff --git a/packages/ui/components/ui/tx/view/undelegate.tsx b/packages/ui/components/ui/tx/view/undelegate.tsx index b5d4fc799d..ef44994c9b 100644 --- a/packages/ui/components/ui/tx/view/undelegate.tsx +++ b/packages/ui/components/ui/tx/view/undelegate.tsx @@ -2,44 +2,40 @@ import { Undelegate } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/cor import { ViewBox } from './viewbox'; import { joinLoHiAmount } from '@penumbra-zone/types/src/amount'; import { bech32IdentityKey } from '@penumbra-zone/types/src/identity-key'; +import { ActionDetails } from './action-details'; /** * Render an `Undelegate` action. - * - * @todo: Make this nicer :) */ export const UndelegateComponent = ({ value }: { value: Undelegate }) => { return ( -
- Epoch index: {value.startEpochIndex.toString()} -
+ + + {value.startEpochIndex.toString()} + {!!value.delegationAmount && ( -
- Delegation amount:{' '} + {joinLoHiAmount(value.delegationAmount).toString()} -
+ )} {!!value.unbondedAmount && ( -
- Unbonded amount:{' '} + {joinLoHiAmount(value.unbondedAmount).toString()} -
+ )} {/** @todo: Render validator name/etc. after fetching? */} {!!value.validatorIdentity && ( -
- Validator identity:{' '} + {bech32IdentityKey(value.validatorIdentity)} -
+ )} -
+ } /> ); diff --git a/packages/ui/components/ui/tx/view/viewbox.tsx b/packages/ui/components/ui/tx/view/viewbox.tsx index 27780085d4..906d1bada3 100644 --- a/packages/ui/components/ui/tx/view/viewbox.tsx +++ b/packages/ui/components/ui/tx/view/viewbox.tsx @@ -9,6 +9,8 @@ export interface ViewBoxProps { visibleContent?: React.ReactElement; } +const Label = ({ label }: { label: string }) => {label}; + export const ViewBox = ({ label, visibleContent }: ViewBoxProps) => { return (
{ >
- {visibleContent && label} + {visibleContent &&