From 3bd009e0bc3fb95cee515b1e84cc612f13ab8c2e Mon Sep 17 00:00:00 2001 From: masuP9 Date: Thu, 4 Jul 2024 11:07:40 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20ActionDialog=E3=81=A7Step=E3=82=92?= =?UTF-8?q?=E4=BD=9C=E3=82=8B=E3=81=A8=E3=81=93=E3=82=8D=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Dialog/DialogTest.stories.tsx | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx diff --git a/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx new file mode 100644 index 0000000000..f3bf26ef32 --- /dev/null +++ b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx @@ -0,0 +1,78 @@ +import { StoryFn } from '@storybook/react' +import React, { ReactNode, useState } from 'react' + +import { Button } from '../Button' +import { FormControl } from '../FormControl' +import { Input } from '../Input' +import { Stack } from '../Layout' + +import { ActionDialog } from '.' + +export default { + title: 'Dialog(ダイアログ)/Step Dialog', + component: ActionDialog, +} + +type DialogContents = { + [key: number]: Omit< + React.ComponentProps, + 'title' | 'onClickClose' | 'isOpen' + > & { children: ReactNode } +} + +export const Default: StoryFn = () => { + const [step, setStep] = useState(0) + const [prevStep, setPrevStep] = useState(step) + + if (step !== prevStep && step > 0) { + setPrevStep(step) + } + + const onClickClose = () => setStep((prev) => prev - 1) + + const dialogContents: DialogContents = { + 1: { + actionText: '次へ', + onClickAction: () => setStep((prev) => prev + 1), + children: ( + + + + ), + }, + 2: { + actionText: '完了', + onClickAction: () => setStep(0), + children: ( + + + + ), + }, + } + + const dialogContent = dialogContents[step] + + return ( + <> + +
+ +
+ + + +
+ + 0} + actionDisabled={step === 2} + onClickClose={onClickClose} + /> + + ) +} From 49c0d96cab662bd3b8d5d6967e2b621f9bcbee5a Mon Sep 17 00:00:00 2001 From: masuP9 Date: Thu, 4 Jul 2024 18:57:36 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20Dialog=E3=81=AEstep=E3=81=A8step?= =?UTF-8?q?=E3=81=AE=E5=A4=89=E5=8C=96=E3=81=AB=E3=82=88=E3=81=A3=E3=81=A6?= =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=BC=E3=82=AB=E3=82=B9=E3=82=92=E3=83=AA?= =?UTF-8?q?=E3=82=BB=E3=83=83=E3=83=88=E3=81=99=E3=82=8B=E3=83=AD=E3=82=B8?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=92useDialogSteps=E3=81=AB=E3=81=BE?= =?UTF-8?q?=E3=81=A8=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Dialog/DialogTest.stories.tsx | 36 +++++++------- .../src/components/Dialog/useDialogSteps.tsx | 47 +++++++++++++++++++ 2 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx diff --git a/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx index f3bf26ef32..184bc0beb9 100644 --- a/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx +++ b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx @@ -1,11 +1,13 @@ import { StoryFn } from '@storybook/react' -import React, { ReactNode, useState } from 'react' +import React, { ReactNode } from 'react' import { Button } from '../Button' import { FormControl } from '../FormControl' import { Input } from '../Input' import { Stack } from '../Layout' +import { useDialogSteps } from './useDialogSteps' + import { ActionDialog } from '.' export default { @@ -21,19 +23,17 @@ type DialogContents = { } export const Default: StoryFn = () => { - const [step, setStep] = useState(0) - const [prevStep, setPrevStep] = useState(step) - - if (step !== prevStep && step > 0) { - setPrevStep(step) - } - - const onClickClose = () => setStep((prev) => prev - 1) + const [currentStep, { setStep, nextStep, prevStep }, renderFocusTarget] = useDialogSteps() const dialogContents: DialogContents = { + 0: { + actionText: '', + onClickAction: nextStep, + children: null, + }, 1: { actionText: '次へ', - onClickAction: () => setStep((prev) => prev + 1), + onClickAction: nextStep, children: ( @@ -51,13 +51,13 @@ export const Default: StoryFn = () => { }, } - const dialogContent = dialogContents[step] + const dialogContent = dialogContents[currentStep] return ( <>
-
@@ -68,11 +68,13 @@ export const Default: StoryFn = () => { 0} - actionDisabled={step === 2} - onClickClose={onClickClose} - /> + title={`Stepper Dialog ${currentStep} / 2`} + isOpen={currentStep > 0} + onClickClose={currentStep === 2 ? () => setStep(0) : prevStep} + > + {renderFocusTarget()} + {dialogContent.children} + ) } diff --git a/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx b/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx new file mode 100644 index 0000000000..629b5911e5 --- /dev/null +++ b/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx @@ -0,0 +1,47 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react' + +type UseDialogStepsResult = [ + number, + { + setStep: React.Dispatch> + nextStep: () => void + prevStep: () => void + }, + () => React.JSX.Element, +] + +export function useDialogSteps(startStep?: number): UseDialogStepsResult { + const [step, setStep] = useState(startStep || 0) + const dialogContentStartElementRef = useRef(null) + const prevStep = useRef(step) + + useEffect(() => { + if ( + step !== prevStep.current && + step > 0 && + dialogContentStartElementRef.current instanceof HTMLElement + ) { + dialogContentStartElementRef.current.focus() + } + + prevStep.current = step + }, [step]) + + const renderFocusTarget = () =>
+ + const dialogSteps: UseDialogStepsResult = [ + step, + { + setStep, + nextStep: useCallback(() => { + setStep((prev) => prev + 1) + }, []), + prevStep: useCallback(() => { + setStep((prev) => prev - 1) + }, []), + }, + renderFocusTarget, + ] + + return dialogSteps +} From 89eaa0fccbab624d6a375f22008425891fe8bb05 Mon Sep 17 00:00:00 2001 From: masuP9 Date: Mon, 2 Sep 2024 13:53:08 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20DOM=E3=82=92=E4=BD=BF=E3=81=86?= =?UTF-8?q?=E3=82=84=E3=82=8A=E6=96=B9=E3=81=AB=E5=A4=89=E3=81=88=E3=81=A6?= =?UTF-8?q?=E3=81=BF=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/Dialog/DialogTest.stories.tsx | 3 +-- .../src/components/Dialog/useDialogSteps.tsx | 16 +++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx index 184bc0beb9..0ec4c69f3f 100644 --- a/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx +++ b/packages/smarthr-ui/src/components/Dialog/DialogTest.stories.tsx @@ -23,7 +23,7 @@ type DialogContents = { } export const Default: StoryFn = () => { - const [currentStep, { setStep, nextStep, prevStep }, renderFocusTarget] = useDialogSteps() + const [currentStep, { setStep, nextStep, prevStep }] = useDialogSteps() const dialogContents: DialogContents = { 0: { @@ -72,7 +72,6 @@ export const Default: StoryFn = () => { isOpen={currentStep > 0} onClickClose={currentStep === 2 ? () => setStep(0) : prevStep} > - {renderFocusTarget()} {dialogContent.children} diff --git a/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx b/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx index 629b5911e5..84e4c9f0a1 100644 --- a/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx +++ b/packages/smarthr-ui/src/components/Dialog/useDialogSteps.tsx @@ -7,28 +7,23 @@ type UseDialogStepsResult = [ nextStep: () => void prevStep: () => void }, - () => React.JSX.Element, ] export function useDialogSteps(startStep?: number): UseDialogStepsResult { const [step, setStep] = useState(startStep || 0) - const dialogContentStartElementRef = useRef(null) const prevStep = useRef(step) useEffect(() => { - if ( - step !== prevStep.current && - step > 0 && - dialogContentStartElementRef.current instanceof HTMLElement - ) { - dialogContentStartElementRef.current.focus() + if (step !== prevStep.current && step > 0) { + const focusTarget = document.querySelector('[role=dialog] > div > div[tabindex]') + if (focusTarget instanceof HTMLDivElement) { + focusTarget.focus() + } } prevStep.current = step }, [step]) - const renderFocusTarget = () =>
- const dialogSteps: UseDialogStepsResult = [ step, { @@ -40,7 +35,6 @@ export function useDialogSteps(startStep?: number): UseDialogStepsResult { setStep((prev) => prev - 1) }, []), }, - renderFocusTarget, ] return dialogSteps