Spinner
An indicator that can be used to show a loading state.
Processing payment...
$100.00
import { styled } from "styled-system/jsx";
import { Item, ItemContent, ItemMedia, ItemTitle } from "@/components/ui/item";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerDemo() {
return (
<styled.div
css={{ display: "flex", w: "full", maxW: "xs", flexDir: "column", gap: "4", rounded: "1rem" }}
>
<Item variant="muted">
<ItemMedia>
<Spinner />
</ItemMedia>
<ItemContent>
<ItemTitle css={{ lineClamp: "1" }}>Processing payment...</ItemTitle>
</ItemContent>
<ItemContent css={{ flex: "none", justifyContent: "flex-end" }}>
<styled.span css={{ textStyle: "sm", fontVariantNumeric: "tabular-nums" }}>
$100.00
</styled.span>
</ItemContent>
</Item>
</styled.div>
);
}
Installation
npx nore-ui-cli@latest add spinnerUsage
import { Spinner } from "@/components/ui/spinner";
<Spinner />
Customization
You can replace the default spinner icon with any other icon by editing the Spinner component.
import { LuLoader } from "react-icons/lu";
import { styled } from "styled-system/jsx";
import { spinner } from "styled-system/recipes";
const Spinner = styled(LuLoader, spinner, {
defaultProps: {
role: "status",
"aria-label": "Loading",
},
});
export default function SpinnerCustom() {
return (
<styled.div css={{ display: "flex", alignItems: "center", gap: "4" }}>
<Spinner />
</styled.div>
);
}
import { LuLoader } from "react-icons/lu";
import { styled } from "styled-system/jsx";
import { spinner } from "styled-system/recipes";
const Spinner = styled(LuLoader, spinner, {
defaultProps: {
role: "status",
"aria-label": "Loading",
},
});
export { Spinner };
Examples
Size
Use width and height to change the size of the spinner.
import { styled } from "styled-system/jsx";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerSize() {
return (
<styled.div css={{ display: "flex", alignItems: "center", gap: "6" }}>
<Spinner css={{ w: "3", h: "3" }} />
<Spinner css={{ w: "4", h: "4" }} />
<Spinner css={{ w: "6", h: "6" }} />
<Spinner css={{ w: "8", h: "8" }} />
</styled.div>
);
}
Color
Use color to change the color of the spinner.
import { styled } from "styled-system/jsx";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerColor() {
return (
<styled.div css={{ display: "flex", alignItems: "center", gap: "6" }}>
<Spinner css={{ w: "6", h: "6", color: "red.500" }} />
<Spinner css={{ w: "6", h: "6", color: "green.500" }} />
<Spinner css={{ w: "6", h: "6", color: "blue.500" }} />
<Spinner css={{ w: "6", h: "6", color: "yellow.500" }} />
<Spinner css={{ w: "6", h: "6", color: "purple.500" }} />
</styled.div>
);
}
Button
Add a spinner to a button to indicate a loading state. The <Button /> will handle the spacing between the spinner and the text.
import { styled } from "styled-system/jsx";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerButton() {
return (
<styled.div css={{ display: "flex", flexDir: "column", alignItems: "center", gap: "4" }}>
<Button disabled size="sm">
<Spinner />
Loading...
</Button>
<Button variant="outline" disabled size="sm">
<Spinner />
Please wait
</Button>
<Button variant="secondary" disabled size="sm">
<Spinner />
Processing
</Button>
</styled.div>
);
}
Badge
You can also use a spinner inside a badge.
SyncingUpdatingProcessing
import { styled } from "styled-system/jsx";
import { Badge } from "@/components/ui/badge";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerBadge() {
return (
<styled.div
css={{
display: "flex",
alignItems: "center",
gap: "4",
"& > .badge": {
rounded: "1.2rem",
},
}}
>
<Badge>
<Spinner />
Syncing
</Badge>
<Badge variant="secondary">
<Spinner />
Updating
</Badge>
<Badge variant="outline">
<Spinner />
Processing
</Badge>
</styled.div>
);
}
Input Group
Input Group can have spinners inside <InputGroupAddon>.
Validating...
import { LuArrowUp } from "react-icons/lu";
import { styled } from "styled-system/jsx";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
InputGroupTextarea,
} from "@/components/ui/input-group";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerInputGroup() {
return (
<styled.div css={{ display: "flex", w: "full", maxW: "md", flexDir: "column", gap: "4" }}>
<InputGroup>
<InputGroupInput placeholder="Send a message..." disabled />
<InputGroupAddon align="inline-end">
<Spinner />
</InputGroupAddon>
</InputGroup>
<InputGroup>
<InputGroupTextarea placeholder="Send a message..." disabled />
<InputGroupAddon align="block-end">
<Spinner /> Validating...
<InputGroupButton css={{ ml: "auto" }} variant="primary">
<LuArrowUp />
<styled.span css={{ srOnly: true }}>Send</styled.span>
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</styled.div>
);
}
Empty
Processing your request
Please wait while we process your request. Do not refresh the page.
import { Button } from "@/components/ui/button";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerEmpty() {
return (
<Empty css={{ w: "full" }}>
<EmptyHeader>
<EmptyMedia variant="icon">
<Spinner />
</EmptyMedia>
<EmptyTitle>Processing your request</EmptyTitle>
<EmptyDescription>
Please wait while we process your request. Do not refresh the page.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button variant="outline" size="sm">
Cancel
</Button>
</EmptyContent>
</Empty>
);
}
Item
Use the spinner inside <ItemMedia> to indicate a loading state.
Downloading...
129 MB / 1000 MB
import { styled } from "styled-system/jsx";
import { Button } from "@/components/ui/button";
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemFooter,
ItemMedia,
ItemTitle,
} from "@/components/ui/item";
import { Progress } from "@/components/ui/progress";
import { Spinner } from "@/components/ui/spinner";
export default function SpinnerItem() {
return (
<styled.div css={{ display: "flex", w: "full", maxW: "md", flexDir: "column", gap: "4" }}>
<Item variant="outline">
<ItemMedia variant="icon">
<Spinner />
</ItemMedia>
<ItemContent>
<ItemTitle>Downloading...</ItemTitle>
<ItemDescription>129 MB / 1000 MB</ItemDescription>
</ItemContent>
<ItemActions css={{ display: "none", sm: { display: "flex" } }}>
<Button variant="outline" size="sm" css={{ rounded: "1rem" }}>
Cancel
</Button>
</ItemActions>
<ItemFooter>
<Progress value={75} css={{ h: "2" }} />
</ItemFooter>
</Item>
</styled.div>
);
}
API Reference
Spinner
Use the Spinner component to display a spinner.
| Prop | Type | Default |
|---|---|---|
css | SystemStyleObject |
<Spinner />