SPB Git

spb/fabri-ka Public

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

HTML 57% Python 19.9% TypeScript 15.3% CSS 7.7%
2.3 KB · 89 lines tsx
Raw Blame History
1import { useEffect } from 'react'2import { Facets, formatInt } from '../api'3import { FiltersBody, FilterValues } from './Filters'4import { IconClose } from './Icons'56interface Props {7  open: boolean8  facets: Facets | null9  values: FilterValues10  total: number | null11  onChange: (patch: Partial<FilterValues>) => void12  onReset: () => void13  onClose: () => void14}1516/**17 * Mobile slide-up bottom sheet holding all catalog filters.18 * Backdrop tap or the close button dismisses it; filters apply live,19 * the footer button confirms and closes.20 */21export default function FilterSheet({22  open,23  facets,24  values,25  total,26  onChange,27  onReset,28  onClose,29}: Props) {30  // Scroll lock + Escape to close while open.31  useEffect(() => {32    if (!open) return33    document.body.style.overflow = 'hidden'34    const onKey = (e: KeyboardEvent) => {35      if (e.key === 'Escape') onClose()36    }37    window.addEventListener('keydown', onKey)38    return () => {39      document.body.style.overflow = ''40      window.removeEventListener('keydown', onKey)41    }42  }, [open, onClose])4344  if (!open) return null4546  return (47    <div className="sheet-root">48      <div className="sheet-backdrop" onClick={onClose} aria-hidden="true" />49      <div50        className="sheet"51        role="dialog"52        aria-modal="true"53        aria-label="Filtres"54      >55        <div className="sheet-handle" aria-hidden="true" />56        <header className="sheet-header">57          <h2>Filtres</h2>58          <button59            type="button"60            className="sheet-close"61            onClick={onClose}62            aria-label="Fermer les filtres"63          >64            <IconClose size={20} />65          </button>66        </header>67        <div className="sheet-content">68          <FiltersBody69            facets={facets}70            values={values}71            onChange={onChange}72            idPrefix="sheet-"73          />74        </div>75        <footer className="sheet-footer">76          <button type="button" className="btn btn-secondary" onClick={onReset}>77            Réinitialiser78          </button>79          <button type="button" className="btn btn-primary" onClick={onClose}>80            {total !== null81              ? `Voir ${formatInt(total)} produit${total === 1 ? '' : 's'}`82              : 'Voir les produits'}83          </button>84        </footer>85      </div>86    </div>87  )88}89