From 5593bbfc06e1f6675b89aaef20bda8620b4d7b4c Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Fri, 16 Aug 2024 18:09:47 -0700 Subject: [PATCH] Tweak generics --- .../AssetSelectorDialogContent/index.tsx | 18 ++++++++------- .../ui/src/AssetSelector/index.stories.tsx | 23 ++++++++++++++++--- packages/ui/src/AssetSelector/index.tsx | 16 ++++++------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/packages/ui/src/AssetSelector/AssetSelectorDialogContent/index.tsx b/packages/ui/src/AssetSelector/AssetSelectorDialogContent/index.tsx index cb27212e07..461b272fb3 100644 --- a/packages/ui/src/AssetSelector/AssetSelectorDialogContent/index.tsx +++ b/packages/ui/src/AssetSelector/AssetSelectorDialogContent/index.tsx @@ -45,23 +45,25 @@ const OptionsWrapper = styled.div` gap: ${props => props.theme.spacing(1)}; `; -export interface AssetSelectorDialogContentProps { +export interface AssetSelectorDialogContentProps< + ValueType extends (BalancesResponse | Metadata) | Metadata, +> { title: string; layoutId: string; - value?: IncludesBalancesResponses extends true ? BalancesResponse | Metadata : Metadata; - onChange: ( - value: IncludesBalancesResponses extends true ? BalancesResponse | Metadata : Metadata, - ) => void; - options: IncludesBalancesResponses extends true ? (BalancesResponse | Metadata)[] : Metadata[]; + value?: ValueType; + onChange: (value: ValueType) => void; + options: ValueType[]; } -export const AssetSelectorDialogContent = ({ +export const AssetSelectorDialogContent = < + ValueType extends (BalancesResponse | Metadata) | Metadata, +>({ title, layoutId, value, onChange, options, -}: AssetSelectorDialogContentProps) => { +}: AssetSelectorDialogContentProps) => { const [search, setSearch] = useState(''); const filteredOptions = useMemo( () => options.filter(filterMetadataOrBalancesResponseByText(search)), diff --git a/packages/ui/src/AssetSelector/index.stories.tsx b/packages/ui/src/AssetSelector/index.stories.tsx index fc8791aa85..c5d89ab4a1 100644 --- a/packages/ui/src/AssetSelector/index.stories.tsx +++ b/packages/ui/src/AssetSelector/index.stories.tsx @@ -4,6 +4,7 @@ import { useArgs } from '@storybook/preview-api'; import { AssetSelector } from '.'; import { AssetId, Metadata } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb'; import { BalancesResponse } from '@penumbra-zone/protobuf/penumbra/view/v1/view_pb'; +import { useState } from 'react'; const u8 = (length: number) => Uint8Array.from({ length }, () => Math.floor(Math.random() * 256)); @@ -113,7 +114,8 @@ const umBalance1 = new BalancesResponse({ }, }); -const options = [pizza, umBalance0, umBalance1, osmoBalance0]; +const mixedOptions: (BalancesResponse | Metadata)[] = [pizza, umBalance0, umBalance1, osmoBalance0]; +const metadataOnlyOptions: Metadata[] = [pizza, um, osmo]; const meta: Meta = { component: AssetSelector, @@ -127,11 +129,11 @@ export default meta; type Story = StoryObj; -export const Basic: Story = { +export const MixedBalancesResponsesAndMetadata: Story = { args: { dialogTitle: 'Transfer Assets', value: umBalance0, - options, + options: mixedOptions, }, render: function Render(props) { @@ -142,3 +144,18 @@ export const Basic: Story = { return ; }, }; + +export const MetadataOnly: Story = { + render: function Render() { + const [value, setValue] = useState(um); + + return ( + + ); + }, +}; diff --git a/packages/ui/src/AssetSelector/index.tsx b/packages/ui/src/AssetSelector/index.tsx index 27416aac0a..9b04fe3d0f 100644 --- a/packages/ui/src/AssetSelector/index.tsx +++ b/packages/ui/src/AssetSelector/index.tsx @@ -30,37 +30,35 @@ const Row = styled.div<{ $density: Density }>` align-items: center; `; -export interface AssetSelectorProps { +export interface AssetSelectorProps { /** * The currently selected `Metadata` or `BalancesResponse`. */ - value?: IncludesBalancesResponses extends true ? BalancesResponse | Metadata : Metadata; - onChange: ( - value: IncludesBalancesResponses extends true ? BalancesResponse | Metadata : Metadata, - ) => void; + value?: ValueType; + onChange: (value: ValueType) => void; /** * An array of `Metadata`s and possibly `BalancesResponse`s to render as * options. If `BalancesResponse`s are included in the `options` array, those * options will be rendered with the user's balance of them. */ - options: IncludesBalancesResponses extends true ? (BalancesResponse | Metadata)[] : Metadata[]; + options: ValueType[]; /** The title to show above the asset selector dialog when it opens. */ dialogTitle: string; } -export const AssetSelector = ({ +export const AssetSelector = ({ value, onChange, options, dialogTitle, -}: AssetSelectorProps) => { +}: AssetSelectorProps) => { const layoutId = useId(); const density = useDensity(); const metadata = isMetadata(value) ? value : getMetadataFromBalancesResponse.optional()(value); const [isOpen, setIsOpen] = useState(false); - const handleChange = (newValue: typeof value) => { + const handleChange = (newValue: ValueType) => { onChange(newValue); setIsOpen(false); };