From 3e142a8fa8d4e0db67a1646aee8a439b113a3de9 Mon Sep 17 00:00:00 2001 From: TutnTut Date: Mon, 20 Jul 2026 05:15:10 +0000 Subject: [PATCH 1/4] feat(paper-forms): progress bar on create-form set-up pages [part 1] Add a thin linear progress bar across the paper-tracking create-form set-up pages (title -> data source -> secret key). It fills proportionally as the admin advances, and is gated behind the paper-tracking flag so other create-form flows are unaffected. Exposes progressbar aria semantics for accessibility. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../CreateFormModalContent.tsx | 21 ++++++++++- .../CreateFormProgressBar.test.tsx | 29 +++++++++++++++ .../CreateFormProgressBar.tsx | 37 +++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.test.tsx create mode 100644 apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormModalContent.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormModalContent.tsx index 19143c2903..82fe3e4463 100644 --- a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormModalContent.tsx +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormModalContent.tsx @@ -9,6 +9,7 @@ import { import { CreateFormDetailsScreen } from './CreateFormDetailsScreen' import { CreateFormOriginScreen } from './CreateFormOriginScreen' +import { CreateFormProgressBar } from './CreateFormProgressBar' import { CreateFormStorageModeScreen } from './CreateFormStorageModeScreen' import { EmailModeCreationScreen, @@ -16,16 +17,34 @@ import { } from './EmailModeFeedbackAndCreateScreen' import { SaveSecretKeyScreen } from './SaveSecretKeyScreen' +// Set-up pages the progress bar spans, in order. +const PROGRESS_STEP_ORDER = [ + CreateFormFlowStates.Details, + CreateFormFlowStates.Origin, + CreateFormFlowStates.Landing, +] + /** * @preconditions Requires CreateFormWizardProvider parent * Display screen content depending on the current step (with animation). */ export const CreateFormModalContent = () => { - const { direction, currentStep } = useCreateFormWizard() + const { direction, currentStep, isPaperTrackingSetUpPageEnabled } = + useCreateFormWizard() + + const progressStepIdx = PROGRESS_STEP_ORDER.indexOf(currentStep) + const showProgressBar = + isPaperTrackingSetUpPageEnabled && progressStepIdx !== -1 return ( <> {currentStep !== CreateFormFlowStates.Landing && } + {showProgressBar && ( + + )} {currentStep === CreateFormFlowStates.Details && ( diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.test.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.test.tsx new file mode 100644 index 0000000000..2be03bf772 --- /dev/null +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.test.tsx @@ -0,0 +1,29 @@ +import { screen } from '@testing-library/react' + +import { render } from '~/test-utils' + +import { CreateFormProgressBar } from './CreateFormProgressBar' + +describe('CreateFormProgressBar', () => { + it('reports the current step through progressbar aria attributes', () => { + render() + + const bar = screen.getByRole('progressbar') + expect(bar).toHaveAttribute('aria-valuenow', '2') + expect(bar).toHaveAttribute('aria-valuemin', '1') + expect(bar).toHaveAttribute('aria-valuemax', '3') + expect(bar).toHaveAccessibleName('Step 2 of 3') + }) + + it('fills proportionally to the current step', () => { + render() + + expect(screen.getByTestId('progress-fill')).toHaveStyle({ width: '25%' }) + }) + + it('is fully filled on the final step', () => { + render() + + expect(screen.getByTestId('progress-fill')).toHaveStyle({ width: '100%' }) + }) +}) diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx new file mode 100644 index 0000000000..1baec8e266 --- /dev/null +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx @@ -0,0 +1,37 @@ +import { Box } from '@chakra-ui/react' + +interface CreateFormProgressBarProps { + currentStepIdx: number + numSteps: number +} + +/** Progress bar shown across the paper-tracking create-form set-up pages. */ +export const CreateFormProgressBar = ({ + currentStepIdx, + numSteps, +}: CreateFormProgressBarProps): JSX.Element => { + const currentStep = currentStepIdx + 1 + const progress = (currentStep / numSteps) * 100 + + return ( + + + + ) +} From 6ffa4697620f7f142dc491c2917edc86b4b62716 Mon Sep 17 00:00:00 2001 From: TutnTut Date: Mon, 20 Jul 2026 05:15:33 +0000 Subject: [PATCH 2/4] style(paper-forms): soften create-form progress bar styling [part 2] Round the track and fill corners, lighten the track (neutral.300 -> neutral.200), and ease the fill transition, matching the workflow-v2 phase bar so the paper-tracking surfaces feel consistent. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../CreateFormModalContent/CreateFormProgressBar.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx index 1baec8e266..66fbea5ba2 100644 --- a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx @@ -22,7 +22,8 @@ export const CreateFormProgressBar = ({ aria-label={`Step ${currentStep} of ${numSteps}`} h="0.25rem" w="100%" - bg="neutral.300" + bg="neutral.200" + borderRadius="2px" overflow="hidden" > ) From 04dd89c5440b1152c4c112ca8ba4b4ae79948cb7 Mon Sep 17 00:00:00 2001 From: TutnTut Date: Mon, 20 Jul 2026 05:16:00 +0000 Subject: [PATCH 3/4] feat(paper-forms): center create-form progress bar on content column [part 3] Wrap the bar in the same centered 45rem container the set-up screens use, with matching horizontal padding, so it spans from the "Set up your form" header to the primary button rather than the full modal width. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../CreateFormProgressBar.tsx | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx index 66fbea5ba2..cf0374b223 100644 --- a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormProgressBar.tsx @@ -1,4 +1,4 @@ -import { Box } from '@chakra-ui/react' +import { Box, Container } from '@chakra-ui/react' interface CreateFormProgressBarProps { currentStepIdx: number @@ -14,26 +14,30 @@ export const CreateFormProgressBar = ({ const progress = (currentStep / numSteps) * 100 return ( - - + + + + + + ) } From f3fa1e7c66a4bb55c44f993b03b79d640c18b591 Mon Sep 17 00:00:00 2001 From: TutnTut Date: Mon, 20 Jul 2026 05:16:16 +0000 Subject: [PATCH 4/4] fix(paper-forms): align data-source and secret-key pages to Details width [part 4] The Details page uses a 45rem content column but the data-source and secret-key pages used 42.5rem, so content shifted between steps and the progress bar only lined up on the first page. Standardise all three on 45rem so the column and the bar stay put across the wizard. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../CreateFormModalContent/CreateFormOriginScreen.tsx | 4 ++-- .../CreateFormModalContent/SaveSecretKeyContent.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormOriginScreen.tsx b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormOriginScreen.tsx index 5f1df2d58d..b466a6c56b 100644 --- a/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormOriginScreen.tsx +++ b/apps/frontend/src/features/workspace/components/CreateFormModal/CreateFormModalContent/CreateFormOriginScreen.tsx @@ -56,12 +56,12 @@ export const CreateFormOriginScreen = ({ return ( <> - + {t(`${ORIGIN_I18N_PREFIX}.question`)} - + - +