/** * L'intestazione delle schermate su Android: la nostra, non quella di sistema. * * Sull'iPhone, dal 01/10, la barra è quella di sistema, di vetro * (useIntestazione, il perché in logica-intestazione.ts), e questa non si * disegna. Su Android resta questa, com'era: la si era fatta nostra perché il * pulsante indietro nativo si porta dietro il titolo della schermata di * partenza («‹ Quanto Basta»), lungo, che si tronca da solo. * * Quello che NON si perde togliendo l'header nativo: la transizione fra le * schermate e il gesto di trascinare dal bordo per tornare indietro restano, * perche' sono del navigatore e non della barra. * * Il titolo sta in mezzo e i due lati hanno la stessa larghezza minima, cosi' * resta centrato sullo schermo anche quando a destra c'e' un comando solo. Con * un titolo lungo si tronca invece di spingere via i comandi. */ import type { ReactNode } from 'react'; import { useMemo } from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import type { Colori } from '../tema.ts'; import { SPAZIO, TESTO, useColori } from '../tema.ts'; import Segno from './Segno.tsx'; export interface PropsBarra { /** Se c'e', compare la freccia. Se manca, la barra non ha nulla a sinistra. */ onIndietro?: () => void; /** L'etichetta della freccia, tradotta da chi chiama. */ etichettaIndietro?: string; /** Il titolo al centro. Stringa vuota o assente: niente titolo. */ titolo?: string; /** Il colore del titolo, per l'elenco che prende la tinta della categoria. */ coloreTitolo?: string; /** Al posto del titolo: serve al marchio della schermata principale. */ centro?: ReactNode; /** I comandi a destra. */ azioni?: ReactNode; } export default function Barra({ onIndietro, etichettaIndietro, titolo, coloreTitolo, centro, azioni, }: PropsBarra) { const colori = useColori(); const stili = useMemo(() => creaStili(colori), [colori]); // Il notch, la Dynamic Island, la barra di stato: quanto scendere prima di // disegnare. Lo sa il sistema, non lo si indovina con un numero. const alto = useSafeAreaInsets().top; return ( {onIndietro !== undefined && ( [stili.tasto, pressed && stili.premuto]} > )} {centro ?? (titolo !== undefined && titolo !== '' ? ( {titolo} ) : null)} {azioni} ); } const creaStili = (colori: Colori) => StyleSheet.create({ barra: { flexDirection: 'row', alignItems: 'center', backgroundColor: colori.fondo, paddingHorizontal: SPAZIO.m, paddingBottom: SPAZIO.s, // Niente linea sotto e niente ombra: il fondo e' lo stesso della // schermata, e la barra si separa dal contenuto con lo spazio. }, /** * I due lati hanno la stessa larghezza minima cosi' il titolo resta al * centro dello SCHERMO e non al centro dello spazio che avanza: con un * comando solo a destra, senza questo, il titolo starebbe storto. */ lato: { minWidth: 44, flexDirection: 'row', alignItems: 'center' }, azioni: { justifyContent: 'flex-end', gap: SPAZIO.m }, centro: { flex: 1, alignItems: 'center', justifyContent: 'center', minHeight: 44 }, titolo: { ...TESTO.titolo, color: colori.testo, textAlign: 'center' }, tasto: { width: 40, height: 40, alignItems: 'center', justifyContent: 'flex-start', flexDirection: 'row' }, premuto: { opacity: 0.5 }, });