mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
close filter on apply
This commit is contained in:
@@ -17,12 +17,13 @@ export type Props = {
|
||||
className?: string,
|
||||
ref?: MutableRefObject<undefined>
|
||||
playlist?: boolean,
|
||||
filter: MapFilter
|
||||
onChange?: (filter: MapFilter) => void
|
||||
onApply?: (filter: MapFilter) => void
|
||||
filter: MapFilter,
|
||||
onChange?: (filter: MapFilter) => void,
|
||||
onApply?: (filter: MapFilter) => void,
|
||||
onClose?: (filter: MapFilter) => void
|
||||
}
|
||||
|
||||
export function FilterPanel({className, ref, playlist = false, filter, onChange, onApply}: Props) {
|
||||
export function FilterPanel({className, ref, playlist = false, filter, onChange, onApply, onClose}: Props) {
|
||||
|
||||
const t = useTranslation();
|
||||
|
||||
@@ -148,6 +149,12 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
|
||||
onChange(newFilter);
|
||||
}
|
||||
|
||||
const handleApply = () => {
|
||||
onApply(filter);
|
||||
setHaveChanged(() => false);
|
||||
onClose?.(filter);
|
||||
}
|
||||
|
||||
return !playlist ? (
|
||||
<motion.div ref={ref} className={`${className} bg-light-main-color-2 dark:bg-main-color-3`} initial={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0}}>
|
||||
<div className="w-full h-6 grid grid-cols-2 gap-x-12 px-4 mb-6 pt-2">
|
||||
@@ -190,7 +197,7 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
|
||||
</div>
|
||||
{onApply && (
|
||||
<div className="inline float-right relative w-fit h-fit mt-2">
|
||||
<BsmButton className="inline float-right rounded-md font-bold px-1 py-0.5 text-sm" text="Appliquer" typeColor="primary" withBar={false} onClick={e => {e.preventDefault(); onApply(filter); setHaveChanged(() => false)}}/>
|
||||
<BsmButton className="inline float-right rounded-md font-bold px-1 py-0.5 text-sm" text="Appliquer" typeColor="primary" withBar={false} onClick={handleApply}/>
|
||||
{haveChanged && <div className="glow-on-hover !opacity-100"></div>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -28,6 +28,7 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
|
||||
const currentDownload = useObservable(mapsDownloader.currentMapDownload$);
|
||||
const mapsInQueue = useObservable(mapsDownloader.mapsInQueue$);
|
||||
const t = useTranslation();
|
||||
const filterContainerRef = useRef(null);
|
||||
const [filter, setFilter] = useState<MapFilter>({});
|
||||
const [query, setQuery] = useState("");
|
||||
const [maps, setMaps] = useState<BsvMapDetail[]>([]);
|
||||
@@ -156,8 +157,8 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
|
||||
return (
|
||||
<form className="text-gray-800 dark:text-gray-200 flex flex-col max-w-[95vw] w-[970px] h-[85vh] gap-3" onSubmit={e => {e.preventDefault(); handleSearch()}}>
|
||||
<div className="flex h-9 gap-2 shrink-0">
|
||||
<BsmDropdownButton className="shrink-0 h-full relative z-[1] flex justify-start" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1 !bg-light-main-color-1 dark:!bg-main-color-1" icon="filter" text="pages.version-viewer.maps.search-bar.filters-btn" withBar={false}>
|
||||
<FilterPanel className="absolute top-[calc(100%+3px)] origin-top w-[450px] h-fit p-2 rounded-md shadow-md shadow-black" filter={filter} onChange={setFilter} onApply={handleSearch}/>
|
||||
<BsmDropdownButton ref={filterContainerRef} className="shrink-0 h-full relative z-[1] flex justify-start" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1 !bg-light-main-color-1 dark:!bg-main-color-1" icon="filter" text="pages.version-viewer.maps.search-bar.filters-btn" withBar={false}>
|
||||
<FilterPanel className="absolute top-[calc(100%+3px)] origin-top w-[450px] h-fit p-2 rounded-md shadow-md shadow-black" filter={filter} onChange={setFilter} onApply={handleSearch} onClose={() => filterContainerRef.current.close()}/>
|
||||
</BsmDropdownButton>
|
||||
<input className="h-full bg-light-main-color-1 dark:bg-main-color-1 rounded-full px-2 grow pb-0.5" type="text" name="" id="" placeholder={t("pages.version-viewer.maps.search-bar.search-placeholder")} value={query} onChange={e => setQuery(e.target.value)}/>
|
||||
<BsmButton className="shrink-0 rounded-full py-1 px-3 !bg-light-main-color-1 dark:!bg-main-color-1 flex justify-center items-center capitalize" icon="search" text="modals.download-maps.search-btn" withBar={false} onClick={e => {e.preventDefault(); handleSearch()}}/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from "react"
|
||||
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react"
|
||||
import { BsmIconType, BsmIcon } from "../svgs/bsm-icon.component"
|
||||
import { BsmButton } from "./bsm-button.component"
|
||||
import { useTranslation } from "renderer/hooks/use-translation.hook"
|
||||
@@ -17,30 +17,42 @@ type Props = {
|
||||
menuTranslationY?: string|number
|
||||
children?: JSX.Element,
|
||||
text?: string,
|
||||
textClassName?: string
|
||||
}
|
||||
|
||||
export function BsmDropdownButton({className, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text, textClassName}: Props) {
|
||||
export const BsmDropdownButton = forwardRef(({className, items, align, withBar = true, icon = "settings", buttonClassName, menuTranslationY, children, text}: Props, fowardRed) => {
|
||||
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const t = useTranslation();
|
||||
const ref = useRef(null)
|
||||
const ref = useRef(fowardRed)
|
||||
useClickOutside(ref, () => setExpanded(false));
|
||||
|
||||
useImperativeHandle(fowardRed, () => ({
|
||||
close(){
|
||||
setExpanded(() => false);
|
||||
},
|
||||
open(){
|
||||
setExpanded(() => true);
|
||||
}
|
||||
}),
|
||||
[],
|
||||
)
|
||||
|
||||
|
||||
const defaultButtonClassName = "relative z-[1] p-1 rounded-md text-inherit w-full h-full shadow-md shadow-black"
|
||||
|
||||
const handleClickOutside = () => {
|
||||
if(children){ return; }
|
||||
setExpanded(false);
|
||||
if(children){ return; }
|
||||
setExpanded(false);
|
||||
}
|
||||
|
||||
const alignClass = (() => {
|
||||
if(align === "center"){ return "right-1/2 origin-top-right translate-x-[50%]" }
|
||||
if(align === "left"){ return "left-0 origin-top-left"; }
|
||||
return "right-0 origin-top-right";
|
||||
if(align === "center"){ return "right-1/2 origin-top-right translate-x-[50%]" }
|
||||
if(align === "left"){ return "left-0 origin-top-left"; }
|
||||
return "right-0 origin-top-right";
|
||||
})()
|
||||
|
||||
return (
|
||||
// @ts-ignore
|
||||
<div ref={ref} className={className}>
|
||||
<BsmButton onClick={() => setExpanded(!expanded)} className={buttonClassName ?? defaultButtonClassName} icon={icon} active={expanded} onClickOutside={handleClickOutside} withBar={withBar} text={text}/>
|
||||
<div className={`py-1 w-fit absolute cursor-pointer top-[calc(100%-4px)] rounded-md bg-inherit text-sm text-gray-800 dark:text-gray-200 shadow-md shadow-black transition-[scale] ease-in-out ${alignClass}`} style={{scale: expanded ? "1" : "0", translate: `0 ${menuTranslationY}`}}>
|
||||
@@ -60,4 +72,4 @@ export function BsmDropdownButton({className, items, align, withBar = true, icon
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user