1867 timebox add storybook tests on meta typesinputcomponents (#1972)
* working on DateFieldInput story * wip * wip * wip * Fix story * Fix other story * finish stories for BooleanFieldInput and DateFieldInput * reorganize stories in UI/Field in Input and Display folders * unite FieldDisplayContextProvider and FieldInputContextProvider in one file FieldContextProvider --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -3,17 +3,17 @@ import {
|
||||
GenericFieldContextType,
|
||||
} from '@/ui/field/contexts/FieldContext';
|
||||
|
||||
type FieldDisplayContextProviderProps = {
|
||||
type FieldContextProviderProps = {
|
||||
children: React.ReactNode;
|
||||
fieldDefinition: GenericFieldContextType['fieldDefinition'];
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
export const FieldDisplayContextProvider = ({
|
||||
export const FieldContextProvider = ({
|
||||
children,
|
||||
fieldDefinition,
|
||||
entityId,
|
||||
}: FieldDisplayContextProviderProps) => {
|
||||
}: FieldContextProviderProps) => {
|
||||
return (
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
@ -3,11 +3,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useDateField } from '../../../hooks/useDateField';
|
||||
import { DateFieldDisplay } from '../DateFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const formattedDate = new Date();
|
||||
|
||||
const DateFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
@ -30,7 +29,7 @@ const DateFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: DateFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'date',
|
||||
name: 'Date',
|
||||
@ -43,12 +42,12 @@ const DateFieldDisplayWithContext = ({
|
||||
>
|
||||
<DateFieldValueSetterEffect value={value} />
|
||||
<DateFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/DateFieldDisplay',
|
||||
title: 'UI/Field/Display/DateFieldDisplay',
|
||||
component: DateFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -3,11 +3,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useDoubleTextField } from '../../../hooks/useDoubleTextField';
|
||||
import { DoubleTextFieldDisplay } from '../DoubleTextFieldDisplay'; // Import your component
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const DoubleTextFieldDisplayValueSetterEffect = ({
|
||||
firstValue,
|
||||
secondValue,
|
||||
@ -37,7 +36,7 @@ const DoubleTextFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: DoubleTextFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text',
|
||||
name: 'Double-Text',
|
||||
@ -56,12 +55,12 @@ const DoubleTextFieldDisplayWithContext = ({
|
||||
secondValue={secondValue}
|
||||
/>
|
||||
<DoubleTextFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/DoubleTextFieldDisplay',
|
||||
title: 'UI/Field/Display/DoubleTextFieldDisplay',
|
||||
component: DoubleTextFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -4,11 +4,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useEmailField } from '../../../hooks/useEmailField';
|
||||
import { EmailFieldDisplay } from '../EmailFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const EmailFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useEmailField();
|
||||
|
||||
@ -29,7 +28,7 @@ const EmailFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: EmailFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'email',
|
||||
name: 'Email',
|
||||
@ -45,12 +44,12 @@ const EmailFieldDisplayWithContext = ({
|
||||
<EmailFieldValueSetterEffect value={value} />
|
||||
<EmailFieldDisplay />
|
||||
</MemoryRouter>
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/EmailFieldDisplay',
|
||||
title: 'UI/Field/Display/EmailFieldDisplay',
|
||||
component: EmailFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -6,11 +6,10 @@ import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useMoneyField } from '../../../hooks/useMoneyField';
|
||||
import { MoneyFieldDisplay } from '../MoneyFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const MoneyFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useMoneyField();
|
||||
|
||||
@ -31,7 +30,7 @@ const MoneyFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: MoneyFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'money',
|
||||
name: 'Money',
|
||||
@ -46,12 +45,12 @@ const MoneyFieldDisplayWithContext = ({
|
||||
>
|
||||
<MoneyFieldValueSetterEffect value={value} />
|
||||
<MoneyFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/MoneyFieldDisplay',
|
||||
title: 'UI/Field/Display/MoneyFieldDisplay',
|
||||
component: MoneyFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -6,11 +6,10 @@ import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useNumberField } from '../../../hooks/useNumberField';
|
||||
import { NumberFieldDisplay } from '../NumberFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const NumberFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useNumberField();
|
||||
|
||||
@ -31,7 +30,7 @@ const NumberFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: NumberFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'number',
|
||||
name: 'Number',
|
||||
@ -46,12 +45,12 @@ const NumberFieldDisplayWithContext = ({
|
||||
>
|
||||
<NumberFieldValueSetterEffect value={value} />
|
||||
<NumberFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/NumberFieldDisplay',
|
||||
title: 'UI/Field/Display/NumberFieldDisplay',
|
||||
component: NumberFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -4,11 +4,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { usePhoneField } from '../../../hooks/usePhoneField';
|
||||
import { PhoneFieldDisplay } from '../PhoneFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const PhoneFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = usePhoneField();
|
||||
|
||||
@ -29,7 +28,7 @@ const PhoneFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: PhoneFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'phone',
|
||||
name: 'Phone',
|
||||
@ -45,12 +44,12 @@ const PhoneFieldDisplayWithContext = ({
|
||||
<PhoneFieldValueSetterEffect value={value} />
|
||||
<PhoneFieldDisplay />
|
||||
</MemoryRouter>
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/PhoneFieldDisplay',
|
||||
title: 'UI/Field/Display/PhoneFieldDisplay',
|
||||
component: PhoneFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -6,11 +6,10 @@ import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useTextField } from '../../../hooks/useTextField';
|
||||
import { TextFieldDisplay } from '../TextFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const TextFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useTextField();
|
||||
|
||||
@ -31,7 +30,7 @@ const TextFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: TextFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
@ -45,12 +44,12 @@ const TextFieldDisplayWithContext = ({
|
||||
>
|
||||
<TextFieldValueSetterEffect value={value} />
|
||||
<TextFieldDisplay />
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/TextFieldDisplay',
|
||||
title: 'UI/Field/Display/TextFieldDisplay',
|
||||
component: TextFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -4,11 +4,10 @@ import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useURLField } from '../../../hooks/useURLField';
|
||||
import { URLFieldDisplay } from '../URLFieldDisplay';
|
||||
|
||||
import { FieldDisplayContextProvider } from './FieldDisplayContextProvider';
|
||||
|
||||
const URLFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useURLField();
|
||||
|
||||
@ -29,7 +28,7 @@ const URLFieldDisplayWithContext = ({
|
||||
entityId,
|
||||
}: URLFieldDisplayWithContextProps) => {
|
||||
return (
|
||||
<FieldDisplayContextProvider
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'URL',
|
||||
name: 'URL',
|
||||
@ -45,12 +44,12 @@ const URLFieldDisplayWithContext = ({
|
||||
<URLFieldValueSetterEffect value={value} />
|
||||
<URLFieldDisplay />
|
||||
</MemoryRouter>
|
||||
</FieldDisplayContextProvider>
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/URLFieldDisplay',
|
||||
title: 'UI/Field/Display/URLFieldDisplay',
|
||||
component: URLFieldDisplayWithContext,
|
||||
};
|
||||
|
||||
|
||||
@ -5,11 +5,15 @@ import { useBooleanField } from '../../hooks/useBooleanField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type BooleanFieldInputProps = {
|
||||
export type BooleanFieldInputProps = {
|
||||
onSubmit?: FieldInputEvent;
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
export const BooleanFieldInput = ({ onSubmit }: BooleanFieldInputProps) => {
|
||||
export const BooleanFieldInput = ({
|
||||
onSubmit,
|
||||
testId,
|
||||
}: BooleanFieldInputProps) => {
|
||||
const { fieldValue } = useBooleanField();
|
||||
|
||||
const persistField = usePersistField();
|
||||
@ -18,5 +22,11 @@ export const BooleanFieldInput = ({ onSubmit }: BooleanFieldInputProps) => {
|
||||
onSubmit?.(() => persistField(newValue));
|
||||
};
|
||||
|
||||
return <BooleanInput value={fieldValue ?? ''} onToggle={handleToggle} />;
|
||||
return (
|
||||
<BooleanInput
|
||||
value={fieldValue ?? ''}
|
||||
onToggle={handleToggle}
|
||||
testId={testId}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,7 +6,7 @@ import { useDateField } from '../../hooks/useDateField';
|
||||
|
||||
export type FieldInputEvent = (persist: () => void) => void;
|
||||
|
||||
type DateFieldInputProps = {
|
||||
export type DateFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
import { useEffect } from 'react';
|
||||
import { jest } from '@storybook/jest';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, within } from '@storybook/testing-library';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useBooleanField } from '../../../hooks/useBooleanField';
|
||||
import {
|
||||
BooleanFieldInput,
|
||||
BooleanFieldInputProps,
|
||||
} from '../BooleanFieldInput';
|
||||
|
||||
const BooleanFieldValueSetterEffect = ({ value }: { value: boolean }) => {
|
||||
const { setFieldValue } = useBooleanField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type BooleanFieldInputWithContextProps = BooleanFieldInputProps & {
|
||||
value: boolean;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const BooleanFieldInputWithContext = ({
|
||||
value,
|
||||
entityId,
|
||||
onSubmit,
|
||||
}: BooleanFieldInputWithContextProps) => {
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'boolean',
|
||||
name: 'Boolean',
|
||||
type: 'boolean',
|
||||
metadata: {
|
||||
fieldName: 'Boolean',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<BooleanFieldValueSetterEffect value={value} />
|
||||
<BooleanFieldInput onSubmit={onSubmit} testId="boolean-field-input" />
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/BooleanFieldInput',
|
||||
component: BooleanFieldInputWithContext,
|
||||
args: {
|
||||
value: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof BooleanFieldInputWithContext>;
|
||||
|
||||
const submitJestFn = jest.fn();
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Toggle: Story = {
|
||||
args: {
|
||||
onSubmit: submitJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onSubmit: {
|
||||
control: false,
|
||||
},
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const input = canvas.getByTestId('boolean-field-input');
|
||||
|
||||
const trueText = await within(input).findByText('True');
|
||||
|
||||
await expect(trueText).toBeInTheDocument();
|
||||
|
||||
await expect(submitJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await userEvent.click(input);
|
||||
|
||||
await expect(input).toHaveTextContent('False');
|
||||
|
||||
await expect(submitJestFn).toHaveBeenCalledTimes(1);
|
||||
|
||||
await userEvent.click(input);
|
||||
|
||||
await expect(input).toHaveTextContent('True');
|
||||
|
||||
await expect(submitJestFn).toHaveBeenCalledTimes(2);
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,131 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { jest } from '@storybook/jest';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useDateField } from '../../../hooks/useDateField';
|
||||
import { DateFieldInput, DateFieldInputProps } from '../DateFieldInput';
|
||||
|
||||
const formattedDate = new Date();
|
||||
|
||||
const DateFieldValueSetterEffect = ({ value }: { value: Date }) => {
|
||||
const { setFieldValue } = useDateField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value.toISOString());
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type DateFieldInputWithContextProps = DateFieldInputProps & {
|
||||
value: Date;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const DateFieldInputWithContext = ({
|
||||
value,
|
||||
entityId,
|
||||
onEscape,
|
||||
onEnter,
|
||||
onClickOutside,
|
||||
}: DateFieldInputWithContextProps) => {
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotkeyScope('hotkey-scope');
|
||||
}, [setHotkeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'date',
|
||||
name: 'Date',
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'Date',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<DateFieldValueSetterEffect value={value} />
|
||||
<DateFieldInput
|
||||
onEscape={onEscape}
|
||||
onEnter={onEnter}
|
||||
onClickOutside={onClickOutside}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div"></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const escapeJestFn = jest.fn();
|
||||
const enterJestFn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/DateFieldInput',
|
||||
component: DateFieldInputWithContext,
|
||||
args: {
|
||||
value: formattedDate,
|
||||
onEscape: escapeJestFn,
|
||||
onEnter: enterJestFn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEscape: {
|
||||
control: false,
|
||||
},
|
||||
onEnter: {
|
||||
control: false,
|
||||
},
|
||||
onClickOutside: {
|
||||
control: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DateFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
await expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
await userEvent.click(emptyDiv);
|
||||
|
||||
await expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
await expect(escapeJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await userEvent.keyboard('{esc}');
|
||||
|
||||
await expect(escapeJestFn).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
await expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await userEvent.keyboard('{enter}');
|
||||
|
||||
await expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
};
|
||||
@ -20,9 +20,14 @@ const StyledEditableBooleanFieldValue = styled.div`
|
||||
type BooleanInputProps = {
|
||||
value: boolean;
|
||||
onToggle?: (newValue: boolean) => void;
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
export const BooleanInput = ({ value, onToggle }: BooleanInputProps) => {
|
||||
export const BooleanInput = ({
|
||||
value,
|
||||
onToggle,
|
||||
testId,
|
||||
}: BooleanInputProps) => {
|
||||
const [internalValue, setInternalValue] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
@ -37,7 +42,10 @@ export const BooleanInput = ({ value, onToggle }: BooleanInputProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<StyledEditableBooleanFieldContainer onClick={handleClick}>
|
||||
<StyledEditableBooleanFieldContainer
|
||||
onClick={handleClick}
|
||||
data-testid={testId}
|
||||
>
|
||||
{internalValue ? (
|
||||
<IconCheck size={theme.icon.size.sm} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user