From 065704b07c22dcad483ab251c78a366ae5c94336 Mon Sep 17 00:00:00 2001 From: coji Date: Sat, 8 Mar 2025 14:18:10 +0900 Subject: [PATCH] feat: add loading state to Button component and integrate with form submissions --- app/components/ui/button.tsx | 18 +++++++++++++++--- app/routes/$handle+/posts.$id.edit/route.tsx | 4 +++- app/routes/auth+/sign_in/route.tsx | 6 +++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/components/ui/button.tsx b/app/components/ui/button.tsx index 2e2feb0..7a0ae84 100644 --- a/app/components/ui/button.tsx +++ b/app/components/ui/button.tsx @@ -1,4 +1,4 @@ -import { Slot } from '@radix-ui/react-slot' +import { Slot, Slottable } from '@radix-ui/react-slot' import { cva, type VariantProps } from 'class-variance-authority' import type * as React from 'react' @@ -26,10 +26,14 @@ const buttonVariants = cva( lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', icon: 'size-9', }, + isLoading: { + true: 'cursor-progress', + }, }, defaultVariants: { variant: 'default', size: 'default', + isLoading: false, }, }, ) @@ -39,19 +43,27 @@ function Button({ variant, size, asChild = false, + isLoading = false, + children, ...props }: React.ComponentProps<'button'> & VariantProps & { asChild?: boolean + isLoading?: boolean }) { const Comp = asChild ? Slot : 'button' return ( + > + {isLoading && ( + + )} + {children} + ) } diff --git a/app/routes/$handle+/posts.$id.edit/route.tsx b/app/routes/$handle+/posts.$id.edit/route.tsx index 3ea026a..19658d8 100644 --- a/app/routes/$handle+/posts.$id.edit/route.tsx +++ b/app/routes/$handle+/posts.$id.edit/route.tsx @@ -6,7 +6,7 @@ import { } from '@conform-to/react' import { parseWithZod } from '@conform-to/zod' import { ArrowLeftIcon } from 'lucide-react' -import { data, Form, href, Link, redirect } from 'react-router' +import { data, Form, href, Link, redirect, useNavigation } from 'react-router' import { z } from 'zod' import { AppHeadingSection } from '~/components/AppHeadingSection' import { Button, Input, Label, Textarea } from '~/components/ui' @@ -95,6 +95,7 @@ export default function PostEditPage({ shouldValidate: 'onInput', onValidate: ({ formData }) => parseWithZod(formData, { schema }), }) + const navigation = useNavigation() return (
@@ -130,6 +131,7 @@ export default function PostEditPage({ name="intent" value="update" form={form.id} + isLoading={navigation.state === 'submitting'} > 更新する diff --git a/app/routes/auth+/sign_in/route.tsx b/app/routes/auth+/sign_in/route.tsx index 9e79389..2d12f87 100644 --- a/app/routes/auth+/sign_in/route.tsx +++ b/app/routes/auth+/sign_in/route.tsx @@ -35,7 +35,11 @@ const SignInForm = () => { return (
-