-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: StepFormDialogコンポーネントの作成 #5004
Open
schktjm
wants to merge
20
commits into
master
Choose a base branch
from
feat/step-dialog
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+643
−9
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
020059d
feat: FocusTrap を任意のタイミングで focus できるように ref のフォワーディング追加
schktjm 4664cf2
feat: DialogContentInner へ focusTrap の props を追加
schktjm 92a6154
feat: StepActionDialog の作成
schktjm 463ab26
feat: FormDialog 用storybookの作成
schktjm f78c283
refactor: FormDialog と別概念なため story の名称変更
schktjm fc89865
fix: remoteTrigger 用コンポーネントは必須ではないため作らない
schktjm fa6453d
feat: 利用側で渡した関数を実行するようにした
schktjm a36f26a
refactor: クラス名追加と実装順の変更
schktjm 394b884
feat: index ファイルにコンポーネントを追加
schktjm f04ee15
feat: Stepを飛ばせるようにidで管理する
schktjm 27a4c22
feat: storybookのスタイルを整える
schktjm dfeba97
feat: 修正
schktjm 6e41e43
fix: 戻る機能の修正
schktjm ffaf5fa
feat: StepFormDialogのテストの実装
schktjm ca7d76c
fix: test
schktjm 4aa8b69
fix: test
schktjm 872e9a0
fix: 問題の箇所にasync/awaitをつけてみる
schktjm a2fa3a2
fix: test
schktjm b9c570e
fix: test
schktjm f2622cf
fix: assertion消したら動くのか
schktjm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
161 changes: 161 additions & 0 deletions
161
packages/smarthr-ui/src/components/Dialog/StepFormDialog.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { action } from '@storybook/addon-actions' | ||
import { StoryFn } from '@storybook/react' | ||
import React, { ComponentProps, useState } from 'react' | ||
import styled from 'styled-components' | ||
|
||
import { Button } from '../Button' | ||
import { CheckBox } from '../CheckBox' | ||
import { Fieldset } from '../Fieldset' | ||
import { FormControl } from '../FormControl' | ||
import { Input } from '../Input' | ||
import { Cluster } from '../Layout' | ||
import { RadioButton } from '../RadioButton' | ||
|
||
import { StepFormDialog, StepFormDialogItem } from './StepFormDialog' | ||
|
||
import { ActionDialog, ActionDialogContent, DialogTrigger } from '.' | ||
|
||
export default { | ||
title: 'Dialog(ダイアログ)/StepFormDialog', | ||
component: StepFormDialog, | ||
subcomponents: { | ||
DialogTrigger, | ||
ActionDialogContent, | ||
}, | ||
parameters: { | ||
docs: { | ||
source: { | ||
type: 'code', | ||
}, | ||
story: { | ||
inline: false, | ||
iframeHeight: '500px', | ||
}, | ||
}, | ||
withTheming: true, | ||
}, | ||
} | ||
|
||
export const Default: StoryFn = () => { | ||
const [openedDialog, setOpenedDialog] = useState<'normal' | 'opened' | null>(null) | ||
const [value, setValue] = React.useState('Apple') | ||
const [responseMessage, setResponseMessage] = | ||
useState<ComponentProps<typeof ActionDialog>['responseMessage']>() | ||
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => setValue(e.currentTarget.name) | ||
const stepOrder = [ | ||
{ id: 'a', stepNumber: 1 }, | ||
{ | ||
id: 'b', | ||
stepNumber: 2, | ||
}, | ||
{ id: 'c', stepNumber: 3 }, | ||
] | ||
|
||
return ( | ||
<Cluster> | ||
<Button | ||
onClick={() => setOpenedDialog('normal')} | ||
aria-haspopup="dialog" | ||
aria-controls="dialog-form" | ||
data-test="dialog-trigger" | ||
> | ||
StepFormDialog | ||
</Button> | ||
{/* // eslint-disable-next-line smarthr/a11y-delegate-element-has-role-presentation */} | ||
<StepFormDialog | ||
isOpen={openedDialog === 'normal'} | ||
title="StepFormDialog" | ||
submitLabel="保存" | ||
firstStep={stepOrder[0]} | ||
onSubmit={(closeDialog, e, currentStep) => { | ||
action('onSubmit')() | ||
setResponseMessage(undefined) | ||
if (currentStep.id === stepOrder[2].id) { | ||
closeDialog() | ||
} | ||
if (currentStep.id === stepOrder[0].id) { | ||
const skip = e.currentTarget.elements.namedItem('skip') as HTMLInputElement | ||
if (skip.checked) { | ||
return stepOrder[2] | ||
} | ||
} | ||
const currentStepIndex = stepOrder.findIndex((step) => step.id === currentStep.id) | ||
return stepOrder.at(currentStepIndex + 1) | ||
}} | ||
onClickClose={() => { | ||
action('closed')() | ||
setOpenedDialog(null) | ||
setResponseMessage(undefined) | ||
}} | ||
onClickBack={() => { | ||
action('back')() | ||
}} | ||
stepLength={3} | ||
responseMessage={responseMessage} | ||
id="dialog-form" | ||
data-test="form-dialog-content" | ||
width="40em" | ||
> | ||
<StepFormDialogItem {...stepOrder[0]}> | ||
<Fieldset title="fruits" innerMargin={0.5}> | ||
<RadioListCluster forwardedAs="ul"> | ||
<li> | ||
<RadioButton name="Apple" checked={value === 'Apple'} onChange={onChange}> | ||
Apple | ||
</RadioButton> | ||
</li> | ||
<li> | ||
<RadioButton name="Orange" checked={value === 'Orange'} onChange={onChange}> | ||
Orange | ||
</RadioButton> | ||
</li> | ||
<li> | ||
<RadioButton name="skip" checked={value === 'skip'} onChange={onChange}> | ||
これを選ぶとステップ2を飛ばして3に進みます | ||
</RadioButton> | ||
</li> | ||
</RadioListCluster> | ||
</Fieldset> | ||
</StepFormDialogItem> | ||
<StepFormDialogItem {...stepOrder[1]}> | ||
<FormControl id="b" title="Sample"> | ||
<Input type="text" name="text" /> | ||
</FormControl> | ||
</StepFormDialogItem> | ||
<StepFormDialogItem {...stepOrder[2]}> | ||
<Fieldset title="fruits" innerMargin={0.5}> | ||
<ul> | ||
<li> | ||
<CheckBox name="1">CheckBox</CheckBox> | ||
</li> | ||
|
||
<li> | ||
<CheckBox name="error" error> | ||
CheckBox / error | ||
</CheckBox> | ||
</li> | ||
|
||
<li> | ||
<CheckBox name="disabled" disabled> | ||
CheckBox / disabled | ||
</CheckBox> | ||
</li> | ||
</ul> | ||
</Fieldset> | ||
</StepFormDialogItem> | ||
</StepFormDialog> | ||
</Cluster> | ||
) | ||
} | ||
|
||
Default.parameters = { | ||
docs: { | ||
description: { | ||
story: '`StepFormDialog` is a form dialog that can be divided into multiple steps.', | ||
}, | ||
}, | ||
} | ||
|
||
const RadioListCluster = styled(Cluster).attrs({ gap: 1.25 })` | ||
list-style: none; | ||
` |
91 changes: 91 additions & 0 deletions
91
packages/smarthr-ui/src/components/Dialog/StepFormDialog/StepFormDialog.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { userEvent } from '@storybook/test' | ||
import { act, render, screen, waitFor } from '@testing-library/react' | ||
import React, { useState } from 'react' | ||
|
||
import { Button } from '../../Button' | ||
import { Text } from '../../Text' | ||
|
||
import { StepFormDialog } from './StepFormDialog' | ||
import { StepFormDialogItem } from './StepFormDialogItem' | ||
|
||
describe('StepFormDialog', () => { | ||
const DialogTemplate: React.FC = () => { | ||
const [isOpen, setIsOpen] = useState<boolean>(false) | ||
const steps = [ | ||
{ id: 'a', stepNumber: 1 }, | ||
{ id: 'b', stepNumber: 2 }, | ||
] | ||
return ( | ||
<> | ||
<Button onClick={() => setIsOpen(true)}>StepFormDialog</Button> | ||
<StepFormDialog | ||
isOpen={isOpen} | ||
title="StepFormDialog" | ||
submitLabel="保存" | ||
stepLength={2} | ||
firstStep={steps[0]} | ||
onSubmit={(closeDialog, _, currentStep) => { | ||
closeDialog() | ||
const nextStep = steps.find((step) => step.stepNumber === currentStep.stepNumber + 1) | ||
return nextStep | ||
}} | ||
onClickClose={() => { | ||
setIsOpen(false) | ||
}} | ||
> | ||
<StepFormDialogItem {...steps[0]}> | ||
<Text>Step1</Text> | ||
</StepFormDialogItem> | ||
<StepFormDialogItem {...steps[1]}> | ||
<Text>Step2</Text> | ||
</StepFormDialogItem> | ||
</StepFormDialog> | ||
</> | ||
) | ||
} | ||
it('ダイアログが開閉できること', async () => { | ||
render(<DialogTemplate />) | ||
|
||
expect(screen.queryByRole('dialog', { name: 'StepFormDialog 1/2' })).toBeNull() | ||
await act(() => userEvent.tab()) | ||
await act(() => userEvent.keyboard('{enter}')) | ||
expect(screen.getByRole('dialog', { name: 'StepFormDialog 1/2' })).toBeVisible() | ||
|
||
await act(() => userEvent.click(screen.getByRole('button', { name: 'キャンセル' }))) | ||
await waitFor( | ||
() => { | ||
expect(screen.queryByRole('dialog', { name: 'StepFormDialog 1/2' })).toBeNull() | ||
}, | ||
{ timeout: 1000 }, | ||
) | ||
|
||
// ダイアログを閉じた後、トリガがフォーカスされることを確認 | ||
expect(screen.getByRole('button', { name: 'StepFormDialog' })).toHaveFocus() | ||
}) | ||
|
||
it('ダイアログのステップの移動ができること', async () => { | ||
render(<DialogTemplate />) | ||
|
||
await act(() => userEvent.tab()) | ||
await act(() => userEvent.keyboard('{enter}')) | ||
expect(screen.getByRole('dialog', { name: 'StepFormDialog 1/2' })).toBeVisible() | ||
|
||
await act(() => userEvent.click(screen.getByRole('button', { name: '次へ' }))) | ||
expect(screen.getByRole('dialog', { name: 'StepFormDialog 2/2' })).toBeVisible() | ||
|
||
await act(() => userEvent.click(screen.getByRole('button', { name: '戻る' }))) | ||
expect(screen.getByRole('dialog', { name: 'StepFormDialog 1/2' })).toBeVisible() | ||
|
||
await act(() => userEvent.click(screen.getByRole('button', { name: '次へ' }))) | ||
await act(() => userEvent.click(screen.getByRole('button', { name: '保存' }))) | ||
await waitFor( | ||
() => { | ||
expect(screen.queryByRole('dialog', { name: 'StepFormDialog 2/2' })).toBeNull() | ||
}, | ||
{ timeout: 1000 }, | ||
) | ||
|
||
// ダイアログを閉じた後、トリガがフォーカスされることを確認 | ||
expect(screen.getByRole('button', { name: 'StepFormDialog' })).toHaveFocus() | ||
}) | ||
}) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HELP
今は通っているんですが、この次へを押した次に 2/2 ステップ目かの assertion を入れるとCI上でだけ落ちる事件が発生していました。。。原因わからずです