Skip to content

Commit

Permalink
feat: add simple version of asset input [LW-9231]
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikGuzei committed Oct 9, 2024
1 parent 674f6a6 commit f3ca7f1
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 29 deletions.
5 changes: 4 additions & 1 deletion src/design-system/asset-input/amount-input.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ import React from 'react';
import { Box } from '../box';

import * as cx from './amount-input.css';
import { AmountInputAlignments } from './types';

interface Props {
alignment?: AmountInputAlignments;
onChange?: (value: string) => void;
value?: string;
id: string;
}

export const AmountInput = ({
alignment = 'right',
onChange,
value,
id,
}: Readonly<Props>): JSX.Element => {
return (
<Box className={cx.amountInputSizer} data-value={value}>
<input
className={cx.amountInput}
className={cx.amountInput[alignment]}
value={value}
size={1}
onChange={({ target }): void => onChange?.(target.value)}
Expand Down
20 changes: 18 additions & 2 deletions src/design-system/asset-input/amount-input.css.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { styleVariants } from '@vanilla-extract/css';

import { style, vars } from '../../design-tokens';
import { bold } from '../text/text.css';

Expand All @@ -20,12 +22,11 @@ export const amountInputSizer = style([
},
]);

export const amountInput = style([
const amountInputBase = style([
inputTypography,
bold,
{
gridArea: '1 / 2',
textAlign: 'right',
border: 'none',
width: 'auto',
background: 'none',
Expand All @@ -39,3 +40,18 @@ export const amountInput = style([
},
},
]);

export const amountInput = styleVariants({
left: [
amountInputBase,
{
textAlign: 'left',
},
],
right: [
amountInputBase,
{
textAlign: 'right',
},
],
});
8 changes: 4 additions & 4 deletions src/design-system/asset-input/asset-input.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import * as cx from './asset-input.css';
import { MaxButton } from './max-button.component';
import { TickerButton } from './ticker-button.component';

import type { Asset, AssetState } from './asset-input.data';
import type { AssetWithFiat, AssetState } from './asset-input.data';

interface Props {
state: AssetState;
onTickerClick?: (asset: Readonly<Asset>) => void;
onAmountChange?: (asset: Readonly<Asset>, amount: string) => void;
onMaxClick?: (asset: Readonly<Asset>) => void;
onTickerClick?: (asset: Readonly<AssetWithFiat>) => void;
onAmountChange?: (asset: Readonly<AssetWithFiat>, amount: string) => void;
onMaxClick?: (asset: Readonly<AssetWithFiat>) => void;
}

export const AssetInput = ({
Expand Down
9 changes: 6 additions & 3 deletions src/design-system/asset-input/asset-input.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ export interface Asset {
ticker: string;
balance: string;
amount: string;
}

export interface AssetWithFiat extends Asset {
fiat: {
value: string;
ticker: string;
};
}

export type AssetState =
export type AssetState<A extends Asset = AssetWithFiat> =
| {
type: 'valid';
asset: Asset;
asset: A;
}
| { type: 'invalid'; asset: Asset; error: string };
| { type: 'invalid'; asset: A; error: string };
4 changes: 2 additions & 2 deletions src/design-system/asset-input/asset-input.fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Asset, AssetState } from './asset-input.data';
import type { AssetWithFiat, AssetState } from './asset-input.data';

export const asset: Asset = {
export const asset: AssetWithFiat = {
balance: String(10_000_000),
amount: '',
id: '',
Expand Down
34 changes: 27 additions & 7 deletions src/design-system/asset-input/asset-input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import {
ColorSchemaTable,
} from '../decorators';
import { Divider } from '../divider';
import { Grid } from '../grid';
import { Cell } from '../grid/cell.component';
import { Cell, Grid } from '../grid';

import { AssetInput } from './asset-input.component';
import { invalidState, validState } from './asset-input.fixtures';
import { MaxButton } from './max-button.component';
import { SimpleAssetInput } from './simple-asset-input.component';

import type { Asset, AssetState } from './asset-input.data';
import type { AssetWithFiat, AssetState } from './asset-input.data';

const subtitle = ``;

Expand Down Expand Up @@ -61,7 +61,12 @@ export const Overview = (): JSX.Element => (
<Cell>
<Section title="Overview">
<Variants.Table
headers={['Browser view — simple', 'Browser view — simple + error']}
headers={[
'Complex — valid',
'Complex — invalid',
'Simple - valid',
'Simple - invalid',
]}
>
<Variants.Row>
<Variants.Cell>
Expand All @@ -70,6 +75,18 @@ export const Overview = (): JSX.Element => (
<Variants.Cell>
<AssetInput state={invalidState('1')} />
</Variants.Cell>
<Variants.Cell>
<SimpleAssetInput
state={validState('1')}
balanceLabel="Balance Available"
/>
</Variants.Cell>
<Variants.Cell>
<SimpleAssetInput
state={invalidState('1')}
balanceLabel="Balance Available"
/>
</Variants.Cell>
</Variants.Row>
</Variants.Table>
</Section>
Expand Down Expand Up @@ -105,14 +122,17 @@ type Interactions = ComponentStory<typeof AssetInput>;
export const Interactions: Interactions = (): JSX.Element => {
const [state, setState] = useState<AssetState>(validState('1'));

const onTickerClick = (asset: Readonly<Asset>): void => {
const onTickerClick = (asset: Readonly<AssetWithFiat>): void => {
setState(currentState => ({
...currentState,
asset: { ...currentState.asset, ticker: `Token ${asset.id}` },
}));
};

const onAmountChange = (asset: Readonly<Asset>, amount: string): void => {
const onAmountChange = (
asset: Readonly<AssetWithFiat>,
amount: string,
): void => {
setState(currentState => {
if (currentState.asset.id !== asset.id) {
return currentState;
Expand Down Expand Up @@ -141,7 +161,7 @@ export const Interactions: Interactions = (): JSX.Element => {
});
};

const onMaxClick = (asset: Readonly<Asset>): void => {
const onMaxClick = (asset: Readonly<AssetWithFiat>): void => {
setState(currentState => {
return {
...currentState,
Expand Down
1 change: 1 addition & 0 deletions src/design-system/asset-input/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { AssetInput } from './asset-input.component';
export { SimpleAssetInput } from './simple-asset-input.component';
export * as Data from './asset-input.data';
49 changes: 49 additions & 0 deletions src/design-system/asset-input/simple-asset-input.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';

import { Box } from '../box';
import { Text } from '../text';

import { AmountInput } from './amount-input.component';
import * as cx from './simple-asset-input.css';

import type { Asset, AssetState } from './asset-input.data';

interface Props {
state: AssetState<Asset>;
balanceLabel: string;
onAmountChange?: (asset: Readonly<Asset>, amount: string) => void;
}

export const SimpleAssetInput = ({
state,
balanceLabel,
onAmountChange,
}: Readonly<Props>): JSX.Element => (
<div className={cx.root}>
<Box className={cx.amountBox}>
<AmountInput
id={state.asset.id}
value={state.asset.amount}
alignment="left"
onChange={(value): void => {
onAmountChange?.(state.asset, value);
}}
/>
</Box>
<Box className={cx.balance}>
<Text.Body.Normal color="secondary">
{balanceLabel}: {state.asset.balance} {state.asset.ticker}
</Text.Body.Normal>
</Box>
{state.type === 'invalid' && (
<Box className={cx.error}>
<Text.Label
color="error"
data-testid={`asset-input-error-${state.asset.id}`}
>
{state.error}
</Text.Label>
</Box>
)}
</div>
);
25 changes: 25 additions & 0 deletions src/design-system/asset-input/simple-asset-input.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { sx, style, vars } from '../../design-tokens';

export const root = style([
sx({
width: '$fill',
rowGap: '$10',
}),
{
background: vars.colors.$input_container_bgColor,
borderRadius: vars.radius.$medium,
padding: `${vars.spacing.$16} ${vars.spacing.$20}`,
display: 'grid',
gridTemplateAreas: `
"amount amount"
"balance balance"
"error ."
`,
},
]);

export const amountBox = style({ gridArea: 'amount' });

export const balance = style({ gridArea: 'balance' });

export const error = style({ gridArea: 'error' });
1 change: 1 addition & 0 deletions src/design-system/asset-input/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type AmountInputAlignments = 'left' | 'right';
11 changes: 7 additions & 4 deletions src/design-system/bundle-input/bundle-input.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ import type { Data } from '../asset-input';
export type Props = PropsWithChildren<{
state?: Data.AssetState[];
onAddAsset?: () => void;
onRemoveAsset?: (asset: Readonly<Data.Asset>) => void;
onAmountChange?: (asset: Readonly<Data.Asset>, amount: string) => void;
onTickerClick?: (asset: Readonly<Data.Asset>) => void;
onMaxClick?: (asset: Readonly<Data.Asset>) => void;
onRemoveAsset?: (asset: Readonly<Data.AssetWithFiat>) => void;
onAmountChange?: (
asset: Readonly<Data.AssetWithFiat>,
amount: string,
) => void;
onTickerClick?: (asset: Readonly<Data.AssetWithFiat>) => void;
onMaxClick?: (asset: Readonly<Data.AssetWithFiat>) => void;
}>;

export const BundleInput = ({
Expand Down
16 changes: 11 additions & 5 deletions src/design-system/bundle-input/bundle-input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { Cell } from '../grid/cell.component';
import { BundleInput } from './bundle-input.component';
import { RemoveButton } from './remove-button.component';

import type { Asset, AssetState } from '../asset-input/asset-input.data';
import type {
AssetWithFiat,
AssetState,
} from '../asset-input/asset-input.data';

const subtitle = ``;

Expand Down Expand Up @@ -132,7 +135,7 @@ export const Interactions: Interactions = (): JSX.Element => {
setState([...state, validState((state.length + 1).toString())]);
};

const onTickerClick = (asset: Readonly<Asset>): void => {
const onTickerClick = (asset: Readonly<AssetWithFiat>): void => {
setState(
state.map(currentState => {
if (currentState.asset.id === asset.id) {
Expand All @@ -147,7 +150,10 @@ export const Interactions: Interactions = (): JSX.Element => {
);
};

const onAmountChange = (asset: Readonly<Asset>, amount: string): void => {
const onAmountChange = (
asset: Readonly<AssetWithFiat>,
amount: string,
): void => {
setState(
state.map(currentState => {
if (currentState.asset.id !== asset.id) {
Expand Down Expand Up @@ -178,7 +184,7 @@ export const Interactions: Interactions = (): JSX.Element => {
);
};

const onMaxClick = (asset: Readonly<Asset>): void => {
const onMaxClick = (asset: Readonly<AssetWithFiat>): void => {
setState(
state.map(currentState => {
if (currentState.asset.id !== asset.id) {
Expand All @@ -197,7 +203,7 @@ export const Interactions: Interactions = (): JSX.Element => {
);
};

const onRemoveAsset = (asset: Readonly<Asset>): void => {
const onRemoveAsset = (asset: Readonly<AssetWithFiat>): void => {
setState(state.filter(currentState => currentState.asset.id !== asset.id));
};

Expand Down
2 changes: 1 addition & 1 deletion src/design-system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export { Divider } from './divider';
export { Flex } from './flex';
export { Grid, Cell } from './grid';
export { Text } from './text';
export { AssetInput } from './asset-input';
export { AssetInput, SimpleAssetInput } from './asset-input';
export { BundleInput } from './bundle-input';
export * as SubNavigation from './sub-navigation';
export * as NavigationButton from './navigation-buttons';
Expand Down

0 comments on commit f3ca7f1

Please sign in to comment.