7d6430dc46
* Extract out useFilterTasks * WIP on Combobox * Revert "WIP on Combobox" This reverts commit f0a9b2e57c67f24d5e0876630e17a54252ceb86b. * Added ariakit * Started adding a Listbox component * Listbox WIP * More WIP on the list box * More work on the Listbox * WIP on filterable Listbox using headless… but it’s going to be a nightmare to make it good. Wrong approach * WIP using Ariakit * Multiple selection working * WIP in reworking it so search is built in and it’s easier to use * Nicer API for listbox * Allow sections to be rendered with filtering * More progress on the styling of the menu * The empty state * Removed focus outline * Allow filtering based on the section title * Render the shortcut correctly * Allow passing static children to Select and render a separator if a section has no title * Static example and added subtle focus * Allow static data with no items array passed in * Allow shortcuts on select items * Only how heading if true * Tooltip for keyboard shortcut * useShortcutKeys fixes - Can be passed an undefined definition (so we render the same number of hooks always). - Fix for enabledOnInputElements not being used… * Shortcut keys working with lists * Don’t render shortcut numbers higher than 0 * More improvements * WIP on a Link row * Nicer API for the children function * Much nicer shortcut key support * Separated SelectTrigger out * Heading separated out * More styled elements created * Removed unused element * Reordered statuses * Added search context * Fixes for default values * Removed tab elements * Combo box * Simplified it more * Started work on Filter menu * Experiments with filter menu * Filter menu proof of concept working * Nice hook for using a search param * The escape key goes back to the previous menu * Added filter page to storybook * Added other variants * Renamed Select file to OldSelect, implemented Feedback form * Added placeholder support * Added an optional dropdown icon (defaults to a chevron down) * Feedback new Select * Feedback just use static items * New project page * Renamed storybook pages * Lots of progress on the new run filters * Added new tasks filters * Show the applied filters * Added period filtering * Fix for escape resetting the period value to the previous value when escape is pressed * Show the Clear button sooner * Removed unused code * Reworked useSearchParams so multiple values can be set at once… * Renamed file: OldSelect -> SImpleSelect * Fix for new Select not working in forms because props weren’t being passed through * New Select on the schedules page * Better layout when there are lots of run filters * Many style improvements to run filters * Status filter allows you to select as well * Rolled out the menus for the other files * Minor improvements to schedule page and page padding * Latest lockfile
144 lines
5.0 KiB
TypeScript
144 lines
5.0 KiB
TypeScript
"use client";
|
|
|
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
import { Check, ChevronDown } from "lucide-react";
|
|
import * as React from "react";
|
|
import { cn } from "~/utils/cn";
|
|
|
|
const sizes = {
|
|
"secondary/small":
|
|
"text-xs h-6 bg-tertiary border border-tertiary group-hover:text-text-bright hover:border-charcoal-600 pr-2 pl-1.5",
|
|
medium: "text-sm h-8 bg-tertiary border border-tertiary hover:border-charcoal-600 px-2.5",
|
|
minimal: "text-xs h-6 bg-transparent hover:bg-tertiary pl-1.5 pr-2",
|
|
};
|
|
|
|
export type SelectProps = {
|
|
size?: keyof typeof sizes;
|
|
width?: "content" | "full";
|
|
};
|
|
|
|
const Select = SelectPrimitive.Root;
|
|
const SelectGroup = SelectPrimitive.Group;
|
|
const SelectValue = SelectPrimitive.Value;
|
|
const SelectTrigger = React.forwardRef<
|
|
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & SelectProps
|
|
>(({ className, children, width = "content", size = "secondary/small", ...props }, ref) => {
|
|
const sizeClassName = sizes[size];
|
|
return (
|
|
<SelectPrimitive.Trigger
|
|
ref={ref}
|
|
className={cn(
|
|
"ring-offset-background focus-visible:ring-ring group flex items-center justify-between gap-x-1 rounded text-text-dimmed transition placeholder:text-text-dimmed hover:text-text-bright focus-visible:bg-tertiary focus-visible:text-text-bright focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50",
|
|
width === "full" ? "w-full" : "w-min",
|
|
sizeClassName,
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
<SelectPrimitive.Icon asChild>
|
|
<ChevronDown
|
|
className={cn(
|
|
"size-4 text-text-dimmed transition group-hover:text-text-bright group-focus:text-text-bright"
|
|
)}
|
|
/>
|
|
</SelectPrimitive.Icon>
|
|
</SelectPrimitive.Trigger>
|
|
);
|
|
});
|
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
|
|
const SelectContent = React.forwardRef<
|
|
React.ElementRef<typeof SelectPrimitive.Content>,
|
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
|
>(({ className, children, position = "popper", ...props }, ref) => (
|
|
<SelectPrimitive.Portal>
|
|
<SelectPrimitive.Content
|
|
ref={ref}
|
|
className={cn(
|
|
"relative z-50 min-w-max overflow-hidden rounded-md border border-charcoal-700 bg-background-dimmed text-text-bright shadow-md animate-in fade-in-40",
|
|
position === "popper" && "translate-y-1",
|
|
className
|
|
)}
|
|
position={position}
|
|
{...props}
|
|
>
|
|
<SelectPrimitive.Viewport
|
|
className={cn(
|
|
"space-y-0.5 px-1 py-1",
|
|
position === "popper" &&
|
|
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
|
)}
|
|
>
|
|
{children}
|
|
</SelectPrimitive.Viewport>
|
|
</SelectPrimitive.Content>
|
|
</SelectPrimitive.Portal>
|
|
));
|
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
|
|
const SelectLabel = React.forwardRef<
|
|
React.ElementRef<typeof SelectPrimitive.Label>,
|
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
|
>(({ className, ...props }, ref) => (
|
|
<SelectPrimitive.Label
|
|
ref={ref}
|
|
className={cn(
|
|
"-ml-1 -mr-1 mb-1 bg-charcoal-900 py-1.5 pl-2 pr-2 font-sans text-xxs font-normal uppercase leading-normal tracking-wider text-text-dimmed first-of-type:-mt-0",
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
));
|
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
|
|
type SelectItemProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {
|
|
contentClassName?: string;
|
|
};
|
|
|
|
const SelectItem = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Item>, SelectItemProps>(
|
|
({ className, children, contentClassName, ...props }, ref) => (
|
|
<SelectPrimitive.Item
|
|
ref={ref}
|
|
className={cn(
|
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-12 text-sm outline-none transition data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-charcoal-750 focus:bg-charcoal-750/50",
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
<SelectPrimitive.ItemIndicator>
|
|
<Check className="h-4 w-4" />
|
|
</SelectPrimitive.ItemIndicator>
|
|
</span>
|
|
|
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
</SelectPrimitive.Item>
|
|
)
|
|
);
|
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
|
|
const SelectSeparator = React.forwardRef<
|
|
React.ElementRef<typeof SelectPrimitive.Separator>,
|
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
|
>(({ className, ...props }, ref) => (
|
|
<SelectPrimitive.Separator
|
|
ref={ref}
|
|
className={cn("bg-muted -mx-1 my-1 h-px", className)}
|
|
{...props}
|
|
/>
|
|
));
|
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
|
|
export {
|
|
Select,
|
|
SelectContent,
|
|
SelectGroup,
|
|
SelectItem,
|
|
SelectLabel,
|
|
SelectSeparator,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
};
|