Skip to content

Commit

Permalink
feat: ✨ new spinner component
Browse files Browse the repository at this point in the history
  • Loading branch information
flixlix committed Apr 20, 2024
1 parent 9aaaf42 commit 3d8f691
Show file tree
Hide file tree
Showing 16 changed files with 569 additions and 36 deletions.
76 changes: 67 additions & 9 deletions apps/www/__registry__/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,17 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"spinner": {
name: "spinner",
type: "components:ui",
registryDependencies: undefined,
component: React.lazy(() => import("@/registry/default/ui/spinner")),
source: "",
files: ["registry/default/ui/spinner.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"switch": {
name: "switch",
type: "components:ui",
Expand Down Expand Up @@ -1589,6 +1600,28 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"spinner-demo": {
name: "spinner-demo",
type: "components:example",
registryDependencies: ["spinner"],
component: React.lazy(() => import("@/registry/default/example/spinner-demo")),
source: "",
files: ["registry/default/example/spinner-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"spinner-size": {
name: "spinner-size",
type: "components:example",
registryDependencies: ["spinner"],
component: React.lazy(() => import("@/registry/default/example/spinner-size")),
source: "",
files: ["registry/default/example/spinner-size.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"switch-demo": {
name: "switch-demo",
type: "components:example",
Expand Down Expand Up @@ -2802,6 +2835,17 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"spinner": {
name: "spinner",
type: "components:ui",
registryDependencies: undefined,
component: React.lazy(() => import("@/registry/new-york/ui/spinner")),
source: "",
files: ["registry/new-york/ui/spinner.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"switch": {
name: "switch",
type: "components:ui",
Expand Down Expand Up @@ -3979,6 +4023,28 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"spinner-demo": {
name: "spinner-demo",
type: "components:example",
registryDependencies: ["spinner"],
component: React.lazy(() => import("@/registry/new-york/example/spinner-demo")),
source: "",
files: ["registry/new-york/example/spinner-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"spinner-size": {
name: "spinner-size",
type: "components:example",
registryDependencies: ["spinner"],
component: React.lazy(() => import("@/registry/new-york/example/spinner-size")),
source: "",
files: ["registry/new-york/example/spinner-size.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"switch-demo": {
name: "switch-demo",
type: "components:example",
Expand Down Expand Up @@ -4525,20 +4591,12 @@ export const Index: Record<string, any> = {
subcategory: "Dashboard",
chunks: [{
name: "dashboard-06-chunk-0",
description: "A breadcrumb with two links and a page indicator.",
description: "A list of products in a table with actions. Each row has an image, name, status, price, total sales, created at and actions.",
component: React.lazy(() => import("@/registry/new-york/block/dashboard-06-chunk-0")),
file: "registry/new-york/block/dashboard-06-chunk-0.tsx",
container: {
className: "undefined"
}
},{
name: "dashboard-06-chunk-1",
description: "A list of products in a table with actions. Each row has an image, name, status, price, total sales, created at and actions.",
component: React.lazy(() => import("@/registry/new-york/block/dashboard-06-chunk-1")),
file: "registry/new-york/block/dashboard-06-chunk-1.tsx",
container: {
className: "undefined"
}
}]
},
"dashboard-07": {
Expand Down
5 changes: 5 additions & 0 deletions apps/www/config/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ export const docsConfig: DocsConfig = {
href: "/docs/components/sonner",
items: [],
},
{
title: "Spinner",
href: "/docs/components/spinner",
items: [],
},
{
title: "Switch",
href: "/docs/components/switch",
Expand Down
66 changes: 66 additions & 0 deletions apps/www/content/docs/components/spinner.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Spinner
description: Renders a loading indicator.
component: true
---

<ComponentPreview name="spinner-demo" />

## About

The Spinner is built and maintained by [flixlix](https://luca-felix.com).

## Installation

<Tabs defaultValue="cli">

<TabsList>
<TabsTrigger value="cli">CLI</TabsTrigger>
<TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">

<Steps>

<Step>Run the following command:</Step>

```bash
npx shadcn-ui@latest add spinner
```

<Step>Add the `spinner` animation to your tailwind config</Step>
```js title="tailwind.config.js" {9-12, 16}
/** @type {import('tailwindcss').Config} */
module.exports = {
...
theme: {
extend: {
...
keyframes: {
...
"spinner": {
"0%": { opacity: 1 },
"to": { opacity: .15 }
}
},
animation: {
...
"spinner": "spinner 1.2s linear infinite"
},
},
},
...
}
```

</Steps>

</TabsContent>

</Tabs>

## Examples

### custom size

<ComponentPreview name="spinner-size" />
10 changes: 10 additions & 0 deletions apps/www/public/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,16 @@
],
"type": "components:ui"
},
{
"name": "spinner",
"dependencies": [
"spinner"
],
"files": [
"ui/spinner.tsx"
],
"type": "components:ui"
},
{
"name": "switch",
"dependencies": [
Expand Down
13 changes: 13 additions & 0 deletions apps/www/public/registry/styles/default/spinner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "spinner",
"dependencies": [
"spinner"
],
"files": [
{
"name": "spinner.tsx",
"content": "import React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Spinner = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<\"div\">\n>(({ className, ...props }, ref) => {\n const computeDelay = (i: number) => `${-1.2 + i * 0.1}s`\n const computeRotation = (i: number) => `${i * 30}deg`\n return (\n <div\n className={cn(\"size-5\", className)}\n role=\"status\"\n aria-label=\"Loading\"\n ref={ref}\n {...props}\n >\n <div className=\"relative left-1/2 top-1/2 size-full\">\n {[...Array(12)].map((_, i) => (\n <div\n key={i}\n className=\"absolute left-[-10%] top-[-3.9%] h-[8%] w-[24%] animate-spinner rounded-full bg-foreground\"\n style={{\n animationDelay: computeDelay(i),\n transform: `rotate(${computeRotation(i)}) translate(146%)`,\n }}\n />\n ))}\n </div>\n </div>\n )\n})\nSpinner.displayName = \"Spinner\"\n\nexport { Spinner }\n"
}
],
"type": "components:ui"
}
13 changes: 13 additions & 0 deletions apps/www/public/registry/styles/new-york/spinner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "spinner",
"dependencies": [
"spinner"
],
"files": [
{
"name": "spinner.tsx",
"content": "import React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Spinner = React.forwardRef<\n HTMLDivElement,\n React.ComponentPropsWithoutRef<\"div\">\n>(({ className, ...props }, ref) => {\n const computeDelay = (i: number) => `${-1.2 + i * 0.1}s`\n const computeRotation = (i: number) => `${i * 30}deg`\n return (\n <div\n className={cn(\"size-5\", className)}\n role=\"status\"\n aria-label=\"Loading\"\n ref={ref}\n {...props}\n >\n <div className=\"relative left-1/2 top-1/2 size-full\">\n {[...Array(12)].map((_, i) => (\n <div\n key={i}\n className=\"absolute left-[-10%] top-[-3.9%] h-[8%] w-[24%] animate-spinner bg-foreground\"\n style={{\n animationDelay: computeDelay(i),\n transform: `rotate(${computeRotation(i)}) translate(146%)`,\n }}\n />\n ))}\n </div>\n </div>\n )\n})\nSpinner.displayName = \"Spinner\"\n\nexport { Spinner }\n"
}
],
"type": "components:ui"
}
5 changes: 5 additions & 0 deletions apps/www/registry/default/example/spinner-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Spinner } from "@/registry/default/ui/spinner"

export default function SpinnerDemo() {
return <Spinner />
}
5 changes: 5 additions & 0 deletions apps/www/registry/default/example/spinner-size.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Spinner } from "@/registry/default/ui/spinner"

export default function SpinnerSize() {
return <Spinner className="size-8" />
}
36 changes: 36 additions & 0 deletions apps/www/registry/default/ui/spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react"

import { cn } from "@/lib/utils"

const Spinner = React.forwardRef<
HTMLDivElement,
React.ComponentPropsWithoutRef<"div">
>(({ className, ...props }, ref) => {
const computeDelay = (i: number) => `${-1.2 + i * 0.1}s`
const computeRotation = (i: number) => `${i * 30}deg`
return (
<div
className={cn("size-5", className)}
role="status"
aria-label="Loading"
ref={ref}
{...props}
>
<div className="relative left-1/2 top-1/2 size-full">
{[...Array(12)].map((_, i) => (
<div
key={i}
className="absolute left-[-10%] top-[-3.9%] h-[8%] w-[24%] animate-spinner rounded-full bg-foreground"
style={{
animationDelay: computeDelay(i),
transform: `rotate(${computeRotation(i)}) translate(146%)`,
}}
/>
))}
</div>
</div>
)
})
Spinner.displayName = "Spinner"

export { Spinner }
12 changes: 12 additions & 0 deletions apps/www/registry/examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,18 @@ export const examples: Registry = [
registryDependencies: ["sonner"],
files: ["example/sonner-demo.tsx"],
},
{
name: "spinner-demo",
type: "components:example",
registryDependencies: ["spinner"],
files: ["example/spinner-demo.tsx"],
},
{
name: "spinner-size",
type: "components:example",
registryDependencies: ["spinner"],
files: ["example/spinner-size.tsx"],
},
{
name: "switch-demo",
type: "components:example",
Expand Down

0 comments on commit 3d8f691

Please sign in to comment.