Spinner
An animated loading spinner.
import { Spinner, type SpinnerProps } from '~/components/ui/spinner'
export const Demo = (props: SpinnerProps) => {
  return <Spinner {...props} />
}
import { Spinner, type SpinnerProps } from '~/components/ui/spinner'
export const Demo = (props: SpinnerProps) => {
  return <Spinner {...props} />
}
Usage
import { Spinner } from '~/components/ui/spinner'Examples
Customizing Color
Use the colorPalette prop to change the spinner's color.
Loading...
<Spinner colorPalette="red" />Customizing Track Color
Use the borderColor prop to change the spinner's track color.
Loading...
<Spinner borderLeftColor="bg.emphasized" borderBottomColor="bg.emphasized" />Customizing Thickness
Use the borderWidth prop to change the spinner's thickness.
Loading...
<Spinner borderWidth="4px" />Installation
npx @park-ui/cli components add spinner1
Add Styled Primitive
Copy the code snippet below into ~/components/ui/styled/spinner.tsx
import { ark } from '@ark-ui/react/factory'
import { styled } from 'styled-system/jsx'
import { spinner } from 'styled-system/recipes'
import type { ComponentProps } from 'styled-system/types'
export type SpinnerProps = ComponentProps<typeof Spinner>
export const Spinner = styled(ark.div, spinner)
import { ark } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { styled } from 'styled-system/jsx'
import { spinner } from 'styled-system/recipes'
export type SpinnerProps = ComponentProps<typeof Spinner>
export const Spinner = styled(ark.div, spinner)
No snippet found2
Add Composition
Copy the composition snippet below into ~/components/ui/spinner.tsx
import { forwardRef } from 'react'
import { styled } from 'styled-system/jsx'
import { Spinner as StyledSpinner, type SpinnerProps as StyledSpinnerProps } from './styled/spinner'
export interface SpinnerProps extends StyledSpinnerProps {
  /**
   * For accessibility, it is important to add a fallback loading text.
   * This text will be visible to screen readers.
   * @default "Loading..."
   */
  label?: string
}
export const Spinner = forwardRef<HTMLDivElement, SpinnerProps>((props, ref) => {
  const { label = 'Loading...', ...rest } = props
  return (
    <StyledSpinner
      ref={ref}
      borderBottomColor="transparent"
      borderLeftColor="transparent"
      {...rest}
    >
      {label && <styled.span srOnly>{label}</styled.span>}
    </StyledSpinner>
  )
})
Spinner.displayName = 'Spinner'
import { mergeProps, splitProps } from 'solid-js'
import { styled } from 'styled-system/jsx'
import { Spinner as StyledSpinner, type SpinnerProps as StyledSpinnerProps } from './styled/spinner'
export interface SpinnerProps extends StyledSpinnerProps {
  /**
   * For accessibility, it is important to add a fallback loading text.
   * This text will be visible to screen readers.
   * @default "Loading..."
   */
  label?: string
}
export const Spinner = (props: SpinnerProps) => {
  const [_localProps, rootProps] = splitProps(props, ['label'])
  const localProps = mergeProps({ label: 'Loading...' }, _localProps)
  return (
    <StyledSpinner borderBottomColor="transparent" borderLeftColor="transparent" {...rootProps}>
      <styled.span srOnly>{localProps.label}</styled.span>
    </StyledSpinner>
  )
}
3
Integrate Recipe
If you're not using @park-ui/preset, add the following recipe to yourpanda.config.ts:
import { defineRecipe } from '@pandacss/dev'
export const spinner = defineRecipe({
  className: 'spinner',
  base: {
    display: 'inline-block',
    borderWidth: '2px',
    borderColor: 'colorPalette.default',
    borderStyle: 'solid',
    borderRadius: 'full',
    width: 'var(--size)',
    height: 'var(--size)',
    animation: 'spin',
    animationDuration: 'slowest',
  },
  defaultVariants: {
    size: 'md',
  },
  variants: {
    size: {
      xs: { '--size': 'sizes.3' },
      sm: { '--size': 'sizes.4' },
      md: { '--size': 'sizes.6' },
      lg: { '--size': 'sizes.8' },
      xl: { '--size': 'sizes.12' },
    },
  },
})