Skip to content
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: Stepを持つダイアログをキーボードフォーカスしやすく開発しやすくするカスタムフックを作る #4756

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

masuP9
Copy link
Contributor

@masuP9 masuP9 commented Jul 4, 2024

Related URL

Overview

useDialogStepsを作成

返り値

type UseDialogStepsResult = [
  number, // currentStep
  {
    setStep: React.Dispatch<React.SetStateAction<number>> // stepをset
    nextStep: () => void // 次のstepへ
    prevStep: () => void // 前のstepへ
  },
  () => React.JSX.Element, // ステップ移動したときにフォーカスを当て直すための要素。通常は Dialog の children の最初に配置する
]

アプリケーション側の実装

// useDialogSteps()を実行して必要なものを作る
const [currentStep, { setStep, nextStep, prevStep }, renderFocusTarget] = useDialogSteps()

const dialogContents: DialogContents = {
  0: (各ステップごとのDialogのPropsを定義しておく),
  1: ...,
  2: ...,
}

const dialogContent = dialogContents[currentStep]

return (
  <ActionDialog
    {...dialogContent}
    title={`Stepper Dialog ${currentStep} / 2`}
    isOpen={currentStep > 0}
    onClickClose={currentStep === 2 ? () => setStep(0) : prevStep}
  >
    /* childrenの最初で、renderFocusTarget() を実行する。stepが変わったらこの位置に focus がリセットされる */
    {renderFocusTarget()}
    {dialogContent.children}
  </ActionDialog>
)

What I did

Capture

@masuP9 masuP9 changed the title feat: ActionDialogでStepを作るところまで feat: Stepを持つダイアログをキーボードフォーカスしやすく開発しやすくするカスタムフックを作る Jul 4, 2024
@schktjm
Copy link
Contributor

schktjm commented Sep 2, 2024

検討している実装方法

  • focusTargetRef のような、Dialog に渡すための値を返り値に持つ useDialogSteps を提供する
    • メリット
      • 実装側が Dialog, ActionDialog 関係なく使える
    • デメリット
    • ref を Dialog に渡し忘れがありそう
  • <StepsDialog> コンポーネントを実装する
    • メリット
      • 実装側で Dialog を持つため渡し忘れがない
    • デメリット
      • 開発チーム側で独自にダイアログを実装していた場合に対応できない

@schktjm
Copy link
Contributor

schktjm commented Sep 2, 2024

focusTargetRef のような、Dialog に渡すための値を返り値に持つ useDialogSteps を提供する

返り値

type UseDialogStepsResult = [
  number, // currentStep
  {
    setStep: React.Dispatch<React.SetStateAction<number>> // stepをset
    nextStep: () => void // 次のstepへ
    prevStep: () => void // 前のstepへ
  },
  refObject<HTMLElement> // ステップ移動したときにフォーカスを当て直すための要素にわたすための ref。Dialog の props として渡す想定
]

アプリケーション側

// useDialogSteps()を実行して必要なものを作る
const [currentStep, { setStep, nextStep, prevStep }, focusTargetRef] = useDialogSteps()

const dialogContents: DialogContents = {
  0: (各ステップごとのDialogのPropsを定義しておく),
  1: ...,
  2: ...,
}

const dialogContent = dialogContents[currentStep]

return (
  <ActionDialog
    {...dialogContent}
    focusTargetRef={focusTargetRef}
    title={`Stepper Dialog ${currentStep} / 2`}
    isOpen={currentStep > 0}
    onClickClose={currentStep === 2 ? () => setStep(0) : prevStep}
  >
    {dialogContent.children}
  </ActionDialog>
)

@schktjm
Copy link
Contributor

schktjm commented Sep 2, 2024

WIP: <StepsDialog> コンポーネントを実装する

イメージ

type Props = {
  onNext: (index: number) => void;
  onPrev: (index: number) => void;
  children: ReactNode;
  defaultIndex: number
} & ActionDialogProps

使う側

const [currentStep, setCurrentStep] = useState(0)

const dialogContents: DialogContents = {
  0: (各ステップごとのDialogのPropsを定義しておく),
  1: ...,
  2: ...,
}

const dialogContent = dialogContents[currentStep]

const onNextStep = (step: number) => {
  setCurrentStep(step)
}

return (
  <StepsDialog
    {...dialogContent}
    title={`Stepper Dialog ${currentStep} / 2`}
    isOpen={currentStep > 0}
    onClickClose={currentStep === 2 ? () => setStep(0) : prevStep}
    onNext={onNextStep}
  >
    {dialogContent.children}
  </StepsDialog>
)



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants