/** * I bottoni, uno per ruolo, con una forma sola per ruolo. * * I tester della schermata Modifica non distinguevano un bottone da * un'etichetta: tutto era testo terracotta, e spento voleva dire grigio come * le etichette. Da qui le regole, disegnate nel campionario * docs/design/campionari/modifica.html: * * - `BottonePrincipale`: pieno di accento, uno al massimo per schermata; * - `BottoneSecondario`: fondo `accentoTenue`, scritta accento, sempre col * segno, per le azioni frequenti («Aggiungi», «Incolla elenco»); * - `ComandoLeggero`: solo scritta e segno, per le azioni rare. Mai senza * segno: senza, è identico a un'etichetta colorata; * - `PillolaSalva`: il principale della barra. * * Spento vuol dire la STESSA forma, grigia: fondo `bordo` e scritta * `testoTenue` (4,54:1 nel chiaro, 5,18:1 nello scuro). La forma resta, e si * capisce che è un bottone che adesso non va, non una scritta. * * I colori non si scrivono qui: vengono da tema.ts, come nelle altre schermate. */ import { useMemo } from 'react'; import type { StyleProp, ViewStyle } from 'react-native'; import { Pressable, StyleSheet, Text } from 'react-native'; import type { ChiaveSegno } from '../segni.ts'; import type { Colori } from '../tema.ts'; import { RAGGIO, SPAZIO, TESTO, useColori } from '../tema.ts'; import Segno from './Segno.tsx'; interface PropsBottone { testo: string; onPress: () => void; spento?: boolean; segno?: ChiaveSegno; stile?: StyleProp; accessibilityLabel?: string; } export function BottonePrincipale({ testo, onPress, spento = false, segno, stile, accessibilityLabel }: PropsBottone) { const colori = useColori(); const stili = useMemo(() => creaStili(colori), [colori]); const colore = spento ? colori.testoTenue : colori.accentoSopra; return ( [stili.principale, spento ? stili.spento : null, pressed ? stili.premuto : null, stile]} > {segno !== undefined ? : null} {testo} ); } export function BottoneSecondario({ testo, onPress, spento = false, segno, stile, accessibilityLabel }: PropsBottone) { const colori = useColori(); const stili = useMemo(() => creaStili(colori), [colori]); const colore = spento ? colori.testoTenue : colori.accento; return ( [stili.secondario, spento ? stili.spento : null, pressed ? stili.premuto : null, stile]} > {segno !== undefined ? : null} {testo} ); } export function ComandoLeggero({ testo, onPress, segno, pericolo = false, stile, accessibilityLabel, }: PropsBottone & { segno: ChiaveSegno; pericolo?: boolean }) { const colori = useColori(); const stili = useMemo(() => creaStili(colori), [colori]); const colore = pericolo ? colori.errore : colori.accento; return ( [stili.leggero, pressed ? stili.premuto : null, stile]} > {testo} ); } /** «Salva» nella barra: una pillola piena quando si può, grigia quando no. */ export function PillolaSalva({ testo, onPress, spento = false }: PropsBottone) { const colori = useColori(); const stili = useMemo(() => creaStili(colori), [colori]); return ( [stili.pillola, spento ? stili.spento : null, pressed ? stili.premuto : null]} > {testo} ); } const creaStili = (colori: Colori) => StyleSheet.create({ principale: { minHeight: 50, borderRadius: RAGGIO.riga, backgroundColor: colori.accento, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: SPAZIO.s, paddingHorizontal: SPAZIO.l, }, principaleTesto: { ...TESTO.corpo, fontWeight: '600' }, secondario: { minHeight: 44, borderRadius: RAGGIO.campo, backgroundColor: colori.accentoTenue, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 6, paddingHorizontal: SPAZIO.m, }, secondarioTesto: { ...TESTO.etichetta, fontWeight: '600' }, leggero: { minHeight: 44, flexDirection: 'row', alignItems: 'center', gap: 6, alignSelf: 'flex-start' }, pillola: { minHeight: 34, borderRadius: RAGGIO.tondo, backgroundColor: colori.accento, paddingHorizontal: SPAZIO.l, alignItems: 'center', justifyContent: 'center', }, pillolaTesto: { ...TESTO.etichetta, fontWeight: '600' }, spento: { backgroundColor: colori.bordo }, premuto: { opacity: 0.6 }, });