Liste déroulante

C’est un vrai <select> avec le menu déroulant du navigateur — ce qui veut dire qu’il marche sans JavaScript, s’ouvre correctement sur un téléphone, et se parcourt au clavier sans rien devoir à cette bibliothèque.

select() est le contrôle nu ; selectField() l’enveloppe d’un libellé, d’un texte d’aide et d’un message d’erreur, comme le fait textField().

Liste de base

Les options peuvent être de simples chaînes, auquel cas la valeur et le libellé sont identiques.

selectField({
  label: 'Thème',
  name: 'theme',
  options: ['Clair', 'Sombre', 'Système'],
})

Valeurs et libellés

Passez des objets quand la valeur soumise diffère du texte lu par une personne. value marque l’option sélectionnée.

selectField({
  label: 'Sortie',
  name: 'output',
  value: 'dist',
  options: [
    { value: 'dist', label: 'dist/ — le défaut' },
    { value: 'build', label: 'build/' },
    { value: 'public', label: 'public/', disabled: true },
  ],
})

Texte indicatif

Un placeholder devient une première option désactivée, sélectionnée quand value est absent — le champ démarre donc vide sans être un choix valable.

selectField({
  label: 'Cible de déploiement',
  name: 'target',
  placeholder: 'Choisissez un hébergeur…',
  options: ['Netlify', 'Vercel', 'Cloudflare Pages', 'GitHub Pages'],
})

Groupes

Une entrée avec son propre tableau options devient un <optgroup>.

selectField({
  label: 'Extension de page',
  name: 'ext',
  value: '.ht.js',
  options: [
    { label: 'JavaScript', options: ['.ht.js', '.html.js'] },
    { label: 'TypeScript', options: ['.ht.ts', '.html.ts'] },
    { label: 'JSX', options: ['.ht.jsx', '.ht.tsx'] },
  ],
})

Tailles

stack({ gap: 'md' },
  selectField({ label: 'Petite', name: 'sm', size: 'sm', options: ['Un', 'Deux'] }),
  selectField({ label: 'Moyenne', name: 'md', size: 'md', options: ['Un', 'Deux'] }),
  selectField({ label: 'Grande', name: 'lg', size: 'lg', options: ['Un', 'Deux'] }),
)

Aide, erreur et désactivation

Sert à l’attribut lang du html.
Choisissez un framework pour continuer.
stack({ gap: 'lg' },
  selectField({
    label: 'Langue',
    name: 'locale',
    options: ['en', 'es', 'fr'],
    help: 'Sert à l’attribut lang du html.',
  }),
  selectField({
    label: 'Framework',
    name: 'framework',
    placeholder: 'Choisissez-en un…',
    options: ['sitelo'],
    error: 'Choisissez un framework pour continuer.',
  }),
  selectField({
    label: 'Formule',
    name: 'plan',
    options: ['Gratuite'],
    disabled: true,
  }),
)

À partir de données

Les options ne sont qu’un tableau : elles viennent donc en général de ce que data() a déjà chargé pour la page.

return (() => {
  const posts = [
    { slug: 'hello-world', title: 'Bonjour le monde' },
    { slug: 'static-first', title: 'Le statique d’abord' },
    { slug: 'no-runtime', title: 'Aucun runtime' },
  ]

  return selectField({
    label: 'Billet à la une',
    name: 'featured',
    value: 'static-first',
    options: posts.map((post) => ({ value: post.slug, label: post.title })),
  })
})()

Props

PropTypeDéfautDescription
optionsSelectOption[][]Des chaînes, des objets { value, label, disabled }, ou { label, options } pour un groupe.
valuestring | number—L’option sélectionnée.
placeholderstring—Première option désactivée, sélectionnée en l’absence de valeur.
size'sm' | 'md' | 'lg''md'Hauteur du contrôle et taille du texte.
namestring—Nom du champ ; l’id en découle.
invalidbooleanfalsePose aria-invalid. selectField le fait pour vous à partir d’error.
disabledbooleanfalseDésactive le contrôle.

selectField() prend en plus label, help, error, required et fieldClass — voir textField(). Les enfants sont ajoutés après les options générées : vous pouvez donc en écrire à la main.