1 import type { FC } from 'react';
2 import { useState } from 'react';
4 import { c } from 'ttag';
6 import { Button } from '@proton/atoms/Button/Button';
7 import Step from '@proton/atoms/Stepper/Step';
8 import Stepper from '@proton/atoms/Stepper/Stepper';
9 import { type ModalProps, ModalTwoFooter } from '@proton/components';
10 import Icon from '@proton/components/components/icon/Icon';
11 import { ModalTwoContent, ModalTwoHeader } from '@proton/components/index';
12 import { PassModal } from '@proton/pass/components/Layout/Modal/PassModal';
13 import { wait } from '@proton/shared/lib/helpers/promise';
15 import { useOnboarding } from './OnboardingProvider';
17 import './OnboardingModal.scss';
19 export const OnboardingModal: FC<ModalProps> = ({ size = 'xlarge', ...props }) => {
20 const { acknowledge, steps, markCompleted } = useOnboarding();
21 const [loading, setLoading] = useState(false);
22 const [step, setStep] = useState(0);
24 const currentStep = steps[step];
26 const onComplete = () => {
29 void wait(250).then(props.onClose);
32 const onStep = (offset: 1 | -1) => {
33 if (offset === 1) markCompleted(steps[step].key);
35 const nextStep = step + offset;
36 if (nextStep < steps.length) setStep(Math.max(0, nextStep));
40 const onContinue = () => {
41 currentStep.action?.();
47 <Button className="mr-auto" icon pill shape="ghost" onClick={() => onStep(-1)}>
48 <Icon name="arrow-left" />
53 <PassModal {...props} onClose={props.onClose} size={size} className="pass-onboarding-modal">
54 <ModalTwoHeader actions={backButton} closeButtonProps={{ pill: true, icon: true }} />
56 <Stepper activeStep={step}>
57 {steps.map((step) => (
58 <Step key={step.key} />
63 {/* height accommodates largest content without layout shifts */}
64 <div className="h-custom flex items-center" style={{ '--h-custom': '23rem' }}>
65 <div className="flex flex-column w-full">
66 <div className="flex items-center gap-6 text-left w-full">
67 <div className="flex-1">
68 <p className="text-uppercase text-sm text-bold m-0 mb-3 pass-onboarding-modal--group">
71 <p className="text-4xl text-bold m-0 mb-3">{currentStep.title}</p>
72 <p className="text-weak text-pre-wrap m-0">{currentStep.description}</p>
75 <div className="flex-1">{currentStep.component}</div>
80 <ModalTwoFooter className="mt-0">
81 <div className="flex justify-end w-full">
83 className="mr-auto pass-onboarding-modal--skip"
86 onClick={() => onStep(1)}
92 <Button pill shape="solid" onClick={onContinue} disabled={loading}>
93 {currentStep.actionText ?? 'Continue'}