diff --git a/src/components/Common/TaxInputs/TaxInputs.stories.tsx b/src/components/Common/TaxInputs/TaxInputs.stories.tsx
new file mode 100644
index 0000000000..e22731efed
--- /dev/null
+++ b/src/components/Common/TaxInputs/TaxInputs.stories.tsx
@@ -0,0 +1,45 @@
+import type { TaxRequirement } from '@gusto/embedded-api/models/components/taxrequirement'
+import { FormWrapper } from '../../../../.storybook/helpers/FormWrapper'
+import { QuestionInput } from './TaxInputs'
+
+export default {
+ title: 'UI/Form/Fields/TaxInputs',
+}
+
+const einSuffixRequirement: TaxRequirement = {
+ key: 'einSuffix',
+ label: 'EIN suffix',
+ description: 'Some tax agencies use an account number that is your federal EIN plus two digits.',
+ value: null,
+ metadata: {
+ type: 'account_number',
+ mask: '##',
+ prefix: 'XXXXX1234',
+ },
+}
+
+const uiaAccountNumberRequirement: TaxRequirement = {
+ key: 'uiaAccountNumber',
+ label: 'UIA Account Number',
+ description: 'No prefix on this requirement -- matches most account_number requirements today.',
+ value: null,
+ metadata: {
+ type: 'account_number',
+ mask: '###-####-#',
+ prefix: null,
+ },
+}
+
+// SDK-1143: account_number requirements with metadata.prefix should render it as a
+// fixed prefix ahead of the masked value, matching Rails' TaxRequirements::InputBuilder.
+export const AccountNumberWithPrefix = () => (
+
+
+
+)
+
+export const AccountNumberWithoutPrefix = () => (
+
+
+
+)
diff --git a/src/components/Common/TaxInputs/TaxInputs.test.tsx b/src/components/Common/TaxInputs/TaxInputs.test.tsx
new file mode 100644
index 0000000000..0827b80d1a
--- /dev/null
+++ b/src/components/Common/TaxInputs/TaxInputs.test.tsx
@@ -0,0 +1,55 @@
+import { describe, expect, it } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import { FormProvider, useForm } from 'react-hook-form'
+import type { TaxRequirement } from '@gusto/embedded-api/models/components/taxrequirement'
+import { QuestionInput } from './TaxInputs'
+import { GustoTestProvider } from '@/test/GustoTestApiProvider'
+
+function TestForm({ requirement }: { requirement: TaxRequirement }) {
+ const methods = useForm({ defaultValues: { [requirement.key as string]: requirement.value } })
+ return (
+
+
+
+
+
+ )
+}
+
+describe('TaxInputs', () => {
+ describe('account_number question type', () => {
+ it('renders metadata.prefix as a start adornment ahead of the masked value', () => {
+ render(
+ ,
+ )
+
+ expect(screen.getByText('XXXXX1234')).toBeInTheDocument()
+ expect(screen.getByLabelText('EIN suffix')).toHaveAttribute('placeholder', '##')
+ })
+
+ it('renders normally, without a start adornment, when metadata.prefix is null', () => {
+ render(
+ ,
+ )
+
+ expect(screen.getByLabelText('UBI number')).toHaveAttribute('placeholder', '### ### ###')
+ })
+ })
+})
diff --git a/src/components/Common/TaxInputs/TaxInputs.tsx b/src/components/Common/TaxInputs/TaxInputs.tsx
index acdab3600a..e4d00030fc 100644
--- a/src/components/Common/TaxInputs/TaxInputs.tsx
+++ b/src/components/Common/TaxInputs/TaxInputs.tsx
@@ -43,7 +43,7 @@ export function QuestionInput({
case 'radio':
return
case 'text':
- case 'account_number': //TODO: temporary - need special handling for account numbers
+ case 'account_number':
return
case 'select':
return
@@ -105,6 +105,7 @@ export function TextInput({
const { key, label, description } = question ? question : requirement
const value = question ? question.answers[0]?.value : requirement.value
const mask = requirement?.metadata?.mask ?? null
+ const prefix = requirement?.metadata?.prefix ?? undefined
const transform = useMaskedTransform(mask)
if (!key) return null
@@ -120,6 +121,7 @@ export function TextInput({
transform={mask ? transform : undefined}
placeholder={mask ? mask : undefined}
type={type}
+ adornmentStart={prefix}
adornmentEnd={isPercent ? '%' : undefined}
/>
)