Files
localesp/src/components/BotonFlotante.jsx
T
edgar.friendly 003b1e209f
deploy-branch / deploy (push) Failing after 6s
deploy-branch / teardown (push) Skipped
feat(propuesta): pasarela paso a paso con autodetección de ubicación y FAB
- 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
2026-08-16 01:35:02 +02:00

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>
);
}