Skip to content

Commit

Permalink
feat: Use ToggleGroup for quest group toggle instead of Dropdown (#220
Browse files Browse the repository at this point in the history
)
  • Loading branch information
evadecker authored Nov 26, 2024
1 parent 401f59e commit 913fbde
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-balloons-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"namesake": minor
---

Simplify quest grouping UX
35 changes: 29 additions & 6 deletions src/components/ToggleButton/ToggleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
import type { LucideIcon } from "lucide-react";
import {
ToggleButton as AriaToggleButton,
type ToggleButtonProps,
type ToggleButtonProps as AriaToggleButtonProps,
composeRenderProps,
} from "react-aria-components";
import { tv } from "tailwind-variants";
import { buttonStyles } from "../Button";
import { focusRing } from "../utils";

export interface ToggleButtonProps extends AriaToggleButtonProps {
children?: React.ReactNode;
icon?: LucideIcon;
size?: "small" | "medium";
}

const styles = tv({
extend: focusRing,
base: "h-10 px-3.5 [&:has(svg:only-child)]:px-2 text-sm text-center transition rounded-lg border border-black/10 dark:border-white/10",
base: "px-3.5 [&:has(svg:only-child)]:px-2 text-sm text-center transition rounded-lg border border-black/10 dark:border-white/10",
variants: {
isSelected: {
false: buttonStyles.variants.variant.secondary,
true: "bg-gray-12 dark:bg-graydark-12 text-gray-1 dark:text-gray-12 shadow-sm",
},
isDisabled: buttonStyles.variants.isDisabled,
size: {
small: "h-8",
medium: "h-10",
},
},
defaultVariants: {
size: "medium",
},
});

export function ToggleButton(props: ToggleButtonProps) {
export function ToggleButton({
size,
icon: Icon,
className,
children,
...props
}: ToggleButtonProps) {
return (
<AriaToggleButton
{...props}
className={composeRenderProps(props.className, (className, renderProps) =>
styles({ ...renderProps, className }),
className={composeRenderProps(className, (className, renderProps) =>
styles({ ...renderProps, size, className }),
)}
/>
>
{Icon && <Icon size={size === "small" ? 16 : 20} />}
{children}
</AriaToggleButton>
);
}
2 changes: 1 addition & 1 deletion src/components/ToggleButtonGroup/ToggleButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { tv } from "tailwind-variants";

const styles = tv({
base: "border rounded-lg grid grid-flow-col auto-cols-fr border-black/10 dark:border-white/10 *:border-0",
base: "rounded-lg grid grid-flow-col auto-cols-fr shadow-[inset_0_0_0_1px_rgba(0,0,0,0.1)] dark:shadow-[inset_0_0_0_1px_rgba(255,255,255,0.1)] *:border-0",
variants: {
orientation: {
horizontal: "flex-row",
Expand Down
69 changes: 45 additions & 24 deletions src/routes/_authenticated/_home.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import {
Badge,
Button,
Container,
Empty,
Menu,
MenuItem,
MenuSection,
MenuTrigger,
Nav,
NavGroup,
NavItem,
ProgressBar,
StatusBadge,
ToggleButton,
ToggleButtonGroup,
Tooltip,
TooltipTrigger,
} from "@/components";
Expand All @@ -32,10 +29,34 @@ import {
} from "@convex/constants";
import { Outlet, createFileRoute } from "@tanstack/react-router";
import { Authenticated, Unauthenticated, useQuery } from "convex/react";
import { LayoutList, Milestone } from "lucide-react";
import {
History,
List,
ListTodo,
type LucideIcon,
Milestone,
} from "lucide-react";
import { useEffect, useState } from "react";
import type { Selection } from "react-aria-components";

const GROUP_OPTIONS: Record<
GroupQuestsBy,
{ icon: LucideIcon; tooltip: string }
> = {
category: {
icon: List,
tooltip: "Group by category",
},
status: {
icon: ListTodo,
tooltip: "Group by status",
},
dateAdded: {
icon: History,
tooltip: "Group by date added",
},
} as const;

export const Route = createFileRoute("/_authenticated/_home")({
component: IndexRoute,
});
Expand Down Expand Up @@ -115,24 +136,24 @@ function IndexRoute() {
labelHidden
className="mr-4"
/>
<TooltipTrigger>
<MenuTrigger>
<Button icon={LayoutList} variant="icon" />
<Menu
selectionMode="single"
selectedKeys={groupBy}
onSelectionChange={setGroupBy}
disallowEmptySelection
>
<MenuSection title="Group by">
<MenuItem id="category">Category</MenuItem>
<MenuItem id="status">Status</MenuItem>
<MenuItem id="dateAdded">Date added</MenuItem>
</MenuSection>
</Menu>
</MenuTrigger>
<Tooltip placement="right">Group by</Tooltip>
</TooltipTrigger>
<ToggleButtonGroup
selectionMode="single"
selectedKeys={groupBy}
onSelectionChange={setGroupBy}
disallowEmptySelection
>
{Object.keys(GROUP_OPTIONS).map((option) => {
const Icon = GROUP_OPTIONS[option as GroupQuestsBy].icon;
return (
<TooltipTrigger key={option}>
<ToggleButton id={option} size="small" icon={Icon} />
<Tooltip>
{GROUP_OPTIONS[option as GroupQuestsBy].tooltip}
</Tooltip>
</TooltipTrigger>
);
})}
</ToggleButtonGroup>
</div>
<Nav>
{Object.keys(groupedQuests).length === 0 ? (
Expand Down

0 comments on commit 913fbde

Please sign in to comment.