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 { FieldDefinition } from '../types/FieldDefinition';
|
||||||
import { FieldMetadata } from '../types/FieldMetadata';
|
import { FieldMetadata } from '../types/FieldMetadata';
|
||||||
|
|
||||||
type GenericFieldContextType = {
|
export type GenericFieldContextType = {
|
||||||
fieldDefinition: FieldDefinition<FieldMetadata>;
|
fieldDefinition: FieldDefinition<FieldMetadata>;
|
||||||
// TODO: add better typing for mutation hook
|
// TODO: add better typing for mutation hook
|
||||||
useUpdateEntityMutation: () => [(params: any) => void, any];
|
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';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
const StyledLayout = styled.div`
|
const StyledLayout = styled.div<{ width?: number }>`
|
||||||
background: ${({ theme }) => theme.background.primary};
|
background: ${({ theme }) => theme.background.primary};
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@ -12,13 +12,17 @@ const StyledLayout = styled.div`
|
|||||||
max-width: calc(100% - 40px);
|
max-width: calc(100% - 40px);
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
width: fit-content;
|
width: ${({ width }) => (width ? width + 'px' : 'fit-content')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
type ComponentStorybookLayoutProps = {
|
||||||
|
width?: number;
|
||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ComponentStorybookLayout = ({ children }: OwnProps) => (
|
export const ComponentStorybookLayout = ({
|
||||||
<StyledLayout>{children}</StyledLayout>
|
width,
|
||||||
|
children,
|
||||||
|
}: ComponentStorybookLayoutProps) => (
|
||||||
|
<StyledLayout width={width}>{children}</StyledLayout>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -108,41 +108,47 @@ export const CatalogDecorator: Decorator = (Story, context) => {
|
|||||||
<StyledColumnContainer key={value4}>
|
<StyledColumnContainer key={value4}>
|
||||||
<StyledColumnTitle>
|
<StyledColumnTitle>
|
||||||
{dimension4.labels?.(value4) ??
|
{dimension4.labels?.(value4) ??
|
||||||
(typeof value4 === 'string' ? value4 : '')}
|
(['string', 'number'].includes(typeof value4) ? value4 : '')}
|
||||||
</StyledColumnTitle>
|
</StyledColumnTitle>
|
||||||
{dimension3.values.map((value3: any) => (
|
{dimension3.values.map((value3: any) => (
|
||||||
<StyledRowsContainer key={value3}>
|
<StyledRowsContainer key={value3}>
|
||||||
<StyledRowsTitle>
|
<StyledRowsTitle>
|
||||||
{dimension3.labels?.(value3) ??
|
{dimension3.labels?.(value3) ??
|
||||||
(typeof value3 === 'string' ? value3 : '')}
|
(['string', 'number'].includes(typeof value3) ? value3 : '')}
|
||||||
</StyledRowsTitle>
|
</StyledRowsTitle>
|
||||||
{dimension2.values.map((value2: any) => (
|
{dimension2.values.map((value2: any) => (
|
||||||
<StyledRowContainer key={value2}>
|
<StyledRowContainer key={value2}>
|
||||||
<StyledRowTitle>
|
<StyledRowTitle>
|
||||||
{dimension2.labels?.(value2) ??
|
{dimension2.labels?.(value2) ??
|
||||||
(typeof value2 === 'string' ? value2 : '')}
|
(['string', 'number'].includes(typeof value2)
|
||||||
|
? value2
|
||||||
|
: '')}
|
||||||
</StyledRowTitle>
|
</StyledRowTitle>
|
||||||
{dimension1.values.map((value1: any) => (
|
{dimension1.values.map((value1: any) => {
|
||||||
<StyledCellContainer key={value1} id={value1}>
|
return (
|
||||||
<StyledElementTitle>
|
<StyledCellContainer key={value1} id={value1}>
|
||||||
{dimension1.labels?.(value1) ??
|
<StyledElementTitle>
|
||||||
(typeof value1 === 'string' ? value1 : '')}
|
{dimension1.labels?.(value1) ??
|
||||||
</StyledElementTitle>
|
(['string', 'number'].includes(typeof value1)
|
||||||
<StyledElementContainer
|
? value1
|
||||||
width={options?.elementContainer?.width}
|
: '')}
|
||||||
>
|
</StyledElementTitle>
|
||||||
<Story
|
<StyledElementContainer
|
||||||
args={{
|
width={options?.elementContainer?.width}
|
||||||
...context.args,
|
>
|
||||||
...dimension1.props(value1),
|
<Story
|
||||||
...dimension2.props(value2),
|
args={{
|
||||||
...dimension3.props(value3),
|
...context.args,
|
||||||
...dimension4.props(value4),
|
...dimension1.props(value1),
|
||||||
}}
|
...dimension2.props(value2),
|
||||||
/>
|
...dimension3.props(value3),
|
||||||
</StyledElementContainer>
|
...dimension4.props(value4),
|
||||||
</StyledCellContainer>
|
}}
|
||||||
))}
|
/>
|
||||||
|
</StyledElementContainer>
|
||||||
|
</StyledCellContainer>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</StyledRowContainer>
|
</StyledRowContainer>
|
||||||
))}
|
))}
|
||||||
</StyledRowsContainer>
|
</StyledRowsContainer>
|
||||||
|
|||||||
@ -2,8 +2,12 @@ import { Decorator } from '@storybook/react';
|
|||||||
|
|
||||||
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
|
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
|
||||||
|
|
||||||
export const ComponentDecorator: Decorator = (Story) => (
|
export const ComponentDecorator: Decorator = (Story, context) => {
|
||||||
<ComponentStorybookLayout>
|
const { container } = context.parameters;
|
||||||
<Story />
|
|
||||||
</ComponentStorybookLayout>
|
return (
|
||||||
);
|
<ComponentStorybookLayout width={container?.width}>
|
||||||
|
<Story />
|
||||||
|
</ComponentStorybookLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user