SPB Git

spb/fabri-ka

Public

Agrégateur de produits québécois — www.fabri-ka.com

3.3 KB · 102 lines tsx
1import { FormEvent, useEffect, useRef, useState } from 'react'2import { useLocation, useNavigate } from 'react-router-dom'3import { IconClose, IconSearch } from './Icons'4import KaTabbar from '../ka/KaTabbar'56/**7 * Mobile bottom tab bar (<768px) — Accueil, Produits, Boutiques, Recherche.8 * "Recherche" opens a full-screen search overlay with an autofocused input.9 */10export default function BottomNav() {11  const [searchOpen, setSearchOpen] = useState(false)12  const [query, setQuery] = useState('')13  const inputRef = useRef<HTMLInputElement>(null)14  const navigate = useNavigate()15  const location = useLocation()1617  // Close the overlay on navigation.18  useEffect(() => {19    setSearchOpen(false)20  }, [location.pathname, location.search])2122  // Autofocus + scroll lock while the overlay is open.23  useEffect(() => {24    if (!searchOpen) return25    document.documentElement.classList.add('ka-scroll-lock')26    const t = window.setTimeout(() => inputRef.current?.focus(), 60)27    const onKey = (e: KeyboardEvent) => {28      if (e.key === 'Escape') setSearchOpen(false)29    }30    window.addEventListener('keydown', onKey)31    return () => {32      document.documentElement.classList.remove('ka-scroll-lock')33      window.clearTimeout(t)34      window.removeEventListener('keydown', onKey)35    }36  }, [searchOpen])3738  function onSubmit(e: FormEvent) {39    e.preventDefault()40    const q = query.trim()41    setSearchOpen(false)42    setQuery('')43    navigate(q ? `/produits?q=${encodeURIComponent(q)}` : '/produits')44  }4546  return (47    <>48      {searchOpen && (49        <div50          className="search-overlay"51          role="dialog"52          aria-modal="true"53          aria-label="Recherche"54        >55          <div className="search-overlay-bar">56            <form className="search-overlay-form" onSubmit={onSubmit} role="search">57              <span className="search-overlay-icon" aria-hidden="true">58                <IconSearch size={18} />59              </span>60              <input61                ref={inputRef}62                type="search"63                value={query}64                onChange={(e) => setQuery(e.target.value)}65                placeholder="Rechercher un produit québécois…"66                aria-label="Rechercher"67                enterKeyHint="search"68              />69            </form>70            <button71              type="button"72              className="search-overlay-close"73              onClick={() => setSearchOpen(false)}74              aria-label="Fermer la recherche"75            >76              <IconClose size={22} />77            </button>78          </div>79          <p className="search-overlay-hint">80            Produits fabriqués, conçus et vendus au Québec.81          </p>82        </div>83      )}8485      <KaTabbar86        theme="dark"87        tabs={[88          { label: 'Accueil', icon: 'home', to: '/', active: location.pathname === '/' },89          {90            label: 'Produits',91            icon: 'grid',92            to: '/produits',93            active: ['/produits', '/categorie', '/region'].some((r) => location.pathname.startsWith(r)),94          },95          { label: 'Boutiques', icon: 'store', to: '/boutiques', active: location.pathname.startsWith('/boutiques') },96          { label: 'Recherche', icon: 'search', onPress: () => setSearchOpen(true), active: searchOpen },97        ]}98      />99    </>100  )101}102
Files · 9f0b379f746232cdbfc2b15ddcf9df30a5c71418
Menu

Theme