Merge pull request #9549 from colinux/form-identite-fix-accessibilite

ETQ usager, le formulaire d'identité est un peu plus accessible
This commit is contained in:
Colin Darie 2023-10-03 09:23:48 +00:00 committed by GitHub
commit e1dab5bb39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 80 additions and 61 deletions

View file

@ -649,3 +649,19 @@ textarea::placeholder {
} }
} }
} }
.fr-fieldset__element {
@media (min-width: 48em) {
// Logic taken from DSFR source code to limit width of fieldset element.
// Cf dsfr/src/component/form/style/_scheme.scss
$short-text-width: 32rem;
&--short-text {
flex: 0 0 #{$short-text-width};
}
&--short-text:not(&--inline) {
margin-right: calc(100% - #{$short-text-width});
}
}
}

View file

@ -67,6 +67,10 @@ class Dsfr::InputComponent < ApplicationComponent
@input_type == :email_field @input_type == :email_field
end end
def required?
@required
end
def show_password_id def show_password_id
dom_id(object, "#{@attribute}_show_password") dom_id(object, "#{@attribute}_show_password")
end end

View file

@ -2,8 +2,13 @@
= @form.label @attribute, label_opts do = @form.label @attribute, label_opts do
- capture do - capture do
= label = label
- if required?
= render EditableChamp::AsteriskMandatoryComponent.new
- if hint? - if hint?
%span.fr-hint-text= hint %span.fr-hint-text= hint
= @form.public_send(@input_type, @attribute, input_opts) = @form.public_send(@input_type, @attribute, input_opts)
- if errors_on_attribute? - if errors_on_attribute?

View file

@ -26,7 +26,7 @@
.fr-input-group .fr-input-group
= f.label :duree_conservation_dossiers_dans_ds, class: 'fr-label' do = f.label :duree_conservation_dossiers_dans_ds, class: 'fr-label' do
Sur #{APPLICATION_NAME} Sur #{APPLICATION_NAME}
%span.mandatory * = render EditableChamp::AsteriskMandatoryComponent.new
= f.number_field :duree_conservation_dossiers_dans_ds, { class: 'fr-input', placeholder: '6', required: true, max: f.object.max_duree_conservation_dossiers_dans_ds } = f.number_field :duree_conservation_dossiers_dans_ds, { class: 'fr-input', placeholder: '6', required: true, max: f.object.max_duree_conservation_dossiers_dans_ds }

View file

@ -4,38 +4,36 @@
- if !dossier_submission_is_closed?(@dossier) - if !dossier_submission_is_closed?(@dossier)
= form_for @dossier.individual, url: update_identite_dossier_path(@dossier), html: { class: "form" } do |f| = form_for @dossier.individual, url: update_identite_dossier_path(@dossier), html: { class: "form" } do |f|
%h2.fr-h4= t('views.users.dossiers.identite.identity_data')
%p.fr-text--sm= t('views.users.dossiers.identite.complete_data')
%p.fr-hint-text.fr-mb-3w= t('views.users.dossiers.identite.all_required')
%fieldset.fr-fieldset %fieldset.fr-fieldset
%legend.fr-fieldset__legend--regular.fr-fieldset__legend %legend.fr-fieldset__legend--regular.fr-fieldset__legend
= f.label :gender, t('activerecord.attributes.individual.gender') %h2.fr-h4= t('views.users.dossiers.identite.identity_data')
.fr-fieldset__element.fr-fieldset__element--inline .fr-fieldset__element
.fr-radio-group %fieldset.fr-fieldset
= f.radio_button :gender, Individual::GENDER_FEMALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_FEMALE}" %legend.fr-fieldset__legend--regular.fr-fieldset__legend
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_FEMALE}" } = t('activerecord.attributes.individual.gender')
= Individual.human_attribute_name('gender.female') = render EditableChamp::AsteriskMandatoryComponent.new
.fr-fieldset__element.fr-fieldset__element--inline .fr-fieldset__element
.fr-radio-group .fr-radio-group
= f.radio_button :gender, Individual::GENDER_MALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_MALE}" = f.radio_button :gender, Individual::GENDER_FEMALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_FEMALE}"
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_MALE}" } %label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_FEMALE}" }
= Individual.human_attribute_name('gender.male') = Individual.human_attribute_name('gender.female')
.fr-fieldset__element
.fr-radio-group
= f.radio_button :gender, Individual::GENDER_MALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_MALE}"
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_MALE}" }
= Individual.human_attribute_name('gender.male')
.flex .fr-fieldset__element.fr-fieldset__element--short-text
.inline-champ = render Dsfr::InputComponent.new(form: f, attribute: :prenom, opts: { autocomplete: 'given-name' })
= f.label :prenom, for: 'identite_champ_first_name', class: 'fr-label'
= f.text_field :prenom, class: 'fr-input', required: true, autocomplete: 'given-name', id: 'identite_champ_first_name'
.inline-champ
= f.label :nom, class: 'fr-label', for: 'identite_champ_last_name'
= f.text_field :nom, class: "fr-input", required: true, autocomplete: 'family-name', id: 'identite_champ_last_name'
.fr-fieldset__element.fr-fieldset__element--short-text
= render Dsfr::InputComponent.new(form: f, attribute: :nom, opts: { autocomplete: 'family-name' })
- if @dossier.procedure.ask_birthday? - if @dossier.procedure.ask_birthday?
.fr-input-group .fr-fieldset__element
= f.label :birthdate, class: "fr-label", for: 'identite_champ_birthdate' = render Dsfr::InputComponent.new(form: f, attribute: :birthdate, input_type: :date_field,
= f.date_field :birthdate, value: @dossier.individual.birthdate, placeholder: 'format : AAAA-MM-JJ', required: true, class: "fr-input", "aria-describedby" => "identite-champ-date-birthday", id: 'identite_champ_birthdate' opts: { placeholder: 'Format : AAAA-MM-JJ', max: Date.today.iso8601, min: "1900-01-01", autocomplete: 'bday' })
= f.submit t('views.users.dossiers.identite.continue'), class: "fr-btn fr-btn--lg fr-mt-4w" .fr-fieldset__element
= f.submit t('views.users.dossiers.identite.continue'), class: "fr-btn fr-btn--lg fr-my-2w"

View file

@ -12,7 +12,7 @@
.fr-fieldset__element .fr-fieldset__element
%p.fr-text--sm= t('views.users.dossiers.identite.complete_siret') %p.fr-text--sm= t('views.users.dossiers.identite.complete_siret')
.fr-fieldset__element .fr-fieldset__element.fr-fieldset__element--short-text
= render Dsfr::InputComponent.new form: f, attribute: :siret, opts: { placeholder: t('views.users.dossiers.identite.siret_placeholder') } = render Dsfr::InputComponent.new form: f, attribute: :siret, opts: { placeholder: t('views.users.dossiers.identite.siret_placeholder') }
.fr-fieldset__element .fr-fieldset__element

View file

@ -412,12 +412,10 @@ en:
identite: identite:
identity_data: Identity data identity_data: Identity data
identity_siret: Identify your establishment identity_siret: Identify your establishment
all_required: All fields are required.
civility: Civility civility: Civility
first_name: First Name first_name: First Name
last_name: Last Name last_name: Last Name
birthdate: Birth date birthdate: Birth date
complete_data: Complete your personal information to access the procedure.
complete_siret: Fill the SIRET number of your company, administration or association to start the procedure. complete_siret: Fill the SIRET number of your company, administration or association to start the procedure.
siret_help_html: To find your SIRET number, use %{annuaire_link} or ask your accounting department. siret_help_html: To find your SIRET number, use %{annuaire_link} or ask your accounting department.
siret_placeholder: 14-digit SIRET number siret_placeholder: 14-digit SIRET number

View file

@ -412,14 +412,12 @@ fr:
dossiers: dossiers:
archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire" archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire"
identite: identite:
identity_data: Données didentité identity_data: Identité du demandeur
identity_siret: Identifier votre établissement identity_siret: Identifier votre établissement
all_required: Tous les champs sont obligatoires.
civility: Civilité civility: Civilité
first_name: Prénom first_name: Prénom
last_name: Nom last_name: Nom
birthdate: Date de naissance birthdate: Date de naissance
complete_data: Renseignez vos informations personnelles pour accéder à la démarche.
complete_siret: Renseignez le numéro de SIRET de votre entreprise, administration ou association pour commencer la démarche. complete_siret: Renseignez le numéro de SIRET de votre entreprise, administration ou association pour commencer la démarche.
siret_help_html: Pour trouver votre numéro SIRET, utilisez %{annuaire_link} ou renseignez-vous auprès de votre service comptable. siret_help_html: Pour trouver votre numéro SIRET, utilisez %{annuaire_link} ou renseignez-vous auprès de votre service comptable.
siret_placeholder: Numéro SIRET à 14 chiffres siret_placeholder: Numéro SIRET à 14 chiffres

View file

@ -110,8 +110,8 @@ describe 'wcag rules for usager', js: true, retry: 3 do
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label', text: 'Monsieur') find('label', text: 'Monsieur')
fill_in('identite_champ_first_name', with: 'prenom') fill_in('Prénom', with: 'prenom')
fill_in('identite_champ_last_name', with: 'nom') fill_in('Nom', with: 'nom')
click_on 'Continuer' click_on 'Continuer'
expect(page).to be_axe_clean expect(page).to be_axe_clean

View file

@ -267,8 +267,8 @@ describe 'fetch API Particulier Data', js: true, retry: 3 do
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'prenom') fill_in('Prénom', with: 'prenom')
fill_in('identite_champ_last_name', with: 'nom') fill_in('Nom', with: 'nom')
click_button('Continuer') click_button('Continuer')
@ -326,8 +326,8 @@ describe 'fetch API Particulier Data', js: true, retry: 3 do
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'Georges') fill_in('Prénom', with: 'Georges')
fill_in('identite_champ_last_name', with: 'Moustaki') fill_in('Nom', with: 'Moustaki')
click_button('Continuer') click_button('Continuer')
@ -399,9 +399,9 @@ describe 'fetch API Particulier Data', js: true, retry: 3 do
visit commencer_path(path: procedure.path) visit commencer_path(path: procedure.path)
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label[for="identite_champ_radio_Mme"]').click find('label', text: 'Madame').click
fill_in('identite_champ_last_name', with: 'Dubois') fill_in('Prénom', with: 'Dubois')
fill_in('identite_champ_first_name', with: 'Angela Claire Louise') fill_in('Nom', with: 'Angela Claire Louise')
click_button('Continuer') click_button('Continuer')
@ -463,9 +463,9 @@ describe 'fetch API Particulier Data', js: true, retry: 3 do
visit commencer_path(path: procedure.path) visit commencer_path(path: procedure.path)
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label[for="identite_champ_radio_Mme"]').click find('label', text: 'Madame').click
fill_in('identite_champ_last_name', with: 'FERRI') fill_in('Nom', with: 'FERRI')
fill_in('identite_champ_first_name', with: 'Karine') fill_in('Prénom', with: 'Karine')
click_button('Continuer') click_button('Continuer')

View file

@ -263,8 +263,8 @@ describe 'The routing with rules', js: true, retry: 3 do
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'Prenom') fill_in('Prénom', with: 'Prenom')
fill_in('identite_champ_last_name', with: 'Nom') fill_in('Nom', with: 'Nom')
click_button('Continuer') click_button('Continuer')
# the old system should not be present # the old system should not be present

View file

@ -43,7 +43,7 @@ describe 'Signin in:' do
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last) expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
expect(page).to have_content(procedure.libelle) expect(page).to have_content(procedure.libelle)
expect(page).to have_content "Données didentité" expect(page).to have_content "Identité du demandeur"
end end
end end

View file

@ -566,7 +566,7 @@ describe 'The user' do
visit "/commencer/#{procedure.path}" visit "/commencer/#{procedure.path}"
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
expect(page).to have_content("Données didentité") expect(page).to have_content("Identité du demandeur")
expect(page).to have_current_path(identite_dossier_path(user_dossier)) expect(page).to have_current_path(identite_dossier_path(user_dossier))
end end
@ -581,8 +581,8 @@ describe 'The user' do
def fill_individual def fill_individual
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'prenom') fill_in('Prénom', with: 'prenom')
fill_in('identite_champ_last_name', with: 'nom') fill_in('Nom', with: 'nom')
click_on 'Continuer' click_on 'Continuer'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end end

View file

@ -22,8 +22,8 @@ describe 'Creating a new dossier:' do
expect(page).to have_title(libelle) expect(page).to have_title(libelle)
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'Prenom') fill_in('Prénom', with: 'Prenom')
fill_in('identite_champ_last_name', with: 'Nom') fill_in('Nom', with: 'Nom')
end end
shared_examples 'the user can create a new draft' do shared_examples 'the user can create a new draft' do
@ -41,7 +41,7 @@ describe 'Creating a new dossier:' do
let(:expected_birthday) { Date.new(1987, 10, 14) } let(:expected_birthday) { Date.new(1987, 10, 14) }
before do before do
fill_in 'identite_champ_birthdate', with: birthday_format fill_in 'Date de naissance', with: birthday_format
end end
context 'when the browser supports `type=date` input fields' do context 'when the browser supports `type=date` input fields' do

View file

@ -75,8 +75,8 @@ describe 'dropdown list with other option activated', js: true, retry: 3 do
def fill_individual def fill_individual
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'prenom') fill_in('Prénom', with: 'prenom')
fill_in('identite_champ_last_name', with: 'nom') fill_in('Nom', with: 'nom')
click_on 'Continuer' click_on 'Continuer'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end end

View file

@ -75,14 +75,14 @@ describe 'linked dropdown lists' do
expect(page).to have_current_path(commencer_path(path: procedure.path)) expect(page).to have_current_path(commencer_path(path: procedure.path))
click_on 'Commencer la démarche' click_on 'Commencer la démarche'
expect(page).to have_content("Données didentité") expect(page).to have_content("Identité du demandeur")
expect(page).to have_current_path(identite_dossier_path(user_dossier)) expect(page).to have_current_path(identite_dossier_path(user_dossier))
end end
def fill_individual def fill_individual
find('label', text: 'Monsieur').click find('label', text: 'Monsieur').click
fill_in('identite_champ_first_name', with: 'prenom') fill_in('Prénom', with: 'prenom')
fill_in('identite_champ_last_name', with: 'nom') fill_in('Nom', with: 'nom')
click_on 'Continuer' click_on 'Continuer'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end end