Skip to content

Commit

Permalink
enhance: simplify button loading state (#1712)
Browse files Browse the repository at this point in the history
* enhance: simplify button loading state

- loading states now replace all content with a loading spinner
- prevents buttons from expanding horizontally during loading states
- allows for simpler code with button internals

* fix: remove asChild prop from button.
  • Loading branch information
ryanhopperlowe authored Feb 11, 2025
1 parent f7eee66 commit 9a15b03
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 52 deletions.
39 changes: 14 additions & 25 deletions ui/admin/app/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import { Loader2 } from "lucide-react";
import * as React from "react";

import { cn } from "~/lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors hover:shadow-inner focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"relative inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors hover:shadow-inner focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
Expand Down Expand Up @@ -55,7 +54,6 @@ const buttonVariants = cva(

export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
loading?: boolean;
startContent?: React.ReactNode;
endContent?: React.ReactNode;
Expand All @@ -71,7 +69,6 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
variant,
size,
shape,
asChild = false,
loading = false,
startContent,
endContent,
Expand All @@ -81,36 +78,28 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
},
ref
) => {
const Comp = asChild ? Slot : "button";

return (
<Comp
<button
className={cn(buttonVariants({ variant, size, shape, className }))}
ref={ref}
{...props}
>
{getContent()}
</Comp>
);

function getContent() {
if ((size === "icon" || size === "icon-sm") && loading)
return <Loader2 className="animate-spin" />;

return loading ? (
<div className="flex items-center gap-2">
<Loader2 className="mr-2 animate-spin" />
{children}
{endContent}
</div>
) : (
<div className={cn("flex items-center gap-2", classNames?.content)}>
<div
className={cn("flex items-center gap-2", classNames?.content, {
invisible: loading,
})}
>
{startContent}
{children}
{endContent}
</div>
);
}
{loading && (
<div className="absolute inset-0 flex items-center justify-center">
<Loader2 className="animate-spin" />
</div>
)}
</button>
);
}
);
Button.displayName = "Button";
Expand Down
13 changes: 0 additions & 13 deletions ui/admin/app/lib/service/api/workspaceTableApiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,6 @@ import {

const param = (x: string) => x as Todo;

const Keys = {
getTables: (namespace: TableNamespace, entityId: string) => [
namespace,
entityId,
"tables",
],
getTableRows: (
namespace: TableNamespace,
entityId: string,
tableName: string
) => [...Keys.getTables(namespace, entityId), tableName],
};

const getTables = createFetcher(
QueryService.queryable.extend({
namespace: z.nativeEnum(TableNamespace),
Expand Down
6 changes: 2 additions & 4 deletions ui/admin/app/routes/_auth.threads.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,9 @@ export default function ChatAgent() {
variant="outline"
size="icon"
className="absolute left-4 top-4 z-10"
asChild
onClick={() => navigate(-1)}
>
<Button size="icon" variant="outline" onClick={() => navigate(-1)}>
<ArrowLeftIcon className="h-4 w-4" />
</Button>
<ArrowLeftIcon className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>Go Back</TooltipContent>
Expand Down
21 changes: 11 additions & 10 deletions ui/admin/app/routes/_auth.threads._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { PuzzleIcon, Trash, XIcon } from "lucide-react";
import { useMemo } from "react";
import {
ClientLoaderFunctionArgs,
Link,
MetaFunction,
useLoaderData,
useNavigate,
Expand All @@ -27,6 +26,7 @@ import { timeSince } from "~/lib/utils";

import { DataTable } from "~/components/composed/DataTable";
import { Button } from "~/components/ui/button";
import { Link } from "~/components/ui/link";
import { ScrollArea } from "~/components/ui/scroll-area";
import {
Tooltip,
Expand Down Expand Up @@ -193,15 +193,16 @@ export default function Threads() {
<div className="flex justify-end gap-2">
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="icon" asChild>
<Link
to={$path("/threads/:id", {
id: row.original.id,
})}
>
<ReaderIcon width={21} height={21} />
</Link>
</Button>
<Link
to={$path("/threads/:id", {
id: row.original.id,
})}
as="button"
variant="ghost"
size="icon"
>
<ReaderIcon width={21} height={21} />
</Link>
</TooltipTrigger>

<TooltipContent>
Expand Down

0 comments on commit 9a15b03

Please sign in to comment.