- Campo universal de ubicación (Google Maps/Waze/OSM/coordenadas/dirección) sobre proveedores extensibles (src/utils/ubicacion) con resolver e inferencia inversa Nominatim (nombre/provincia pre-rellenados, alias cooficiales) - FAB flotante abajo a la derecha que abre la pasarela en un modal accesible (Escape, foco contenido, responsive); sin descripción ni puntuación; avisos de duplicado y filtro de palabras dentro del modal - Aviso PWA reposicionado: tarjeta abajo a la izquierda en móvil, botón compacto arriba a la izquierda en PC (no tapa el FAB) - Suite de pruebas: 88 unitarias/componente (vitest + RTL, offline) y 10 de integración (supertest + SQLite :memory: y Nominatim real opt-in) - CI: workflow de Gitea Actions con npm test + build en push/PR e integración manual
61 lines
2.2 KiB
React
61 lines
2.2 KiB
React
import { useState } from "react";
|
|
|
|
const TEXTO_TOOLTIP = "Añade un nuevo local al directorio";
|
|
|
|
// Botón de acción flotante (FAB) para proponer un local: fijo en la esquina
|
|
// inferior derecha, visible en PC y móvil, respetando la barra de la PWA con
|
|
// env(safe-area-inset-bottom). Su z-index queda por debajo del modal de la
|
|
// pasarela (1000) y del toast (2000). Muestra un tooltip propio al hacer
|
|
// hover o recibir foco (posicionado a la izquierda) y expone aria-label
|
|
// para accesibilidad sin ratón.
|
|
export default function BotonFlotante({ onClick }) {
|
|
const [tooltipVisible, setTooltipVisible] = useState(false);
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: "fixed",
|
|
right: 16,
|
|
bottom: 0,
|
|
zIndex: 900,
|
|
paddingBottom: "env(safe-area-inset-bottom)",
|
|
}}
|
|
>
|
|
<div style={{ position: "relative", marginBottom: 16 }}>
|
|
<button
|
|
type="button"
|
|
onClick={onClick}
|
|
aria-label={TEXTO_TOOLTIP}
|
|
onMouseEnter={() => setTooltipVisible(true)}
|
|
onMouseLeave={() => setTooltipVisible(false)}
|
|
onFocus={() => setTooltipVisible(true)}
|
|
onBlur={() => setTooltipVisible(false)}
|
|
style={{
|
|
display: "flex", alignItems: "center", justifyContent: "center",
|
|
width: 54, height: 54, borderRadius: "50%",
|
|
background: "#8B0000", color: "white", border: "none",
|
|
boxShadow: "0 4px 14px rgba(139,0,0,0.4)",
|
|
fontSize: 24, cursor: "pointer",
|
|
}}
|
|
>
|
|
<i className="ti ti-plus" aria-hidden="true"></i>
|
|
</button>
|
|
{tooltipVisible && (
|
|
<span
|
|
role="tooltip"
|
|
style={{
|
|
position: "absolute", right: "calc(100% + 10px)", top: "50%", transform: "translateY(-50%)",
|
|
background: "var(--color-text-primary)", color: "var(--color-background-primary)",
|
|
padding: "6px 10px", borderRadius: "var(--border-radius-md)",
|
|
fontSize: 12, fontWeight: 500, whiteSpace: "nowrap", pointerEvents: "none",
|
|
boxShadow: "0 4px 12px rgba(0,0,0,0.25)",
|
|
}}
|
|
>
|
|
{TEXTO_TOOLTIP}
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|