WoodyLab
WoodyLabBuild with UIMS

Documentazione · src/react/components

I componenti

Sessanta file, quattro famiglie. Nessuno di loro sa quale blocco l’ha generato: leggono da `data` e disegnano.

Struttura e contenuto

La famiglia più numerosa e la più silenziosa: componenti che disegnano e basta. Tag, classi, slot. Sono componenti server, non entrano nel bundle, e sono quelli che si sostituiscono più facilmente — un `Card` diverso è un componente nuovo nella mappa e un viewMode che lo nomina.

  • components/Box.tsx — il contenitore generico
  • components/Container.tsx — il contenitore con larghezza e centratura
  • components/Section.tsx — la sezione di pagina
  • components/Card.tsx — la card
  • components/Text.tsx — un testo con un ruolo (titolo, eyebrow, label)
  • components/RichText.tsx — il Lexical di Payload, con i convertitori per i link interni
  • components/Figure.tsx — immagine con `fill`, alt e didascalia
  • components/Icon.tsx — un’icona dal catalogo
  • components/Avatar.tsx — immagine circolare con fallback
  • components/Separator.tsx — il separatore
  • components/Progress.tsx — la barra di avanzamento
  • components/View.tsx — il guscio di una vista: la griglia che tiene le righe

La cornice del sito

Header, footer, navigazione, il selettore di tema, l’indice di pagina: le cose che stanno intorno al contenuto. Sono componenti come gli altri — nessun trattamento speciale — ma di solito sono montati da un global invece che da una pagina.

`Scrollspy` merita una nota: costruisce l’indice leggendo il DOM, non i dati. Cerca le sezioni con un selettore e per ognuna il primo titolo; una sezione senza titolo viene saltata. Questo lo rende utilizzabile su qualunque pagina senza doverla predisporre.

  • components/Header.tsx — l’intestazione del sito
  • components/Footer.tsx — il piede
  • components/Navigation.tsx — il menu, con la parte client per gli stati aperti
  • components/NavigationClient.tsx — la parte interattiva della navigazione
  • components/ThemeSwitch.tsx — il selettore di tema
  • components/Scrollspy.tsx — l’indice di pagina, costruito dal DOM
  • components/TopProgressBar.tsx — la barra di avanzamento della lettura
  • components/Action.tsx — link, bottone o comando: un solo componente, il tipo lo dice il dato

Gli interattivi, e i loro wrapper

Otto componenti hanno stato: accordion, collapsible, tabs, toggle, gruppo di toggle, swiper, hover card, dialog. Ognuno è diviso in due file — la parte server che disegna e il wrapper client che tiene lo stato — e il wrapper registra la propria slice nello store invece di tenere uno stato React privato.

La differenza non è accademica. Uno stato React privato è raggiungibile solo dall’interno del componente; una slice nello store ha un indirizzo, quindi qualcun altro può leggerla o cambiarla — un bottone in fondo alla pagina può aprire l’accordion in cima senza che i due si conoscano.

I nomi delle slice sono dichiarati come dato, non decisi dentro il componente: `open` è booleano, `active` dice quale figlio, `pressed` è booleano, `value` è il valore di un gruppo, `index` è una posizione. Il vocabolario è di cinque parole ed è verificato da un test, perché la stessa parola con due significati è il tipo di ambiguità che non dà nessun errore.

  • components/Accordion.tsx + AccordionClientWrapper.tsx — slice `active`: quale sezione è aperta
  • components/Collapsible.tsx + CollapsibleClientWrapper.tsx — slice `open`: aperto o chiuso
  • components/Tabs.tsx + TabsClientWrapper.tsx — slice `active`: quale scheda
  • components/Toggle.tsx + ToggleClientWrapper.tsx — slice `pressed`
  • components/ToggleGroup.tsx + ToggleGroupClientWrapper.tsx — slice `value`: il valore del gruppo
  • components/Swiper.tsx + SwiperClientWrapper.tsx — slice `index`: la slide corrente
  • components/HoverCard.tsx + HoverCardClientWrapper.tsx — il pannello che appare al passaggio
  • components/AlertDialog.tsx + AlertDialogClientWrapper.tsx — il dialogo modale
  • components/ActionClientWrapper.tsx — la parte client di un’azione: click, comandi, eventi

I form

Dodici file per una cosa sola: un form in cui i controlli si registrano da soli in un contesto, e il contesto sa raccogliere, validare e inviare. Il componente `Form` monta il contesto; ogni input dichiara il proprio nome e il resto viene da sé.

Ogni input è un componente normale, quindi ha i suoi viewMode e si può ridisegnare senza toccare la logica: cambiare l’aspetto di una checkbox non ha niente a che vedere con l’invio.

  • components/Form/Form.tsx + FormClientWrapper.tsx — il form e la sua parte client
  • components/Form/FormContext.tsx — valori, errori, invio: il contesto a cui i controlli si registrano
  • components/Form/FormControl.tsx — il controllo generico: label, input, errore
  • components/Form/FormLabel.tsx + FormError.tsx — etichetta e messaggio di errore
  • components/Form/FormInputText.tsx — testo, email, numero
  • components/Form/FormInputSelect.tsx + FormInputRadio.tsx + FormInputCheckbox.tsx — le scelte
  • components/Form/FormInputSwitch.tsx + FormInputSlider.tsx — interruttore e cursore

I componenti dell’editor

Sette componenti che esistono per la AdminBar: la sezione modificabile, l’albero delle sezioni, gli slot editabili, i campi. Vivono qui e non in `admin/` perché sono componenti a tutti gli effetti — hanno viewMode, stanno nella mappa, li risolve lo stesso motore.

Usano però un tema a parte, `admin`, invece di `uims`. La ragione è concreta: la AdminBar esiste per cambiare l’aspetto del sito, e se prendesse la propria forma dai viewMode che sta modificando basterebbe un tema sbagliato per non riuscire più a rimetterlo a posto.

  • components/admin/AdminSection.tsx + AdminSectionTree.tsx — la sezione modificabile e l’albero
  • components/admin/AdminSlot.tsx — uno slot editabile
  • components/admin/AdminText.tsx + AdminRichTextField.tsx — i campi di testo
  • components/admin/AdminUploadField.tsx — il campo immagine
  • components/admin/AdminAction.tsx — i comandi dell’editor
Login