Planning — Semaine & Jour
La grille horaire : les jours en colonnes, les heures en profondeur, et les événements en rectangles placés. C'est la vue qui exerce enfin le calcul de chevauchement et l'échelle temps-pixels.
Scheduler — la grille horaire
La vue où un événement cesse d'être une ligne et devient un rectangle placé : le haut vient de son début, la hauteur de sa durée, et la largeur se partage avec ce qui le recouvre. Un seul composant sert Jour et Semaine — la fenêtre dit déjà s'il y a une colonne ou sept.
Semaine
Trois bandes, et une seule défile : les noms de jours et la bande « journée entière » restent en place pendant que les heures glissent dessous. La grille s'ouvre sur scrollTime et non sur minuit, mais les bornes couvrent bien les 24 h — les restreindre masquerait une astreinte de nuit sans le dire.
onEventClick → —
Déplacer, étirer, créer — movable, resizable, creatable
Trois gestes, trois props, toutes éteintes par défaut. Déplacer : à la souris on prend le bloc et on le pose ; au doigt on appuie une demi-seconde puis on glisse — le temps que le geste se distingue d'un défilement. Étirer : au survol, une poignée apparaît sur chaque bord réel. Créer : on trace sur une plage vide, ou on clique. Dans tous les cas la position d'origine reste en place, grisée, un aperçu suit le pointeur, et rien n'est recalculé avant le relâché — refaire le partage des colonnes à chaque image ferait sauter le bloc sous le doigt. Les bords s'aimantent au quart d'heure (snapMinutes), indépendamment du pas de la grille. Échap annule, et près d'un bord la zone défile toute seule.
L'inventaire ne bouge pas : isEventMovable le refuse. Un geste qui ne ferait rien au relâché n'est pas proposé du tout — le curseur ne change même pas, et les poignées n'apparaissent pas.
Créer rapporte une plage à onEventCreate ; ici le rappel renvoie un objet, et la grille le pose. Renvoyer un objet est ce qui fait apparaître l'événement — sans retour, rien n'est ajouté et c'est à l'application de créer, ce que fera l'ouverture d'un éditeur. La librairie n'invente jamais d'identifiant : une clé inventée est une collision inventée. Un clic vaut une plage de createDuration ; tracer une durée plus courte que le pas donne le pas.
onChange → —
Même règle sans qu'on ait à l'écrire : les occurrences d'une règle récurrente (le cycle d'initiation, le club de lecture) refusent le glisser comme l'étirement, car écrire le patch déplacerait toute la série. Les événements datés de la même grille, eux, se déplacent.
Le chevauchement, enfin à l’écran
layoutOverlaps est livré depuis le lot 1 et n'avait jamais rien dessiné. Jeudi, trois événements se recouvrent : ils se partagent la colonne, et celui qui n'a personne à côté de lui à un instant donné s'étend pour occuper la place libre.
Jour
La même grille, une seule colonne. Rien à changer : c'est la fenêtre qui décide, pas le composant.
pixelsPerHour et slotDuration
Le zoom et le pas de la grille sont deux réglages distincts — comme le sont le pas de la grille et l'aimant du glisser. Ici : 32 px/h avec un trait à l'heure, puis 64 px/h avec un trait au quart d'heure.
32 px/h · slot 60
64 px/h · slot 15
Au clavier
Tabuler amène sur chaque bloc — ce sont des boutons depuis le début, ils ont enfin un anneau de focus et une étiquette qui dit l'événement en entier : le titre, le jour, les deux bornes, et l'état quand il y en a un. Entrée ouvre la fiche.
| ↑↓ | Déplacer d'un pas (snapMinutes) |
| ←→ | Changer de jour |
| Maj↑↓ | Tirer le bord de fin |
| Enter | Valider |
| Esc | Remettre en place |
Sur un bloc déplaçable, les flèches font le reste. Rien n'est écrit avant Entrée : les flèches construisent un aperçu — l'original reste en place, grisé — et Échap le remet. Une touche qui écrirait ferait dix enregistrements pour traverser une matinée.
Chaque pas est annoncé dans une région live invisible, ainsi que chaque changement commis, y compris à la souris. Sans ça, une flèche déplace quelque chose que personne n'entend bouger.
Ce qui n'est pas fait est dit : pas de navigation aux flèches d'un bloc à l'autre ni d'une case de mois à l'autre. Ce serait le contrat de role="grid", que le composant ne revendique pas — une promesse non tenue vaut moins que pas de promesse.
Au doigt — interactive
Une prop pour les quatre : interactive allume le déplacement, l'étirement, la création et la fiche. Les quatre et pas trois — sans la fiche, resizable promettrait à un doigt un geste qu'il ne peut pas faire, puisque les poignées font huit pixels et n'existent qu'au survol. Chacune des quatre reste prioritaire si on la passe : interactive avec resizable={ false } est un calendrier où l'on déplace sans étirer.
jeudi 13 août
vendredi 14 août
Ouvrir. Sur téléphone la vue par défaut est l'agenda, et une ligne d'agenda ouvre désormais la fiche. C'est le seul chemin qu'un doigt ait vers une réservation : ici il n'y a ni axe où tracer, ni bord à tirer.
Créer. Taper un créneau vide de la grille donne createDuration, exactement comme un clic à la souris. Un doigt qui s'attarde fait mûrir le geste sans l'avoir demandé : tant qu'il ne quitte pas le pas où il s'est posé, on lui rend un clic et non une plage d'un quart d'heure.
Redimensionner. Au doigt, ça se corrige dans le formulaire et pas au bord : ouvrir la fiche, Modifier, changer l'heure de fin. Une poignée de huit pixels au survol n'a aucun sens sur un écran tactile, et en inventer une de quatorze en cacherait le déplacement.
Le mois n'a pas d'heures. Taper un jour ouvre sa fiche, et « Nouveau » y crée un événement d'une journée entière — décider qu'un rendez-vous commence à neuf heures serait une invention ; c'est le formulaire qui choisit l'heure.
Et le bouton « Nouveau » de la barre : c'est la création sans pointeur, la seule que le clavier et l'agenda puissent atteindre. Elle vise la prochaine heure ronde du jour regardé, et le formulaire corrige. showCreateButton l'enlève pour qui place le sien.
Étroit, elle défile
Les colonnes gardent une largeur plancher et la zone défile latéralement. Écraser sept jours dans un téléphone ne rend pas la semaine lisible, ça la rend fausse — c'est justement pour ça que l'agenda existe.