Adding storybook tests on meta-types/display/components (#1862)
* working on a story for MoneyFieldDisplay * Write test on MoneyDisplayField
This commit is contained in:
@ -3,7 +3,7 @@ import { createContext } from 'react';
|
||||
import { FieldDefinition } from '../types/FieldDefinition';
|
||||
import { FieldMetadata } from '../types/FieldMetadata';
|
||||
|
||||
type GenericFieldContextType = {
|
||||
export type GenericFieldContextType = {
|
||||
fieldDefinition: FieldDefinition<FieldMetadata>;
|
||||
// TODO: add better typing for mutation hook
|
||||
useUpdateEntityMutation: () => [(params: any) => void, any];
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import {
|
||||
FieldContext,
|
||||
GenericFieldContextType,
|
||||
} from '@/ui/field/contexts/FieldContext';
|
||||
|
||||
type FieldDisplayContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
fieldDefinition: GenericFieldContextType['fieldDefinition'];
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
export const FieldDisplayContextProvider = ({
|
||||
children,
|
||||
fieldDefinition,
|
||||
entityId,
|
||||
}: FieldDisplayContextProviderProps) => {
|
||||
return (
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
entityId: entityId ?? '1',
|
||||
recoilScopeId: '1',
|
||||
hotkeyScope: 'hotkey-scope',
|
||||
fieldDefinition,
|
||||
useUpdateEntityMutation: () => [
|
||||
() => {
|
||||
return;
|
||||
},
|
||||
{},
|
||||
],
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</FieldContext.Provider>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,112 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { useMoneyField } from '../../../hooks/useMoneyField';
|
||||
import { MoneyFieldDisplay } from '../MoneyFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const MoneyFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useMoneyField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type MoneyFieldDisplayWithContextProps = {
|
||||
value: number;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const MoneyFieldDisplayWithContext = ({
|
||||
value,
|
||||
entityId,
|
||||
}: MoneyFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'money',
|
||||
name: 'Money',
|
||||
type: 'moneyAmount',
|
||||
metadata: {
|
||||
fieldName: 'Amount',
|
||||
placeHolder: 'Amount',
|
||||
isPositive: true,
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<MoneyFieldValueSetterEffect value={value} />
|
||||
<MoneyFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/MoneyFieldDisplay',
|
||||
component: MoneyFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof MoneyFieldDisplayWithContext>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
value: 100,
|
||||
},
|
||||
};
|
||||
|
||||
export const Elipsis: Story = {
|
||||
args: {
|
||||
value: 1e100,
|
||||
},
|
||||
argTypes: {
|
||||
value: { control: false },
|
||||
},
|
||||
parameters: {
|
||||
container: {
|
||||
width: 100,
|
||||
},
|
||||
},
|
||||
decorators: [ComponentDecorator],
|
||||
};
|
||||
|
||||
export const Catalog: CatalogStory<Story, typeof MoneyFieldDisplayWithContext> =
|
||||
{
|
||||
argTypes: {
|
||||
value: { control: false },
|
||||
},
|
||||
parameters: {
|
||||
catalog: {
|
||||
dimensions: [
|
||||
{
|
||||
name: 'currency',
|
||||
values: ['$'] satisfies string[],
|
||||
props: (_value: string) => ({}),
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
values: [
|
||||
100, 1000, -1000, 1e10, 1.357802, -1.283, 0,
|
||||
] satisfies number[],
|
||||
props: (value: number) => ({ value, entityId: v4() }),
|
||||
},
|
||||
],
|
||||
options: {
|
||||
elementContainer: {
|
||||
width: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [CatalogDecorator],
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledLayout = styled.div`
|
||||
const StyledLayout = styled.div<{ width?: number }>`
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-radius: 5px;
|
||||
@ -12,13 +12,17 @@ const StyledLayout = styled.div`
|
||||
max-width: calc(100% - 40px);
|
||||
min-width: 300px;
|
||||
padding: 20px;
|
||||
width: fit-content;
|
||||
width: ${({ width }) => (width ? width + 'px' : 'fit-content')};
|
||||
`;
|
||||
|
||||
type OwnProps = {
|
||||
type ComponentStorybookLayoutProps = {
|
||||
width?: number;
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
||||
export const ComponentStorybookLayout = ({ children }: OwnProps) => (
|
||||
<StyledLayout>{children}</StyledLayout>
|
||||
export const ComponentStorybookLayout = ({
|
||||
width,
|
||||
children,
|
||||
}: ComponentStorybookLayoutProps) => (
|
||||
<StyledLayout width={width}>{children}</StyledLayout>
|
||||
);
|
||||
|
||||
@ -108,41 +108,47 @@ export const CatalogDecorator: Decorator = (Story, context) => {
|
||||
<StyledColumnContainer key={value4}>
|
||||
<StyledColumnTitle>
|
||||
{dimension4.labels?.(value4) ??
|
||||
(typeof value4 === 'string' ? value4 : '')}
|
||||
(['string', 'number'].includes(typeof value4) ? value4 : '')}
|
||||
</StyledColumnTitle>
|
||||
{dimension3.values.map((value3: any) => (
|
||||
<StyledRowsContainer key={value3}>
|
||||
<StyledRowsTitle>
|
||||
{dimension3.labels?.(value3) ??
|
||||
(typeof value3 === 'string' ? value3 : '')}
|
||||
(['string', 'number'].includes(typeof value3) ? value3 : '')}
|
||||
</StyledRowsTitle>
|
||||
{dimension2.values.map((value2: any) => (
|
||||
<StyledRowContainer key={value2}>
|
||||
<StyledRowTitle>
|
||||
{dimension2.labels?.(value2) ??
|
||||
(typeof value2 === 'string' ? value2 : '')}
|
||||
(['string', 'number'].includes(typeof value2)
|
||||
? value2
|
||||
: '')}
|
||||
</StyledRowTitle>
|
||||
{dimension1.values.map((value1: any) => (
|
||||
<StyledCellContainer key={value1} id={value1}>
|
||||
<StyledElementTitle>
|
||||
{dimension1.labels?.(value1) ??
|
||||
(typeof value1 === 'string' ? value1 : '')}
|
||||
</StyledElementTitle>
|
||||
<StyledElementContainer
|
||||
width={options?.elementContainer?.width}
|
||||
>
|
||||
<Story
|
||||
args={{
|
||||
...context.args,
|
||||
...dimension1.props(value1),
|
||||
...dimension2.props(value2),
|
||||
...dimension3.props(value3),
|
||||
...dimension4.props(value4),
|
||||
}}
|
||||
/>
|
||||
</StyledElementContainer>
|
||||
</StyledCellContainer>
|
||||
))}
|
||||
{dimension1.values.map((value1: any) => {
|
||||
return (
|
||||
<StyledCellContainer key={value1} id={value1}>
|
||||
<StyledElementTitle>
|
||||
{dimension1.labels?.(value1) ??
|
||||
(['string', 'number'].includes(typeof value1)
|
||||
? value1
|
||||
: '')}
|
||||
</StyledElementTitle>
|
||||
<StyledElementContainer
|
||||
width={options?.elementContainer?.width}
|
||||
>
|
||||
<Story
|
||||
args={{
|
||||
...context.args,
|
||||
...dimension1.props(value1),
|
||||
...dimension2.props(value2),
|
||||
...dimension3.props(value3),
|
||||
...dimension4.props(value4),
|
||||
}}
|
||||
/>
|
||||
</StyledElementContainer>
|
||||
</StyledCellContainer>
|
||||
);
|
||||
})}
|
||||
</StyledRowContainer>
|
||||
))}
|
||||
</StyledRowsContainer>
|
||||
|
||||
@ -2,8 +2,12 @@ import { Decorator } from '@storybook/react';
|
||||
|
||||
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
|
||||
|
||||
export const ComponentDecorator: Decorator = (Story) => (
|
||||
<ComponentStorybookLayout>
|
||||
<Story />
|
||||
</ComponentStorybookLayout>
|
||||
);
|
||||
export const ComponentDecorator: Decorator = (Story, context) => {
|
||||
const { container } = context.parameters;
|
||||
|
||||
return (
|
||||
<ComponentStorybookLayout width={container?.width}>
|
||||
<Story />
|
||||
</ComponentStorybookLayout>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user