Chore(front): Add storybook tests on meta-types/input/components (#1987)
* Add storybook tests on meta-types/input/components Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Add storybook tests on meta-types/input/components Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Add storybook tests on meta-types/input/components Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Add storybook tests on meta-types/input/components Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Add storybook tests on meta-types/input/components Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Fix the tests Co-authored-by: v1b3m <vibenjamin6@gmail.com> * modify props spread in stories * Remove storybook-addon-mock --------- Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: bosiraphael <raphael.bosi@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -5,7 +5,7 @@ import { useChipField } from '../../hooks/useChipField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type ChipFieldInputProps = {
|
||||
export type ChipFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -6,7 +6,7 @@ import { useDoubleTextChipField } from '../../hooks/useDoubleTextChipField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type DoubleTextChipFieldInputProps = {
|
||||
export type DoubleTextChipFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -6,7 +6,7 @@ import { useDoubleTextField } from '../../hooks/useDoubleTextField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type DoubleTextFieldInputProps = {
|
||||
export type DoubleTextFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -5,7 +5,7 @@ import { useEmailField } from '../../hooks/useEmailField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type EmailFieldInputProps = {
|
||||
export type EmailFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -4,7 +4,7 @@ import { useMoneyField } from '../../hooks/useMoneyField';
|
||||
|
||||
export type FieldInputEvent = (persist: () => void) => void;
|
||||
|
||||
type MoneyFieldInputProps = {
|
||||
export type MoneyFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -4,7 +4,7 @@ import { useNumberField } from '../../hooks/useNumberField';
|
||||
|
||||
export type FieldInputEvent = (persist: () => void) => void;
|
||||
|
||||
type NumberFieldInputProps = {
|
||||
export type NumberFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -4,7 +4,7 @@ import { usePhoneField } from '../../hooks/usePhoneField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type PhoneFieldInputProps = {
|
||||
export type PhoneFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -5,7 +5,7 @@ import { useProbabilityField } from '../../hooks/useProbabilityField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type ProbabilityFieldInputProps = {
|
||||
export type ProbabilityFieldInputProps = {
|
||||
onSubmit?: FieldInputEvent;
|
||||
};
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ const StyledRelationPickerContainer = styled.div`
|
||||
top: -8px;
|
||||
`;
|
||||
|
||||
type RelationFieldInputProps = {
|
||||
export type RelationFieldInputProps = {
|
||||
onSubmit?: FieldInputEvent;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
@ -5,7 +5,7 @@ import { useTextField } from '../../hooks/useTextField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type TextFieldInputProps = {
|
||||
export type TextFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -4,7 +4,7 @@ import { useURLField } from '../../hooks/useURLField';
|
||||
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
type URLFieldInputProps = {
|
||||
export type URLFieldInputProps = {
|
||||
onClickOutside?: FieldInputEvent;
|
||||
onEnter?: FieldInputEvent;
|
||||
onEscape?: FieldInputEvent;
|
||||
|
||||
@ -0,0 +1,177 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useChipField } from '../../../hooks/useChipField';
|
||||
import { ChipFieldInput, ChipFieldInputProps } from '../ChipFieldInput';
|
||||
|
||||
const ChipFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setContentFieldValue } = useChipField();
|
||||
|
||||
useEffect(() => {
|
||||
setContentFieldValue(value);
|
||||
}, [setContentFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type ChipFieldInputWithContextProps = ChipFieldInputProps & {
|
||||
value: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const ChipFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: ChipFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'chip',
|
||||
name: 'Chip',
|
||||
type: 'chip',
|
||||
metadata: {
|
||||
contentFieldName: 'name',
|
||||
urlFieldName: 'xURL',
|
||||
placeHolder: 'X URL',
|
||||
relationType: Entity.Person,
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<ChipFieldValueSetterEffect value={value} />
|
||||
<ChipFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/ChipFieldInput',
|
||||
component: ChipFieldInputWithContext,
|
||||
args: {
|
||||
value: 'chip',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof ChipFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,194 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useDoubleTextChipField } from '../../../hooks/useDoubleTextChipField';
|
||||
import {
|
||||
DoubleTextChipFieldInput,
|
||||
DoubleTextChipFieldInputProps,
|
||||
} from '../DoubleTextChipFieldInput';
|
||||
|
||||
const DoubleTextChipFieldValueSetterEffect = ({
|
||||
firstValue,
|
||||
secondValue,
|
||||
}: {
|
||||
firstValue: string;
|
||||
secondValue: string;
|
||||
}) => {
|
||||
const { setFirstValue, setSecondValue } = useDoubleTextChipField();
|
||||
|
||||
useEffect(() => {
|
||||
setFirstValue(firstValue);
|
||||
setSecondValue(secondValue);
|
||||
}, [firstValue, secondValue, setFirstValue, setSecondValue]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type DoubleTextChipFieldInputWithContextProps =
|
||||
DoubleTextChipFieldInputProps & {
|
||||
firstValue: string;
|
||||
secondValue: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const DoubleTextChipFieldInputWithContext = ({
|
||||
entityId,
|
||||
firstValue,
|
||||
secondValue,
|
||||
onClickOutside,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: DoubleTextChipFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text-chip',
|
||||
name: 'Double-Text-Chip',
|
||||
type: 'double-text-chip',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
firstValuePlaceholder: 'First-text',
|
||||
secondValueFieldName: 'Second-text',
|
||||
secondValuePlaceholder: 'Second-text',
|
||||
avatarUrlFieldName: 'avatarUrl',
|
||||
entityType: Entity.Person,
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<DoubleTextChipFieldValueSetterEffect
|
||||
{...{ firstValue, secondValue }}
|
||||
/>
|
||||
<DoubleTextChipFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/DoubleTextChipFieldInput',
|
||||
component: DoubleTextChipFieldInputWithContext,
|
||||
args: {
|
||||
firstValue: 'first value',
|
||||
secondValue: 'second value',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DoubleTextChipFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,191 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useDoubleTextField } from '../../../hooks/useDoubleTextField';
|
||||
import {
|
||||
DoubleTextFieldInput,
|
||||
DoubleTextFieldInputProps,
|
||||
} from '../DoubleTextFieldInput';
|
||||
|
||||
const DoubleTextFieldValueSetterEffect = ({
|
||||
firstValue,
|
||||
secondValue,
|
||||
}: {
|
||||
firstValue: string;
|
||||
secondValue: string;
|
||||
}) => {
|
||||
const { setFirstValue, setSecondValue } = useDoubleTextField();
|
||||
|
||||
useEffect(() => {
|
||||
setFirstValue(firstValue);
|
||||
setSecondValue(secondValue);
|
||||
}, [firstValue, secondValue, setFirstValue, setSecondValue]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type DoubleTextFieldInputWithContextProps = DoubleTextFieldInputProps & {
|
||||
firstValue: string;
|
||||
secondValue: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const DoubleTextFieldInputWithContext = ({
|
||||
entityId,
|
||||
firstValue,
|
||||
secondValue,
|
||||
onClickOutside,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: DoubleTextFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text',
|
||||
name: 'Double-Text',
|
||||
type: 'double-text',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
firstValuePlaceholder: 'First-text',
|
||||
secondValueFieldName: 'Second-text',
|
||||
secondValuePlaceholder: 'Second-text',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<DoubleTextFieldValueSetterEffect {...{ firstValue, secondValue }} />
|
||||
<DoubleTextFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/DoubleTextFieldInput',
|
||||
component: DoubleTextFieldInputWithContext,
|
||||
args: {
|
||||
firstValue: 'first value',
|
||||
secondValue: 'second value',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof DoubleTextFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = await canvas.findByTestId(
|
||||
'data-field-input-click-outside-div',
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,174 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useEmailField } from '../../../hooks/useEmailField';
|
||||
import { EmailFieldInput, EmailFieldInputProps } from '../EmailFieldInput';
|
||||
|
||||
const EmailFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useEmailField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type EmailFieldInputWithContextProps = EmailFieldInputProps & {
|
||||
value: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const EmailFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: EmailFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'email',
|
||||
name: 'Email',
|
||||
type: 'email',
|
||||
metadata: {
|
||||
fieldName: 'email',
|
||||
placeHolder: 'username@email.com',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<EmailFieldValueSetterEffect value={value} />
|
||||
<EmailFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/EmailFieldInput',
|
||||
component: EmailFieldInputWithContext,
|
||||
args: {
|
||||
value: 'username@email.com',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof EmailFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,175 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useMoneyField } from '../../../hooks/useMoneyField';
|
||||
import { MoneyFieldInput, MoneyFieldInputProps } from '../MoneyFieldInput';
|
||||
|
||||
const MoneyFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useMoneyField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type MoneyFieldInputWithContextProps = MoneyFieldInputProps & {
|
||||
value: number;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const MoneyFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: MoneyFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'moneyAmount',
|
||||
name: 'MoneyAmout',
|
||||
type: 'moneyAmount',
|
||||
metadata: {
|
||||
fieldName: 'moneyAmount',
|
||||
placeHolder: 'Enter Amount',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<MoneyFieldValueSetterEffect value={value} />
|
||||
<MoneyFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/MoneyFieldInput',
|
||||
component: MoneyFieldInputWithContext,
|
||||
args: {
|
||||
value: 1000,
|
||||
isPositive: true,
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof MoneyFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,175 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useNumberField } from '../../../hooks/useNumberField';
|
||||
import { NumberFieldInput, NumberFieldInputProps } from '../NumberFieldInput';
|
||||
|
||||
const NumberFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useNumberField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type NumberFieldInputWithContextProps = NumberFieldInputProps & {
|
||||
value: number;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const NumberFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: NumberFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'number',
|
||||
name: 'Number',
|
||||
type: 'number',
|
||||
metadata: {
|
||||
fieldName: 'number',
|
||||
placeHolder: 'Enter number',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<NumberFieldValueSetterEffect value={value} />
|
||||
<NumberFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/NumberFieldInput',
|
||||
component: NumberFieldInputWithContext,
|
||||
args: {
|
||||
value: 1000,
|
||||
isPositive: true,
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof NumberFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,175 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { usePhoneField } from '../../../hooks/usePhoneField';
|
||||
import { PhoneFieldInput, PhoneFieldInputProps } from '../PhoneFieldInput';
|
||||
|
||||
const PhoneFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = usePhoneField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type PhoneFieldInputWithContextProps = PhoneFieldInputProps & {
|
||||
value: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const PhoneFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: PhoneFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'phone',
|
||||
name: 'Phone',
|
||||
type: 'phone',
|
||||
metadata: {
|
||||
fieldName: 'Phone',
|
||||
placeHolder: 'Enter phone number',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<PhoneFieldValueSetterEffect value={value} />
|
||||
<PhoneFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/PhoneFieldInput',
|
||||
component: PhoneFieldInputWithContext,
|
||||
args: {
|
||||
value: '+1-12-123-456',
|
||||
isPositive: true,
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof PhoneFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,106 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, 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 { useProbabilityField } from '../../../hooks/useProbabilityField';
|
||||
import {
|
||||
ProbabilityFieldInput,
|
||||
ProbabilityFieldInputProps,
|
||||
} from '../ProbabilityFieldInput';
|
||||
|
||||
const ProbabilityFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useProbabilityField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type ProbabilityFieldInputWithContextProps = ProbabilityFieldInputProps & {
|
||||
value: number;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const ProbabilityFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onSubmit,
|
||||
}: ProbabilityFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'probability',
|
||||
name: 'Probability',
|
||||
type: 'probability',
|
||||
metadata: {
|
||||
fieldName: 'Probability',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<ProbabilityFieldValueSetterEffect value={value} />
|
||||
<ProbabilityFieldInput onSubmit={onSubmit} />
|
||||
</FieldContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const submitJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
submitJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/ProbabilityFieldInput',
|
||||
component: ProbabilityFieldInputWithContext,
|
||||
args: {
|
||||
value: 25,
|
||||
isPositive: true,
|
||||
onSubmit: submitJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onSubmit: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof ProbabilityFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Submit: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(submitJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const item = (await canvas.findByText('25%'))?.nextElementSibling
|
||||
?.firstElementChild;
|
||||
|
||||
if (item) {
|
||||
userEvent.click(item);
|
||||
}
|
||||
|
||||
expect(submitJestFn).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,134 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useRelationField } from '../../../hooks/useRelationField';
|
||||
import {
|
||||
RelationFieldInput,
|
||||
RelationFieldInputProps,
|
||||
} from '../RelationFieldInput';
|
||||
|
||||
const RelationFieldValueSetterEffect = ({ value }: { value: number }) => {
|
||||
const { setFieldValue } = useRelationField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type RelationFieldInputWithContextProps = RelationFieldInputProps & {
|
||||
value: number;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const RelationFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: RelationFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'relation',
|
||||
name: 'Relation',
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'Relation',
|
||||
relationType: Entity.Person,
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<RelationFieldValueSetterEffect value={value} />
|
||||
<RelationFieldInput onSubmit={onSubmit} onCancel={onCancel} />
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const submitJestFn = jest.fn();
|
||||
const cancelJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
submitJestFn.mockClear();
|
||||
cancelJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/RelationFieldInput',
|
||||
component: RelationFieldInputWithContext,
|
||||
args: {
|
||||
useEditButton: true,
|
||||
onSubmit: submitJestFn,
|
||||
onCancel: cancelJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onSubmit: { control: false },
|
||||
onCancel: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof RelationFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {
|
||||
decorators: [ComponentWithRecoilScopeDecorator],
|
||||
};
|
||||
|
||||
export const Submit: Story = {
|
||||
decorators: [ComponentWithRecoilScopeDecorator],
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(submitJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const item = await canvas.findByText('Jane Doe');
|
||||
|
||||
userEvent.click(item);
|
||||
|
||||
expect(submitJestFn).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
};
|
||||
|
||||
export const Cancel: Story = {
|
||||
decorators: [ComponentWithRecoilScopeDecorator],
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(cancelJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(cancelJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,174 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useTextField } from '../../../hooks/useTextField';
|
||||
import { TextFieldInput, TextFieldInputProps } from '../TextFieldInput';
|
||||
|
||||
const TextFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useTextField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type TextFieldInputWithContextProps = TextFieldInputProps & {
|
||||
value: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const TextFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: TextFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'Text',
|
||||
placeHolder: 'Enter text',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<TextFieldValueSetterEffect value={value} />
|
||||
<TextFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/TextFieldInput',
|
||||
component: TextFieldInputWithContext,
|
||||
args: {
|
||||
value: 'text',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof TextFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,174 @@
|
||||
import { useEffect } from 'react';
|
||||
import { expect, jest } from '@storybook/jest';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
|
||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||
|
||||
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
|
||||
import { useURLField } from '../../../hooks/useURLField';
|
||||
import { URLFieldInput, URLFieldInputProps } from '../URLFieldInput';
|
||||
|
||||
const URLFieldValueSetterEffect = ({ value }: { value: string }) => {
|
||||
const { setFieldValue } = useURLField();
|
||||
|
||||
useEffect(() => {
|
||||
setFieldValue(value);
|
||||
}, [setFieldValue, value]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
type URLFieldInputWithContextProps = URLFieldInputProps & {
|
||||
value: string;
|
||||
entityId?: string;
|
||||
};
|
||||
|
||||
const URLFieldInputWithContext = ({
|
||||
entityId,
|
||||
value,
|
||||
onEnter,
|
||||
onEscape,
|
||||
onClickOutside,
|
||||
onTab,
|
||||
onShiftTab,
|
||||
}: URLFieldInputWithContextProps) => {
|
||||
const setHotKeyScope = useSetHotkeyScope();
|
||||
|
||||
useEffect(() => {
|
||||
setHotKeyScope('hotkey-scope');
|
||||
}, [setHotKeyScope]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'url',
|
||||
name: 'URL',
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'URL',
|
||||
placeHolder: 'Enter URL',
|
||||
},
|
||||
}}
|
||||
entityId={entityId}
|
||||
>
|
||||
<URLFieldValueSetterEffect value={value} />
|
||||
<URLFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
</FieldContextProvider>
|
||||
<div data-testid="data-field-input-click-outside-div" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const enterJestFn = jest.fn();
|
||||
const escapeJestfn = jest.fn();
|
||||
const clickOutsideJestFn = jest.fn();
|
||||
const tabJestFn = jest.fn();
|
||||
const shiftTabJestFn = jest.fn();
|
||||
|
||||
const clearMocksDecorator: Decorator = (Story, context) => {
|
||||
if (context.parameters.clearMocks) {
|
||||
enterJestFn.mockClear();
|
||||
escapeJestfn.mockClear();
|
||||
clickOutsideJestFn.mockClear();
|
||||
tabJestFn.mockClear();
|
||||
shiftTabJestFn.mockClear();
|
||||
}
|
||||
return <Story />;
|
||||
};
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'UI/Field/Input/URLFieldInput',
|
||||
component: URLFieldInputWithContext,
|
||||
args: {
|
||||
value: 'https://username.domain',
|
||||
onEnter: enterJestFn,
|
||||
onEscape: escapeJestfn,
|
||||
onClickOutside: clickOutsideJestFn,
|
||||
onTab: tabJestFn,
|
||||
onShiftTab: shiftTabJestFn,
|
||||
},
|
||||
argTypes: {
|
||||
onEnter: { control: false },
|
||||
onEscape: { control: false },
|
||||
onClickOutside: { control: false },
|
||||
onTab: { control: false },
|
||||
onShiftTab: { control: false },
|
||||
},
|
||||
decorators: [clearMocksDecorator],
|
||||
parameters: {
|
||||
clearMocks: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof URLFieldInputWithContext>;
|
||||
|
||||
export const Default: Story = {};
|
||||
|
||||
export const Enter: Story = {
|
||||
play: async () => {
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{enter}');
|
||||
expect(enterJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Escape: Story = {
|
||||
play: async () => {
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{esc}');
|
||||
expect(escapeJestfn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ClickOutside: Story = {
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
const emptyDiv = canvas.getByTestId('data-field-input-click-outside-div');
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.click(emptyDiv);
|
||||
expect(clickOutsideJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const Tab: Story = {
|
||||
play: async () => {
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{tab}');
|
||||
expect(tabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const ShiftTab: Story = {
|
||||
play: async () => {
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(0);
|
||||
|
||||
await waitFor(() => {
|
||||
userEvent.keyboard('{shift>}{tab}');
|
||||
expect(shiftTabJestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
},
|
||||
};
|
||||
@ -1,5 +1,6 @@
|
||||
import {
|
||||
Activity,
|
||||
Attachment,
|
||||
ColorScheme,
|
||||
Company,
|
||||
User,
|
||||
@ -34,6 +35,7 @@ type MockedUser = Pick<
|
||||
>;
|
||||
assignedActivities: Array<Activity>;
|
||||
authoredActivities: Array<Activity>;
|
||||
authoredAttachments: Array<Attachment>;
|
||||
companies: Array<Company>;
|
||||
comments: Array<Comment>;
|
||||
};
|
||||
@ -74,6 +76,7 @@ export const mockedUsersData: Array<MockedUser> = [
|
||||
locale: 'en',
|
||||
colorScheme: ColorScheme.System,
|
||||
},
|
||||
authoredAttachments: [],
|
||||
assignedActivities: [],
|
||||
authoredActivities: [],
|
||||
companies: [],
|
||||
@ -113,6 +116,7 @@ export const mockedUsersData: Array<MockedUser> = [
|
||||
locale: 'en',
|
||||
colorScheme: ColorScheme.System,
|
||||
},
|
||||
authoredAttachments: [],
|
||||
assignedActivities: [],
|
||||
authoredActivities: [],
|
||||
companies: [],
|
||||
@ -156,6 +160,7 @@ export const mockedOnboardingUsersData: Array<MockedUser> = [
|
||||
locale: 'en',
|
||||
colorScheme: ColorScheme.System,
|
||||
},
|
||||
authoredAttachments: [],
|
||||
assignedActivities: [],
|
||||
authoredActivities: [],
|
||||
companies: [],
|
||||
@ -196,6 +201,7 @@ export const mockedOnboardingUsersData: Array<MockedUser> = [
|
||||
locale: 'en',
|
||||
colorScheme: ColorScheme.System,
|
||||
},
|
||||
authoredAttachments: [],
|
||||
assignedActivities: [],
|
||||
authoredActivities: [],
|
||||
companies: [],
|
||||
|
||||
@ -19490,6 +19490,7 @@ workbox-window@6.6.1:
|
||||
workbox-core "6.6.1"
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
name wrap-ansi-cjs
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
|
||||
Reference in New Issue
Block a user