Skip to content

Commit

Permalink
feat(dashboard): add button loading state prop (#7191)
Browse files Browse the repository at this point in the history
  • Loading branch information
scopsy authored Dec 2, 2024
1 parent d8a7db6 commit a4115c8
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 11 deletions.
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/confirmation-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const ConfirmationModal = ({
</Button>
</DialogClose>

<Button type="button" size="sm" variant="primary" onClick={onConfirm} disabled={isLoading}>
<Button type="button" size="sm" variant="primary" onClick={onConfirm} isLoading={isLoading}>
{confirmButtonText}
</Button>
</DialogFooter>
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/create-workflow-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export const CreateWorkflowButton = (props: CreateWorkflowButtonProps) => {
</SheetMain>
<Separator />
<SheetFooter>
<Button disabled={isPending} variant="default" type="submit" form="create-workflow">
<Button isLoading={isPending} variant="default" type="submit" form="create-workflow">
Create workflow
</Button>
</SheetFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const EditBridgeUrlButton = () => {
type="submit"
variant="primary"
size="xs"
isLoading={isUpdatingBridgeUrl}
disabled={!isDirty || isValidatingBridgeUrl || isUpdatingBridgeUrl}
>
Update endpoint
Expand Down
27 changes: 25 additions & 2 deletions apps/dashboard/src/components/primitives/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/utils/ui';
import { RiLoader4Line } from 'react-icons/ri';

export const buttonVariants = cva(
`relative isolate inline-flex items-center justify-center whitespace-nowrap rounded-lg gap-1 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50`,
Expand Down Expand Up @@ -43,12 +44,34 @@ export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
isLoading?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
({ className, variant, size, asChild = false, isLoading = false, children, disabled, ...props }, ref) => {
const Comp = asChild ? Slot : 'button';
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />;
return (
<Comp
className={cn(buttonVariants({ variant, size, className }), isLoading && 'animate-pulse-subtle')}
ref={ref}
disabled={disabled || isLoading}
{...props}
>
<span
className={cn(
'flex items-center gap-1 transition-all duration-300',
isLoading ? 'scale-95 transform opacity-0' : 'scale-100 opacity-100'
)}
>
{children}
</span>
{isLoading && (
<div className="animate-in zoom-in-50 fade-in absolute inset-0 flex items-center justify-center text-current duration-300">
<RiLoader4Line className="size-4 animate-spin" />
</div>
)}
</Comp>
);
}
);
Button.displayName = 'Button';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { Link, useParams } from 'react-router-dom';
import { RiPlayCircleLine, RiProgress1Fill } from 'react-icons/ri';
import { RiPlayCircleLine } from 'react-icons/ri';
import { useForm } from 'react-hook-form';
// eslint-disable-next-line
// @ts-ignore
Expand Down Expand Up @@ -127,8 +127,8 @@ export const TestWorkflowTabs = ({ testData }: { testData: WorkflowTestDataRespo
</Link>
</TabsTrigger>
<div className="ml-auto">
<Button type="submit" variant="primary" size="sm" className="flex gap-1" disabled={isPending}>
{isPending ? <RiProgress1Fill className="size-5" /> : <RiPlayCircleLine className="size-5" />}
<Button type="submit" variant="primary" size="sm" className="flex gap-1" isLoading={isPending}>
<RiPlayCircleLine className="size-5" />
<span>Test workflow</span>
</Button>
</div>
Expand Down
4 changes: 1 addition & 3 deletions apps/dashboard/src/pages/usecase-select-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { useNavigate } from 'react-router-dom';
import { OnboardingArrowLeft } from '../components/icons/onboarding-arrow-left';
import { updateClerkOrgMetadata } from '../api/organization';
import { ChannelTypeEnum } from '@novu/shared';
import { RiLoader2Line } from 'react-icons/ri';
import { PageMeta } from '../components/page-meta';
import { useTelemetry } from '../hooks';
import { TelemetryEvent } from '../utils/telemetry';
Expand Down Expand Up @@ -79,9 +78,8 @@ export function UsecaseSelectPage() {
/>

<div className="flex w-full flex-col items-center gap-3">
<Button disabled={selectedUseCases.length === 0 || isPending} className="w-full" type="submit">
<Button disabled={selectedUseCases.length === 0} isLoading={isPending} className="w-full" type="submit">
Continue
{isPending && <RiLoader2Line className="animate-spin" />}
</Button>
<Button type="button" variant="link" className="pt-0 text-xs text-[#717784]" onClick={handleSkip}>
Skip to Homepage
Expand Down
8 changes: 7 additions & 1 deletion apps/dashboard/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ export default {
boxShadow: '0 0 0 0 rgba(255, 82, 82, 0)',
},
},
'pulse-subtle': {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.85' },
},
'accordion-down': {
from: {
height: '0',
Expand Down Expand Up @@ -181,11 +185,13 @@ export default {
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
'pulse-subtle': 'pulse-subtle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
swing: 'swing 3s ease-in-out',
jingle: 'jingle 3s ease-in-out',
},
backgroundImage: {
'test-pattern': 'repeating-linear-gradient(135deg, hsl(var(--neutral-100)) 0, hsl(var(--neutral-100)) 2px, hsl(var(--neutral-200)) 2px, hsl(var(--neutral-200)) 4px)',
'test-pattern':
'repeating-linear-gradient(135deg, hsl(var(--neutral-100)) 0, hsl(var(--neutral-100)) 2px, hsl(var(--neutral-200)) 2px, hsl(var(--neutral-200)) 4px)',
},
},
},
Expand Down

0 comments on commit a4115c8

Please sign in to comment.