expria-frontend/src/features/simulations/components/SpecialCharsKeyboard.tsx
Hermann_Kitio b68f160bce feat(design-system): reskin Charcoal — tokens dark-default + sidebar navy permanent
- Remplacement intégral index.css par palette Charcoal (DESIGN_SYSTEM.md v2.0)
- Dark = thème par défaut, .light = override via @custom-variant light
- Sidebar navy #0C1528 permanent (identique dark+light)
- Script anti-FOUC inline dans index.html
- Layout : radial-gradient sur <main>, sidebar 230px, max-w-[1100px]
- Renommage tokens Boréal→Charcoal sur ~45 composants
- Inversion dark: → baseline + light: sur primitives shadcn
- Fix logo blanc forcé dans sidebar
- ADR 006 mis à jour

Typecheck: OK · Tests: 122/122 

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 23:09:15 +03:00

75 lines
1.8 KiB
TypeScript

/**
* Clavier de caractères spéciaux français pour la zone de saisie.
*
* Affiche une rangée horizontale scrollable de 30 caractères accentués
* (15 minuscules + 15 majuscules). Un clic insère le caractère à la
* position du curseur via le callback `onInsert`.
*
* Règle H : purement présentationnel, la logique d'insertion est dans le parent.
* Règle L : tokens Direction H exclusivement.
*
* `onMouseDown preventDefault` empêche le textarea de perdre le focus au clic,
* ce qui permet de conserver la position du curseur lors de l'insertion.
*/
const SPECIAL_CHARS = [
'à',
'â',
'é',
'è',
'ê',
'ë',
'î',
'ï',
'ô',
'ù',
'û',
'ü',
'ç',
'œ',
'æ',
'À',
'Â',
'É',
'È',
'Ê',
'Ë',
'Î',
'Ï',
'Ô',
'Ù',
'Û',
'Ü',
'Ç',
'Œ',
'Æ',
] as const
interface Props {
onInsert: (char: string) => void
disabled?: boolean
}
export function SpecialCharsKeyboard({ onInsert, disabled = false }: Props) {
return (
<div
role="toolbar"
aria-label="Caractères spéciaux"
className="flex flex-wrap gap-1.5 rounded-md border border-border bg-surface p-2"
>
{SPECIAL_CHARS.map((char) => (
<button
key={char}
type="button"
disabled={disabled}
onMouseDown={(e) => e.preventDefault()}
onClick={() => onInsert(char)}
aria-label={`Insérer le caractère ${char}`}
className="size-8 shrink-0 rounded-md border border-border bg-surface text-sm font-medium text-ink-primary transition-colors hover:border-brand hover:bg-brand-soft hover:text-brand-text focus:border-brand focus:outline-none focus:shadow-focus disabled:cursor-not-allowed disabled:opacity-50"
>
{char}
</button>
))}
</div>
)
}