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%
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