Files
supabase/apps/studio/components/interfaces/ProjectCreation/DatabasePasswordInput.tsx
Gildas Garcia 72aa214b0c fix: new project form accessibility issues (#47785)
## Problem

The new project form has accessibility issues:
- labels are not linked to inputs
- description are not linked to inputs

## How to test

Navigate through the form inputs with voice over and make sure every
input makes sense

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved form field identification consistency across project creation
screens (compute size, database password, project name, PostgreSQL
version, region, and organization).
* Enhanced selector/input accessibility by adding explicit element
identifiers to key controls.
* Updated region and repository UI structure to improve reliable
rendering without changing setup behavior.
* Preserved existing password, version, and routing logic while making
dropdowns and fields easier to locate and interact with.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-09 18:11:57 +02:00

87 lines
2.8 KiB
TypeScript

import { UseFormReturn } from 'react-hook-form'
import { FormControl, FormField } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { CreateProjectForm } from './ProjectCreation.schema'
import Panel from '@/components/ui/Panel'
import { PasswordStrengthBar } from '@/components/ui/PasswordStrengthBar'
import { passwordStrength } from '@/lib/password-strength'
import { generateStrongPassword } from '@/lib/project'
interface DatabasePasswordInputProps {
form: UseFormReturn<CreateProjectForm>
}
const updatePasswordStrength = async (form: UseFormReturn<CreateProjectForm>, value: string) => {
try {
const { warning, message, strength } = await passwordStrength(value)
form.setValue('dbPassStrength', strength, { shouldValidate: false, shouldDirty: false })
form.setValue('dbPassStrengthMessage', message ?? '', {
shouldValidate: false,
shouldDirty: false,
})
form.setValue('dbPassStrengthWarning', warning ?? '', {
shouldValidate: false,
shouldDirty: false,
})
form.trigger('dbPass')
} catch (error) {
console.error(error)
}
}
export const DatabasePasswordInput = ({ form }: DatabasePasswordInputProps) => {
// [Refactor] DB Password could be a common component used in multiple pages with repeated logic
async function generatePassword() {
const password = generateStrongPassword()
form.setValue('dbPass', password)
updatePasswordStrength(form, password)
}
return (
<Panel.Content>
<FormField
control={form.control}
name="dbPass"
render={({ field }) => {
return (
<FormItemLayout
id="dbPass"
label="Database password"
layout="horizontal"
description={
<PasswordStrengthBar
passwordStrengthScore={form.getValues('dbPassStrength')}
password={field.value}
passwordStrengthMessage={form.getValues('dbPassStrengthMessage')}
generateStrongPassword={generatePassword}
/>
}
>
<FormControl>
<Input
copy={field.value.length > 0}
type="password"
placeholder="Type in a strong password"
{...field}
id="dbPass"
autoComplete="off"
onChange={async (event) => {
const newValue = event.target.value
field.onChange(event)
updatePasswordStrength(form, newValue)
}}
/>
</FormControl>
</FormItemLayout>
)
}}
/>
</Panel.Content>
)
}