Skip to content

Commit 2513e9f

Browse files
committed
improvement: loading
1 parent 0d99463 commit 2513e9f

File tree

7 files changed

+105
-21
lines changed

7 files changed

+105
-21
lines changed

apps/sim/app/workspace/[workspaceId]/logs/components/logs-toolbar/logs-toolbar.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
'use client'
22

33
import { useCallback, useMemo } from 'react'
4-
import { ArrowUp, Bell, Library, Loader2, MoreHorizontal, RefreshCw } from 'lucide-react'
4+
import { ArrowUp, Bell, Library, MoreHorizontal, RefreshCw } from 'lucide-react'
55
import { useParams } from 'next/navigation'
66
import {
77
Button,
88
Combobox,
99
type ComboboxOption,
10+
Loader,
1011
Popover,
1112
PopoverContent,
1213
PopoverItem,
1314
PopoverScrollArea,
1415
PopoverTrigger,
15-
Tooltip,
1616
} from '@/components/emcn'
1717
import { cn } from '@/lib/core/utils/cn'
1818
import { getTriggerOptions } from '@/lib/logs/get-trigger-options'
@@ -330,22 +330,18 @@ export function LogsToolbar({
330330
</Popover>
331331

332332
{/* Refresh button */}
333-
<Tooltip.Root>
334-
<Tooltip.Trigger asChild>
335-
<Button
336-
variant='default'
337-
className={cn('h-[32px] w-[32px] rounded-[6px] p-0', isRefreshing && 'opacity-50')}
338-
onClick={isRefreshing ? undefined : onRefresh}
339-
>
340-
{isRefreshing ? (
341-
<Loader2 className='h-[14px] w-[14px] animate-spin' />
342-
) : (
343-
<RefreshCw className='h-[14px] w-[14px]' />
344-
)}
345-
</Button>
346-
</Tooltip.Trigger>
347-
<Tooltip.Content>{isRefreshing ? 'Refreshing...' : 'Refresh'}</Tooltip.Content>
348-
</Tooltip.Root>
333+
<Button
334+
variant='default'
335+
className='h-[32px] rounded-[6px] px-[10px]'
336+
onClick={isRefreshing ? undefined : onRefresh}
337+
disabled={isRefreshing}
338+
>
339+
{isRefreshing ? (
340+
<Loader className='h-[14px] w-[14px]' animate />
341+
) : (
342+
<RefreshCw className='h-[14px] w-[14px]' />
343+
)}
344+
</Button>
349345

350346
{/* Live button */}
351347
<Button

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,14 @@ const WorkflowContent = React.memo(() => {
21592159
className={`absolute inset-0 z-[5] flex items-center justify-center bg-[var(--bg)] transition-opacity duration-150 ${isWorkflowReady ? 'pointer-events-none opacity-0' : 'opacity-100'}`}
21602160
>
21612161
<div
2162-
className={`h-[18px] w-[18px] rounded-full border-[1.5px] border-muted-foreground border-t-transparent ${isWorkflowReady ? '' : 'animate-spin'}`}
2162+
className={`h-[18px] w-[18px] rounded-full ${isWorkflowReady ? '' : 'animate-spin'}`}
2163+
style={{
2164+
background:
2165+
'conic-gradient(from 0deg, hsl(var(--muted-foreground)) 0deg 120deg, transparent 120deg 180deg, hsl(var(--muted-foreground)) 180deg 300deg, transparent 300deg 360deg)',
2166+
mask: 'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
2167+
WebkitMask:
2168+
'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
2169+
}}
21632170
/>
21642171
</div>
21652172

apps/sim/app/workspace/[workspaceId]/w/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,16 @@ export default function WorkflowsPage() {
5858
<div className='flex h-full w-full flex-col overflow-hidden bg-[var(--bg)]'>
5959
<div className='relative h-full w-full flex-1 bg-[var(--bg)]'>
6060
<div className='workflow-container flex h-full items-center justify-center bg-[var(--bg)]'>
61-
<div className='h-[18px] w-[18px] animate-spin rounded-full border-[1.5px] border-muted-foreground border-t-transparent' />
61+
<div
62+
className='h-[18px] w-[18px] animate-spin rounded-full'
63+
style={{
64+
background:
65+
'conic-gradient(from 0deg, hsl(var(--muted-foreground)) 0deg 120deg, transparent 120deg 180deg, hsl(var(--muted-foreground)) 180deg 300deg, transparent 300deg 360deg)',
66+
mask: 'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
67+
WebkitMask:
68+
'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
69+
}}
70+
/>
6271
</div>
6372
<Panel />
6473
</div>

apps/sim/app/workspace/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,16 @@ export default function WorkspacePage() {
117117
if (isPending) {
118118
return (
119119
<div className='flex h-screen w-full items-center justify-center'>
120-
<div className='h-[18px] w-[18px] animate-spin rounded-full border-[1.5px] border-muted-foreground border-t-transparent' />
120+
<div
121+
className='h-[18px] w-[18px] animate-spin rounded-full'
122+
style={{
123+
background:
124+
'conic-gradient(from 0deg, hsl(var(--muted-foreground)) 0deg 120deg, transparent 120deg 180deg, hsl(var(--muted-foreground)) 180deg 300deg, transparent 300deg 360deg)',
125+
mask: 'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
126+
WebkitMask:
127+
'radial-gradient(farthest-side, transparent calc(100% - 1.5px), black calc(100% - 1.5px))',
128+
}}
129+
/>
121130
</div>
122131
)
123132
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Loader icon animation
3+
* Continuous spinning animation for loading states
4+
* Uses GPU acceleration for smooth performance
5+
*/
6+
7+
@keyframes spin {
8+
from {
9+
transform: rotate(0deg);
10+
}
11+
to {
12+
transform: rotate(360deg);
13+
}
14+
}
15+
16+
.animated-loader-svg {
17+
animation: spin 1s linear infinite;
18+
transform-origin: center center;
19+
will-change: transform;
20+
}

apps/sim/components/emcn/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export { HexSimple } from './hex-simple'
1212
export { Key } from './key'
1313
export { Layout } from './layout'
1414
export { Library } from './library'
15+
export { Loader } from './loader'
1516
export { MoreHorizontal } from './more-horizontal'
1617
export { NoWrap } from './no-wrap'
1718
export { PanelLeft } from './panel-left'
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type { SVGProps } from 'react'
2+
import styles from '@/components/emcn/icons/animate/loader.module.css'
3+
4+
export interface LoaderProps extends SVGProps<SVGSVGElement> {
5+
/**
6+
* Enable animation on the loader icon
7+
* @default false
8+
*/
9+
animate?: boolean
10+
}
11+
12+
/**
13+
* Loader icon component with optional CSS-based spinning animation
14+
* Based on refresh-cw but without the arrows, just the circular arcs.
15+
* When animate is false, this is a lightweight static icon with no animation overhead.
16+
* When animate is true, CSS module animations are applied for continuous spin.
17+
* @param props - SVG properties including className, animate, etc.
18+
*/
19+
export function Loader({ animate = false, className, ...props }: LoaderProps) {
20+
const svgClassName = animate
21+
? `${styles['animated-loader-svg']} ${className || ''}`.trim()
22+
: className
23+
24+
return (
25+
<svg
26+
xmlns='http://www.w3.org/2000/svg'
27+
width='24'
28+
height='24'
29+
viewBox='0 0 24 24'
30+
fill='none'
31+
stroke='currentColor'
32+
strokeWidth='2'
33+
strokeLinecap='round'
34+
strokeLinejoin='round'
35+
className={svgClassName}
36+
{...props}
37+
>
38+
<path d='M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74' />
39+
<path d='M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74' />
40+
</svg>
41+
)
42+
}

0 commit comments

Comments
 (0)