mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-02 08:58:36 +00:00
Compare commits
117 Commits
shadcn/cli
...
shadcn-ui@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7c42169a6 | ||
|
|
2c2fe97eb9 | ||
|
|
d64374d009 | ||
|
|
e24e51a2fa | ||
|
|
cdfecd1d97 | ||
|
|
2c043e709f | ||
|
|
aed19aa911 | ||
|
|
9e35d229ae | ||
|
|
db1975ef4d | ||
|
|
961e0b62d7 | ||
|
|
70c684c224 | ||
|
|
4ff64ba818 | ||
|
|
500a353816 | ||
|
|
c830780d62 | ||
|
|
debd51a854 | ||
|
|
78426dd862 | ||
|
|
6e47a94a8f | ||
|
|
ab6a856930 | ||
|
|
b33d3868e9 | ||
|
|
9e0a86122a | ||
|
|
2b276de95a | ||
|
|
64739f8399 | ||
|
|
f0cff7e0eb | ||
|
|
e242adaa9c | ||
|
|
986c00ee0e | ||
|
|
d0eece06d4 | ||
|
|
0a0a566a4e | ||
|
|
bf5a79c4d4 | ||
|
|
f02b412478 | ||
|
|
0d31293c7b | ||
|
|
3d1d19fc1b | ||
|
|
e5b56c84a9 | ||
|
|
630afe836e | ||
|
|
52c12bc27a | ||
|
|
182f2083cd | ||
|
|
3febcdc523 | ||
|
|
ced2513137 | ||
|
|
93ae8bd67f | ||
|
|
3259fb7ca1 | ||
|
|
d8397d80a8 | ||
|
|
06e74fce78 | ||
|
|
bc9e5eaaab | ||
|
|
c9b69d0836 | ||
|
|
539212c49e | ||
|
|
123887c36c | ||
|
|
35c1ba57c2 | ||
|
|
b34516f471 | ||
|
|
66b95402c1 | ||
|
|
5460177a7a | ||
|
|
b0049c2266 | ||
|
|
4e6e21f094 | ||
|
|
3b808c83be | ||
|
|
0e6b37e99a | ||
|
|
9ec433838f | ||
|
|
444ff70590 | ||
|
|
27bc5deff1 | ||
|
|
cacd7c8798 | ||
|
|
f227f93742 | ||
|
|
87e099a3d7 | ||
|
|
303d65718c | ||
|
|
909219df14 | ||
|
|
e8ada4e3c7 | ||
|
|
8fc80836ff | ||
|
|
d0a308cc64 | ||
|
|
e461c02389 | ||
|
|
50c2f6045a | ||
|
|
14aca65eee | ||
|
|
14c952b594 | ||
|
|
1e9434e6f9 | ||
|
|
f3d14c48cb | ||
|
|
c668c35bb9 | ||
|
|
1297abc882 | ||
|
|
36ebbf26dc | ||
|
|
a2abc4ad95 | ||
|
|
4b546bfb13 | ||
|
|
5fc9ade413 | ||
|
|
96880e7c9a | ||
|
|
7dfdb029e7 | ||
|
|
28f34ed3c3 | ||
|
|
bd54184e60 | ||
|
|
ce3adfa075 | ||
|
|
674807c1b4 | ||
|
|
c62167a449 | ||
|
|
061083006f | ||
|
|
1af66c2d08 | ||
|
|
0993d98cc7 | ||
|
|
52d223393a | ||
|
|
207b69fe8d | ||
|
|
408760a93b | ||
|
|
a9ab7afebf | ||
|
|
b6221ea524 | ||
|
|
9ef7967b0d | ||
|
|
64b2f1a5ad | ||
|
|
f4ca57a79c | ||
|
|
99ff9caf71 | ||
|
|
cd9a55b76a | ||
|
|
49373eed96 | ||
|
|
078dfe6607 | ||
|
|
77fc5ec8db | ||
|
|
cfba3fdf70 | ||
|
|
4e4118f3cf | ||
|
|
faa7a67fb3 | ||
|
|
701e1160ea | ||
|
|
f5931f8d09 | ||
|
|
5a28937c6e | ||
|
|
0b74059d38 | ||
|
|
fab9877586 | ||
|
|
0f7591f67c | ||
|
|
81c7e44863 | ||
|
|
2fac3e40c2 | ||
|
|
5ad11ff851 | ||
|
|
6b92dd8eaf | ||
|
|
84540f551d | ||
|
|
99588fff8f | ||
|
|
f99cd2aa5d | ||
|
|
a62a155aac | ||
|
|
dc8853c8df |
@@ -7,5 +7,5 @@
|
|||||||
"access": "public",
|
"access": "public",
|
||||||
"baseBranch": "main",
|
"baseBranch": "main",
|
||||||
"updateInternalDependencies": "patch",
|
"updateInternalDependencies": "patch",
|
||||||
"ignore": ["www", "**-template"]
|
"ignore": ["www"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
"shadcn-ui": patch
|
|
||||||
---
|
|
||||||
|
|
||||||
update zod imports
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"plugin:tailwindcss/recommended"
|
"plugin:tailwindcss/recommended"
|
||||||
],
|
],
|
||||||
"plugins": ["tailwindcss"],
|
"plugins": ["tailwindcss"],
|
||||||
|
"ignorePatterns": ["**/fixtures/**"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"@next/next/no-html-link-for-pages": "off",
|
"@next/next/no-html-link-for-pages": "off",
|
||||||
"tailwindcss/no-custom-classname": "off",
|
"tailwindcss/no-custom-classname": "off",
|
||||||
|
|||||||
2
.github/version-script-beta.js
vendored
2
.github/version-script-beta.js
vendored
@@ -4,7 +4,7 @@
|
|||||||
import { exec } from "child_process"
|
import { exec } from "child_process"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
|
|
||||||
const pkgJsonPath = "packages/cli/package.json"
|
const pkgJsonPath = "packages/shadcn/package.json"
|
||||||
try {
|
try {
|
||||||
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath))
|
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath))
|
||||||
exec("git rev-parse --short HEAD", (err, stdout) => {
|
exec("git rev-parse --short HEAD", (err, stdout) => {
|
||||||
|
|||||||
2
.github/version-script-next.js
vendored
2
.github/version-script-next.js
vendored
@@ -4,7 +4,7 @@
|
|||||||
import { exec } from "child_process"
|
import { exec } from "child_process"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
|
|
||||||
const pkgJsonPath = "packages/cli/package.json"
|
const pkgJsonPath = "packages/shadcn/package.json"
|
||||||
try {
|
try {
|
||||||
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath))
|
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath))
|
||||||
exec("git rev-parse --short HEAD", (err, stdout) => {
|
exec("git rev-parse --short HEAD", (err, stdout) => {
|
||||||
|
|||||||
9
.github/workflows/issue-stale.yml
vendored
9
.github/workflows/issue-stale.yml
vendored
@@ -16,11 +16,12 @@ jobs:
|
|||||||
name: "Close stale issues with no reproduction"
|
name: "Close stale issues with no reproduction"
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.STALE_TOKEN }}
|
repo-token: ${{ secrets.STALE_TOKEN }}
|
||||||
close-issue-message: "This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you."
|
close-issue-message: "This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please reopen or leave a comment. Thank you.\n(This is an automated message.)"
|
||||||
days-before-issue-close: 7
|
days-before-issue-close: 7
|
||||||
days-before-issue-stale: 15
|
days-before-issue-stale: 30
|
||||||
stale-pr-label: "stale?"
|
stale-pr-label: "stale?"
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: 7
|
||||||
days-before-pr-stale: -1
|
days-before-pr-stale: 15
|
||||||
|
only-pr-labels: "postpone: more info or changes requested,please add a reproduction"
|
||||||
exempt-issue-labels: "roadmap,next,bug"
|
exempt-issue-labels: "roadmap,next,bug"
|
||||||
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
|
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
|
||||||
|
|||||||
4
.github/workflows/prerelease-comment.yml
vendored
4
.github/workflows/prerelease-comment.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
|
|
||||||
for (const artifact of allArtifacts.data.artifacts) {
|
for (const artifact of allArtifacts.data.artifacts) {
|
||||||
// Extract the PR number and package version from the artifact name
|
// Extract the PR number and package version from the artifact name
|
||||||
const match = /^npm-package-shadcn-ui@(.*?)-pr-(\d+)/.exec(artifact.name);
|
const match = /^npm-package-shadcn@(.*?)-pr-(\d+)/.exec(artifact.name);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
require("fs").appendFileSync(
|
require("fs").appendFileSync(
|
||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
A new prerelease is available for testing:
|
A new prerelease is available for testing:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npx shadcn-ui@${{ env.BETA_PACKAGE_VERSION }}
|
npx shadcn@${{ env.BETA_PACKAGE_VERSION }}
|
||||||
```
|
```
|
||||||
|
|
||||||
- name: "Remove the autorelease label once published"
|
- name: "Remove the autorelease label once published"
|
||||||
|
|||||||
10
.github/workflows/prerelease.yml
vendored
10
.github/workflows/prerelease.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
|||||||
run: node .github/version-script-beta.js
|
run: node .github/version-script-beta.js
|
||||||
|
|
||||||
- name: Authenticate to NPM
|
- name: Authenticate to NPM
|
||||||
run: echo "//registry.npmjs.org/:_authToken=$NPM_ACCESS_TOKEN" >> packages/cli/.npmrc
|
run: echo "//registry.npmjs.org/:_authToken=$NPM_ACCESS_TOKEN" >> packages/shadcn/.npmrc
|
||||||
env:
|
env:
|
||||||
NPM_ACCESS_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
|
NPM_ACCESS_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
|
||||||
|
|
||||||
@@ -51,10 +51,10 @@ jobs:
|
|||||||
id: package-version
|
id: package-version
|
||||||
uses: martinbeentjes/npm-get-version-action@main
|
uses: martinbeentjes/npm-get-version-action@main
|
||||||
with:
|
with:
|
||||||
path: packages/cli
|
path: packages/shadcn
|
||||||
|
|
||||||
- name: Upload packaged artifact
|
- name: Upload packaged artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: npm-package-shadcn-ui@${{ steps.package-version.outputs.current-version }}-pr-${{ github.event.number }} # encode the PR number into the artifact name
|
name: npm-package-shadcn@${{ steps.package-version.outputs.current-version }}-pr-${{ github.event.number }} # encode the PR number into the artifact name
|
||||||
path: packages/cli/dist/index.js
|
path: packages/shadcn/dist/index.js
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
|||||||
# run: pnpm check
|
# run: pnpm check
|
||||||
|
|
||||||
- name: Build the package
|
- name: Build the package
|
||||||
run: pnpm build:cli
|
run: pnpm shadcn:build
|
||||||
|
|
||||||
- name: Create Version PR or Publish to NPM
|
- name: Create Version PR or Publish to NPM
|
||||||
id: changesets
|
id: changesets
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -34,3 +34,8 @@ yarn-error.log*
|
|||||||
|
|
||||||
.contentlayer
|
.contentlayer
|
||||||
tsconfig.tsbuildinfo
|
tsconfig.tsbuildinfo
|
||||||
|
|
||||||
|
# ide
|
||||||
|
.idea
|
||||||
|
.fleet
|
||||||
|
.vscode
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ node_modules
|
|||||||
build
|
build
|
||||||
.contentlayer
|
.contentlayer
|
||||||
apps/www/pages/api/registry.json
|
apps/www/pages/api/registry.json
|
||||||
|
**/fixtures
|
||||||
|
|||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -6,5 +6,10 @@
|
|||||||
"tailwindCSS.experimental.classRegex": [
|
"tailwindCSS.experimental.classRegex": [
|
||||||
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
|
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
|
||||||
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
|
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
|
||||||
|
],
|
||||||
|
"vitest.debugExclude": [
|
||||||
|
"<node_internals>/**",
|
||||||
|
"**/node_modules/**",
|
||||||
|
"**/fixtures/**"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
273
apps/www/__registry__/default/block/_sink/page.tsx
Normal file
273
apps/www/__registry__/default/block/_sink/page.tsx
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
import { AccordionDemo } from "@/registry/default/block/_sink/components/accordion-demo"
|
||||||
|
import { AlertDemo } from "@/registry/default/block/_sink/components/alert-demo"
|
||||||
|
import { AlertDialogDemo } from "@/registry/default/block/_sink/components/alert-dialog-demo"
|
||||||
|
import { AppSidebar } from "@/registry/default/block/_sink/components/app-sidebar"
|
||||||
|
import { AspectRatioDemo } from "@/registry/default/block/_sink/components/aspect-ratio-demo"
|
||||||
|
import { AvatarDemo } from "@/registry/default/block/_sink/components/avatar-demo"
|
||||||
|
import { BadgeDemo } from "@/registry/default/block/_sink/components/badge-demo"
|
||||||
|
import { BadgeDestructive } from "@/registry/default/block/_sink/components/badge-destructive"
|
||||||
|
import { BadgeOutline } from "@/registry/default/block/_sink/components/badge-outline"
|
||||||
|
import { BadgeSecondary } from "@/registry/default/block/_sink/components/badge-secondary"
|
||||||
|
import { BreadcrumbDemo } from "@/registry/default/block/_sink/components/breadcrumb-demo"
|
||||||
|
import { ButtonDemo } from "@/registry/default/block/_sink/components/button-demo"
|
||||||
|
import { ButtonDestructive } from "@/registry/default/block/_sink/components/button-destructive"
|
||||||
|
import { ButtonGhost } from "@/registry/default/block/_sink/components/button-ghost"
|
||||||
|
import { ButtonLink } from "@/registry/default/block/_sink/components/button-link"
|
||||||
|
import { ButtonLoading } from "@/registry/default/block/_sink/components/button-loading"
|
||||||
|
import { ButtonOutline } from "@/registry/default/block/_sink/components/button-outline"
|
||||||
|
import { ButtonSecondary } from "@/registry/default/block/_sink/components/button-secondary"
|
||||||
|
import { ButtonWithIcon } from "@/registry/default/block/_sink/components/button-with-icon"
|
||||||
|
import { CalendarDemo } from "@/registry/default/block/_sink/components/calendar-demo"
|
||||||
|
import { CardDemo } from "@/registry/default/block/_sink/components/card-demo"
|
||||||
|
import { CarouselDemo } from "@/registry/default/block/_sink/components/carousel-demo"
|
||||||
|
import { CheckboxDemo } from "@/registry/default/block/_sink/components/checkbox-demo"
|
||||||
|
import { CollapsibleDemo } from "@/registry/default/block/_sink/components/collapsible-demo"
|
||||||
|
import { ComboboxDemo } from "@/registry/default/block/_sink/components/combobox-demo"
|
||||||
|
import { CommandDemo } from "@/registry/default/block/_sink/components/command-demo"
|
||||||
|
import { ComponentWrapper } from "@/registry/default/block/_sink/components/component-wrapper"
|
||||||
|
import { ContextMenuDemo } from "@/registry/default/block/_sink/components/context-menu-demo"
|
||||||
|
import { DatePickerDemo } from "@/registry/default/block/_sink/components/date-picker-demo"
|
||||||
|
import { DialogDemo } from "@/registry/default/block/_sink/components/dialog-demo"
|
||||||
|
import { DrawerDemo } from "@/registry/default/block/_sink/components/drawer-demo"
|
||||||
|
import { DropdownMenuDemo } from "@/registry/default/block/_sink/components/dropdown-menu-demo"
|
||||||
|
import { HoverCardDemo } from "@/registry/default/block/_sink/components/hover-card-demo"
|
||||||
|
import { InputDemo } from "@/registry/default/block/_sink/components/input-demo"
|
||||||
|
import { InputOTPDemo } from "@/registry/default/block/_sink/components/input-otp-demo"
|
||||||
|
import { LabelDemo } from "@/registry/default/block/_sink/components/label-demo"
|
||||||
|
import { MenubarDemo } from "@/registry/default/block/_sink/components/menubar-demo"
|
||||||
|
import { NavigationMenuDemo } from "@/registry/default/block/_sink/components/navigation-menu-demo"
|
||||||
|
import { PaginationDemo } from "@/registry/default/block/_sink/components/pagination-demo"
|
||||||
|
import { PopoverDemo } from "@/registry/default/block/_sink/components/popover-demo"
|
||||||
|
import { ProgressDemo } from "@/registry/default/block/_sink/components/progress-demo"
|
||||||
|
import { RadioGroupDemo } from "@/registry/default/block/_sink/components/radio-group-demo"
|
||||||
|
import { ResizableHandleDemo } from "@/registry/default/block/_sink/components/resizable-handle"
|
||||||
|
import { ScrollAreaDemo } from "@/registry/default/block/_sink/components/scroll-area-demo"
|
||||||
|
import { SelectDemo } from "@/registry/default/block/_sink/components/select-demo"
|
||||||
|
import { SeparatorDemo } from "@/registry/default/block/_sink/components/separator-demo"
|
||||||
|
import { SheetDemo } from "@/registry/default/block/_sink/components/sheet-demo"
|
||||||
|
import { SkeletonDemo } from "@/registry/default/block/_sink/components/skeleton-demo"
|
||||||
|
import { SliderDemo } from "@/registry/default/block/_sink/components/slider-demo"
|
||||||
|
import { SonnerDemo } from "@/registry/default/block/_sink/components/sonner-demo"
|
||||||
|
import { SwitchDemo } from "@/registry/default/block/_sink/components/switch-demo"
|
||||||
|
import { TableDemo } from "@/registry/default/block/_sink/components/table-demo"
|
||||||
|
import { TabsDemo } from "@/registry/default/block/_sink/components/tabs-demo"
|
||||||
|
import { TextareaDemo } from "@/registry/default/block/_sink/components/textarea-demo"
|
||||||
|
import { ToastDemo } from "@/registry/default/block/_sink/components/toast-demo"
|
||||||
|
import { ToggleDemo } from "@/registry/default/block/_sink/components/toggle-demo"
|
||||||
|
import { ToggleDisabled } from "@/registry/default/block/_sink/components/toggle-disabled"
|
||||||
|
import { ToggleGroupDemo } from "@/registry/default/block/_sink/components/toggle-group-demo"
|
||||||
|
import { ToggleOutline } from "@/registry/default/block/_sink/components/toggle-outline"
|
||||||
|
import { ToggleWithText } from "@/registry/default/block/_sink/components/toggle-with-text"
|
||||||
|
import { TooltipDemo } from "@/registry/default/block/_sink/components/tooltip-demo"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function SinkPage() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
|
||||||
|
<div className="flex items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<ComponentWrapper name="Accordion">
|
||||||
|
<AccordionDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Alert">
|
||||||
|
<AlertDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="AlertDialog">
|
||||||
|
<AlertDialogDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="AspectRatio">
|
||||||
|
<AspectRatioDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Avatar">
|
||||||
|
<AvatarDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Badge">
|
||||||
|
<BadgeDemo />
|
||||||
|
<BadgeDestructive />
|
||||||
|
<BadgeOutline />
|
||||||
|
<BadgeSecondary />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Breadcrumb">
|
||||||
|
<BreadcrumbDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Button">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<ButtonDemo />
|
||||||
|
<ButtonDestructive />
|
||||||
|
<ButtonGhost />
|
||||||
|
<ButtonLink />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<ButtonLoading />
|
||||||
|
<ButtonOutline />
|
||||||
|
<ButtonSecondary />
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<ButtonWithIcon />
|
||||||
|
</div>
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Calendar">
|
||||||
|
<CalendarDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Card">
|
||||||
|
<CardDemo className="w-full" />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper
|
||||||
|
name="Carousel"
|
||||||
|
className="[&_.max-w-xs]:max-w-[70%]"
|
||||||
|
>
|
||||||
|
<CarouselDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Checkbox">
|
||||||
|
<CheckboxDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Collapsible">
|
||||||
|
<CollapsibleDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Combobox">
|
||||||
|
<ComboboxDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper
|
||||||
|
name="Command"
|
||||||
|
className="[&_[cmdk-root]]:md:min-w-max"
|
||||||
|
>
|
||||||
|
<CommandDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="ContextMenu">
|
||||||
|
<ContextMenuDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="DatePicker">
|
||||||
|
<DatePickerDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Dialog">
|
||||||
|
<DialogDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Drawer">
|
||||||
|
<DrawerDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="DropdownMenu">
|
||||||
|
<DropdownMenuDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="HoverCard">
|
||||||
|
<HoverCardDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Input">
|
||||||
|
<InputDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="InputOTP">
|
||||||
|
<InputOTPDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Label">
|
||||||
|
<LabelDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Menubar">
|
||||||
|
<MenubarDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="NavigationMenu" className="col-span-2">
|
||||||
|
<NavigationMenuDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Pagination">
|
||||||
|
<PaginationDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Popover">
|
||||||
|
<PopoverDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Progress">
|
||||||
|
<ProgressDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="RadioGroup">
|
||||||
|
<RadioGroupDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Resizable" className="col-span-2">
|
||||||
|
<ResizableHandleDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="ScrollArea">
|
||||||
|
<ScrollAreaDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Select">
|
||||||
|
<SelectDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Separator">
|
||||||
|
<SeparatorDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Sheet">
|
||||||
|
<SheetDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Skeleton">
|
||||||
|
<SkeletonDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Slider">
|
||||||
|
<SliderDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Sonner">
|
||||||
|
<SonnerDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Switch">
|
||||||
|
<SwitchDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Table" className="col-span-2">
|
||||||
|
<TableDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Tabs">
|
||||||
|
<TabsDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Textarea">
|
||||||
|
<TextareaDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Toast">
|
||||||
|
<ToastDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Toggle">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<ToggleDemo />
|
||||||
|
<ToggleDisabled />
|
||||||
|
<ToggleOutline />
|
||||||
|
<ToggleWithText />
|
||||||
|
</div>
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="ToggleGroup">
|
||||||
|
<ToggleGroupDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
<ComponentWrapper name="Tooltip">
|
||||||
|
<TooltipDemo />
|
||||||
|
</ComponentWrapper>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -56,7 +56,7 @@ export default function Dashboard() {
|
|||||||
<aside className="inset-y fixed left-0 z-20 flex h-full flex-col border-r">
|
<aside className="inset-y fixed left-0 z-20 flex h-full flex-col border-r">
|
||||||
<div className="border-b p-2">
|
<div className="border-b p-2">
|
||||||
<Button variant="outline" size="icon" aria-label="Home">
|
<Button variant="outline" size="icon" aria-label="Home">
|
||||||
<Triangle className="size-5 fill-foreground" />
|
<Triangle className="w-5 h-5 fill-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<nav className="grid gap-1 p-2">
|
<nav className="grid gap-1 p-2">
|
||||||
@@ -68,7 +68,7 @@ export default function Dashboard() {
|
|||||||
className="rounded-lg bg-muted"
|
className="rounded-lg bg-muted"
|
||||||
aria-label="Playground"
|
aria-label="Playground"
|
||||||
>
|
>
|
||||||
<SquareTerminal className="size-5" />
|
<SquareTerminal className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -83,7 +83,7 @@ export default function Dashboard() {
|
|||||||
className="rounded-lg"
|
className="rounded-lg"
|
||||||
aria-label="Models"
|
aria-label="Models"
|
||||||
>
|
>
|
||||||
<Bot className="size-5" />
|
<Bot className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -98,7 +98,7 @@ export default function Dashboard() {
|
|||||||
className="rounded-lg"
|
className="rounded-lg"
|
||||||
aria-label="API"
|
aria-label="API"
|
||||||
>
|
>
|
||||||
<Code2 className="size-5" />
|
<Code2 className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -113,7 +113,7 @@ export default function Dashboard() {
|
|||||||
className="rounded-lg"
|
className="rounded-lg"
|
||||||
aria-label="Documentation"
|
aria-label="Documentation"
|
||||||
>
|
>
|
||||||
<Book className="size-5" />
|
<Book className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -128,7 +128,7 @@ export default function Dashboard() {
|
|||||||
className="rounded-lg"
|
className="rounded-lg"
|
||||||
aria-label="Settings"
|
aria-label="Settings"
|
||||||
>
|
>
|
||||||
<Settings2 className="size-5" />
|
<Settings2 className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -145,7 +145,7 @@ export default function Dashboard() {
|
|||||||
className="mt-auto rounded-lg"
|
className="mt-auto rounded-lg"
|
||||||
aria-label="Help"
|
aria-label="Help"
|
||||||
>
|
>
|
||||||
<LifeBuoy className="size-5" />
|
<LifeBuoy className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -160,7 +160,7 @@ export default function Dashboard() {
|
|||||||
className="mt-auto rounded-lg"
|
className="mt-auto rounded-lg"
|
||||||
aria-label="Account"
|
aria-label="Account"
|
||||||
>
|
>
|
||||||
<SquareUser className="size-5" />
|
<SquareUser className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="right" sideOffset={5}>
|
<TooltipContent side="right" sideOffset={5}>
|
||||||
@@ -175,7 +175,7 @@ export default function Dashboard() {
|
|||||||
<Drawer>
|
<Drawer>
|
||||||
<DrawerTrigger asChild>
|
<DrawerTrigger asChild>
|
||||||
<Button variant="ghost" size="icon" className="md:hidden">
|
<Button variant="ghost" size="icon" className="md:hidden">
|
||||||
<Settings className="size-4" />
|
<Settings className="w-4 h-4" />
|
||||||
<span className="sr-only">Settings</span>
|
<span className="sr-only">Settings</span>
|
||||||
</Button>
|
</Button>
|
||||||
</DrawerTrigger>
|
</DrawerTrigger>
|
||||||
@@ -203,7 +203,7 @@ export default function Dashboard() {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="genesis">
|
<SelectItem value="genesis">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Rabbit className="size-5" />
|
<Rabbit className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -219,7 +219,7 @@ export default function Dashboard() {
|
|||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="explorer">
|
<SelectItem value="explorer">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Bird className="size-5" />
|
<Bird className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -235,7 +235,7 @@ export default function Dashboard() {
|
|||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="quantum">
|
<SelectItem value="quantum">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Turtle className="size-5" />
|
<Turtle className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -296,7 +296,7 @@ export default function Dashboard() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="ml-auto gap-1.5 text-sm"
|
className="ml-auto gap-1.5 text-sm"
|
||||||
>
|
>
|
||||||
<Share className="size-3.5" />
|
<Share className="w-3.5 h-3.5" />
|
||||||
Share
|
Share
|
||||||
</Button>
|
</Button>
|
||||||
</header>
|
</header>
|
||||||
@@ -322,7 +322,7 @@ export default function Dashboard() {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="genesis">
|
<SelectItem value="genesis">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Rabbit className="size-5" />
|
<Rabbit className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -338,7 +338,7 @@ export default function Dashboard() {
|
|||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="explorer">
|
<SelectItem value="explorer">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Bird className="size-5" />
|
<Bird className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -354,7 +354,7 @@ export default function Dashboard() {
|
|||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="quantum">
|
<SelectItem value="quantum">
|
||||||
<div className="flex items-start gap-3 text-muted-foreground">
|
<div className="flex items-start gap-3 text-muted-foreground">
|
||||||
<Turtle className="size-5" />
|
<Turtle className="w-5 h-5" />
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
<p>
|
<p>
|
||||||
Neural{" "}
|
Neural{" "}
|
||||||
@@ -435,7 +435,7 @@ export default function Dashboard() {
|
|||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button variant="ghost" size="icon">
|
<Button variant="ghost" size="icon">
|
||||||
<Paperclip className="size-4" />
|
<Paperclip className="w-4 h-4" />
|
||||||
<span className="sr-only">Attach file</span>
|
<span className="sr-only">Attach file</span>
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -444,7 +444,7 @@ export default function Dashboard() {
|
|||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button variant="ghost" size="icon">
|
<Button variant="ghost" size="icon">
|
||||||
<Mic className="size-4" />
|
<Mic className="w-4 h-4" />
|
||||||
<span className="sr-only">Use Microphone</span>
|
<span className="sr-only">Use Microphone</span>
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
@@ -452,7 +452,7 @@ export default function Dashboard() {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Button type="submit" size="sm" className="ml-auto gap-1.5">
|
<Button type="submit" size="sm" className="ml-auto gap-1.5">
|
||||||
Send Message
|
Send Message
|
||||||
<CornerDownLeft className="size-3.5" />
|
<CornerDownLeft className="w-3.5 h-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import {
|
||||||
|
Frame,
|
||||||
|
LifeBuoy,
|
||||||
|
Map,
|
||||||
|
PanelLeftClose,
|
||||||
|
PanelLeftOpen,
|
||||||
|
PieChart,
|
||||||
|
Send,
|
||||||
|
} from "lucide-react"
|
||||||
|
|
||||||
|
import { Button } from "@/registry/default/ui/button"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "Design Engineering",
|
||||||
|
url: "#",
|
||||||
|
icon: Frame,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sales & Marketing",
|
||||||
|
url: "#",
|
||||||
|
icon: PieChart,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel",
|
||||||
|
url: "#",
|
||||||
|
icon: Map,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Support",
|
||||||
|
url: "#",
|
||||||
|
icon: LifeBuoy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feedback",
|
||||||
|
url: "#",
|
||||||
|
icon: Send,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
const [open, setOpen] = React.useState(true)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarProvider open={open} onOpenChange={setOpen}>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{projects.map((project) => (
|
||||||
|
<SidebarMenuItem key={project.name}>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href={project.url}>
|
||||||
|
<project.icon />
|
||||||
|
<span>{project.name}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex items-center h-12 px-4 justify-between">
|
||||||
|
<Button
|
||||||
|
onClick={() => setOpen((open) => !open)}
|
||||||
|
size="sm"
|
||||||
|
variant="ghost"
|
||||||
|
>
|
||||||
|
{open ? <PanelLeftClose /> : <PanelLeftOpen />}
|
||||||
|
<span>{open ? "Close" : "Open"} Sidebar</span>
|
||||||
|
</Button>
|
||||||
|
</header>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
66
apps/www/__registry__/default/block/demo-sidebar-footer.tsx
Normal file
66
apps/www/__registry__/default/block/demo-sidebar-footer.tsx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { ChevronDown, ChevronUp, User2 } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/registry/default/ui/dropdown-menu"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarFooter,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarHeader />
|
||||||
|
<SidebarContent />
|
||||||
|
<SidebarFooter>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<SidebarMenuButton className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground">
|
||||||
|
Username
|
||||||
|
<ChevronUp className="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent
|
||||||
|
side="top"
|
||||||
|
className="w-[--radix-popper-anchor-width]"
|
||||||
|
>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Account</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Billing</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Sign out</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarFooter>
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex items-center justify-between px-4 h-12">
|
||||||
|
<SidebarTrigger />
|
||||||
|
</header>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChevronDown,
|
||||||
|
Frame,
|
||||||
|
LifeBuoy,
|
||||||
|
Map,
|
||||||
|
PieChart,
|
||||||
|
Plus,
|
||||||
|
Send,
|
||||||
|
} from "lucide-react"
|
||||||
|
import { Toaster, toast } from "sonner"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupAction,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Toaster
|
||||||
|
position="bottom-left"
|
||||||
|
toastOptions={{
|
||||||
|
className: "ml-[160px]",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupAction
|
||||||
|
title="Add Project"
|
||||||
|
onClick={() => toast("You clicked the group action!")}
|
||||||
|
>
|
||||||
|
<Plus /> <span className="sr-only">Add Project</span>
|
||||||
|
</SidebarGroupAction>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href="#">
|
||||||
|
<Frame />
|
||||||
|
<span>Design Engineering</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href="#">
|
||||||
|
<PieChart />
|
||||||
|
<span>Sales & Marketing</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href="#">
|
||||||
|
<Map />
|
||||||
|
<span>Travel</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { ChevronDown, LifeBuoy, Send } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from "@/registry/default/ui/collapsible"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<Collapsible defaultOpen className="group/collapsible">
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel
|
||||||
|
asChild
|
||||||
|
className="text-sm hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
||||||
|
>
|
||||||
|
<CollapsibleTrigger>
|
||||||
|
Help
|
||||||
|
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
</SidebarGroupLabel>
|
||||||
|
<CollapsibleContent>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton>
|
||||||
|
<LifeBuoy />
|
||||||
|
Support
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton>
|
||||||
|
<Send />
|
||||||
|
Feedback
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</Collapsible>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
45
apps/www/__registry__/default/block/demo-sidebar-group.tsx
Normal file
45
apps/www/__registry__/default/block/demo-sidebar-group.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { LifeBuoy, Send } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Help</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton>
|
||||||
|
<LifeBuoy />
|
||||||
|
Support
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton>
|
||||||
|
<Send />
|
||||||
|
Feedback
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
apps/www/__registry__/default/block/demo-sidebar-header.tsx
Normal file
56
apps/www/__registry__/default/block/demo-sidebar-header.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { ChevronDown } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/registry/default/ui/dropdown-menu"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarHeader,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarHeader>
|
||||||
|
<SidebarMenu>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<SidebarMenuButton className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground">
|
||||||
|
Select Workspace
|
||||||
|
<ChevronDown className="ml-auto" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="w-[--radix-popper-anchor-width]">
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Acme Inc</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Acme Corp.</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarHeader>
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex items-center justify-between px-4 h-12">
|
||||||
|
<SidebarTrigger />
|
||||||
|
</header>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
104
apps/www/__registry__/default/block/demo-sidebar-menu-action.tsx
Normal file
104
apps/www/__registry__/default/block/demo-sidebar-menu-action.tsx
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Frame,
|
||||||
|
LifeBuoy,
|
||||||
|
Map,
|
||||||
|
MoreHorizontal,
|
||||||
|
PieChart,
|
||||||
|
Send,
|
||||||
|
} from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/registry/default/ui/dropdown-menu"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuAction,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "Design Engineering",
|
||||||
|
url: "#",
|
||||||
|
icon: Frame,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sales & Marketing",
|
||||||
|
url: "#",
|
||||||
|
icon: PieChart,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel",
|
||||||
|
url: "#",
|
||||||
|
icon: Map,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Support",
|
||||||
|
url: "#",
|
||||||
|
icon: LifeBuoy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feedback",
|
||||||
|
url: "#",
|
||||||
|
icon: Send,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{projects.map((project, index) => (
|
||||||
|
<SidebarMenuItem key={project.name}>
|
||||||
|
<SidebarMenuButton
|
||||||
|
asChild
|
||||||
|
className="group-has-[[data-state=open]]/menu-item:bg-sidebar-accent"
|
||||||
|
>
|
||||||
|
<a href={project.url}>
|
||||||
|
<project.icon />
|
||||||
|
<span>{project.name}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<SidebarMenuAction>
|
||||||
|
<MoreHorizontal />
|
||||||
|
<span className="sr-only">More</span>
|
||||||
|
</SidebarMenuAction>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent side="right" align="start">
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Edit Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<span>Delete Project</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Frame, LifeBuoy, Map, PieChart, Send } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuBadge,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "Design Engineering",
|
||||||
|
url: "#",
|
||||||
|
icon: Frame,
|
||||||
|
badge: "24",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sales & Marketing",
|
||||||
|
url: "#",
|
||||||
|
icon: PieChart,
|
||||||
|
badge: "12",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel",
|
||||||
|
url: "#",
|
||||||
|
icon: Map,
|
||||||
|
badge: "3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Support",
|
||||||
|
url: "#",
|
||||||
|
icon: LifeBuoy,
|
||||||
|
badge: "21",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feedback",
|
||||||
|
url: "#",
|
||||||
|
icon: Send,
|
||||||
|
badge: "8",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{projects.map((project) => (
|
||||||
|
<SidebarMenuItem key={project.name}>
|
||||||
|
<SidebarMenuButton
|
||||||
|
asChild
|
||||||
|
className="group-has-[[data-state=open]]/menu-item:bg-sidebar-accent"
|
||||||
|
>
|
||||||
|
<a href={project.url}>
|
||||||
|
<project.icon />
|
||||||
|
<span>{project.name}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<SidebarMenuBadge>{project.badge}</SidebarMenuBadge>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { ChevronRight } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from "@/registry/default/ui/collapsible"
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarMenuSub,
|
||||||
|
SidebarMenuSubButton,
|
||||||
|
SidebarMenuSubItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
title: "Getting Started",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Installation",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Project Structure",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Building Your Application",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Routing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Data Fetching",
|
||||||
|
url: "#",
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Rendering",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Caching",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Styling",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Optimizing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Configuring",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Testing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Authentication",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Deploying",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Upgrading",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Examples",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "API Reference",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Components",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "File Conventions",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Functions",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "next.config.js Options",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "CLI",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Edge Runtime",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Architecture",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Accessibility",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Fast Refresh",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Next.js Compiler",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Supported Browsers",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Turbopack",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<Collapsible
|
||||||
|
key={index}
|
||||||
|
className="group/collapsible"
|
||||||
|
defaultOpen={index === 0}
|
||||||
|
>
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<CollapsibleTrigger asChild>
|
||||||
|
<SidebarMenuButton>
|
||||||
|
<span>{item.title}</span>
|
||||||
|
<ChevronRight className="transition-transform ml-auto group-data-[state=open]/collapsible:rotate-90" />
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
<CollapsibleContent>
|
||||||
|
<SidebarMenuSub>
|
||||||
|
{item.items.map((subItem, subIndex) => (
|
||||||
|
<SidebarMenuSubItem key={subIndex}>
|
||||||
|
<SidebarMenuSubButton asChild>
|
||||||
|
<a href={subItem.url}>
|
||||||
|
<span>{subItem.title}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuSubButton>
|
||||||
|
</SidebarMenuSubItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenuSub>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
</Collapsible>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
180
apps/www/__registry__/default/block/demo-sidebar-menu-sub.tsx
Normal file
180
apps/www/__registry__/default/block/demo-sidebar-menu-sub.tsx
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarMenuSub,
|
||||||
|
SidebarMenuSubButton,
|
||||||
|
SidebarMenuSubItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
title: "Getting Started",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Installation",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Project Structure",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Building Your Application",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Routing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Data Fetching",
|
||||||
|
url: "#",
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Rendering",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Caching",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Styling",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Optimizing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Configuring",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Testing",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Authentication",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Deploying",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Upgrading",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Examples",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "API Reference",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Components",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "File Conventions",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Functions",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "next.config.js Options",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "CLI",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Edge Runtime",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Architecture",
|
||||||
|
url: "#",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
title: "Accessibility",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Fast Refresh",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Next.js Compiler",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Supported Browsers",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Turbopack",
|
||||||
|
url: "#",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<SidebarMenuItem key={index}>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href={item.url}>
|
||||||
|
<span>{item.title}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<SidebarMenuSub>
|
||||||
|
{item.items.map((subItem, subIndex) => (
|
||||||
|
<SidebarMenuSubItem key={subIndex}>
|
||||||
|
<SidebarMenuSubButton asChild>
|
||||||
|
<a href={subItem.url}>
|
||||||
|
<span>{subItem.title}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuSubButton>
|
||||||
|
</SidebarMenuSubItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenuSub>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
71
apps/www/__registry__/default/block/demo-sidebar-menu.tsx
Normal file
71
apps/www/__registry__/default/block/demo-sidebar-menu.tsx
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Frame, LifeBuoy, Map, PieChart, Send } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "Design Engineering",
|
||||||
|
url: "#",
|
||||||
|
icon: Frame,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sales & Marketing",
|
||||||
|
url: "#",
|
||||||
|
icon: PieChart,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel",
|
||||||
|
url: "#",
|
||||||
|
icon: Map,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Support",
|
||||||
|
url: "#",
|
||||||
|
icon: LifeBuoy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feedback",
|
||||||
|
url: "#",
|
||||||
|
icon: Send,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{projects.map((project) => (
|
||||||
|
<SidebarMenuItem key={project.name}>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href={project.url}>
|
||||||
|
<project.icon />
|
||||||
|
<span>{project.name}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
104
apps/www/__registry__/default/block/demo-sidebar-rsc.tsx
Normal file
104
apps/www/__registry__/default/block/demo-sidebar-rsc.tsx
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import { Frame, LifeBuoy, Map, PieChart, Send } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarMenuSkeleton,
|
||||||
|
SidebarProvider,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
const projects = [
|
||||||
|
{
|
||||||
|
name: "Design Engineering",
|
||||||
|
url: "#",
|
||||||
|
icon: Frame,
|
||||||
|
badge: "24",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sales & Marketing",
|
||||||
|
url: "#",
|
||||||
|
icon: PieChart,
|
||||||
|
badge: "12",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Travel",
|
||||||
|
url: "#",
|
||||||
|
icon: Map,
|
||||||
|
badge: "3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Support",
|
||||||
|
url: "#",
|
||||||
|
icon: LifeBuoy,
|
||||||
|
badge: "21",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Feedback",
|
||||||
|
url: "#",
|
||||||
|
icon: Send,
|
||||||
|
badge: "8",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// Dummy fetch function
|
||||||
|
async function fetchProjects() {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||||
|
return projects
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Projects</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<React.Suspense fallback={<NavProjectsSkeleton />}>
|
||||||
|
<NavProjects />
|
||||||
|
</React.Suspense>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function NavProjectsSkeleton() {
|
||||||
|
return (
|
||||||
|
<SidebarMenu>
|
||||||
|
{Array.from({ length: 5 }).map((_, index) => (
|
||||||
|
<SidebarMenuItem key={index}>
|
||||||
|
<SidebarMenuSkeleton showIcon />
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function NavProjects() {
|
||||||
|
const projects = await fetchProjects()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarMenu>
|
||||||
|
{projects.map((project) => (
|
||||||
|
<SidebarMenuItem key={project.name}>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href={project.url}>
|
||||||
|
<project.icon />
|
||||||
|
<span>{project.name}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
)
|
||||||
|
}
|
||||||
79
apps/www/__registry__/default/block/demo-sidebar.tsx
Normal file
79
apps/www/__registry__/default/block/demo-sidebar.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Calendar, Home, Inbox, Search, Settings } from "lucide-react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarGroup,
|
||||||
|
SidebarGroupContent,
|
||||||
|
SidebarGroupLabel,
|
||||||
|
SidebarInset,
|
||||||
|
SidebarMenu,
|
||||||
|
SidebarMenuButton,
|
||||||
|
SidebarMenuItem,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
// Menu items.
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
title: "Home",
|
||||||
|
url: "#",
|
||||||
|
icon: Home,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Inbox",
|
||||||
|
url: "#",
|
||||||
|
icon: Inbox,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Calendar",
|
||||||
|
url: "#",
|
||||||
|
icon: Calendar,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Search",
|
||||||
|
url: "#",
|
||||||
|
icon: Search,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Settings",
|
||||||
|
url: "#",
|
||||||
|
icon: Settings,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function AppSidebar() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<Sidebar>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Application</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu>
|
||||||
|
{items.map((item) => (
|
||||||
|
<SidebarMenuItem key={item.title}>
|
||||||
|
<SidebarMenuButton asChild>
|
||||||
|
<a href={item.url}>
|
||||||
|
<item.icon />
|
||||||
|
<span>{item.title}</span>
|
||||||
|
</a>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
))}
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
</Sidebar>
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex items-center justify-between px-4 h-12">
|
||||||
|
<SidebarTrigger />
|
||||||
|
</header>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
13
apps/www/__registry__/default/block/login-01.tsx
Normal file
13
apps/www/__registry__/default/block/login-01.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { LoginForm } from "@/registry/default/block/login-01/components/login-form"
|
||||||
|
|
||||||
|
export const iframeHeight = "870px"
|
||||||
|
|
||||||
|
export const containerClassName = "w-full h-full"
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen w-full items-center justify-center px-4">
|
||||||
|
<LoginForm />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
import { Button } from "@/registry/default/ui/button"
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/registry/default/ui/card"
|
||||||
|
import { Input } from "@/registry/default/ui/input"
|
||||||
|
import { Label } from "@/registry/default/ui/label"
|
||||||
|
|
||||||
|
export function LoginForm() {
|
||||||
|
return (
|
||||||
|
<Card className="mx-auto max-w-sm">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="text-2xl">Login</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Enter your email below to login to your account
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid gap-4">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="email">Email</Label>
|
||||||
|
<Input
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
placeholder="m@example.com"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Label htmlFor="password">Password</Label>
|
||||||
|
<Link href="#" className="ml-auto inline-block text-sm underline">
|
||||||
|
Forgot your password?
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<Input id="password" type="password" required />
|
||||||
|
</div>
|
||||||
|
<Button type="submit" className="w-full">
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
<Button variant="outline" className="w-full">
|
||||||
|
Login with Google
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 text-center text-sm">
|
||||||
|
Don't have an account?{" "}
|
||||||
|
<Link href="#" className="underline">
|
||||||
|
Sign up
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
15
apps/www/__registry__/default/block/login-01/page.tsx
Normal file
15
apps/www/__registry__/default/block/login-01/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { LoginForm } from "@/registry/default/block/login-01/components/login-form"
|
||||||
|
|
||||||
|
export const description = "A simple login form."
|
||||||
|
|
||||||
|
export const iframeHeight = "870px"
|
||||||
|
|
||||||
|
export const containerClassName = "w-full h-full"
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen w-full items-center justify-center px-4">
|
||||||
|
<LoginForm />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
25
apps/www/__registry__/default/block/sidebar-01.tsx
Normal file
25
apps/www/__registry__/default/block/sidebar-01.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-01/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
SidebarLayout,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/block/sidebar-01/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "870px"
|
||||||
|
|
||||||
|
export const containerClassName = "w-full h-full"
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
const { cookies } = await import("next/headers")
|
||||||
|
return (
|
||||||
|
<SidebarLayout
|
||||||
|
defaultOpen={cookies().get("sidebar:state")?.value === "true"}
|
||||||
|
>
|
||||||
|
<AppSidebar />
|
||||||
|
<main className="flex flex-1 flex-col p-2 transition-all duration-300 ease-in-out">
|
||||||
|
<div className="h-full rounded-md border-2 border-dashed p-2">
|
||||||
|
<SidebarTrigger />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</SidebarLayout>
|
||||||
|
)
|
||||||
|
}
|
||||||
55
apps/www/__registry__/default/block/sidebar-01/page.tsx
Normal file
55
apps/www/__registry__/default/block/sidebar-01/page.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-01/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description =
|
||||||
|
"A simple sidebar with navigation grouped by section."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
54
apps/www/__registry__/default/block/sidebar-02/page.tsx
Normal file
54
apps/www/__registry__/default/block/sidebar-02/page.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-02/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with collapsible sections."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex sticky top-0 bg-background h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
{Array.from({ length: 24 }).map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="aspect-video h-12 w-full rounded-lg bg-muted/50"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
apps/www/__registry__/default/block/sidebar-03/page.tsx
Normal file
56
apps/www/__registry__/default/block/sidebar-03/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-03/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with submenus."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b">
|
||||||
|
<div className="flex items-center gap-2 px-3">
|
||||||
|
<SidebarTrigger />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
60
apps/www/__registry__/default/block/sidebar-04/page.tsx
Normal file
60
apps/www/__registry__/default/block/sidebar-04/page.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-04/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A floating sidebar with submenus."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
"--sidebar-width": "19rem",
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
54
apps/www/__registry__/default/block/sidebar-05/page.tsx
Normal file
54
apps/www/__registry__/default/block/sidebar-05/page.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-05/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with collapsible submenus."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
54
apps/www/__registry__/default/block/sidebar-06/page.tsx
Normal file
54
apps/www/__registry__/default/block/sidebar-06/page.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-06/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with submenus as dropdowns."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
apps/www/__registry__/default/block/sidebar-07/page.tsx
Normal file
56
apps/www/__registry__/default/block/sidebar-07/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-07/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar that collapses to icons."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
|
||||||
|
<div className="flex items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
apps/www/__registry__/default/block/sidebar-08/page.tsx
Normal file
56
apps/www/__registry__/default/block/sidebar-08/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-08/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "An inset sidebar with secondary navigation."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2">
|
||||||
|
<div className="flex items-center gap-2 px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4 pt-0">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
58
apps/www/__registry__/default/block/sidebar-09/page.tsx
Normal file
58
apps/www/__registry__/default/block/sidebar-09/page.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-09/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "Collapsible nested sidebars."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
"--sidebar-width": "350px",
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="sticky top-0 flex shrink-0 items-center gap-2 border-b bg-background p-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">All Inboxes</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Inbox</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
{Array.from({ length: 24 }).map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="aspect-video h-12 w-full rounded-lg bg-muted/50"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
50
apps/www/__registry__/default/block/sidebar-10/page.tsx
Normal file
50
apps/www/__registry__/default/block/sidebar-10/page.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-10/components/app-sidebar"
|
||||||
|
import { NavActions } from "@/registry/default/block/sidebar-10/components/nav-actions"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar in a popover."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-14 shrink-0 items-center gap-2">
|
||||||
|
<div className="flex flex-1 items-center gap-2 px-3">
|
||||||
|
<SidebarTrigger />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage className="line-clamp-1">
|
||||||
|
Project Management & Task Tracking
|
||||||
|
</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
<div className="ml-auto px-3">
|
||||||
|
<NavActions />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 px-4 py-10">
|
||||||
|
<div className="mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50" />
|
||||||
|
<div className="mx-auto h-full w-full max-w-3xl rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
56
apps/www/__registry__/default/block/sidebar-11/page.tsx
Normal file
56
apps/www/__registry__/default/block/sidebar-11/page.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-11/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with a collapsible file tree."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">components</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">ui</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>button.tsx</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
45
apps/www/__registry__/default/block/sidebar-12/page.tsx
Normal file
45
apps/www/__registry__/default/block/sidebar-12/page.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-12/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar with a calendar."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<AppSidebar />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="sticky top-0 flex h-16 shrink-0 items-center gap-2 border-b bg-background px-4">
|
||||||
|
<SidebarTrigger className="-ml-1" />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>October 2024</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-5">
|
||||||
|
{Array.from({ length: 20 }).map((_, i) => (
|
||||||
|
<div key={i} className="aspect-square rounded-xl bg-muted/50" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
13
apps/www/__registry__/default/block/sidebar-13/page.tsx
Normal file
13
apps/www/__registry__/default/block/sidebar-13/page.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { SettingsDialog } from "@/registry/default/block/sidebar-13/components/settings-dialog"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar in a dialog."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<div className="flex h-svh items-center justify-center">
|
||||||
|
<SettingsDialog />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
52
apps/www/__registry__/default/block/sidebar-14/page.tsx
Normal file
52
apps/www/__registry__/default/block/sidebar-14/page.tsx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { AppSidebar } from "@/registry/default/block/sidebar-14/components/app-sidebar"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
BreadcrumbSeparator,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A sidebar on the right."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem className="hidden md:block">
|
||||||
|
<BreadcrumbLink href="#">
|
||||||
|
Building Your Application
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
<SidebarTrigger className="-mr-1 ml-auto rotate-180" />
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
<div className="aspect-video rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
<AppSidebar side="right" />
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
48
apps/www/__registry__/default/block/sidebar-15/page.tsx
Normal file
48
apps/www/__registry__/default/block/sidebar-15/page.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { SidebarLeft } from "@/registry/default/block/sidebar-15/components/sidebar-left"
|
||||||
|
import { SidebarRight } from "@/registry/default/block/sidebar-15/components/sidebar-right"
|
||||||
|
import {
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbList,
|
||||||
|
BreadcrumbPage,
|
||||||
|
} from "@/registry/default/ui/breadcrumb"
|
||||||
|
import { Separator } from "@/registry/default/ui/separator"
|
||||||
|
import {
|
||||||
|
SidebarInset,
|
||||||
|
SidebarProvider,
|
||||||
|
SidebarTrigger,
|
||||||
|
} from "@/registry/default/ui/sidebar"
|
||||||
|
|
||||||
|
export const iframeHeight = "800px"
|
||||||
|
|
||||||
|
export const description = "A left and right sidebar."
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<SidebarProvider>
|
||||||
|
<SidebarLeft />
|
||||||
|
<SidebarInset>
|
||||||
|
<header className="sticky top-0 flex h-14 shrink-0 items-center gap-2 bg-background">
|
||||||
|
<div className="flex flex-1 items-center gap-2 px-3">
|
||||||
|
<SidebarTrigger />
|
||||||
|
<Separator orientation="vertical" className="mr-2 h-4" />
|
||||||
|
<Breadcrumb>
|
||||||
|
<BreadcrumbList>
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbPage className="line-clamp-1">
|
||||||
|
Project Management & Task Tracking
|
||||||
|
</BreadcrumbPage>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</BreadcrumbList>
|
||||||
|
</Breadcrumb>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div className="flex flex-1 flex-col gap-4 p-4">
|
||||||
|
<div className="mx-auto h-24 w-full max-w-3xl rounded-xl bg-muted/50" />
|
||||||
|
<div className="mx-auto h-[100vh] w-full max-w-3xl rounded-xl bg-muted/50" />
|
||||||
|
</div>
|
||||||
|
</SidebarInset>
|
||||||
|
<SidebarRight />
|
||||||
|
</SidebarProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { AlertCircle } from "lucide-react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Alert,
|
|
||||||
AlertDescription,
|
|
||||||
AlertTitle,
|
|
||||||
} from "@/registry/default/ui/alert"
|
|
||||||
|
|
||||||
export default function AlertDestructive() {
|
|
||||||
return (
|
|
||||||
<Alert variant="destructive">
|
|
||||||
<AlertCircle className="h-4 w-4" />
|
|
||||||
<AlertTitle>Error</AlertTitle>
|
|
||||||
<AlertDescription>
|
|
||||||
Your session has expired. Please log in again.
|
|
||||||
</AlertDescription>
|
|
||||||
</Alert>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Breadcrumb,
|
|
||||||
BreadcrumbEllipsis,
|
|
||||||
BreadcrumbItem,
|
|
||||||
BreadcrumbLink,
|
|
||||||
BreadcrumbList,
|
|
||||||
BreadcrumbPage,
|
|
||||||
BreadcrumbSeparator,
|
|
||||||
} from "@/registry/default/ui/breadcrumb"
|
|
||||||
|
|
||||||
export default function BreadcrumbCollapsed() {
|
|
||||||
return (
|
|
||||||
<Breadcrumb>
|
|
||||||
<BreadcrumbList>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink asChild>
|
|
||||||
<Link href="/">Home</Link>
|
|
||||||
</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbEllipsis />
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink asChild>
|
|
||||||
<Link href="/docs/components">Components</Link>
|
|
||||||
</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
</BreadcrumbList>
|
|
||||||
</Breadcrumb>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Breadcrumb,
|
|
||||||
BreadcrumbItem,
|
|
||||||
BreadcrumbLink,
|
|
||||||
BreadcrumbList,
|
|
||||||
BreadcrumbPage,
|
|
||||||
BreadcrumbSeparator,
|
|
||||||
} from "@/registry/default/ui/breadcrumb"
|
|
||||||
|
|
||||||
export default function BreadcrumbWithCustomSeparator() {
|
|
||||||
return (
|
|
||||||
<Breadcrumb>
|
|
||||||
<BreadcrumbList>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink>
|
|
||||||
<Link href="/">Home</Link>
|
|
||||||
</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink>
|
|
||||||
<Link href="/components">Components</Link>
|
|
||||||
</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
</BreadcrumbList>
|
|
||||||
</Breadcrumb>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import { useMediaQuery } from "@/hooks/use-media-query"
|
|
||||||
import {
|
|
||||||
Breadcrumb,
|
|
||||||
BreadcrumbEllipsis,
|
|
||||||
BreadcrumbItem,
|
|
||||||
BreadcrumbLink,
|
|
||||||
BreadcrumbList,
|
|
||||||
BreadcrumbPage,
|
|
||||||
BreadcrumbSeparator,
|
|
||||||
} from "@/registry/default/ui/breadcrumb"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Drawer,
|
|
||||||
DrawerClose,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerDescription,
|
|
||||||
DrawerFooter,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerTitle,
|
|
||||||
DrawerTrigger,
|
|
||||||
} from "@/registry/default/ui/drawer"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
{ href: "#", label: "Home" },
|
|
||||||
{ href: "#", label: "Documentation" },
|
|
||||||
{ href: "#", label: "Building Your Application" },
|
|
||||||
{ href: "#", label: "Data Fetching" },
|
|
||||||
{ label: "Caching and Revalidating" },
|
|
||||||
]
|
|
||||||
|
|
||||||
const ITEMS_TO_DISPLAY = 3
|
|
||||||
|
|
||||||
export default function BreadcrumbResponsive() {
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
const isDesktop = useMediaQuery("(min-width: 768px)")
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Breadcrumb>
|
|
||||||
<BreadcrumbList>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink href={items[0].href}>{items[0].label}</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
{items.length > ITEMS_TO_DISPLAY ? (
|
|
||||||
<>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
{isDesktop ? (
|
|
||||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
|
||||||
<DropdownMenuTrigger
|
|
||||||
className="flex items-center gap-1"
|
|
||||||
aria-label="Toggle menu"
|
|
||||||
>
|
|
||||||
<BreadcrumbEllipsis className="h-4 w-4" />
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="start">
|
|
||||||
{items.slice(1, -2).map((item, index) => (
|
|
||||||
<DropdownMenuItem key={index}>
|
|
||||||
<Link href={item.href ? item.href : "#"}>
|
|
||||||
{item.label}
|
|
||||||
</Link>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
))}
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
) : (
|
|
||||||
<Drawer open={open} onOpenChange={setOpen}>
|
|
||||||
<DrawerTrigger aria-label="Toggle Menu">
|
|
||||||
<BreadcrumbEllipsis className="h-4 w-4" />
|
|
||||||
</DrawerTrigger>
|
|
||||||
<DrawerContent>
|
|
||||||
<DrawerHeader className="text-left">
|
|
||||||
<DrawerTitle>Navigate to</DrawerTitle>
|
|
||||||
<DrawerDescription>
|
|
||||||
Select a page to navigate to.
|
|
||||||
</DrawerDescription>
|
|
||||||
</DrawerHeader>
|
|
||||||
<div className="grid gap-1 px-4">
|
|
||||||
{items.slice(1, -2).map((item, index) => (
|
|
||||||
<Link
|
|
||||||
key={index}
|
|
||||||
href={item.href ? item.href : "#"}
|
|
||||||
className="py-1 text-sm"
|
|
||||||
>
|
|
||||||
{item.label}
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<DrawerFooter className="pt-4">
|
|
||||||
<DrawerClose asChild>
|
|
||||||
<Button variant="outline">Close</Button>
|
|
||||||
</DrawerClose>
|
|
||||||
</DrawerFooter>
|
|
||||||
</DrawerContent>
|
|
||||||
</Drawer>
|
|
||||||
)}
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
{items.slice(-ITEMS_TO_DISPLAY + 1).map((item, index) => (
|
|
||||||
<BreadcrumbItem key={index}>
|
|
||||||
{item.href ? (
|
|
||||||
<>
|
|
||||||
<BreadcrumbLink
|
|
||||||
asChild
|
|
||||||
className="max-w-20 truncate md:max-w-none"
|
|
||||||
>
|
|
||||||
<Link href={item.href}>{item.label}</Link>
|
|
||||||
</BreadcrumbLink>
|
|
||||||
<BreadcrumbSeparator />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<BreadcrumbPage className="max-w-20 truncate md:max-w-none">
|
|
||||||
{item.label}
|
|
||||||
</BreadcrumbPage>
|
|
||||||
)}
|
|
||||||
</BreadcrumbItem>
|
|
||||||
))}
|
|
||||||
</BreadcrumbList>
|
|
||||||
</Breadcrumb>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import { Slash } from "lucide-react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Breadcrumb,
|
|
||||||
BreadcrumbItem,
|
|
||||||
BreadcrumbLink,
|
|
||||||
BreadcrumbList,
|
|
||||||
BreadcrumbPage,
|
|
||||||
BreadcrumbSeparator,
|
|
||||||
} from "@/registry/default/ui/breadcrumb"
|
|
||||||
|
|
||||||
export default function BreadcrumbWithCustomSeparator() {
|
|
||||||
return (
|
|
||||||
<Breadcrumb>
|
|
||||||
<BreadcrumbList>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator>
|
|
||||||
<Slash />
|
|
||||||
</BreadcrumbSeparator>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbLink href="/components">Components</BreadcrumbLink>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
<BreadcrumbSeparator>
|
|
||||||
<Slash />
|
|
||||||
</BreadcrumbSeparator>
|
|
||||||
<BreadcrumbItem>
|
|
||||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
|
||||||
</BreadcrumbItem>
|
|
||||||
</BreadcrumbList>
|
|
||||||
</Breadcrumb>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import Link from "next/link"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
|
|
||||||
export default function ButtonAsChild() {
|
|
||||||
return (
|
|
||||||
<Button asChild>
|
|
||||||
<Link href="/login">Login</Link>
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Mail } from "lucide-react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
|
|
||||||
export default function ButtonWithIcon() {
|
|
||||||
return (
|
|
||||||
<Button>
|
|
||||||
<Mail className="mr-2 h-4 w-4" /> Login with Email
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { format } from "date-fns"
|
|
||||||
import { CalendarIcon } from "lucide-react"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Calendar } from "@/registry/default/ui/calendar"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
dob: z.date({
|
|
||||||
required_error: "A date of birth is required.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function CalendarForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="dob"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-col">
|
|
||||||
<FormLabel>Date of birth</FormLabel>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
variant={"outline"}
|
|
||||||
className={cn(
|
|
||||||
"w-[240px] pl-3 text-left font-normal",
|
|
||||||
!field.value && "text-muted-foreground"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{field.value ? (
|
|
||||||
format(field.value, "PPP")
|
|
||||||
) : (
|
|
||||||
<span>Pick a date</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-auto p-0" align="start">
|
|
||||||
<Calendar
|
|
||||||
mode="single"
|
|
||||||
selected={field.value}
|
|
||||||
onSelect={field.onChange}
|
|
||||||
disabled={(date) =>
|
|
||||||
date > new Date() || date < new Date("1900-01-01")
|
|
||||||
}
|
|
||||||
initialFocus
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<FormDescription>
|
|
||||||
Your date of birth is used to calculate your age.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardFooter,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "@/registry/default/ui/card"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/registry/default/ui/select"
|
|
||||||
|
|
||||||
export default function CardWithForm() {
|
|
||||||
return (
|
|
||||||
<Card className="w-[350px]">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Create project</CardTitle>
|
|
||||||
<CardDescription>Deploy your new project in one-click.</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<form>
|
|
||||||
<div className="grid w-full items-center gap-4">
|
|
||||||
<div className="flex flex-col space-y-1.5">
|
|
||||||
<Label htmlFor="name">Name</Label>
|
|
||||||
<Input id="name" placeholder="Name of your project" />
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col space-y-1.5">
|
|
||||||
<Label htmlFor="framework">Framework</Label>
|
|
||||||
<Select>
|
|
||||||
<SelectTrigger id="framework">
|
|
||||||
<SelectValue placeholder="Select" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent position="popper">
|
|
||||||
<SelectItem value="next">Next.js</SelectItem>
|
|
||||||
<SelectItem value="sveltekit">SvelteKit</SelectItem>
|
|
||||||
<SelectItem value="astro">Astro</SelectItem>
|
|
||||||
<SelectItem value="nuxt">Nuxt.js</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter className="flex justify-between">
|
|
||||||
<Button variant="outline">Cancel</Button>
|
|
||||||
<Button>Deploy</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { Card, CardContent } from "@/registry/default/ui/card"
|
|
||||||
import {
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
type CarouselApi,
|
|
||||||
} from "@/registry/default/ui/carousel"
|
|
||||||
|
|
||||||
export default function CarouselDApiDemo() {
|
|
||||||
const [api, setApi] = React.useState<CarouselApi>()
|
|
||||||
const [current, setCurrent] = React.useState(0)
|
|
||||||
const [count, setCount] = React.useState(0)
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!api) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setCount(api.scrollSnapList().length)
|
|
||||||
setCurrent(api.selectedScrollSnap() + 1)
|
|
||||||
|
|
||||||
api.on("select", () => {
|
|
||||||
console.log("current")
|
|
||||||
setCurrent(api.selectedScrollSnap() + 1)
|
|
||||||
})
|
|
||||||
}, [api])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Carousel setApi={setApi} className="w-full max-w-xs">
|
|
||||||
<CarouselContent>
|
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
|
||||||
<CarouselItem key={index}>
|
|
||||||
<Card>
|
|
||||||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
|
||||||
<span className="text-4xl font-semibold">{index + 1}</span>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
<div className="py-2 text-center text-sm text-muted-foreground">
|
|
||||||
Slide {current} of {count}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { Card, CardContent } from "@/registry/default/ui/card"
|
|
||||||
import {
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
} from "@/registry/default/ui/carousel"
|
|
||||||
|
|
||||||
export default function CarouselOrientation() {
|
|
||||||
return (
|
|
||||||
<Carousel
|
|
||||||
opts={{
|
|
||||||
align: "start",
|
|
||||||
}}
|
|
||||||
orientation="vertical"
|
|
||||||
className="w-full max-w-xs"
|
|
||||||
>
|
|
||||||
<CarouselContent className="-mt-1 h-[200px]">
|
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
|
||||||
<CarouselItem key={index} className="pt-1 md:basis-1/2">
|
|
||||||
<div className="p-1">
|
|
||||||
<Card>
|
|
||||||
<CardContent className="flex items-center justify-center p-6">
|
|
||||||
<span className="text-3xl font-semibold">{index + 1}</span>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import Autoplay from "embla-carousel-autoplay"
|
|
||||||
|
|
||||||
import { Card, CardContent } from "@/registry/default/ui/card"
|
|
||||||
import {
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
} from "@/registry/default/ui/carousel"
|
|
||||||
|
|
||||||
export default function CarouselPlugin() {
|
|
||||||
const plugin = React.useRef(
|
|
||||||
Autoplay({ delay: 2000, stopOnInteraction: true })
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Carousel
|
|
||||||
plugins={[plugin.current]}
|
|
||||||
className="w-full max-w-xs"
|
|
||||||
onMouseEnter={plugin.current.stop}
|
|
||||||
onMouseLeave={plugin.current.reset}
|
|
||||||
>
|
|
||||||
<CarouselContent>
|
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
|
||||||
<CarouselItem key={index}>
|
|
||||||
<div className="p-1">
|
|
||||||
<Card>
|
|
||||||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
|
||||||
<span className="text-4xl font-semibold">{index + 1}</span>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { Card, CardContent } from "@/registry/default/ui/card"
|
|
||||||
import {
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
} from "@/registry/default/ui/carousel"
|
|
||||||
|
|
||||||
export default function CarouselSpacing() {
|
|
||||||
return (
|
|
||||||
<Carousel className="w-full max-w-sm">
|
|
||||||
<CarouselContent className="-ml-1">
|
|
||||||
{Array.from({ length: 5 }).map((_, index) => (
|
|
||||||
<CarouselItem key={index} className="pl-1 md:basis-1/2 lg:basis-1/3">
|
|
||||||
<div className="p-1">
|
|
||||||
<Card>
|
|
||||||
<CardContent className="flex aspect-square items-center justify-center p-6">
|
|
||||||
<span className="text-2xl font-semibold">{index + 1}</span>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<CarouselPrevious />
|
|
||||||
<CarouselNext />
|
|
||||||
</Carousel>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
{
|
|
||||||
id: "recents",
|
|
||||||
label: "Recents",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "home",
|
|
||||||
label: "Home",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "applications",
|
|
||||||
label: "Applications",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "desktop",
|
|
||||||
label: "Desktop",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "downloads",
|
|
||||||
label: "Downloads",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "documents",
|
|
||||||
label: "Documents",
|
|
||||||
},
|
|
||||||
] as const
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
items: z.array(z.string()).refine((value) => value.some((item) => item), {
|
|
||||||
message: "You have to select at least one item.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function CheckboxReactHookFormMultiple() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
items: ["recents", "home"],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="items"
|
|
||||||
render={() => (
|
|
||||||
<FormItem>
|
|
||||||
<div className="mb-4">
|
|
||||||
<FormLabel className="text-base">Sidebar</FormLabel>
|
|
||||||
<FormDescription>
|
|
||||||
Select the items you want to display in the sidebar.
|
|
||||||
</FormDescription>
|
|
||||||
</div>
|
|
||||||
{items.map((item) => (
|
|
||||||
<FormField
|
|
||||||
key={item.id}
|
|
||||||
control={form.control}
|
|
||||||
name="items"
|
|
||||||
render={({ field }) => {
|
|
||||||
return (
|
|
||||||
<FormItem
|
|
||||||
key={item.id}
|
|
||||||
className="flex flex-row items-start space-x-3 space-y-0"
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<Checkbox
|
|
||||||
checked={field.value?.includes(item.id)}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
return checked
|
|
||||||
? field.onChange([...field.value, item.id])
|
|
||||||
: field.onChange(
|
|
||||||
field.value?.filter(
|
|
||||||
(value) => value !== item.id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal">
|
|
||||||
{item.label}
|
|
||||||
</FormLabel>
|
|
||||||
</FormItem>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import Link from "next/link"
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
mobile: z.boolean().default(false).optional(),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function CheckboxReactHookFormSingle() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
mobile: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="mobile"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md border p-4">
|
|
||||||
<FormControl>
|
|
||||||
<Checkbox
|
|
||||||
checked={field.value}
|
|
||||||
onCheckedChange={field.onChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<div className="space-y-1 leading-none">
|
|
||||||
<FormLabel>
|
|
||||||
Use different settings for my mobile devices
|
|
||||||
</FormLabel>
|
|
||||||
<FormDescription>
|
|
||||||
You can manage your mobile notifications in the{" "}
|
|
||||||
<Link href="/examples/forms">mobile settings</Link> page.
|
|
||||||
</FormDescription>
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
|
||||||
|
|
||||||
export default function CheckboxWithText() {
|
|
||||||
return (
|
|
||||||
<div className="items-top flex space-x-2">
|
|
||||||
<Checkbox id="terms1" />
|
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor="terms1"
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
|
||||||
Accept terms and conditions
|
|
||||||
</label>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
You agree to our Terms of Service and Privacy Policy.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { Calendar, MoreHorizontal, Tags, Trash, User } from "lucide-react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Command,
|
|
||||||
CommandEmpty,
|
|
||||||
CommandGroup,
|
|
||||||
CommandInput,
|
|
||||||
CommandItem,
|
|
||||||
CommandList,
|
|
||||||
} from "@/registry/default/ui/command"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuShortcut,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
const labels = [
|
|
||||||
"feature",
|
|
||||||
"bug",
|
|
||||||
"enhancement",
|
|
||||||
"documentation",
|
|
||||||
"design",
|
|
||||||
"question",
|
|
||||||
"maintenance",
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function ComboboxDropdownMenu() {
|
|
||||||
const [label, setLabel] = React.useState("feature")
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex w-full flex-col items-start justify-between rounded-md border px-4 py-3 sm:flex-row sm:items-center">
|
|
||||||
<p className="text-sm font-medium leading-none">
|
|
||||||
<span className="mr-2 rounded-lg bg-primary px-2 py-1 text-xs text-primary-foreground">
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
<span className="text-muted-foreground">Create a new project</span>
|
|
||||||
</p>
|
|
||||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" size="sm">
|
|
||||||
<MoreHorizontal />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end" className="w-[200px]">
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuGroup>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<User className="mr-2 h-4 w-4" />
|
|
||||||
Assign to...
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Calendar className="mr-2 h-4 w-4" />
|
|
||||||
Set due date...
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger>
|
|
||||||
<Tags className="mr-2 h-4 w-4" />
|
|
||||||
Apply label
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuSubContent className="p-0">
|
|
||||||
<Command>
|
|
||||||
<CommandInput
|
|
||||||
placeholder="Filter label..."
|
|
||||||
autoFocus={true}
|
|
||||||
/>
|
|
||||||
<CommandList>
|
|
||||||
<CommandEmpty>No label found.</CommandEmpty>
|
|
||||||
<CommandGroup>
|
|
||||||
{labels.map((label) => (
|
|
||||||
<CommandItem
|
|
||||||
key={label}
|
|
||||||
value={label}
|
|
||||||
onSelect={(value) => {
|
|
||||||
setLabel(value)
|
|
||||||
setOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
</CommandList>
|
|
||||||
</Command>
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem className="text-red-600">
|
|
||||||
<Trash className="mr-2 h-4 w-4" />
|
|
||||||
Delete
|
|
||||||
<DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuGroup>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { Check, ChevronsUpDown } from "lucide-react"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Command,
|
|
||||||
CommandEmpty,
|
|
||||||
CommandGroup,
|
|
||||||
CommandInput,
|
|
||||||
CommandItem,
|
|
||||||
} from "@/registry/default/ui/command"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const languages = [
|
|
||||||
{ label: "English", value: "en" },
|
|
||||||
{ label: "French", value: "fr" },
|
|
||||||
{ label: "German", value: "de" },
|
|
||||||
{ label: "Spanish", value: "es" },
|
|
||||||
{ label: "Portuguese", value: "pt" },
|
|
||||||
{ label: "Russian", value: "ru" },
|
|
||||||
{ label: "Japanese", value: "ja" },
|
|
||||||
{ label: "Korean", value: "ko" },
|
|
||||||
{ label: "Chinese", value: "zh" },
|
|
||||||
] as const
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
language: z.string({
|
|
||||||
required_error: "Please select a language.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function ComboboxForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="language"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-col">
|
|
||||||
<FormLabel>Language</FormLabel>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
role="combobox"
|
|
||||||
className={cn(
|
|
||||||
"w-[200px] justify-between",
|
|
||||||
!field.value && "text-muted-foreground"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{field.value
|
|
||||||
? languages.find(
|
|
||||||
(language) => language.value === field.value
|
|
||||||
)?.label
|
|
||||||
: "Select language"}
|
|
||||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-[200px] p-0">
|
|
||||||
<Command>
|
|
||||||
<CommandInput placeholder="Search language..." />
|
|
||||||
<CommandEmpty>No language found.</CommandEmpty>
|
|
||||||
<CommandGroup>
|
|
||||||
{languages.map((language) => (
|
|
||||||
<CommandItem
|
|
||||||
value={language.label}
|
|
||||||
key={language.value}
|
|
||||||
onSelect={() => {
|
|
||||||
form.setValue("language", language.value)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Check
|
|
||||||
className={cn(
|
|
||||||
"mr-2 h-4 w-4",
|
|
||||||
language.value === field.value
|
|
||||||
? "opacity-100"
|
|
||||||
: "opacity-0"
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{language.label}
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
</Command>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<FormDescription>
|
|
||||||
This is the language that will be used in the dashboard.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import {
|
|
||||||
ArrowUpCircle,
|
|
||||||
CheckCircle2,
|
|
||||||
Circle,
|
|
||||||
HelpCircle,
|
|
||||||
LucideIcon,
|
|
||||||
XCircle,
|
|
||||||
} from "lucide-react"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Command,
|
|
||||||
CommandEmpty,
|
|
||||||
CommandGroup,
|
|
||||||
CommandInput,
|
|
||||||
CommandItem,
|
|
||||||
CommandList,
|
|
||||||
} from "@/registry/default/ui/command"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
|
|
||||||
type Status = {
|
|
||||||
value: string
|
|
||||||
label: string
|
|
||||||
icon: LucideIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
const statuses: Status[] = [
|
|
||||||
{
|
|
||||||
value: "backlog",
|
|
||||||
label: "Backlog",
|
|
||||||
icon: HelpCircle,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "todo",
|
|
||||||
label: "Todo",
|
|
||||||
icon: Circle,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "in progress",
|
|
||||||
label: "In Progress",
|
|
||||||
icon: ArrowUpCircle,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "done",
|
|
||||||
label: "Done",
|
|
||||||
icon: CheckCircle2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "canceled",
|
|
||||||
label: "Canceled",
|
|
||||||
icon: XCircle,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function ComboboxPopover() {
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex items-center space-x-4">
|
|
||||||
<p className="text-sm text-muted-foreground">Status</p>
|
|
||||||
<Popover open={open} onOpenChange={setOpen}>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="w-[150px] justify-start"
|
|
||||||
>
|
|
||||||
{selectedStatus ? (
|
|
||||||
<>
|
|
||||||
<selectedStatus.icon className="mr-2 h-4 w-4 shrink-0" />
|
|
||||||
{selectedStatus.label}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>+ Set status</>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="p-0" side="right" align="start">
|
|
||||||
<Command>
|
|
||||||
<CommandInput placeholder="Change status..." />
|
|
||||||
<CommandList>
|
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
|
||||||
<CommandGroup>
|
|
||||||
{statuses.map((status) => (
|
|
||||||
<CommandItem
|
|
||||||
key={status.value}
|
|
||||||
value={status.value}
|
|
||||||
onSelect={(value) => {
|
|
||||||
setSelectedStatus(
|
|
||||||
statuses.find((priority) => priority.value === value) ||
|
|
||||||
null
|
|
||||||
)
|
|
||||||
setOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<status.icon
|
|
||||||
className={cn(
|
|
||||||
"mr-2 h-4 w-4",
|
|
||||||
status.value === selectedStatus?.value
|
|
||||||
? "opacity-100"
|
|
||||||
: "opacity-40"
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<span>{status.label}</span>
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
</CommandList>
|
|
||||||
</Command>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { useMediaQuery } from "@/hooks/use-media-query"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Command,
|
|
||||||
CommandEmpty,
|
|
||||||
CommandGroup,
|
|
||||||
CommandInput,
|
|
||||||
CommandItem,
|
|
||||||
CommandList,
|
|
||||||
} from "@/registry/default/ui/command"
|
|
||||||
import {
|
|
||||||
Drawer,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerTrigger,
|
|
||||||
} from "@/registry/default/ui/drawer"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
|
|
||||||
type Status = {
|
|
||||||
value: string
|
|
||||||
label: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const statuses: Status[] = [
|
|
||||||
{
|
|
||||||
value: "backlog",
|
|
||||||
label: "Backlog",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "todo",
|
|
||||||
label: "Todo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "in progress",
|
|
||||||
label: "In Progress",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "done",
|
|
||||||
label: "Done",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "canceled",
|
|
||||||
label: "Canceled",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function ComboBoxResponsive() {
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
const isDesktop = useMediaQuery("(min-width: 768px)")
|
|
||||||
const [selectedStatus, setSelectedStatus] = React.useState<Status | null>(
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isDesktop) {
|
|
||||||
return (
|
|
||||||
<Popover open={open} onOpenChange={setOpen}>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button variant="outline" className="w-[150px] justify-start">
|
|
||||||
{selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-[200px] p-0" align="start">
|
|
||||||
<StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Drawer open={open} onOpenChange={setOpen}>
|
|
||||||
<DrawerTrigger asChild>
|
|
||||||
<Button variant="outline" className="w-[150px] justify-start">
|
|
||||||
{selectedStatus ? <>{selectedStatus.label}</> : <>+ Set status</>}
|
|
||||||
</Button>
|
|
||||||
</DrawerTrigger>
|
|
||||||
<DrawerContent>
|
|
||||||
<div className="mt-4 border-t">
|
|
||||||
<StatusList setOpen={setOpen} setSelectedStatus={setSelectedStatus} />
|
|
||||||
</div>
|
|
||||||
</DrawerContent>
|
|
||||||
</Drawer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function StatusList({
|
|
||||||
setOpen,
|
|
||||||
setSelectedStatus,
|
|
||||||
}: {
|
|
||||||
setOpen: (open: boolean) => void
|
|
||||||
setSelectedStatus: (status: Status | null) => void
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<Command>
|
|
||||||
<CommandInput placeholder="Filter status..." />
|
|
||||||
<CommandList>
|
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
|
||||||
<CommandGroup>
|
|
||||||
{statuses.map((status) => (
|
|
||||||
<CommandItem
|
|
||||||
key={status.value}
|
|
||||||
value={status.value}
|
|
||||||
onSelect={(value) => {
|
|
||||||
setSelectedStatus(
|
|
||||||
statuses.find((priority) => priority.value === value) || null
|
|
||||||
)
|
|
||||||
setOpen(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{status.label}
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
</CommandList>
|
|
||||||
</Command>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import {
|
|
||||||
Calculator,
|
|
||||||
Calendar,
|
|
||||||
CreditCard,
|
|
||||||
Settings,
|
|
||||||
Smile,
|
|
||||||
User,
|
|
||||||
} from "lucide-react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
CommandDialog,
|
|
||||||
CommandEmpty,
|
|
||||||
CommandGroup,
|
|
||||||
CommandInput,
|
|
||||||
CommandItem,
|
|
||||||
CommandList,
|
|
||||||
CommandSeparator,
|
|
||||||
CommandShortcut,
|
|
||||||
} from "@/registry/default/ui/command"
|
|
||||||
|
|
||||||
export default function CommandDialogDemo() {
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const down = (e: KeyboardEvent) => {
|
|
||||||
if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
|
|
||||||
e.preventDefault()
|
|
||||||
setOpen((open) => !open)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("keydown", down)
|
|
||||||
return () => document.removeEventListener("keydown", down)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Press{" "}
|
|
||||||
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
|
|
||||||
<span className="text-xs">⌘</span>J
|
|
||||||
</kbd>
|
|
||||||
</p>
|
|
||||||
<CommandDialog open={open} onOpenChange={setOpen}>
|
|
||||||
<CommandInput placeholder="Type a command or search..." />
|
|
||||||
<CommandList>
|
|
||||||
<CommandEmpty>No results found.</CommandEmpty>
|
|
||||||
<CommandGroup heading="Suggestions">
|
|
||||||
<CommandItem>
|
|
||||||
<Calendar className="mr-2 h-4 w-4" />
|
|
||||||
<span>Calendar</span>
|
|
||||||
</CommandItem>
|
|
||||||
<CommandItem>
|
|
||||||
<Smile className="mr-2 h-4 w-4" />
|
|
||||||
<span>Search Emoji</span>
|
|
||||||
</CommandItem>
|
|
||||||
<CommandItem>
|
|
||||||
<Calculator className="mr-2 h-4 w-4" />
|
|
||||||
<span>Calculator</span>
|
|
||||||
</CommandItem>
|
|
||||||
</CommandGroup>
|
|
||||||
<CommandSeparator />
|
|
||||||
<CommandGroup heading="Settings">
|
|
||||||
<CommandItem>
|
|
||||||
<User className="mr-2 h-4 w-4" />
|
|
||||||
<span>Profile</span>
|
|
||||||
<CommandShortcut>⌘P</CommandShortcut>
|
|
||||||
</CommandItem>
|
|
||||||
<CommandItem>
|
|
||||||
<CreditCard className="mr-2 h-4 w-4" />
|
|
||||||
<span>Billing</span>
|
|
||||||
<CommandShortcut>⌘B</CommandShortcut>
|
|
||||||
</CommandItem>
|
|
||||||
<CommandItem>
|
|
||||||
<Settings className="mr-2 h-4 w-4" />
|
|
||||||
<span>Settings</span>
|
|
||||||
<CommandShortcut>⌘S</CommandShortcut>
|
|
||||||
</CommandItem>
|
|
||||||
</CommandGroup>
|
|
||||||
</CommandList>
|
|
||||||
</CommandDialog>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,312 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import {
|
|
||||||
ColumnDef,
|
|
||||||
ColumnFiltersState,
|
|
||||||
SortingState,
|
|
||||||
VisibilityState,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
getPaginationRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
useReactTable,
|
|
||||||
} from "@tanstack/react-table"
|
|
||||||
import { ArrowUpDown, ChevronDown, MoreHorizontal } from "lucide-react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Checkbox } from "@/registry/default/ui/checkbox"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/registry/default/ui/table"
|
|
||||||
|
|
||||||
const data: Payment[] = [
|
|
||||||
{
|
|
||||||
id: "m5gr84i9",
|
|
||||||
amount: 316,
|
|
||||||
status: "success",
|
|
||||||
email: "ken99@yahoo.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "3u1reuv4",
|
|
||||||
amount: 242,
|
|
||||||
status: "success",
|
|
||||||
email: "Abe45@gmail.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "derv1ws0",
|
|
||||||
amount: 837,
|
|
||||||
status: "processing",
|
|
||||||
email: "Monserrat44@gmail.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "5kma53ae",
|
|
||||||
amount: 874,
|
|
||||||
status: "success",
|
|
||||||
email: "Silas22@gmail.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "bhqecj4p",
|
|
||||||
amount: 721,
|
|
||||||
status: "failed",
|
|
||||||
email: "carmella@hotmail.com",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export type Payment = {
|
|
||||||
id: string
|
|
||||||
amount: number
|
|
||||||
status: "pending" | "processing" | "success" | "failed"
|
|
||||||
email: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const columns: ColumnDef<Payment>[] = [
|
|
||||||
{
|
|
||||||
id: "select",
|
|
||||||
header: ({ table }) => (
|
|
||||||
<Checkbox
|
|
||||||
checked={
|
|
||||||
table.getIsAllPageRowsSelected() ||
|
|
||||||
(table.getIsSomePageRowsSelected() && "indeterminate")
|
|
||||||
}
|
|
||||||
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
|
||||||
aria-label="Select all"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<Checkbox
|
|
||||||
checked={row.getIsSelected()}
|
|
||||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
|
||||||
aria-label="Select row"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
enableSorting: false,
|
|
||||||
enableHiding: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "status",
|
|
||||||
header: "Status",
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<div className="capitalize">{row.getValue("status")}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "email",
|
|
||||||
header: ({ column }) => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
|
|
||||||
>
|
|
||||||
Email
|
|
||||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
cell: ({ row }) => <div className="lowercase">{row.getValue("email")}</div>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: "amount",
|
|
||||||
header: () => <div className="text-right">Amount</div>,
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const amount = parseFloat(row.getValue("amount"))
|
|
||||||
|
|
||||||
// Format the amount as a dollar amount
|
|
||||||
const formatted = new Intl.NumberFormat("en-US", {
|
|
||||||
style: "currency",
|
|
||||||
currency: "USD",
|
|
||||||
}).format(amount)
|
|
||||||
|
|
||||||
return <div className="text-right font-medium">{formatted}</div>
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "actions",
|
|
||||||
enableHiding: false,
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const payment = row.original
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
||||||
<span className="sr-only">Open menu</span>
|
|
||||||
<MoreHorizontal className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
||||||
<DropdownMenuItem
|
|
||||||
onClick={() => navigator.clipboard.writeText(payment.id)}
|
|
||||||
>
|
|
||||||
Copy payment ID
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem>View customer</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>View payment details</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function DataTableDemo() {
|
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
React.useState<VisibilityState>({})
|
|
||||||
const [rowSelection, setRowSelection] = React.useState({})
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data,
|
|
||||||
columns,
|
|
||||||
onSortingChange: setSorting,
|
|
||||||
onColumnFiltersChange: setColumnFilters,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
|
||||||
getSortedRowModel: getSortedRowModel(),
|
|
||||||
getFilteredRowModel: getFilteredRowModel(),
|
|
||||||
onColumnVisibilityChange: setColumnVisibility,
|
|
||||||
onRowSelectionChange: setRowSelection,
|
|
||||||
state: {
|
|
||||||
sorting,
|
|
||||||
columnFilters,
|
|
||||||
columnVisibility,
|
|
||||||
rowSelection,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="flex items-center py-4">
|
|
||||||
<Input
|
|
||||||
placeholder="Filter emails..."
|
|
||||||
value={(table.getColumn("email")?.getFilterValue() as string) ?? ""}
|
|
||||||
onChange={(event) =>
|
|
||||||
table.getColumn("email")?.setFilterValue(event.target.value)
|
|
||||||
}
|
|
||||||
className="max-w-sm"
|
|
||||||
/>
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline" className="ml-auto">
|
|
||||||
Columns <ChevronDown className="ml-2 h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{table
|
|
||||||
.getAllColumns()
|
|
||||||
.filter((column) => column.getCanHide())
|
|
||||||
.map((column) => {
|
|
||||||
return (
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
key={column.id}
|
|
||||||
className="capitalize"
|
|
||||||
checked={column.getIsVisible()}
|
|
||||||
onCheckedChange={(value) =>
|
|
||||||
column.toggleVisibility(!!value)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{column.id}
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</div>
|
|
||||||
<div className="rounded-md border">
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<TableRow key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header) => {
|
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
|
||||||
{header.isPlaceholder
|
|
||||||
? null
|
|
||||||
: flexRender(
|
|
||||||
header.column.columnDef.header,
|
|
||||||
header.getContext()
|
|
||||||
)}
|
|
||||||
</TableHead>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{table.getRowModel().rows?.length ? (
|
|
||||||
table.getRowModel().rows.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.id}
|
|
||||||
data-state={row.getIsSelected() && "selected"}
|
|
||||||
>
|
|
||||||
{row.getVisibleCells().map((cell) => (
|
|
||||||
<TableCell key={cell.id}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext()
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
colSpan={columns.length}
|
|
||||||
className="h-24 text-center"
|
|
||||||
>
|
|
||||||
No results.
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-end space-x-2 py-4">
|
|
||||||
<div className="flex-1 text-sm text-muted-foreground">
|
|
||||||
{table.getFilteredSelectedRowModel().rows.length} of{" "}
|
|
||||||
{table.getFilteredRowModel().rows.length} row(s) selected.
|
|
||||||
</div>
|
|
||||||
<div className="space-x-2">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => table.previousPage()}
|
|
||||||
disabled={!table.getCanPreviousPage()}
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => table.nextPage()}
|
|
||||||
disabled={!table.getCanNextPage()}
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { format } from "date-fns"
|
|
||||||
import { CalendarIcon } from "lucide-react"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Calendar } from "@/registry/default/ui/calendar"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
dob: z.date({
|
|
||||||
required_error: "A date of birth is required.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function DatePickerForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="dob"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-col">
|
|
||||||
<FormLabel>Date of birth</FormLabel>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<FormControl>
|
|
||||||
<Button
|
|
||||||
variant={"outline"}
|
|
||||||
className={cn(
|
|
||||||
"w-[240px] pl-3 text-left font-normal",
|
|
||||||
!field.value && "text-muted-foreground"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{field.value ? (
|
|
||||||
format(field.value, "PPP")
|
|
||||||
) : (
|
|
||||||
<span>Pick a date</span>
|
|
||||||
)}
|
|
||||||
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
|
|
||||||
</Button>
|
|
||||||
</FormControl>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-auto p-0" align="start">
|
|
||||||
<Calendar
|
|
||||||
mode="single"
|
|
||||||
selected={field.value}
|
|
||||||
onSelect={field.onChange}
|
|
||||||
disabled={(date) =>
|
|
||||||
date > new Date() || date < new Date("1900-01-01")
|
|
||||||
}
|
|
||||||
initialFocus
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<FormDescription>
|
|
||||||
Your date of birth is used to calculate your age.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { addDays, format } from "date-fns"
|
|
||||||
import { Calendar as CalendarIcon } from "lucide-react"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Calendar } from "@/registry/default/ui/calendar"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/registry/default/ui/select"
|
|
||||||
|
|
||||||
export default function DatePickerWithPresets() {
|
|
||||||
const [date, setDate] = React.useState<Date>()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant={"outline"}
|
|
||||||
className={cn(
|
|
||||||
"w-[280px] justify-start text-left font-normal",
|
|
||||||
!date && "text-muted-foreground"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
||||||
{date ? format(date, "PPP") : <span>Pick a date</span>}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="flex w-auto flex-col space-y-2 p-2">
|
|
||||||
<Select
|
|
||||||
onValueChange={(value) =>
|
|
||||||
setDate(addDays(new Date(), parseInt(value)))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent position="popper">
|
|
||||||
<SelectItem value="0">Today</SelectItem>
|
|
||||||
<SelectItem value="1">Tomorrow</SelectItem>
|
|
||||||
<SelectItem value="3">In 3 days</SelectItem>
|
|
||||||
<SelectItem value="7">In a week</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<div className="rounded-md border">
|
|
||||||
<Calendar mode="single" selected={date} onSelect={setDate} />
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { addDays, format } from "date-fns"
|
|
||||||
import { Calendar as CalendarIcon } from "lucide-react"
|
|
||||||
import { DateRange } from "react-day-picker"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Calendar } from "@/registry/default/ui/calendar"
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/registry/default/ui/popover"
|
|
||||||
|
|
||||||
export default function DatePickerWithRange({
|
|
||||||
className,
|
|
||||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
|
||||||
const [date, setDate] = React.useState<DateRange | undefined>({
|
|
||||||
from: new Date(2022, 0, 20),
|
|
||||||
to: addDays(new Date(2022, 0, 20), 20),
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={cn("grid gap-2", className)}>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
id="date"
|
|
||||||
variant={"outline"}
|
|
||||||
className={cn(
|
|
||||||
"w-[300px] justify-start text-left font-normal",
|
|
||||||
!date && "text-muted-foreground"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
||||||
{date?.from ? (
|
|
||||||
date.to ? (
|
|
||||||
<>
|
|
||||||
{format(date.from, "LLL dd, y")} -{" "}
|
|
||||||
{format(date.to, "LLL dd, y")}
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
format(date.from, "LLL dd, y")
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<span>Pick a date</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-auto p-0" align="start">
|
|
||||||
<Calendar
|
|
||||||
initialFocus
|
|
||||||
mode="range"
|
|
||||||
defaultMonth={date?.from}
|
|
||||||
selected={date}
|
|
||||||
onSelect={setDate}
|
|
||||||
numberOfMonths={2}
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { Copy } from "lucide-react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogClose,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/registry/default/ui/dialog"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
|
|
||||||
export default function DialogCloseButton() {
|
|
||||||
return (
|
|
||||||
<Dialog>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button variant="outline">Share</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent className="sm:max-w-md">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Share link</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Anyone who has this link will be able to view this.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<div className="grid flex-1 gap-2">
|
|
||||||
<Label htmlFor="link" className="sr-only">
|
|
||||||
Link
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
id="link"
|
|
||||||
defaultValue="https://ui.shadcn.com/docs/installation"
|
|
||||||
readOnly
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Button type="submit" size="sm" className="px-3">
|
|
||||||
<span className="sr-only">Copy</span>
|
|
||||||
<Copy className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<DialogFooter className="sm:justify-start">
|
|
||||||
<DialogClose asChild>
|
|
||||||
<Button type="button" variant="secondary">
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
|
||||||
import { useMediaQuery } from "@/hooks/use-media-query"
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/registry/default/ui/dialog"
|
|
||||||
import {
|
|
||||||
Drawer,
|
|
||||||
DrawerClose,
|
|
||||||
DrawerContent,
|
|
||||||
DrawerDescription,
|
|
||||||
DrawerFooter,
|
|
||||||
DrawerHeader,
|
|
||||||
DrawerTitle,
|
|
||||||
DrawerTrigger,
|
|
||||||
} from "@/registry/default/ui/drawer"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
|
|
||||||
export default function DrawerDialogDemo() {
|
|
||||||
const [open, setOpen] = React.useState(false)
|
|
||||||
const isDesktop = useMediaQuery("(min-width: 768px)")
|
|
||||||
|
|
||||||
if (isDesktop) {
|
|
||||||
return (
|
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button variant="outline">Edit Profile</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Edit profile</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Make changes to your profile here. Click save when you're done.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<ProfileForm />
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Drawer open={open} onOpenChange={setOpen}>
|
|
||||||
<DrawerTrigger asChild>
|
|
||||||
<Button variant="outline">Edit Profile</Button>
|
|
||||||
</DrawerTrigger>
|
|
||||||
<DrawerContent>
|
|
||||||
<DrawerHeader className="text-left">
|
|
||||||
<DrawerTitle>Edit profile</DrawerTitle>
|
|
||||||
<DrawerDescription>
|
|
||||||
Make changes to your profile here. Click save when you're done.
|
|
||||||
</DrawerDescription>
|
|
||||||
</DrawerHeader>
|
|
||||||
<ProfileForm className="px-4" />
|
|
||||||
<DrawerFooter className="pt-2">
|
|
||||||
<DrawerClose asChild>
|
|
||||||
<Button variant="outline">Cancel</Button>
|
|
||||||
</DrawerClose>
|
|
||||||
</DrawerFooter>
|
|
||||||
</DrawerContent>
|
|
||||||
</Drawer>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function ProfileForm({ className }: React.ComponentProps<"form">) {
|
|
||||||
return (
|
|
||||||
<form className={cn("grid items-start gap-4", className)}>
|
|
||||||
<div className="grid gap-2">
|
|
||||||
<Label htmlFor="email">Email</Label>
|
|
||||||
<Input type="email" id="email" defaultValue="shadcn@example.com" />
|
|
||||||
</div>
|
|
||||||
<div className="grid gap-2">
|
|
||||||
<Label htmlFor="username">Username</Label>
|
|
||||||
<Input id="username" defaultValue="@shadcn" />
|
|
||||||
</div>
|
|
||||||
<Button type="submit">Save changes</Button>
|
|
||||||
</form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { DropdownMenuCheckboxItemProps } from "@radix-ui/react-dropdown-menu"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
type Checked = DropdownMenuCheckboxItemProps["checked"]
|
|
||||||
|
|
||||||
export default function DropdownMenuCheckboxes() {
|
|
||||||
const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true)
|
|
||||||
const [showActivityBar, setShowActivityBar] = React.useState<Checked>(false)
|
|
||||||
const [showPanel, setShowPanel] = React.useState<Checked>(false)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline">Open</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent className="w-56">
|
|
||||||
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
checked={showStatusBar}
|
|
||||||
onCheckedChange={setShowStatusBar}
|
|
||||||
>
|
|
||||||
Status Bar
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
checked={showActivityBar}
|
|
||||||
onCheckedChange={setShowActivityBar}
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Activity Bar
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
checked={showPanel}
|
|
||||||
onCheckedChange={setShowPanel}
|
|
||||||
>
|
|
||||||
Panel
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import {
|
|
||||||
Cloud,
|
|
||||||
CreditCard,
|
|
||||||
Github,
|
|
||||||
Keyboard,
|
|
||||||
LifeBuoy,
|
|
||||||
LogOut,
|
|
||||||
Mail,
|
|
||||||
MessageSquare,
|
|
||||||
Plus,
|
|
||||||
PlusCircle,
|
|
||||||
Settings,
|
|
||||||
User,
|
|
||||||
UserPlus,
|
|
||||||
Users,
|
|
||||||
} from "lucide-react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuPortal,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuShortcut,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
export default function DropdownMenuDemo() {
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline">Open</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent className="w-56">
|
|
||||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuGroup>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<User className="mr-2 h-4 w-4" />
|
|
||||||
<span>Profile</span>
|
|
||||||
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<CreditCard className="mr-2 h-4 w-4" />
|
|
||||||
<span>Billing</span>
|
|
||||||
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Settings className="mr-2 h-4 w-4" />
|
|
||||||
<span>Settings</span>
|
|
||||||
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Keyboard className="mr-2 h-4 w-4" />
|
|
||||||
<span>Keyboard shortcuts</span>
|
|
||||||
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuGroup>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuGroup>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Users className="mr-2 h-4 w-4" />
|
|
||||||
<span>Team</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger>
|
|
||||||
<UserPlus className="mr-2 h-4 w-4" />
|
|
||||||
<span>Invite users</span>
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuPortal>
|
|
||||||
<DropdownMenuSubContent>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Mail className="mr-2 h-4 w-4" />
|
|
||||||
<span>Email</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<MessageSquare className="mr-2 h-4 w-4" />
|
|
||||||
<span>Message</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<PlusCircle className="mr-2 h-4 w-4" />
|
|
||||||
<span>More...</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuPortal>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Plus className="mr-2 h-4 w-4" />
|
|
||||||
<span>New Team</span>
|
|
||||||
<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuGroup>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<Github className="mr-2 h-4 w-4" />
|
|
||||||
<span>GitHub</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<LifeBuoy className="mr-2 h-4 w-4" />
|
|
||||||
<span>Support</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem disabled>
|
|
||||||
<Cloud className="mr-2 h-4 w-4" />
|
|
||||||
<span>API</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItem>
|
|
||||||
<LogOut className="mr-2 h-4 w-4" />
|
|
||||||
<span>Log out</span>
|
|
||||||
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuRadioGroup,
|
|
||||||
DropdownMenuRadioItem,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
export default function DropdownMenuRadioGroupDemo() {
|
|
||||||
const [position, setPosition] = React.useState("bottom")
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline">Open</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent className="w-56">
|
|
||||||
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
|
|
||||||
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
|
|
||||||
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
|
|
||||||
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
|
|
||||||
</DropdownMenuRadioGroup>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
|
|
||||||
export default function InputDisabled() {
|
|
||||||
return <Input disabled type="email" placeholder="Email" />
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
|
|
||||||
export default function InputFile() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full max-w-sm items-center gap-1.5">
|
|
||||||
<Label htmlFor="picture">Picture</Label>
|
|
||||||
<Input id="picture" type="file" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
username: z.string().min(2, {
|
|
||||||
message: "Username must be at least 2 characters.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function InputForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
username: "",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="username"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder="shadcn" {...field} />
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
InputOTP,
|
|
||||||
InputOTPGroup,
|
|
||||||
InputOTPSlot,
|
|
||||||
} from "@/registry/default/ui/input-otp"
|
|
||||||
|
|
||||||
export default function InputOTPControlled() {
|
|
||||||
const [value, setValue] = React.useState("")
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<InputOTP
|
|
||||||
maxLength={6}
|
|
||||||
value={value}
|
|
||||||
onChange={(value) => setValue(value)}
|
|
||||||
>
|
|
||||||
<InputOTPGroup>
|
|
||||||
<InputOTPSlot index={0} />
|
|
||||||
<InputOTPSlot index={1} />
|
|
||||||
<InputOTPSlot index={2} />
|
|
||||||
<InputOTPSlot index={3} />
|
|
||||||
<InputOTPSlot index={4} />
|
|
||||||
<InputOTPSlot index={5} />
|
|
||||||
</InputOTPGroup>
|
|
||||||
</InputOTP>
|
|
||||||
<div className="text-center text-sm">
|
|
||||||
{value === "" ? (
|
|
||||||
<>Enter your one-time password.</>
|
|
||||||
) : (
|
|
||||||
<>You entered: {value}</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import {
|
|
||||||
InputOTP,
|
|
||||||
InputOTPGroup,
|
|
||||||
InputOTPSlot,
|
|
||||||
} from "@/registry/default/ui/input-otp"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
pin: z.string().min(6, {
|
|
||||||
message: "Your one-time password must be 6 characters.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function InputOTPForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
pin: "",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="pin"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>One-Time Password</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<InputOTP maxLength={6} {...field}>
|
|
||||||
<InputOTPGroup>
|
|
||||||
<InputOTPSlot index={0} />
|
|
||||||
<InputOTPSlot index={1} />
|
|
||||||
<InputOTPSlot index={2} />
|
|
||||||
<InputOTPSlot index={3} />
|
|
||||||
<InputOTPSlot index={4} />
|
|
||||||
<InputOTPSlot index={5} />
|
|
||||||
</InputOTPGroup>
|
|
||||||
</InputOTP>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
Please enter the one-time password sent to your phone.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
|
|
||||||
|
|
||||||
import {
|
|
||||||
InputOTP,
|
|
||||||
InputOTPGroup,
|
|
||||||
InputOTPSlot,
|
|
||||||
} from "@/registry/default/ui/input-otp"
|
|
||||||
|
|
||||||
export default function InputOTPPattern() {
|
|
||||||
return (
|
|
||||||
<InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS_AND_CHARS}>
|
|
||||||
<InputOTPGroup>
|
|
||||||
<InputOTPSlot index={0} />
|
|
||||||
<InputOTPSlot index={1} />
|
|
||||||
<InputOTPSlot index={2} />
|
|
||||||
<InputOTPSlot index={3} />
|
|
||||||
<InputOTPSlot index={4} />
|
|
||||||
<InputOTPSlot index={5} />
|
|
||||||
</InputOTPGroup>
|
|
||||||
</InputOTP>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
|
|
||||||
export default function InputWithButton() {
|
|
||||||
return (
|
|
||||||
<div className="flex w-full max-w-sm items-center space-x-2">
|
|
||||||
<Input type="email" placeholder="Email" />
|
|
||||||
<Button type="submit">Subscribe</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
|
|
||||||
export default function InputWithLabel() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full max-w-sm items-center gap-1.5">
|
|
||||||
<Label htmlFor="email">Email</Label>
|
|
||||||
<Input type="email" id="email" placeholder="Email" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Input } from "@/registry/default/ui/input"
|
|
||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
|
|
||||||
export default function InputWithText() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full max-w-sm items-center gap-1.5">
|
|
||||||
<Label htmlFor="email-2">Email</Label>
|
|
||||||
<Input type="email" id="email-2" placeholder="Email" />
|
|
||||||
<p className="text-sm text-muted-foreground">Enter your email address.</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import { Moon, Sun } from "lucide-react"
|
|
||||||
import { useTheme } from "next-themes"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/registry/default/ui/dropdown-menu"
|
|
||||||
|
|
||||||
export default function ModeToggle() {
|
|
||||||
const { setTheme } = useTheme()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline" size="icon">
|
|
||||||
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
|
||||||
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
|
||||||
<span className="sr-only">Toggle theme</span>
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("light")}>
|
|
||||||
Light
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("dark")}>
|
|
||||||
Dark
|
|
||||||
</DropdownMenuItem>
|
|
||||||
<DropdownMenuItem onClick={() => setTheme("system")}>
|
|
||||||
System
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { RadioGroup, RadioGroupItem } from "@/registry/default/ui/radio-group"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
type: z.enum(["all", "mentions", "none"], {
|
|
||||||
required_error: "You need to select a notification type.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function RadioGroupForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="type"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="space-y-3">
|
|
||||||
<FormLabel>Notify me about...</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<RadioGroup
|
|
||||||
onValueChange={field.onChange}
|
|
||||||
defaultValue={field.value}
|
|
||||||
className="flex flex-col space-y-1"
|
|
||||||
>
|
|
||||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
|
||||||
<FormControl>
|
|
||||||
<RadioGroupItem value="all" />
|
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal">
|
|
||||||
All new messages
|
|
||||||
</FormLabel>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
|
||||||
<FormControl>
|
|
||||||
<RadioGroupItem value="mentions" />
|
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal">
|
|
||||||
Direct messages and mentions
|
|
||||||
</FormLabel>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem className="flex items-center space-x-3 space-y-0">
|
|
||||||
<FormControl>
|
|
||||||
<RadioGroupItem value="none" />
|
|
||||||
</FormControl>
|
|
||||||
<FormLabel className="font-normal">Nothing</FormLabel>
|
|
||||||
</FormItem>
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import {
|
|
||||||
ResizableHandle,
|
|
||||||
ResizablePanel,
|
|
||||||
ResizablePanelGroup,
|
|
||||||
} from "@/registry/default/ui/resizable"
|
|
||||||
|
|
||||||
export default function ResizableDemo() {
|
|
||||||
return (
|
|
||||||
<ResizablePanelGroup
|
|
||||||
direction="horizontal"
|
|
||||||
className="max-w-md rounded-lg border"
|
|
||||||
>
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<div className="flex h-[200px] items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">One</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle withHandle />
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<ResizablePanelGroup direction="vertical">
|
|
||||||
<ResizablePanel defaultSize={25}>
|
|
||||||
<div className="flex h-full items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">Two</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle withHandle />
|
|
||||||
<ResizablePanel defaultSize={75}>
|
|
||||||
<div className="flex h-full items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">Three</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import {
|
|
||||||
ResizableHandle,
|
|
||||||
ResizablePanel,
|
|
||||||
ResizablePanelGroup,
|
|
||||||
} from "@/registry/default/ui/resizable"
|
|
||||||
|
|
||||||
export default function ResizableDemo() {
|
|
||||||
return (
|
|
||||||
<ResizablePanelGroup
|
|
||||||
direction="horizontal"
|
|
||||||
className="max-w-md rounded-lg border"
|
|
||||||
>
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<div className="flex h-[200px] items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">One</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle />
|
|
||||||
<ResizablePanel defaultSize={50}>
|
|
||||||
<ResizablePanelGroup direction="vertical">
|
|
||||||
<ResizablePanel defaultSize={25}>
|
|
||||||
<div className="flex h-full items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">Two</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
<ResizableHandle />
|
|
||||||
<ResizablePanel defaultSize={75}>
|
|
||||||
<div className="flex h-full items-center justify-center p-6">
|
|
||||||
<span className="font-semibold">Three</span>
|
|
||||||
</div>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
</ResizablePanel>
|
|
||||||
</ResizablePanelGroup>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import Image from "next/image"
|
|
||||||
|
|
||||||
import { ScrollArea, ScrollBar } from "@/registry/default/ui/scroll-area"
|
|
||||||
|
|
||||||
export interface Artwork {
|
|
||||||
artist: string
|
|
||||||
art: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const works: Artwork[] = [
|
|
||||||
{
|
|
||||||
artist: "Ornella Binni",
|
|
||||||
art: "https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
artist: "Tom Byrom",
|
|
||||||
art: "https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
artist: "Vladimir Malyavko",
|
|
||||||
art: "https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export default function ScrollAreaHorizontalDemo() {
|
|
||||||
return (
|
|
||||||
<ScrollArea className="w-96 whitespace-nowrap rounded-md border">
|
|
||||||
<div className="flex w-max space-x-4 p-4">
|
|
||||||
{works.map((artwork) => (
|
|
||||||
<figure key={artwork.artist} className="shrink-0">
|
|
||||||
<div className="overflow-hidden rounded-md">
|
|
||||||
<Image
|
|
||||||
src={artwork.art}
|
|
||||||
alt={`Photo by ${artwork.artist}`}
|
|
||||||
className="aspect-[3/4] h-fit w-fit object-cover"
|
|
||||||
width={300}
|
|
||||||
height={400}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<figcaption className="pt-2 text-xs text-muted-foreground">
|
|
||||||
Photo by{" "}
|
|
||||||
<span className="font-semibold text-foreground">
|
|
||||||
{artwork.artist}
|
|
||||||
</span>
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<ScrollBar orientation="horizontal" />
|
|
||||||
</ScrollArea>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import Link from "next/link"
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/registry/default/ui/select"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
email: z
|
|
||||||
.string({
|
|
||||||
required_error: "Please select an email to display.",
|
|
||||||
})
|
|
||||||
.email(),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function SelectForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="email"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Email</FormLabel>
|
|
||||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select a verified email to display" />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="m@example.com">m@example.com</SelectItem>
|
|
||||||
<SelectItem value="m@google.com">m@google.com</SelectItem>
|
|
||||||
<SelectItem value="m@support.com">m@support.com</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormDescription>
|
|
||||||
You can manage email addresses in your{" "}
|
|
||||||
<Link href="/examples/forms">email settings</Link>.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectGroup,
|
|
||||||
SelectItem,
|
|
||||||
SelectLabel,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/registry/default/ui/select"
|
|
||||||
|
|
||||||
export default function SelectScrollable() {
|
|
||||||
return (
|
|
||||||
<Select>
|
|
||||||
<SelectTrigger className="w-[280px]">
|
|
||||||
<SelectValue placeholder="Select a timezone" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>North America</SelectLabel>
|
|
||||||
<SelectItem value="est">Eastern Standard Time (EST)</SelectItem>
|
|
||||||
<SelectItem value="cst">Central Standard Time (CST)</SelectItem>
|
|
||||||
<SelectItem value="mst">Mountain Standard Time (MST)</SelectItem>
|
|
||||||
<SelectItem value="pst">Pacific Standard Time (PST)</SelectItem>
|
|
||||||
<SelectItem value="akst">Alaska Standard Time (AKST)</SelectItem>
|
|
||||||
<SelectItem value="hst">Hawaii Standard Time (HST)</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Europe & Africa</SelectLabel>
|
|
||||||
<SelectItem value="gmt">Greenwich Mean Time (GMT)</SelectItem>
|
|
||||||
<SelectItem value="cet">Central European Time (CET)</SelectItem>
|
|
||||||
<SelectItem value="eet">Eastern European Time (EET)</SelectItem>
|
|
||||||
<SelectItem value="west">
|
|
||||||
Western European Summer Time (WEST)
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="cat">Central Africa Time (CAT)</SelectItem>
|
|
||||||
<SelectItem value="eat">East Africa Time (EAT)</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Asia</SelectLabel>
|
|
||||||
<SelectItem value="msk">Moscow Time (MSK)</SelectItem>
|
|
||||||
<SelectItem value="ist">India Standard Time (IST)</SelectItem>
|
|
||||||
<SelectItem value="cst_china">China Standard Time (CST)</SelectItem>
|
|
||||||
<SelectItem value="jst">Japan Standard Time (JST)</SelectItem>
|
|
||||||
<SelectItem value="kst">Korea Standard Time (KST)</SelectItem>
|
|
||||||
<SelectItem value="ist_indonesia">
|
|
||||||
Indonesia Central Standard Time (WITA)
|
|
||||||
</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Australia & Pacific</SelectLabel>
|
|
||||||
<SelectItem value="awst">
|
|
||||||
Australian Western Standard Time (AWST)
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="acst">
|
|
||||||
Australian Central Standard Time (ACST)
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="aest">
|
|
||||||
Australian Eastern Standard Time (AEST)
|
|
||||||
</SelectItem>
|
|
||||||
<SelectItem value="nzst">New Zealand Standard Time (NZST)</SelectItem>
|
|
||||||
<SelectItem value="fjt">Fiji Time (FJT)</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>South America</SelectLabel>
|
|
||||||
<SelectItem value="art">Argentina Time (ART)</SelectItem>
|
|
||||||
<SelectItem value="bot">Bolivia Time (BOT)</SelectItem>
|
|
||||||
<SelectItem value="brt">Brasilia Time (BRT)</SelectItem>
|
|
||||||
<SelectItem value="clt">Chile Standard Time (CLT)</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/new-york/ui/button"
|
|
||||||
import { Input } from "@/registry/new-york/ui/input"
|
|
||||||
import { Label } from "@/registry/new-york/ui/label"
|
|
||||||
import {
|
|
||||||
Sheet,
|
|
||||||
SheetClose,
|
|
||||||
SheetContent,
|
|
||||||
SheetDescription,
|
|
||||||
SheetFooter,
|
|
||||||
SheetHeader,
|
|
||||||
SheetTitle,
|
|
||||||
SheetTrigger,
|
|
||||||
} from "@/registry/new-york/ui/sheet"
|
|
||||||
|
|
||||||
const SHEET_SIDES = ["top", "right", "bottom", "left"] as const
|
|
||||||
|
|
||||||
type SheetSide = (typeof SHEET_SIDES)[number]
|
|
||||||
|
|
||||||
export default function SheetSide() {
|
|
||||||
return (
|
|
||||||
<div className="grid grid-cols-2 gap-2">
|
|
||||||
{SHEET_SIDES.map((side) => (
|
|
||||||
<Sheet key={side}>
|
|
||||||
<SheetTrigger asChild>
|
|
||||||
<Button variant="outline">{side}</Button>
|
|
||||||
</SheetTrigger>
|
|
||||||
<SheetContent side={side}>
|
|
||||||
<SheetHeader>
|
|
||||||
<SheetTitle>Edit profile</SheetTitle>
|
|
||||||
<SheetDescription>
|
|
||||||
Make changes to your profile here. Click save when you're done.
|
|
||||||
</SheetDescription>
|
|
||||||
</SheetHeader>
|
|
||||||
<div className="grid gap-4 py-4">
|
|
||||||
<div className="grid grid-cols-4 items-center gap-4">
|
|
||||||
<Label htmlFor="name" className="text-right">
|
|
||||||
Name
|
|
||||||
</Label>
|
|
||||||
<Input id="name" value="Pedro Duarte" className="col-span-3" />
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-4 items-center gap-4">
|
|
||||||
<Label htmlFor="username" className="text-right">
|
|
||||||
Username
|
|
||||||
</Label>
|
|
||||||
<Input id="username" value="@peduarte" className="col-span-3" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<SheetFooter>
|
|
||||||
<SheetClose asChild>
|
|
||||||
<Button type="submit">Save changes</Button>
|
|
||||||
</SheetClose>
|
|
||||||
</SheetFooter>
|
|
||||||
</SheetContent>
|
|
||||||
</Sheet>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Skeleton } from "@/registry/default/ui/skeleton"
|
|
||||||
|
|
||||||
export default function SkeletonCard() {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col space-y-3">
|
|
||||||
<Skeleton className="h-[125px] w-[250px] rounded-xl" />
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Skeleton className="h-4 w-[250px]" />
|
|
||||||
<Skeleton className="h-4 w-[200px]" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { Switch } from "@/registry/default/ui/switch"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
marketing_emails: z.boolean().default(false).optional(),
|
|
||||||
security_emails: z.boolean(),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function SwitchForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
security_emails: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-6">
|
|
||||||
<div>
|
|
||||||
<h3 className="mb-4 text-lg font-medium">Email Notifications</h3>
|
|
||||||
<div className="space-y-4">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="marketing_emails"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
|
|
||||||
<div className="space-y-0.5">
|
|
||||||
<FormLabel className="text-base">
|
|
||||||
Marketing emails
|
|
||||||
</FormLabel>
|
|
||||||
<FormDescription>
|
|
||||||
Receive emails about new products, features, and more.
|
|
||||||
</FormDescription>
|
|
||||||
</div>
|
|
||||||
<FormControl>
|
|
||||||
<Switch
|
|
||||||
checked={field.value}
|
|
||||||
onCheckedChange={field.onChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="security_emails"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
|
|
||||||
<div className="space-y-0.5">
|
|
||||||
<FormLabel className="text-base">Security emails</FormLabel>
|
|
||||||
<FormDescription>
|
|
||||||
Receive emails about your account security.
|
|
||||||
</FormDescription>
|
|
||||||
</div>
|
|
||||||
<FormControl>
|
|
||||||
<Switch
|
|
||||||
checked={field.value}
|
|
||||||
onCheckedChange={field.onChange}
|
|
||||||
disabled
|
|
||||||
aria-readonly
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import { Textarea } from "@/registry/default/ui/textarea"
|
|
||||||
|
|
||||||
export default function TextareaDisabled() {
|
|
||||||
return <Textarea placeholder="Type your message here." disabled />
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod"
|
|
||||||
import { useForm } from "react-hook-form"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from "@/registry/default/ui/form"
|
|
||||||
import { Textarea } from "@/registry/default/ui/textarea"
|
|
||||||
import { toast } from "@/registry/default/ui/use-toast"
|
|
||||||
|
|
||||||
const FormSchema = z.object({
|
|
||||||
bio: z
|
|
||||||
.string()
|
|
||||||
.min(10, {
|
|
||||||
message: "Bio must be at least 10 characters.",
|
|
||||||
})
|
|
||||||
.max(160, {
|
|
||||||
message: "Bio must not be longer than 30 characters.",
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
export default function TextareaForm() {
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
})
|
|
||||||
|
|
||||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
toast({
|
|
||||||
title: "You submitted the following values:",
|
|
||||||
description: (
|
|
||||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
|
||||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
|
||||||
</pre>
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="bio"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Bio</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Textarea
|
|
||||||
placeholder="Tell us a little bit about yourself"
|
|
||||||
className="resize-none"
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
You can <span>@mention</span> other users and organizations.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button type="submit">Submit</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Button } from "@/registry/default/ui/button"
|
|
||||||
import { Textarea } from "@/registry/default/ui/textarea"
|
|
||||||
|
|
||||||
export default function TextareaWithButton() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full gap-2">
|
|
||||||
<Textarea placeholder="Type your message here." />
|
|
||||||
<Button>Send message</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
import { Textarea } from "@/registry/default/ui/textarea"
|
|
||||||
|
|
||||||
export default function TextareaWithLabel() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full gap-1.5">
|
|
||||||
<Label htmlFor="message">Your message</Label>
|
|
||||||
<Textarea placeholder="Type your message here." id="message" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { Label } from "@/registry/default/ui/label"
|
|
||||||
import { Textarea } from "@/registry/default/ui/textarea"
|
|
||||||
|
|
||||||
export default function TextareaWithText() {
|
|
||||||
return (
|
|
||||||
<div className="grid w-full gap-1.5">
|
|
||||||
<Label htmlFor="message-2">Your Message</Label>
|
|
||||||
<Textarea placeholder="Type your message here." id="message-2" />
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Your message will be copied to the support team.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user