initial top filter menu #2

Merged
christian merged 5 commits from shadcn into main 2024-05-25 20:13:32 +00:00
4 changed files with 179 additions and 45 deletions
Showing only changes of commit 8b98ff75cf - Show all commits

34
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"@t3-oss/env-nextjs": "^0.10.1",
@ -2254,6 +2255,39 @@
}
}
},
"node_modules/@radix-ui/react-slider": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.2.tgz",
"integrity": "sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/number": "1.0.1",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-collection": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-direction": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-controllable-state": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1",
"@radix-ui/react-use-previous": "1.0.1",
"@radix-ui/react-use-size": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",

View File

@ -15,6 +15,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"@t3-oss/env-nextjs": "^0.10.1",

View File

@ -1,56 +1,126 @@
"use client";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuList,
NavigationMenuTrigger,
} from "~/components/ui/navigation-menu";
import { Input } from "~/components/ui/input";
import { Slider } from "~/components/ui/slider";
import { ChangeEvent, useState } from "react";
export default function Filtermenu() {
const [minPrice, setMinPrice] = useState<number>(0);
const [maxPrice, setMaxPrice] = useState<number>(9999);
const [sliderValues, setSliderValues] = useState<[number, number]>([0, 9999]);
const handleMinPriceChange = (e: ChangeEvent<HTMLInputElement>): void => {
const value = Math.min(Number(e.target.value), maxPrice - 1);
setMinPrice(value);
setSliderValues([value, sliderValues[1]]);
};
const handleMaxPriceChange = (e: ChangeEvent<HTMLInputElement>) => {
const value = Math.max(Number(e.target.value), minPrice + 1);
setMaxPrice(value);
setSliderValues([sliderValues[0], value]);
};
const handleSliderChange = (values: [number, number]) => {
setSliderValues(values);
setMinPrice(values[0]);
setMaxPrice(values[1]);
};
return (
<div className="container flex justify-center gap-4 py-4">
<div className="container flex justify-center gap-2">
{/* TODO:
Checkboxes instead of menuitems. Check boxes are added as badges under the search bar */}
<DropdownMenu>
<DropdownMenuTrigger>Type</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Sparkling</DropdownMenuItem>
<DropdownMenuItem>White</DropdownMenuItem>
<DropdownMenuItem>Red</DropdownMenuItem>
<DropdownMenuItem>Sweet</DropdownMenuItem>
<DropdownMenuItem>Fortified</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Price filter */}
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Price</NavigationMenuTrigger>
<NavigationMenuContent className="min-w- flex overflow-auto p-2">
<Input
value={minPrice}
onChange={handleMinPriceChange}
className="min-w-20"
type="number"
defaultValue={0}
/>
<Slider
value={sliderValues}
onValueChange={handleSliderChange}
className="min-w-36"
min={0}
max={9999}
defaultValue={[0, 9999]}
/>
<Input
value={maxPrice}
onChange={handleMaxPriceChange}
className="min-w-20"
type="number"
defaultValue={9999}
/>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Type</NavigationMenuTrigger>
<NavigationMenuContent>
<p>Anything goes?</p>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
{/* Producer filter */}
<DropdownMenu>
<DropdownMenuTrigger>Producer</DropdownMenuTrigger>
<DropdownMenuContent>
{/* For each producer have DropdownMenuItem. */}
<Input name="searchString" placeholder="search for producer" />
<DropdownMenuSeparator />
<DropdownMenuItem>Store Henning</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Country filter */}
<DropdownMenu>
<DropdownMenuTrigger>Country</DropdownMenuTrigger>
<DropdownMenuContent>
{/* For each Country have DropdownMenuItem. */}
<DropdownMenuItem>France</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* Region filter */}
<DropdownMenu>
<DropdownMenuTrigger>Region</DropdownMenuTrigger>
<DropdownMenuContent>
{/* For each Region have DropdownMenuItem. Check for country filter */}
<Input name="searchString" placeholder="search for region" />
<DropdownMenuSeparator />
<DropdownMenuItem>Bourgogne</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Producer</NavigationMenuTrigger>
<NavigationMenuContent className="w-fit p-2">
<Input placeholder="producer filter" />
<ul>
<li>checkboxes for producer filter</li>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
{/* Country Filter */}
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Producer</NavigationMenuTrigger>
<NavigationMenuContent className="w-fit p-2">
<ul>
<li>ccountry filter</li>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
{/* Region Filter */}
<NavigationMenu>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Region</NavigationMenuTrigger>
<NavigationMenuContent className="w-fit p-2">
<Input placeholder="producer filter" />
<ul>
<li>checkboxes for producer filter</li>
</ul>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
</div>
);
}

View File

@ -0,0 +1,29 @@
"use client";
import * as React from "react";
import * as SliderPrimitive from "@radix-ui/react-slider";
import { cn } from "~/lib/utils";
const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn(
"relative flex w-full touch-none select-none items-center",
className,
)}
{...props}
>
<SliderPrimitive.Track className="relative h-2 w-full grow overflow-hidden rounded-full bg-secondary">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" />
<SliderPrimitive.Thumb className="block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" />
</SliderPrimitive.Root>
));
Slider.displayName = SliderPrimitive.Root.displayName;
export { Slider };