mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-07-02 08:58:36 +00:00
feat: calendar v2 (#7551)
* feat(v4): upgrade calendar * feat: more calendar examples * fix: remove grid * feat: more examples * feat: more examples * fix * feat: update examples * fix: dark mode * fix: calendar in dark mode * fix: examples * fix * docs: update calendar docs * feat: update cmdk * fix: block viewer patterns * feat: update new-york and default * fix: docs and examples * fix: command menu * feat: remove blocks from cmdk * fix * fix: calendar 13 * fix: format * fix * feat: update calendar default
This commit is contained in:
@@ -4,3 +4,4 @@ node_modules
|
||||
build
|
||||
.contentlayer
|
||||
registry/__index__.tsx
|
||||
content/docs/components/calendar.mdx
|
||||
|
||||
@@ -2,29 +2,67 @@
|
||||
|
||||
import * as React from "react"
|
||||
import { addDays } from "date-fns"
|
||||
import { Clock2Icon } from "lucide-react"
|
||||
import { type DateRange } from "react-day-picker"
|
||||
import { es } from "react-day-picker/locale"
|
||||
|
||||
import { Calendar } from "@/registry/new-york-v4/ui/calendar"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Calendar, CalendarDayButton } from "@/registry/new-york-v4/ui/calendar"
|
||||
import { Card, CardContent, CardFooter } from "@/registry/new-york-v4/ui/card"
|
||||
import { Input } from "@/registry/new-york-v4/ui/input"
|
||||
import { Label } from "@/registry/new-york-v4/ui/label"
|
||||
|
||||
export function CalendarDemo() {
|
||||
const [date, setDate] = React.useState<Date | undefined>(new Date())
|
||||
const [dateRange, setDateRange] = React.useState<DateRange | undefined>({
|
||||
from: new Date(new Date().getFullYear(), 0, 12),
|
||||
to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),
|
||||
})
|
||||
const [range, setRange] = React.useState<DateRange | undefined>({
|
||||
from: new Date(new Date().getFullYear(), 0, 12),
|
||||
to: addDays(new Date(new Date().getFullYear(), 0, 12), 50),
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-wrap items-start gap-2 @md:flex-row">
|
||||
<div className="bg-muted flex flex-1 flex-col flex-wrap justify-center gap-8 p-10 lg:flex-row">
|
||||
<CalendarSingle />
|
||||
<CalendarMultiple />
|
||||
<CalendarRange />
|
||||
<CalendarBookedDates />
|
||||
<CalendarRangeMultipleMonths />
|
||||
<CalendarWithTime />
|
||||
<CalendarWithPresets />
|
||||
<CalendarCustomDays />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarSingle() {
|
||||
const [date, setDate] = React.useState<Date | undefined>(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth(), 12)
|
||||
)
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">Single Selection</div>
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
className="rounded-md border shadow-sm"
|
||||
className="rounded-lg border shadow-sm"
|
||||
captionLayout="dropdown"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarMultiple() {
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">Multiple Selection</div>
|
||||
<Calendar mode="multiple" className="rounded-lg border shadow-sm" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarRange() {
|
||||
const [dateRange, setDateRange] = React.useState<DateRange | undefined>({
|
||||
from: new Date(new Date().getFullYear(), 0, 12),
|
||||
to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">Range Selection</div>
|
||||
<Calendar
|
||||
mode="range"
|
||||
defaultMonth={dateRange?.from}
|
||||
@@ -32,16 +70,207 @@ export function CalendarDemo() {
|
||||
onSelect={setDateRange}
|
||||
numberOfMonths={2}
|
||||
disabled={(date) => date > new Date() || date < new Date("1900-01-01")}
|
||||
className="rounded-md border shadow-sm"
|
||||
className="rounded-lg border shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarRangeMultipleMonths() {
|
||||
const [range, setRange] = React.useState<DateRange | undefined>({
|
||||
from: new Date(new Date().getFullYear(), 3, 12),
|
||||
to: addDays(new Date(new Date().getFullYear(), 3, 12), 60),
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">Range Selection + Locale</div>
|
||||
<Calendar
|
||||
mode="range"
|
||||
defaultMonth={range?.from}
|
||||
selected={range}
|
||||
onSelect={setRange}
|
||||
numberOfMonths={3}
|
||||
className="hidden rounded-md border shadow-sm @4xl:flex [&>div]:gap-5"
|
||||
locale={es}
|
||||
fixedWeeks
|
||||
className="rounded-lg border shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarBookedDates() {
|
||||
const [date, setDate] = React.useState<Date | undefined>(
|
||||
new Date(new Date().getFullYear(), 1, 3)
|
||||
)
|
||||
const bookedDates = Array.from(
|
||||
{ length: 15 },
|
||||
(_, i) => new Date(new Date().getFullYear(), new Date().getMonth(), 12 + i)
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">With booked dates</div>
|
||||
<Calendar
|
||||
mode="single"
|
||||
defaultMonth={date}
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
disabled={bookedDates}
|
||||
modifiers={{
|
||||
booked: bookedDates,
|
||||
}}
|
||||
modifiersClassNames={{
|
||||
booked: "[&>button]:line-through opacity-100",
|
||||
}}
|
||||
className="rounded-lg border shadow-sm"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarWithTime() {
|
||||
const [date, setDate] = React.useState<Date | undefined>(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth(), 12)
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">With Time Input</div>
|
||||
<Card className="w-fit py-4">
|
||||
<CardContent className="px-4">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
className="p-0"
|
||||
/>
|
||||
</CardContent>
|
||||
<CardFooter className="flex flex-col gap-3 border-t px-4 pt-4">
|
||||
<div className="flex w-full flex-col gap-2">
|
||||
<Label htmlFor="time-from">Start Time</Label>
|
||||
<div className="relative flex w-full items-center gap-2">
|
||||
<Clock2Icon className="text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none" />
|
||||
<Input
|
||||
id="time-from"
|
||||
type="time"
|
||||
step="1"
|
||||
defaultValue="10:30:00"
|
||||
className="appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full flex-col gap-2">
|
||||
<Label htmlFor="time-to">End Time</Label>
|
||||
<div className="relative flex w-full items-center gap-2">
|
||||
<Clock2Icon className="text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none" />
|
||||
<Input
|
||||
id="time-to"
|
||||
type="time"
|
||||
step="1"
|
||||
defaultValue="12:30:00"
|
||||
className="appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarCustomDays() {
|
||||
const [range, setRange] = React.useState<DateRange | undefined>({
|
||||
from: new Date(new Date().getFullYear(), 11, 8),
|
||||
to: addDays(new Date(new Date().getFullYear(), 11, 8), 10),
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">
|
||||
With Custom Days and Formatters
|
||||
</div>
|
||||
<Calendar
|
||||
mode="range"
|
||||
defaultMonth={range?.from}
|
||||
selected={range}
|
||||
onSelect={setRange}
|
||||
numberOfMonths={1}
|
||||
captionLayout="dropdown"
|
||||
className="rounded-lg border shadow-sm [--cell-size:--spacing(12)]"
|
||||
formatters={{
|
||||
formatMonthDropdown: (date) => {
|
||||
return date.toLocaleString("default", { month: "long" })
|
||||
},
|
||||
}}
|
||||
components={{
|
||||
DayButton: ({ children, modifiers, day, ...props }) => {
|
||||
const isWeekend = day.date.getDay() === 0 || day.date.getDay() === 6
|
||||
|
||||
return (
|
||||
<CalendarDayButton day={day} modifiers={modifiers} {...props}>
|
||||
{children}
|
||||
{!modifiers.outside && (
|
||||
<span>{isWeekend ? "$120" : "$100"}</span>
|
||||
)}
|
||||
</CalendarDayButton>
|
||||
)
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarWithPresets() {
|
||||
const [date, setDate] = React.useState<Date | undefined>(
|
||||
new Date(new Date().getFullYear(), 1, 12)
|
||||
)
|
||||
const [currentMonth, setCurrentMonth] = React.useState<Date>(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth(), 1)
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex max-w-[300px] flex-col gap-3">
|
||||
<div className="px-2 text-center text-sm">With Presets</div>
|
||||
<Card className="w-fit py-4">
|
||||
<CardContent className="px-4">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
month={currentMonth}
|
||||
onMonthChange={setCurrentMonth}
|
||||
fixedWeeks
|
||||
className="p-0 [--cell-size:--spacing(9.5)]"
|
||||
/>
|
||||
</CardContent>
|
||||
<CardFooter className="flex flex-wrap gap-2 border-t px-4 pt-4">
|
||||
{[
|
||||
{ label: "Today", value: 0 },
|
||||
{ label: "Tomorrow", value: 1 },
|
||||
{ label: "In 3 days", value: 3 },
|
||||
{ label: "In a week", value: 7 },
|
||||
{ label: "In 2 weeks", value: 14 },
|
||||
].map((preset) => (
|
||||
<Button
|
||||
key={preset.value}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="flex-1"
|
||||
onClick={() => {
|
||||
const newDate = addDays(new Date(), preset.value)
|
||||
setDate(newDate)
|
||||
setCurrentMonth(
|
||||
new Date(newDate.getFullYear(), newDate.getMonth(), 1)
|
||||
)
|
||||
}}
|
||||
>
|
||||
{preset.label}
|
||||
</Button>
|
||||
))}
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,17 @@ import { CalendarIcon } from "lucide-react"
|
||||
import { DateRange } from "react-day-picker"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useIsMobile } from "@/hooks/use-mobile"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Calendar } from "@/registry/new-york-v4/ui/calendar"
|
||||
import {
|
||||
Drawer,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from "@/registry/new-york-v4/ui/drawer"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
@@ -18,6 +27,7 @@ export function DatePickerDemo() {
|
||||
return (
|
||||
<div className="flex flex-col items-start gap-4 md:flex-row">
|
||||
<DatePickerSimple />
|
||||
<DataPickerWithDropdowns />
|
||||
<DatePickerWithRange />
|
||||
</div>
|
||||
)
|
||||
@@ -41,12 +51,7 @@ function DatePickerSimple() {
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
initialFocus
|
||||
/>
|
||||
<Calendar mode="single" selected={date} onSelect={setDate} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
@@ -86,7 +91,6 @@ function DatePickerWithRange() {
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
initialFocus
|
||||
mode="range"
|
||||
defaultMonth={date?.from}
|
||||
selected={date}
|
||||
@@ -97,3 +101,79 @@ function DatePickerWithRange() {
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
function DataPickerWithDropdowns() {
|
||||
const [date, setDate] = React.useState<Date>()
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const isMobile = useIsMobile(450)
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<Drawer open={open} onOpenChange={setOpen}>
|
||||
<DrawerTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className={cn(
|
||||
"min-w-[200px] justify-start px-2 font-normal",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{date ? format(date, "PPP") : <span>Pick a date</span>}
|
||||
<CalendarIcon className="text-muted-foreground ml-auto" />
|
||||
</Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader className="sr-only">
|
||||
<DrawerTitle>Select a date</DrawerTitle>
|
||||
<DrawerDescription>
|
||||
Pick a date for your appointment.
|
||||
</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={(day) => {
|
||||
setDate(day)
|
||||
setOpen(false)
|
||||
}}
|
||||
/>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
className={cn(
|
||||
"min-w-[200px] justify-start px-2 font-normal",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{date ? format(date, "PPP") : <span>Pick a date</span>}
|
||||
<CalendarIcon className="text-muted-foreground ml-auto" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
captionLayout="dropdown"
|
||||
/>
|
||||
<div className="flex gap-2 border-t p-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="w-full"
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
Done
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function generateMetadata({
|
||||
const description = item.description
|
||||
|
||||
return {
|
||||
title: `${item.name}${item.description ? ` - ${item.description}` : ""}`,
|
||||
title: item.description,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
|
||||
@@ -7,7 +7,9 @@ import {
|
||||
createFileTreeForRegistryItemFiles,
|
||||
getRegistryItem,
|
||||
} from "@/lib/registry"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { BlockViewer } from "@/components/block-viewer"
|
||||
import { ComponentPreview } from "@/components/component-preview"
|
||||
|
||||
export async function BlockDisplay({ name }: { name: string }) {
|
||||
const item = await getCachedRegistryItem(name)
|
||||
@@ -22,7 +24,16 @@ export async function BlockDisplay({ name }: { name: string }) {
|
||||
])
|
||||
|
||||
return (
|
||||
<BlockViewer item={item} tree={tree} highlightedFiles={highlightedFiles} />
|
||||
<BlockViewer item={item} tree={tree} highlightedFiles={highlightedFiles}>
|
||||
<ComponentPreview
|
||||
name={item.name}
|
||||
hideCode
|
||||
className={cn(
|
||||
"my-0 **:[.preview]:h-auto **:[.preview]:p-4 **:[.preview>.p-6]:p-0",
|
||||
item.meta?.containerClassName
|
||||
)}
|
||||
/>
|
||||
</BlockViewer>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
Folder,
|
||||
Fullscreen,
|
||||
Monitor,
|
||||
RotateCw,
|
||||
Smartphone,
|
||||
Tablet,
|
||||
Terminal,
|
||||
@@ -21,6 +22,7 @@ import { z } from "zod"
|
||||
|
||||
import { trackEvent } from "@/lib/events"
|
||||
import { createFileTreeForRegistryItemFiles, FileTree } from "@/lib/registry"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
|
||||
import { getIconForLanguageExtension } from "@/components/icons"
|
||||
import { OpenInV0Button } from "@/components/open-in-v0-button"
|
||||
@@ -66,6 +68,8 @@ type BlockViewerContext = {
|
||||
highlightedContent: string
|
||||
})[]
|
||||
| null
|
||||
iframeKey?: number
|
||||
setIframeKey?: React.Dispatch<React.SetStateAction<number>>
|
||||
}
|
||||
|
||||
const BlockViewerContext = React.createContext<BlockViewerContext | null>(null)
|
||||
@@ -91,6 +95,7 @@ function BlockViewerProvider({
|
||||
BlockViewerContext["activeFile"]
|
||||
>(highlightedFiles?.[0].target ?? null)
|
||||
const resizablePanelRef = React.useRef<ImperativePanelHandle>(null)
|
||||
const [iframeKey, setIframeKey] = React.useState(0)
|
||||
|
||||
return (
|
||||
<BlockViewerContext.Provider
|
||||
@@ -103,12 +108,14 @@ function BlockViewerProvider({
|
||||
setActiveFile,
|
||||
tree,
|
||||
highlightedFiles,
|
||||
iframeKey,
|
||||
setIframeKey,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
id={item.name}
|
||||
data-view={view}
|
||||
className="group/block-view-wrapper flex min-w-0 flex-col-reverse items-stretch gap-4 overflow-hidden md:flex-col"
|
||||
className="group/block-view-wrapper flex min-w-0 scroll-mt-24 flex-col-reverse items-stretch gap-4 overflow-hidden md:flex-col"
|
||||
style={
|
||||
{
|
||||
"--height": item.meta?.iframeHeight ?? "930px",
|
||||
@@ -122,30 +129,30 @@ function BlockViewerProvider({
|
||||
}
|
||||
|
||||
function BlockViewerToolbar() {
|
||||
const { setView, view, item, resizablePanelRef } = useBlockViewer()
|
||||
const { setView, view, item, resizablePanelRef, setIframeKey } =
|
||||
useBlockViewer()
|
||||
const { copyToClipboard, isCopied } = useCopyToClipboard()
|
||||
|
||||
return (
|
||||
<div className="flex w-full items-center gap-2 pl-2 md:pr-[14px]">
|
||||
<div className="hidden w-full items-center gap-2 pl-2 md:pr-6 lg:flex">
|
||||
<Tabs
|
||||
value={view}
|
||||
onValueChange={(value) => setView(value as "preview" | "code")}
|
||||
className="hidden lg:flex"
|
||||
>
|
||||
<TabsList className="grid h-8 grid-cols-2 items-center rounded-md p-1 *:data-[slot=tabs-trigger]:h-6 *:data-[slot=tabs-trigger]:rounded-sm *:data-[slot=tabs-trigger]:px-2 *:data-[slot=tabs-trigger]:text-xs">
|
||||
<TabsTrigger value="preview">Preview</TabsTrigger>
|
||||
<TabsTrigger value="code">Code</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<Separator orientation="vertical" className="mx-2 hidden !h-4 lg:flex" />
|
||||
<Separator orientation="vertical" className="mx-2 !h-4" />
|
||||
<a
|
||||
href={`#${item.name}`}
|
||||
className="flex-1 text-center text-sm font-medium underline-offset-2 hover:underline md:flex-auto md:text-left"
|
||||
>
|
||||
{item.description}
|
||||
{item.description?.replace(/\.$/, "")}
|
||||
</a>
|
||||
<div className="ml-auto hidden items-center gap-2 md:flex">
|
||||
<div className="hidden h-8 items-center gap-1.5 rounded-md border p-1 shadow-none lg:flex">
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<div className="h-8 items-center gap-1.5 rounded-md border p-1 shadow-none">
|
||||
<ToggleGroup
|
||||
type="single"
|
||||
defaultValue="100"
|
||||
@@ -179,15 +186,27 @@ function BlockViewerToolbar() {
|
||||
<Fullscreen />
|
||||
</Link>
|
||||
</Button>
|
||||
<Separator orientation="vertical" className="!h-4" />
|
||||
<Button
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
className="size-6 rounded-sm p-0"
|
||||
title="Refresh Preview"
|
||||
onClick={() => {
|
||||
if (setIframeKey) {
|
||||
setIframeKey((k) => k + 1)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<RotateCw />
|
||||
<span className="sr-only">Refresh Preview</span>
|
||||
</Button>
|
||||
</ToggleGroup>
|
||||
</div>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="mx-1 hidden !h-4 lg:flex"
|
||||
/>
|
||||
<Separator orientation="vertical" className="mx-1 !h-4" />
|
||||
<Button
|
||||
variant="outline"
|
||||
className="hidden w-fit gap-1 px-2 shadow-none md:flex"
|
||||
className="w-fit gap-1 px-2 shadow-none"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
copyToClipboard(`npx shadcn@latest add ${item.name}`)
|
||||
@@ -196,50 +215,48 @@ function BlockViewerToolbar() {
|
||||
{isCopied ? <Check /> : <Terminal />}
|
||||
<span>npx shadcn add {item.name}</span>
|
||||
</Button>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="mx-1 hidden !h-4 xl:flex"
|
||||
/>
|
||||
<Separator orientation="vertical" className="mx-1 !h-4" />
|
||||
<OpenInV0Button name={item.name} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function BlockViewerView() {
|
||||
const { item, resizablePanelRef } = useBlockViewer()
|
||||
function BlockViewerIframe({ className }: { className?: string }) {
|
||||
const { item, iframeKey } = useBlockViewer()
|
||||
|
||||
return (
|
||||
<div className="group-data-[view=code]/block-view-wrapper:hidden md:h-[calc(var(--height)+10px)]">
|
||||
<div className="grid w-full gap-4">
|
||||
<ResizablePanelGroup direction="horizontal" className="relative z-10">
|
||||
<iframe
|
||||
key={iframeKey}
|
||||
src={`/view/${item.name}`}
|
||||
height={item.meta?.iframeHeight ?? 930}
|
||||
loading="lazy"
|
||||
className={cn(
|
||||
"bg-background no-scrollbar relative z-20 w-full",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function BlockViewerView() {
|
||||
const { resizablePanelRef } = useBlockViewer()
|
||||
|
||||
return (
|
||||
<div className="hidden group-data-[view=code]/block-view-wrapper:hidden md:h-(--height) lg:flex">
|
||||
<div className="relative grid w-full gap-4">
|
||||
<div className="absolute inset-0 right-4 [background-image:radial-gradient(#d4d4d4_1px,transparent_1px)] [background-size:20px_20px] dark:[background-image:radial-gradient(#404040_1px,transparent_1px)]"></div>
|
||||
<ResizablePanelGroup
|
||||
direction="horizontal"
|
||||
className="after:bg-surface/50 relative z-10 after:absolute after:inset-0 after:right-3 after:z-0 after:rounded-xl"
|
||||
>
|
||||
<ResizablePanel
|
||||
ref={resizablePanelRef}
|
||||
className="bg-background relative aspect-[4/2.5] overflow-hidden rounded-lg border md:aspect-auto md:rounded-xl"
|
||||
defaultSize={100}
|
||||
minSize={30}
|
||||
>
|
||||
<Image
|
||||
src={`/r/styles/new-york-v4/${item.name}-light.png`}
|
||||
alt={item.name}
|
||||
data-block={item.name}
|
||||
width={1440}
|
||||
height={900}
|
||||
className="object-cover md:hidden dark:hidden md:dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src={`/r/styles/new-york-v4/${item.name}-dark.png`}
|
||||
alt={item.name}
|
||||
data-block={item.name}
|
||||
width={1440}
|
||||
height={900}
|
||||
className="hidden object-cover md:hidden dark:block md:dark:hidden"
|
||||
/>
|
||||
<iframe
|
||||
src={`/view/${item.name}`}
|
||||
height={item.meta?.iframeHeight ?? 930}
|
||||
className="bg-background no-scrollbar relative z-20 hidden w-full md:block"
|
||||
/>
|
||||
<BlockViewerIframe />
|
||||
</ResizablePanel>
|
||||
<ResizableHandle className="after:bg-border relative hidden w-3 bg-transparent p-0 after:absolute after:top-1/2 after:right-0 after:h-8 after:w-[6px] after:translate-x-[-1px] after:-translate-y-1/2 after:rounded-full after:transition-all after:hover:h-10 md:block" />
|
||||
<ResizablePanel defaultSize={0} minSize={0} />
|
||||
@@ -249,6 +266,45 @@ function BlockViewerView() {
|
||||
)
|
||||
}
|
||||
|
||||
function BlockViewerMobile({ children }: { children: React.ReactNode }) {
|
||||
const { item } = useBlockViewer()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 lg:hidden">
|
||||
<div className="flex items-center gap-2 px-2">
|
||||
<div className="line-clamp-1 text-sm font-medium">
|
||||
{item.description}
|
||||
</div>
|
||||
<div className="text-muted-foreground ml-auto shrink-0 font-mono text-xs">
|
||||
{item.name}
|
||||
</div>
|
||||
</div>
|
||||
{item.meta?.mobile === "component" ? (
|
||||
children
|
||||
) : (
|
||||
<div className="overflow-hidden rounded-xl border">
|
||||
<Image
|
||||
src={`/r/styles/new-york-v4/${item.name}-light.png`}
|
||||
alt={item.name}
|
||||
data-block={item.name}
|
||||
width={1440}
|
||||
height={900}
|
||||
className="object-cover dark:hidden"
|
||||
/>
|
||||
<Image
|
||||
src={`/r/styles/new-york-v4/${item.name}-dark.png`}
|
||||
alt={item.name}
|
||||
data-block={item.name}
|
||||
width={1440}
|
||||
height={900}
|
||||
className="hidden object-cover dark:block"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function BlockViewerCode() {
|
||||
const { activeFile, highlightedFiles } = useBlockViewer()
|
||||
|
||||
@@ -269,7 +325,7 @@ function BlockViewerCode() {
|
||||
</div>
|
||||
<figure
|
||||
data-rehype-pretty-code-figure=""
|
||||
className="mt-0 flex min-w-0 flex-1 flex-col rounded-xl border-none"
|
||||
className="!mx-0 mt-0 flex min-w-0 flex-1 flex-col rounded-xl border-none"
|
||||
>
|
||||
<figcaption
|
||||
className="text-code-foreground [&_svg]:text-code-foreground flex h-12 shrink-0 items-center gap-2 border-b px-4 py-2 [&_svg]:size-4 [&_svg]:opacity-70"
|
||||
@@ -299,7 +355,7 @@ export function BlockViewerFileTree() {
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarProvider className="flex !min-h-full flex-col">
|
||||
<SidebarProvider className="flex !min-h-full flex-col border-r">
|
||||
<Sidebar collapsible="none" className="w-full flex-1">
|
||||
<SidebarGroupLabel className="h-12 rounded-none border-b px-4 text-sm">
|
||||
Files
|
||||
@@ -414,8 +470,11 @@ function BlockViewer({
|
||||
item,
|
||||
tree,
|
||||
highlightedFiles,
|
||||
children,
|
||||
...props
|
||||
}: Pick<BlockViewerContext, "item" | "tree" | "highlightedFiles">) {
|
||||
}: Pick<BlockViewerContext, "item" | "tree" | "highlightedFiles"> & {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<BlockViewerProvider
|
||||
item={item}
|
||||
@@ -426,6 +485,7 @@ function BlockViewer({
|
||||
<BlockViewerToolbar />
|
||||
<BlockViewerView />
|
||||
<BlockViewerCode />
|
||||
<BlockViewerMobile>{children}</BlockViewerMobile>
|
||||
</BlockViewerProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as React from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||
import { IconArrowRight } from "@tabler/icons-react"
|
||||
import { CornerDownLeftIcon } from "lucide-react"
|
||||
import { CornerDownLeftIcon, SquareDashedIcon } from "lucide-react"
|
||||
|
||||
import { type Color, type ColorPalette } from "@/lib/colors"
|
||||
import { source } from "@/lib/source"
|
||||
@@ -35,17 +35,19 @@ import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
export function CommandMenu({
|
||||
tree,
|
||||
colors,
|
||||
blocks,
|
||||
...props
|
||||
}: DialogProps & {
|
||||
tree: typeof source.pageTree
|
||||
colors: ColorPalette[]
|
||||
blocks?: { name: string; description: string; categories: string[] }[]
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const isMac = useIsMac()
|
||||
const [config] = useConfig()
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const [selectedType, setSelectedType] = React.useState<
|
||||
"color" | "page" | "component" | null
|
||||
"color" | "page" | "component" | "block" | null
|
||||
>(null)
|
||||
const [copyPayload, setCopyPayload] = React.useState("")
|
||||
const packageManager = config.packageManager || "pnpm"
|
||||
@@ -74,6 +76,14 @@ export function CommandMenu({
|
||||
[setSelectedType, setCopyPayload]
|
||||
)
|
||||
|
||||
const handleBlockHighlight = React.useCallback(
|
||||
(block: { name: string; description: string; categories: string[] }) => {
|
||||
setSelectedType("block")
|
||||
setCopyPayload(`${packageManager} dlx shadcn@latest add ${block.name}`)
|
||||
},
|
||||
[setSelectedType, setCopyPayload, packageManager]
|
||||
)
|
||||
|
||||
const runCommand = React.useCallback((command: () => unknown) => {
|
||||
setOpen(false)
|
||||
command()
|
||||
@@ -104,6 +114,13 @@ export function CommandMenu({
|
||||
})
|
||||
}
|
||||
|
||||
if (selectedType === "block") {
|
||||
copyToClipboardWithMeta(copyPayload, {
|
||||
name: "copy_npm_command",
|
||||
properties: { command: copyPayload, pm: packageManager },
|
||||
})
|
||||
}
|
||||
|
||||
if (selectedType === "page" || selectedType === "component") {
|
||||
copyToClipboardWithMeta(copyPayload, {
|
||||
name: "copy_npm_command",
|
||||
@@ -227,6 +244,41 @@ export function CommandMenu({
|
||||
))}
|
||||
</CommandGroup>
|
||||
))}
|
||||
{blocks?.length ? (
|
||||
<CommandGroup
|
||||
heading="Blocks"
|
||||
className="!p-0 [&_[cmdk-group-heading]]:!p-3"
|
||||
>
|
||||
{blocks.map((block) => (
|
||||
<CommandMenuItem
|
||||
key={block.name}
|
||||
value={block.name}
|
||||
onHighlight={() => {
|
||||
handleBlockHighlight(block)
|
||||
}}
|
||||
keywords={[
|
||||
"block",
|
||||
block.name,
|
||||
block.description,
|
||||
...block.categories,
|
||||
]}
|
||||
onSelect={() => {
|
||||
runCommand(() =>
|
||||
router.push(
|
||||
`/blocks/${block.categories[0]}#${block.name}`
|
||||
)
|
||||
)
|
||||
}}
|
||||
>
|
||||
<SquareDashedIcon />
|
||||
{block.description}
|
||||
<span className="text-muted-foreground ml-auto font-mono text-xs font-normal tabular-nums">
|
||||
{block.name}
|
||||
</span>
|
||||
</CommandMenuItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
) : null}
|
||||
</CommandList>
|
||||
</Command>
|
||||
<div className="text-muted-foreground absolute inset-x-0 bottom-0 z-20 flex h-10 items-center gap-2 rounded-b-xl border-t border-t-neutral-100 bg-neutral-50 px-4 text-xs font-medium dark:border-t-neutral-700 dark:bg-neutral-800">
|
||||
|
||||
@@ -22,7 +22,7 @@ export function ComponentPreviewTabs({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn("group relative my-4 flex flex-col gap-2", className)}
|
||||
className={cn("group relative mt-4 mb-12 flex flex-col gap-2", className)}
|
||||
{...props}
|
||||
>
|
||||
<Tabs
|
||||
|
||||
@@ -14,6 +14,15 @@ export function SiteFooter() {
|
||||
className="font-medium underline underline-offset-4"
|
||||
>
|
||||
shadcn
|
||||
</a>{" "}
|
||||
at{" "}
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=shadcn_site&utm_medium=web&utm_campaign=docs_cta_deploy_now_callout"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="font-medium underline underline-offset-4"
|
||||
>
|
||||
Vercel
|
||||
</a>
|
||||
. The source code is available on{" "}
|
||||
<a
|
||||
|
||||
@@ -9,11 +9,11 @@ import { Icons } from "@/components/icons"
|
||||
import { MainNav } from "@/components/main-nav"
|
||||
import { MobileNav } from "@/components/mobile-nav"
|
||||
import { ModeSwitcher } from "@/components/mode-switcher"
|
||||
import { SiteConfig } from "@/components/site-config"
|
||||
// import blocks from "@/registry/__blocks__.json"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
|
||||
import { SiteConfig } from "./site-config"
|
||||
|
||||
export function SiteHeader() {
|
||||
const colors = getColors()
|
||||
const pageTree = source.pageTree
|
||||
|
||||
@@ -4,6 +4,16 @@ description: Latest updates and announcements.
|
||||
toc: false
|
||||
---
|
||||
|
||||
## June 2025 - Calendar Component
|
||||
|
||||
We've upgraded the `Calendar` component to the latest version of [React DayPicker](https://daypicker.dev).
|
||||
|
||||
This is a major upgrade and includes a lot of new features and improvements. We've also built a collection of 30+ calendar blocks that you can use to build your own calendar components.
|
||||
|
||||
See all calendar blocks in the [Blocks Library](/blocks/calendar) page.
|
||||
|
||||
To upgrade your project to the latest version of the `Calendar` component, see the [upgrade guide](/docs/components/calendar#upgrade-guide).
|
||||
|
||||
## May 2025 - New Site
|
||||
|
||||
We've upgraded [ui.shadcn.com](https://ui.shadcn.com) to Next.js 15.3 and Tailwind v4. The site now uses the upgraded `new-york` components.
|
||||
|
||||
@@ -12,9 +12,11 @@ links:
|
||||
description="A calendar showing the current date."
|
||||
/>
|
||||
|
||||
## About
|
||||
## Blocks
|
||||
|
||||
The `Calendar` component is built on top of [React DayPicker](https://react-day-picker.js.org).
|
||||
We have built a collection of 30+ calendar blocks that you can use to build your own calendar components.
|
||||
|
||||
See all calendar blocks in the [Blocks Library](/blocks/calendar) page.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -72,19 +74,346 @@ return (
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
className="rounded-md border"
|
||||
className="rounded-lg border"
|
||||
/>
|
||||
)
|
||||
```
|
||||
|
||||
See the [React DayPicker](https://react-day-picker.js.org) documentation for more information.
|
||||
|
||||
## About
|
||||
|
||||
The `Calendar` component is built on top of [React DayPicker](https://react-day-picker.js.org).
|
||||
|
||||
## Customization
|
||||
|
||||
See the [React DayPicker](https://react-day-picker.js.org/docs/customization) documentation for more information on how to customize the `Calendar` component.
|
||||
|
||||
## Date Picker
|
||||
|
||||
You can use the `<Calendar>` component to build a date picker. See the [Date Picker](/docs/components/date-picker) page for more information.
|
||||
|
||||
## Persian / Hijri / Jalali Calendar
|
||||
|
||||
To use the Persian calendar, edit `components/ui/calendar.tsx` and replace `react-day-picker` with `react-day-picker/persian`.
|
||||
|
||||
```diff
|
||||
- import { DayPicker } from "react-day-picker"
|
||||
+ import { DayPicker } from "react-day-picker/persian"
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-hijri"
|
||||
title="Persian / Hijri / Jalali Calendar"
|
||||
description="A Persian calendar."
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
### Range Calendar
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-02"
|
||||
title="Range Calendar"
|
||||
description="A calendar showing the current date and range selection."
|
||||
className="**:[.preview]:h-auto lg:**:[.preview]:h-[450px]"
|
||||
/>
|
||||
|
||||
### Month and Year Selector
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-13"
|
||||
title="Month and Year Selector"
|
||||
description="A calendar with month and year dropdowns."
|
||||
/>
|
||||
|
||||
### Date of Birth Picker
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-22"
|
||||
title="Date of Birth Picker"
|
||||
description="A calendar with date of birth picker."
|
||||
/>
|
||||
|
||||
### Date and Time Picker
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-24"
|
||||
title="Date and Time Picker"
|
||||
description="A calendar with date and time picker."
|
||||
/>
|
||||
|
||||
### Natural Language Picker
|
||||
|
||||
This component uses the `chrono-node` library to parse natural language dates.
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-29"
|
||||
title="Natural Language Picker"
|
||||
description="A calendar with natural language picker."
|
||||
/>
|
||||
|
||||
### Form
|
||||
|
||||
<ComponentPreview name="calendar-form" />
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
### Tailwind v4
|
||||
|
||||
If you're already using Tailwind v4, you can upgrade to the latest version of the `Calendar` component by running the following command:
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add calendar
|
||||
```
|
||||
|
||||
When you're prompted to overwrite the existing `Calendar` component, select `Yes`. **If you have made any changes to the `Calendar` component, you will need to merge your changes with the new version.**
|
||||
|
||||
This will update the `Calendar` component and `react-day-picker` to the latest version.
|
||||
|
||||
Next, follow the [React DayPicker](https://daypicker.dev/upgrading) upgrade guide to upgrade your existing components to the latest version.
|
||||
|
||||
#### Installing Blocks
|
||||
|
||||
After upgrading the `Calendar` component, you can install the new blocks by running the `shadcn@latest add` command.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add calendar-02
|
||||
```
|
||||
|
||||
This will install the latest version of the calendar blocks.
|
||||
|
||||
### Tailwind v3
|
||||
|
||||
If you're using Tailwind v3, you can upgrade to the latest version of the `Calendar` by copying the following code to your `calendar.tsx` file.
|
||||
|
||||
<CodeCollapsibleWrapper>
|
||||
|
||||
```tsx showLineNumbers title="components/ui/calendar.tsx"
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
} from "lucide-react"
|
||||
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button, buttonVariants } from "@/components/ui/button"
|
||||
|
||||
function Calendar({
|
||||
className,
|
||||
classNames,
|
||||
showOutsideDays = true,
|
||||
captionLayout = "label",
|
||||
buttonVariant = "ghost",
|
||||
formatters,
|
||||
components,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DayPicker> & {
|
||||
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
|
||||
}) {
|
||||
const defaultClassNames = getDefaultClassNames()
|
||||
|
||||
return (
|
||||
<DayPicker
|
||||
showOutsideDays={showOutsideDays}
|
||||
className={cn(
|
||||
"bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
||||
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
||||
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
||||
className
|
||||
)}
|
||||
captionLayout={captionLayout}
|
||||
formatters={{
|
||||
formatMonthDropdown: (date) =>
|
||||
date.toLocaleString("default", { month: "short" }),
|
||||
...formatters,
|
||||
}}
|
||||
classNames={{
|
||||
root: cn("w-fit", defaultClassNames.root),
|
||||
months: cn(
|
||||
"relative flex flex-col gap-4 md:flex-row",
|
||||
defaultClassNames.months
|
||||
),
|
||||
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
|
||||
nav: cn(
|
||||
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
||||
defaultClassNames.nav
|
||||
),
|
||||
button_previous: cn(
|
||||
buttonVariants({ variant: buttonVariant }),
|
||||
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
|
||||
defaultClassNames.button_previous
|
||||
),
|
||||
button_next: cn(
|
||||
buttonVariants({ variant: buttonVariant }),
|
||||
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
|
||||
defaultClassNames.button_next
|
||||
),
|
||||
month_caption: cn(
|
||||
"flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
|
||||
defaultClassNames.month_caption
|
||||
),
|
||||
dropdowns: cn(
|
||||
"flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
|
||||
defaultClassNames.dropdowns
|
||||
),
|
||||
dropdown_root: cn(
|
||||
"has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
|
||||
defaultClassNames.dropdown_root
|
||||
),
|
||||
dropdown: cn("absolute inset-0 opacity-0", defaultClassNames.dropdown),
|
||||
caption_label: cn(
|
||||
"select-none font-medium",
|
||||
captionLayout === "label"
|
||||
? "text-sm"
|
||||
: "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
|
||||
defaultClassNames.caption_label
|
||||
),
|
||||
table: "w-full border-collapse",
|
||||
weekdays: cn("flex", defaultClassNames.weekdays),
|
||||
weekday: cn(
|
||||
"text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
|
||||
defaultClassNames.weekday
|
||||
),
|
||||
week: cn("mt-2 flex w-full", defaultClassNames.week),
|
||||
week_number_header: cn(
|
||||
"w-[--cell-size] select-none",
|
||||
defaultClassNames.week_number_header
|
||||
),
|
||||
week_number: cn(
|
||||
"text-muted-foreground select-none text-[0.8rem]",
|
||||
defaultClassNames.week_number
|
||||
),
|
||||
day: cn(
|
||||
"group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
|
||||
defaultClassNames.day
|
||||
),
|
||||
range_start: cn(
|
||||
"bg-accent rounded-l-md",
|
||||
defaultClassNames.range_start
|
||||
),
|
||||
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
||||
range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
|
||||
today: cn(
|
||||
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
||||
defaultClassNames.today
|
||||
),
|
||||
outside: cn(
|
||||
"text-muted-foreground aria-selected:text-muted-foreground",
|
||||
defaultClassNames.outside
|
||||
),
|
||||
disabled: cn(
|
||||
"text-muted-foreground opacity-50",
|
||||
defaultClassNames.disabled
|
||||
),
|
||||
hidden: cn("invisible", defaultClassNames.hidden),
|
||||
...classNames,
|
||||
}}
|
||||
components={{
|
||||
Root: ({ className, rootRef, ...props }) => {
|
||||
return (
|
||||
<div
|
||||
data-slot="calendar"
|
||||
ref={rootRef}
|
||||
className={cn(className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
},
|
||||
Chevron: ({ className, orientation, ...props }) => {
|
||||
if (orientation === "left") {
|
||||
return (
|
||||
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
|
||||
)
|
||||
}
|
||||
|
||||
if (orientation === "right") {
|
||||
return (
|
||||
<ChevronRightIcon
|
||||
className={cn("size-4", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
||||
)
|
||||
},
|
||||
DayButton: CalendarDayButton,
|
||||
WeekNumber: ({ children, ...props }) => {
|
||||
return (
|
||||
<td {...props}>
|
||||
<div className="flex size-[--cell-size] items-center justify-center text-center">
|
||||
{children}
|
||||
</div>
|
||||
</td>
|
||||
)
|
||||
},
|
||||
...components,
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function CalendarDayButton({
|
||||
className,
|
||||
day,
|
||||
modifiers,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DayButton>) {
|
||||
const defaultClassNames = getDefaultClassNames()
|
||||
|
||||
const ref = React.useRef<HTMLButtonElement>(null)
|
||||
React.useEffect(() => {
|
||||
if (modifiers.focused) ref.current?.focus()
|
||||
}, [modifiers.focused])
|
||||
|
||||
return (
|
||||
<Button
|
||||
ref={ref}
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
data-day={day.date.toLocaleDateString()}
|
||||
data-selected-single={
|
||||
modifiers.selected &&
|
||||
!modifiers.range_start &&
|
||||
!modifiers.range_end &&
|
||||
!modifiers.range_middle
|
||||
}
|
||||
data-range-start={modifiers.range_start}
|
||||
data-range-end={modifiers.range_end}
|
||||
data-range-middle={modifiers.range_middle}
|
||||
className={cn(
|
||||
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
|
||||
defaultClassNames.day,
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Calendar, CalendarDayButton }
|
||||
```
|
||||
|
||||
</CodeCollapsibleWrapper>
|
||||
|
||||
**If you have made any changes to the `Calendar` component, you will need to merge your changes with the new version.**
|
||||
|
||||
Then follow the [React DayPicker](https://daypicker.dev/upgrading) upgrade guide to upgrade your dependencies and existing components to the latest version.
|
||||
|
||||
#### Installing Blocks
|
||||
|
||||
After upgrading the `Calendar` component, you can install the new blocks by running the `shadcn@latest add` command.
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add calendar-02
|
||||
```
|
||||
|
||||
This will install the latest version of the calendar blocks.
|
||||
|
||||
@@ -5,8 +5,9 @@ component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="date-picker-demo"
|
||||
description="A date picker in a popover"
|
||||
name="calendar-22"
|
||||
title="Date of Birth Picker"
|
||||
description="A calendar with date of birth picker."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
@@ -40,23 +41,16 @@ export function DatePickerDemo() {
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[280px] justify-start text-left font-normal",
|
||||
!date && "text-muted-foreground"
|
||||
)}
|
||||
variant="outline"
|
||||
data-empty={!date}
|
||||
className="data-[empty=true]:text-muted-foreground w-[280px] justify-start text-left font-normal"
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
<CalendarIcon />
|
||||
{date ? format(date, "PPP") : <span>Pick a date</span>}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={date}
|
||||
onSelect={setDate}
|
||||
initialFocus
|
||||
/>
|
||||
<Calendar mode="single" selected={date} onSelect={setDate} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
@@ -67,25 +61,38 @@ See the [React DayPicker](https://react-day-picker.js.org) documentation for mor
|
||||
|
||||
## Examples
|
||||
|
||||
### Date Picker
|
||||
### Date of Birth Picker
|
||||
|
||||
<ComponentPreview
|
||||
name="date-picker-demo"
|
||||
description="A date picker in a popover"
|
||||
name="calendar-22"
|
||||
title="Date of Birth Picker"
|
||||
description="A calendar with date of birth picker."
|
||||
/>
|
||||
|
||||
### Date Range Picker
|
||||
### Picker with Input
|
||||
|
||||
<ComponentPreview
|
||||
name="date-picker-with-range"
|
||||
description="A date range picker"
|
||||
name="calendar-28"
|
||||
title="Picker with Input"
|
||||
description="A calendar with input and picker."
|
||||
/>
|
||||
|
||||
### With Presets
|
||||
### Date and Time Picker
|
||||
|
||||
<ComponentPreview
|
||||
name="date-picker-with-presets"
|
||||
description="A date picker with presets"
|
||||
name="calendar-24"
|
||||
title="Date and Time Picker"
|
||||
description="A calendar with date and time picker."
|
||||
/>
|
||||
|
||||
### Natural Language Picker
|
||||
|
||||
This component uses the `chrono-node` library to parse natural language dates.
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-29"
|
||||
title="Natural Language Picker"
|
||||
description="A calendar with natural language picker."
|
||||
/>
|
||||
|
||||
### Form
|
||||
|
||||
17
apps/v4/hooks/use-mobile.ts
Normal file
17
apps/v4/hooks/use-mobile.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import * as React from "react"
|
||||
|
||||
export function useIsMobile(mobileBreakpoint = 768) {
|
||||
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
||||
|
||||
React.useEffect(() => {
|
||||
const mql = window.matchMedia(`(max-width: ${mobileBreakpoint - 1}px)`)
|
||||
const onChange = () => {
|
||||
setIsMobile(window.innerWidth < mobileBreakpoint)
|
||||
}
|
||||
mql.addEventListener("change", onChange)
|
||||
setIsMobile(window.innerWidth < mobileBreakpoint)
|
||||
return () => mql.removeEventListener("change", onChange)
|
||||
}, [])
|
||||
|
||||
return !!isMobile
|
||||
}
|
||||
@@ -10,18 +10,26 @@ export async function getAllBlockIds(
|
||||
],
|
||||
categories: string[] = []
|
||||
): Promise<string[]> {
|
||||
const blocks = await getAllBlocks(types, categories)
|
||||
|
||||
return blocks.map((block) => block.name)
|
||||
}
|
||||
|
||||
export async function getAllBlocks(
|
||||
types: z.infer<typeof registryItemSchema>["type"][] = [
|
||||
"registry:block",
|
||||
"registry:internal",
|
||||
],
|
||||
categories: string[] = []
|
||||
) {
|
||||
const { Index } = await import("@/registry/__index__")
|
||||
const index = z.record(registryItemSchema).parse(Index)
|
||||
|
||||
return Object.values(index)
|
||||
.filter(
|
||||
(block) =>
|
||||
types.includes(block.type) &&
|
||||
(categories.length === 0 ||
|
||||
block.categories?.some((category) =>
|
||||
categories.includes(category)
|
||||
)) &&
|
||||
!block.name.startsWith("chart-")
|
||||
)
|
||||
.map((block) => block.name)
|
||||
return Object.values(index).filter(
|
||||
(block) =>
|
||||
types.includes(block.type) &&
|
||||
(categories.length === 0 ||
|
||||
block.categories?.some((category) => categories.includes(category))) &&
|
||||
!block.name.startsWith("chart-")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"@tanstack/react-table": "^8.9.1",
|
||||
"@vercel/analytics": "^1.4.1",
|
||||
"change-case": "^5.4.4",
|
||||
"chrono-node": "^2.8.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
@@ -70,6 +71,7 @@
|
||||
"fumadocs-ui": "^15.3.1",
|
||||
"input-otp": "^1.4.2",
|
||||
"jotai": "^2.1.0",
|
||||
"little-date": "^1.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "0.474.0",
|
||||
"motion": "^12.12.1",
|
||||
@@ -77,7 +79,7 @@
|
||||
"next-themes": "0.4.6",
|
||||
"postcss": "^8.5.1",
|
||||
"react": "19.1.0",
|
||||
"react-day-picker": "^8.7.1",
|
||||
"react-day-picker": "^9.7.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-hook-form": "^7.54.2",
|
||||
"react-resizable-panels": "^2.1.7",
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
"name": "calendar",
|
||||
"type": "registry:ui",
|
||||
"dependencies": [
|
||||
"react-day-picker@8.10.1",
|
||||
"react-day-picker@latest",
|
||||
"date-fns"
|
||||
],
|
||||
"registryDependencies": [
|
||||
|
||||
27
apps/v4/public/r/styles/default/calendar-01.json
Normal file
27
apps/v4/public/r/styles/default/calendar-01.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-01",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "A simple calendar.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-01.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar01() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-02.json
Normal file
27
apps/v4/public/r/styles/default/calendar-02.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-02",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with single selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-02.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar02() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n numberOfMonths={2}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-03.json
Normal file
27
apps/v4/public/r/styles/default/calendar-03.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-03",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with multiple selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-03.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar03() {\n const [dates, setDates] = React.useState<Date[]>([\n new Date(2025, 5, 12),\n new Date(2025, 6, 24),\n ])\n\n return (\n <Calendar\n mode=\"multiple\"\n numberOfMonths={2}\n defaultMonth={dates[0]}\n required\n selected={dates}\n onSelect={setDates}\n max={5}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-04.json
Normal file
27
apps/v4/public/r/styles/default/calendar-04.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-04",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Single month with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-04.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar04() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 9),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0 xl:pt-28",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-05.json
Normal file
27
apps/v4/public/r/styles/default/calendar-05.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-05",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-05.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar05() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 6, 15),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-06.json
Normal file
27
apps/v4/public/r/styles/default/calendar-06.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-06",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Range selection with minimum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-06.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar06() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={1}\n min={5}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n A minimum of 5 days is required\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-07.json
Normal file
27
apps/v4/public/r/styles/default/calendar-07.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-07",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Range selection with minimum and maximum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-07.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar07() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 18),\n to: new Date(2025, 6, 7),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n min={2}\n max={20}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n Your stay must be between 2 and 20 nights\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-08.json
Normal file
27
apps/v4/public/r/styles/default/calendar-08.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-08",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Calendar with disabled days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-08.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar08() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n disabled={{\n before: new Date(2025, 5, 12),\n }}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-09.json
Normal file
27
apps/v4/public/r/styles/default/calendar-09.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-09",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Calendar with disabled weekends",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-09.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar09() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n disabled={{ dayOfWeek: [0, 6] }}\n className=\"rounded-lg border shadow-sm\"\n excludeDisabled\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-10.json
Normal file
29
apps/v4/public/r/styles/default/calendar-10.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-10",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Today button",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-10.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/default/ui/card\"\n\nexport default function Calendar10() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const [month, setMonth] = React.useState<Date | undefined>(new Date())\n\n return (\n <Card>\n <CardHeader className=\"relative\">\n <CardTitle>Appointment</CardTitle>\n <CardDescription>Find a date</CardDescription>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"absolute right-4 top-4\"\n onClick={() => {\n setMonth(new Date())\n setDate(new Date())\n }}\n >\n Today\n </Button>\n </CardHeader>\n <CardContent>\n <Calendar\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n />\n </CardContent>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-11.json
Normal file
27
apps/v4/public/r/styles/default/calendar-11.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-11",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Start and end of month",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-11.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar11() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n startMonth={new Date(2025, 5, 1)}\n endMonth={new Date(2025, 6, 31)}\n disableNavigation\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n We are open in June and July only.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-12.json
Normal file
29
apps/v4/public/r/styles/default/calendar-12.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-12",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Localized calendar",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"select"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-12.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\nimport { enUS, es } from \"react-day-picker/locale\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/default/ui/card\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/default/ui/select\"\n\nconst localizedStrings = {\n en: {\n title: \"Book an appointment\",\n description: \"Select the dates for your appointment\",\n },\n es: {\n title: \"Reserva una cita\",\n description: \"Selecciona las fechas para tu cita\",\n },\n} as const\n\nexport default function Calendar12() {\n const [locale, setLocale] =\n React.useState<keyof typeof localizedStrings>(\"es\")\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 8, 9),\n to: new Date(2025, 8, 17),\n })\n\n return (\n <Card>\n <CardHeader className=\"relative border-b\">\n <CardTitle>{localizedStrings[locale].title}</CardTitle>\n <CardDescription>\n {localizedStrings[locale].description}\n </CardDescription>\n <Select\n value={locale}\n onValueChange={(value) =>\n setLocale(value as keyof typeof localizedStrings)\n }\n >\n <SelectTrigger className=\"absolute right-4 top-4 w-[100px]\">\n <SelectValue placeholder=\"Language\" />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value=\"es\">Español</SelectItem>\n <SelectItem value=\"en\">English</SelectItem>\n </SelectContent>\n </Select>\n </CardHeader>\n <CardContent className=\"pt-4\">\n <Calendar\n mode=\"range\"\n selected={dateRange}\n onSelect={setDateRange}\n defaultMonth={dateRange?.from}\n numberOfMonths={2}\n locale={locale === \"es\" ? es : enUS}\n className=\"bg-transparent p-0\"\n buttonVariant=\"outline\"\n />\n </CardContent>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-13.json
Normal file
29
apps/v4/public/r/styles/default/calendar-13.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-13",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With Month and Year Dropdown",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"label",
|
||||
"select"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-13.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/default/ui/select\"\n\nexport default function Calendar13() {\n const [dropdown, setDropdown] =\n React.useState<React.ComponentProps<typeof Calendar>[\"captionLayout\"]>(\n \"dropdown\"\n )\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <div className=\"flex flex-col gap-4\">\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n captionLayout={dropdown}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dropdown\" className=\"px-1\">\n Dropdown\n </Label>\n <Select\n value={dropdown}\n onValueChange={(value) =>\n setDropdown(\n value as React.ComponentProps<typeof Calendar>[\"captionLayout\"]\n )\n }\n >\n <SelectTrigger id=\"dropdown\" className=\"bg-background w-full\">\n <SelectValue placeholder=\"Dropdown\" />\n </SelectTrigger>\n <SelectContent align=\"center\">\n <SelectItem value=\"dropdown\">Month and Year</SelectItem>\n <SelectItem value=\"dropdown-months\">Month Only</SelectItem>\n <SelectItem value=\"dropdown-years\">Year Only</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-14.json
Normal file
27
apps/v4/public/r/styles/default/calendar-14.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-14",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With Booked/Unavailable Days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-14.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar14() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const bookedDates = Array.from(\n { length: 12 },\n (_, i) => new Date(2025, 5, 15 + i)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n disabled={bookedDates}\n modifiers={{\n booked: bookedDates,\n }}\n modifiersClassNames={{\n booked: \"[&>button]:line-through opacity-100\",\n }}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-15.json
Normal file
27
apps/v4/public/r/styles/default/calendar-15.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-15",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With Week Numbers",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-15.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar15() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n showWeekNumber\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-16.json
Normal file
30
apps/v4/public/r/styles/default/calendar-16.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-16",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With time picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-16.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Clock2Icon } from \"lucide-react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/default/ui/card\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\n\nexport default function Calendar16() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n />\n </CardContent>\n <CardFooter className=\"flex flex-col gap-6 border-t px-4 pb-0 pt-4\">\n <div className=\"flex w-full flex-col gap-3\">\n <Label htmlFor=\"time-from\">Start Time</Label>\n <div className=\"relative flex w-full items-center gap-2\">\n <Clock2Icon className=\"text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none\" />\n <Input\n id=\"time-from\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n <div className=\"flex w-full flex-col gap-3\">\n <Label htmlFor=\"time-to\">End Time</Label>\n <div className=\"relative flex w-full items-center gap-2\">\n <Clock2Icon className=\"text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none\" />\n <Input\n id=\"time-to\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-17.json
Normal file
30
apps/v4/public/r/styles/default/calendar-17.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-17",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With time picker inline",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-17.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/default/ui/card\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\n\nexport default function Calendar17() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0 [--cell-size:2.8rem]\"\n />\n </CardContent>\n <CardFooter className=\"*:[div]:w-full flex gap-2 border-t px-4 pb-0 pt-4\">\n <div className=\"flex-1\">\n <Label htmlFor=\"time-from\" className=\"sr-only\">\n Start Time\n </Label>\n <Input\n id=\"time-from\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n <span>-</span>\n <div className=\"flex-1\">\n <Label htmlFor=\"time-to\" className=\"sr-only\">\n End Time\n </Label>\n <Input\n id=\"time-to\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-18.json
Normal file
27
apps/v4/public/r/styles/default/calendar-18.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-18",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Variable size",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-18.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar18() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border [--cell-size:2.75rem] md:[--cell-size:3rem]\"\n buttonVariant=\"ghost\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
33
apps/v4/public/r/styles/default/calendar-19.json
Normal file
33
apps/v4/public/r/styles/default/calendar-19.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-19",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With presets",
|
||||
"dependencies": [
|
||||
"date-fns"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-19.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays } from \"date-fns\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/default/ui/card\"\n\nexport default function Calendar19() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"max-w-[300px] py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n defaultMonth={date}\n className=\"bg-transparent p-0 [--cell-size:2.375rem]\"\n />\n </CardContent>\n <CardFooter className=\"flex flex-wrap gap-2 border-t px-4 pb-0 pt-4\">\n {[\n { label: \"Today\", value: 0 },\n { label: \"Tomorrow\", value: 1 },\n { label: \"In 3 days\", value: 3 },\n { label: \"In a week\", value: 7 },\n { label: \"In 2 weeks\", value: 14 },\n ].map((preset) => (\n <Button\n key={preset.value}\n variant=\"outline\"\n size=\"sm\"\n className=\"flex-1\"\n onClick={() => {\n const newDate = addDays(new Date(), preset.value)\n setDate(newDate)\n }}\n >\n {preset.label}\n </Button>\n ))}\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-20.json
Normal file
29
apps/v4/public/r/styles/default/calendar-20.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-20",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With time presets",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-20.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/default/ui/card\"\n\nexport default function Calendar20() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const [selectedTime, setSelectedTime] = React.useState<string | null>(\"10:00\")\n const timeSlots = Array.from({ length: 37 }, (_, i) => {\n const totalMinutes = i * 15\n const hour = Math.floor(totalMinutes / 60) + 9\n const minute = totalMinutes % 60\n return `${hour.toString().padStart(2, \"0\")}:${minute\n .toString()\n .padStart(2, \"0\")}`\n })\n\n const bookedDates = Array.from(\n { length: 3 },\n (_, i) => new Date(2025, 5, 17 + i)\n )\n\n return (\n <Card className=\"gap-0 p-0\">\n <CardContent className=\"relative p-0 md:pr-48\">\n <div className=\"p-6\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n defaultMonth={date}\n disabled={bookedDates}\n showOutsideDays={false}\n modifiers={{\n booked: bookedDates,\n }}\n modifiersClassNames={{\n booked: \"[&>button]:line-through opacity-100\",\n }}\n className=\"bg-transparent p-0 [--cell-size:2.5rem] md:[--cell-size:3rem]\"\n formatters={{\n formatWeekdayName: (date) => {\n return date.toLocaleString(\"en-US\", { weekday: \"short\" })\n },\n }}\n />\n </div>\n <div className=\"no-scrollbar inset-y-0 right-0 flex max-h-72 w-full scroll-pb-6 flex-col gap-4 overflow-y-auto border-t p-6 md:absolute md:max-h-none md:w-48 md:border-l md:border-t-0\">\n <div className=\"grid gap-2\">\n {timeSlots.map((time) => (\n <Button\n key={time}\n variant={selectedTime === time ? \"default\" : \"outline\"}\n onClick={() => setSelectedTime(time)}\n className=\"w-full shadow-none\"\n >\n {time}\n </Button>\n ))}\n </div>\n </div>\n </CardContent>\n <CardFooter className=\"flex flex-col gap-4 border-t !py-5 px-6 md:flex-row\">\n <div className=\"text-sm\">\n {date && selectedTime ? (\n <>\n Your meeting is booked for{\" \"}\n <span className=\"font-medium\">\n {\" \"}\n {date?.toLocaleDateString(\"en-US\", {\n weekday: \"long\",\n day: \"numeric\",\n month: \"long\",\n })}{\" \"}\n </span>\n at <span className=\"font-medium\">{selectedTime}</span>.\n </>\n ) : (\n <>Select a date and time for your meeting.</>\n )}\n </div>\n <Button\n disabled={!date || !selectedTime}\n className=\"w-full md:ml-auto md:w-auto\"\n variant=\"outline\"\n >\n Continue\n </Button>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/default/calendar-21.json
Normal file
27
apps/v4/public/r/styles/default/calendar-21.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-21",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Custom days and formatters",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-21.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { DateRange } from \"react-day-picker\"\n\nimport { Calendar, CalendarDayButton } from \"@/registry/default/ui/calendar\"\n\nexport default function Calendar21() {\n const [range, setRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 5, 17),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={range?.from}\n selected={range}\n onSelect={setRange}\n numberOfMonths={1}\n captionLayout=\"dropdown\"\n className=\"rounded-lg border shadow-sm [--cell-size:2.75rem] md:[--cell-size:3rem]\"\n formatters={{\n formatMonthDropdown: (date) => {\n return date.toLocaleString(\"default\", { month: \"long\" })\n },\n }}\n components={{\n DayButton: ({ children, modifiers, day, ...props }) => {\n const isWeekend = day.date.getDay() === 0 || day.date.getDay() === 6\n\n return (\n <CalendarDayButton day={day} modifiers={modifiers} {...props}>\n {children}\n {!modifiers.outside && <span>{isWeekend ? \"$220\" : \"$100\"}</span>}\n </CalendarDayButton>\n )\n },\n }}\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-22.json
Normal file
30
apps/v4/public/r/styles/default/calendar-22.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-22",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-22.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar22() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date of birth\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-48 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-23.json
Normal file
30
apps/v4/public/r/styles/default/calendar-23.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-23",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date range picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-23.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar23() {\n const [range, setRange] = React.useState<DateRange | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dates\" className=\"px-1\">\n Select your stay\n </Label>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"dates\"\n className=\"w-56 justify-between font-normal\"\n >\n {range?.from && range?.to\n ? `${range.from.toLocaleDateString()} - ${range.to.toLocaleDateString()}`\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={range}\n captionLayout=\"dropdown\"\n onSelect={(range) => {\n setRange(range)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-24.json
Normal file
30
apps/v4/public/r/styles/default/calendar-24.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-24",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date and Time picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-24.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar24() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-32 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time\" className=\"px-1\">\n Time\n </Label>\n <Input\n type=\"time\"\n id=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
30
apps/v4/public/r/styles/default/calendar-25.json
Normal file
30
apps/v4/public/r/styles/default/calendar-25.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-25",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date and Time range picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-25.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar25() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-full justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-from\" className=\"px-1\">\n From\n </Label>\n <Input\n type=\"time\"\n id=\"time-from\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-to\" className=\"px-1\">\n To\n </Label>\n <Input\n type=\"time\"\n id=\"time-to\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
31
apps/v4/public/r/styles/default/calendar-26.json
Normal file
31
apps/v4/public/r/styles/default/calendar-26.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-26",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date range picker with time",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-26.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar26() {\n const [openFrom, setOpenFrom] = React.useState(false)\n const [openTo, setOpenTo] = React.useState(false)\n const [dateFrom, setDateFrom] = React.useState<Date | undefined>(\n new Date(\"2025-06-01\")\n )\n const [dateTo, setDateTo] = React.useState<Date | undefined>(\n new Date(\"2025-06-03\")\n )\n\n return (\n <div className=\"flex w-full max-w-64 min-w-0 flex-col gap-6\">\n <div className=\"flex gap-4\">\n <div className=\"flex flex-1 flex-col gap-3\">\n <Label htmlFor=\"date-from\" className=\"px-1\">\n Check-in\n </Label>\n <Popover open={openFrom} onOpenChange={setOpenFrom}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date-from\"\n className=\"w-full justify-between font-normal\"\n >\n {dateFrom\n ? dateFrom.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"start\"\n >\n <Calendar\n mode=\"single\"\n selected={dateFrom}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDateFrom(date)\n setOpenFrom(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-from\" className=\"invisible px-1\">\n From\n </Label>\n <Input\n type=\"time\"\n id=\"time-from\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n <div className=\"flex gap-4\">\n <div className=\"flex flex-1 flex-col gap-3\">\n <Label htmlFor=\"date-to\" className=\"px-1\">\n Check-out\n </Label>\n <Popover open={openTo} onOpenChange={setOpenTo}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date-to\"\n className=\"w-full justify-between font-normal\"\n >\n {dateTo\n ? dateTo.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"start\"\n >\n <Calendar\n mode=\"single\"\n selected={dateTo}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDateTo(date)\n setOpenTo(false)\n }}\n disabled={dateFrom && { before: dateFrom }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-to\" className=\"invisible px-1\">\n To\n </Label>\n <Input\n type=\"time\"\n id=\"time-to\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
31
apps/v4/public/r/styles/default/calendar-27.json
Normal file
31
apps/v4/public/r/styles/default/calendar-27.json
Normal file
File diff suppressed because one or more lines are too long
31
apps/v4/public/r/styles/default/calendar-28.json
Normal file
31
apps/v4/public/r/styles/default/calendar-28.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-28",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Input with date picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-28.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nfunction formatDate(date: Date | undefined) {\n if (!date) {\n return \"\"\n }\n\n return date.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n })\n}\n\nfunction isValidDate(date: Date | undefined) {\n if (!date) {\n return false\n }\n return !isNaN(date.getTime())\n}\n\nexport default function Calendar28() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(\"2025-06-01\")\n )\n const [month, setMonth] = React.useState<Date | undefined>(date)\n const [value, setValue] = React.useState(formatDate(date))\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Subscription Date\n </Label>\n <div className=\"relative flex gap-2\">\n <Input\n id=\"date\"\n value={value}\n placeholder=\"June 01, 2025\"\n className=\"bg-background pr-10\"\n onChange={(e) => {\n const date = new Date(e.target.value)\n setValue(e.target.value)\n if (isValidDate(date)) {\n setDate(date)\n setMonth(date)\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setOpen(true)\n }\n }}\n />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id=\"date-picker\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-2 top-1/2 h-6 w-6 -translate-y-1/2\"\n >\n <CalendarIcon className=\"size-3\" />\n <span className=\"sr-only\">Select date</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"end\"\n alignOffset={-8}\n sideOffset={10}\n >\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n onSelect={(date) => {\n setDate(date)\n setValue(formatDate(date))\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
34
apps/v4/public/r/styles/default/calendar-29.json
Normal file
34
apps/v4/public/r/styles/default/calendar-29.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-29",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Natural language date picker",
|
||||
"dependencies": [
|
||||
"chrono-node"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-29.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { parseDate } from \"chrono-node\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Input } from \"@/registry/default/ui/input\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nfunction formatDate(date: Date | undefined) {\n if (!date) {\n return \"\"\n }\n\n return date.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n })\n}\n\nexport default function Calendar29() {\n const [open, setOpen] = React.useState(false)\n const [value, setValue] = React.useState(\"In 2 days\")\n const [date, setDate] = React.useState<Date | undefined>(\n parseDate(value) || undefined\n )\n const [month, setMonth] = React.useState<Date | undefined>(date)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Schedule Date\n </Label>\n <div className=\"relative flex gap-2\">\n <Input\n id=\"date\"\n value={value}\n placeholder=\"Tomorrow or next week\"\n className=\"bg-background pr-10\"\n onChange={(e) => {\n setValue(e.target.value)\n const date = parseDate(e.target.value)\n if (date) {\n setDate(date)\n setMonth(date)\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setOpen(true)\n }\n }}\n />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id=\"date-picker\"\n variant=\"ghost\"\n className=\"absolute top-1/2 right-2 size-6 -translate-y-1/2\"\n >\n <CalendarIcon className=\"size-3.5\" />\n <span className=\"sr-only\">Select date</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"end\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n onSelect={(date) => {\n setDate(date)\n setValue(formatDate(date))\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"text-muted-foreground px-1 text-sm\">\n Your post will be published on{\" \"}\n <span className=\"font-medium\">{formatDate(date)}</span>.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
31
apps/v4/public/r/styles/default/calendar-30.json
Normal file
31
apps/v4/public/r/styles/default/calendar-30.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-30",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With little-date",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-30.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { formatDateRange } from \"little-date\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Label } from \"@/registry/default/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport default function Calendar30() {\n const [range, setRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 4),\n to: new Date(2025, 5, 10),\n })\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dates\" className=\"px-1\">\n Select your stay\n </Label>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"dates\"\n className=\"w-56 justify-between font-normal\"\n >\n {range?.from && range?.to\n ? formatDateRange(range.from, range.to, {\n includeTime: false,\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={range}\n captionLayout=\"dropdown\"\n onSelect={(range) => {\n setRange(range)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-31.json
Normal file
29
apps/v4/public/r/styles/default/calendar-31.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-31",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "With event slots",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-31.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { formatDateRange } from \"little-date\"\nimport { PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/default/ui/card\"\n\nconst events = [\n {\n title: \"Team Sync Meeting\",\n from: \"2025-06-12T09:00:00\",\n to: \"2025-06-12T10:00:00\",\n },\n {\n title: \"Design Review\",\n from: \"2025-06-12T11:30:00\",\n to: \"2025-06-12T12:30:00\",\n },\n {\n title: \"Client Presentation\",\n from: \"2025-06-12T14:00:00\",\n to: \"2025-06-12T15:00:00\",\n },\n]\n\nexport default function Calendar31() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n required\n />\n </CardContent>\n <CardFooter className=\"flex flex-col items-start gap-3 border-t px-4 pb-0 pt-4\">\n <div className=\"flex w-full items-center justify-between px-1\">\n <div className=\"text-sm font-medium\">\n {date?.toLocaleDateString(\"en-US\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n })}\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n title=\"Add Event\"\n >\n <PlusIcon />\n <span className=\"sr-only\">Add Event</span>\n </Button>\n </div>\n <div className=\"flex w-full flex-col gap-2\">\n {events.map((event) => (\n <div\n key={event.title}\n className=\"bg-muted after:bg-primary/70 relative rounded-md p-2 pl-6 text-sm after:absolute after:inset-y-2 after:left-2 after:w-1 after:rounded-full\"\n >\n <div className=\"font-medium\">{event.title}</div>\n <div className=\"text-muted-foreground text-xs\">\n {formatDateRange(new Date(event.from), new Date(event.to))}\n </div>\n </div>\n ))}\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "700px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/default/calendar-32.json
Normal file
29
apps/v4/public/r/styles/default/calendar-32.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-32",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Date picker in a drawer",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"button",
|
||||
"drawer"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-32.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CalendarPlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/default/ui/button\"\nimport { Calendar } from \"@/registry/default/ui/calendar\"\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/default/ui/drawer\"\nimport { Label } from \"@/registry/default/ui/label\"\n\nexport default function Calendar32() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date of birth\n </Label>\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-48 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <CalendarPlusIcon />\n </Button>\n </DrawerTrigger>\n <DrawerContent className=\"w-auto overflow-hidden p-0\">\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Select date</DrawerTitle>\n <DrawerDescription>Set your date of birth</DrawerDescription>\n </DrawerHeader>\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n className=\"mx-auto [--cell-size:clamp(0px,calc(100vw/7.5),52px)]\"\n />\n </DrawerContent>\n </Drawer>\n <div className=\"text-muted-foreground px-1 text-sm\">\n This example works best on mobile.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/examples/accordion-demo.tsx",
|
||||
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/new-york-v4/ui/accordion\"\n\nexport default function AccordionDemo() {\n return (\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Product Information</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n Our flagship product combines cutting-edge technology with sleek\n design. Built with premium materials, it offers unparalleled\n performance and reliability.\n </p>\n <p>\n Key features include advanced processing capabilities, and an\n intuitive user interface designed for both beginners and experts.\n </p>\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\">\n <AccordionTrigger>Shipping Details</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n We offer worldwide shipping through trusted courier partners.\n Standard delivery takes 3-5 business days, while express shipping\n ensures delivery within 1-2 business days.\n </p>\n <p>\n All orders are carefully packaged and fully insured. Track your\n shipment in real-time through our dedicated tracking portal.\n </p>\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-3\">\n <AccordionTrigger>Return Policy</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n We stand behind our products with a comprehensive 30-day return\n policy. If you're not completely satisfied, simply return the\n item in its original condition.\n </p>\n <p>\n Our hassle-free return process includes free return shipping and\n full refunds processed within 48 hours of receiving the returned\n item.\n </p>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n",
|
||||
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/new-york-v4/ui/accordion\"\n\nexport default function AccordionDemo() {\n return (\n <Accordion\n type=\"single\"\n collapsible\n className=\"w-full\"\n defaultValue=\"item-1\"\n >\n <AccordionItem value=\"item-1\">\n <AccordionTrigger>Product Information</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n Our flagship product combines cutting-edge technology with sleek\n design. Built with premium materials, it offers unparalleled\n performance and reliability.\n </p>\n <p>\n Key features include advanced processing capabilities, and an\n intuitive user interface designed for both beginners and experts.\n </p>\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-2\">\n <AccordionTrigger>Shipping Details</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n We offer worldwide shipping through trusted courier partners.\n Standard delivery takes 3-5 business days, while express shipping\n ensures delivery within 1-2 business days.\n </p>\n <p>\n All orders are carefully packaged and fully insured. Track your\n shipment in real-time through our dedicated tracking portal.\n </p>\n </AccordionContent>\n </AccordionItem>\n <AccordionItem value=\"item-3\">\n <AccordionTrigger>Return Policy</AccordionTrigger>\n <AccordionContent className=\"flex flex-col gap-4 text-balance\">\n <p>\n We stand behind our products with a comprehensive 30-day return\n policy. If you're not completely satisfied, simply return the\n item in its original condition.\n </p>\n <p>\n Our hassle-free return process includes free return shipping and\n full refunds processed within 48 hours of receiving the returned\n item.\n </p>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
}
|
||||
]
|
||||
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-01.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-01.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-01",
|
||||
"type": "registry:block",
|
||||
"description": "A simple calendar.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-01.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar01() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-02.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-02.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-02",
|
||||
"type": "registry:block",
|
||||
"description": "Multiple months with single selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-02.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar02() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n numberOfMonths={2}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-03.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-03.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-03",
|
||||
"type": "registry:block",
|
||||
"description": "Multiple months with multiple selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-03.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar03() {\n const [dates, setDates] = React.useState<Date[]>([\n new Date(2025, 5, 12),\n new Date(2025, 6, 24),\n ])\n\n return (\n <Calendar\n mode=\"multiple\"\n numberOfMonths={2}\n defaultMonth={dates[0]}\n required\n selected={dates}\n onSelect={setDates}\n max={5}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-04.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-04.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-04",
|
||||
"type": "registry:block",
|
||||
"description": "Single month with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-04.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar04() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 9),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0 xl:pt-28",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-05.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-05.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-05",
|
||||
"type": "registry:block",
|
||||
"description": "Multiple months with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-05.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar05() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 6, 15),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-06.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-06.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-06",
|
||||
"type": "registry:block",
|
||||
"description": "Range selection with minimum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-06.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar06() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={1}\n min={5}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n A minimum of 5 days is required\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-07.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-07.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-07",
|
||||
"type": "registry:block",
|
||||
"description": "Range selection with minimum and maximum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-07.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar07() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 18),\n to: new Date(2025, 6, 7),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n min={2}\n max={20}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n Your stay must be between 2 and 20 nights\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-08.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-08.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-08",
|
||||
"type": "registry:block",
|
||||
"description": "Calendar with disabled days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-08.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar08() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n disabled={{\n before: new Date(2025, 5, 12),\n }}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-09.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-09.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-09",
|
||||
"type": "registry:block",
|
||||
"description": "Calendar with disabled weekends",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-09.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar09() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n disabled={{ dayOfWeek: [0, 6] }}\n className=\"rounded-lg border shadow-sm\"\n excludeDisabled\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-10.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-10.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-10",
|
||||
"type": "registry:block",
|
||||
"description": "Today button",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-10.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york-v4/ui/card\"\n\nexport default function Calendar10() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const [month, setMonth] = React.useState<Date | undefined>(new Date())\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>Appointment</CardTitle>\n <CardDescription>Find a date</CardDescription>\n <CardAction>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setMonth(new Date())\n setDate(new Date())\n }}\n >\n Today\n </Button>\n </CardAction>\n </CardHeader>\n <CardContent>\n <Calendar\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n />\n </CardContent>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-11.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-11.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-11",
|
||||
"type": "registry:block",
|
||||
"description": "Start and end of month",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-11.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar11() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n startMonth={new Date(2025, 5, 1)}\n endMonth={new Date(2025, 6, 31)}\n disableNavigation\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n We are open in June and July only.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-12.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-12.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-12",
|
||||
"type": "registry:block",
|
||||
"description": "Localized calendar",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"select"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-12.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\nimport { enUS, es } from \"react-day-picker/locale\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york-v4/ui/card\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york-v4/ui/select\"\n\nconst localizedStrings = {\n en: {\n title: \"Book an appointment\",\n description: \"Select the dates for your appointment\",\n },\n es: {\n title: \"Reserva una cita\",\n description: \"Selecciona las fechas para tu cita\",\n },\n} as const\n\nexport default function Calendar12() {\n const [locale, setLocale] =\n React.useState<keyof typeof localizedStrings>(\"es\")\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 8, 9),\n to: new Date(2025, 8, 17),\n })\n\n return (\n <Card>\n <CardHeader className=\"border-b\">\n <CardTitle>{localizedStrings[locale].title}</CardTitle>\n <CardDescription>\n {localizedStrings[locale].description}\n </CardDescription>\n <CardAction>\n <Select\n value={locale}\n onValueChange={(value) =>\n setLocale(value as keyof typeof localizedStrings)\n }\n >\n <SelectTrigger className=\"w-[100px]\">\n <SelectValue placeholder=\"Language\" />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value=\"es\">Español</SelectItem>\n <SelectItem value=\"en\">English</SelectItem>\n </SelectContent>\n </Select>\n </CardAction>\n </CardHeader>\n <CardContent>\n <Calendar\n mode=\"range\"\n selected={dateRange}\n onSelect={setDateRange}\n defaultMonth={dateRange?.from}\n numberOfMonths={2}\n locale={locale === \"es\" ? es : enUS}\n className=\"bg-transparent p-0\"\n buttonVariant=\"outline\"\n />\n </CardContent>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-13.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-13.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-13",
|
||||
"type": "registry:block",
|
||||
"description": "With Month and Year Dropdown",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"label",
|
||||
"select"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-13.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/registry/new-york-v4/ui/select\"\n\nexport default function Calendar13() {\n const [dropdown, setDropdown] =\n React.useState<React.ComponentProps<typeof Calendar>[\"captionLayout\"]>(\n \"dropdown\"\n )\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <div className=\"flex flex-col gap-4\">\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n captionLayout={dropdown}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dropdown\" className=\"px-1\">\n Dropdown\n </Label>\n <Select\n value={dropdown}\n onValueChange={(value) =>\n setDropdown(\n value as React.ComponentProps<typeof Calendar>[\"captionLayout\"]\n )\n }\n >\n <SelectTrigger\n id=\"dropdown\"\n size=\"sm\"\n className=\"bg-background w-full\"\n >\n <SelectValue placeholder=\"Dropdown\" />\n </SelectTrigger>\n <SelectContent align=\"center\">\n <SelectItem value=\"dropdown\">Month and Year</SelectItem>\n <SelectItem value=\"dropdown-months\">Month Only</SelectItem>\n <SelectItem value=\"dropdown-years\">Year Only</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-14.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-14.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-14",
|
||||
"type": "registry:block",
|
||||
"description": "With Booked/Unavailable Days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-14.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar14() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const bookedDates = Array.from(\n { length: 12 },\n (_, i) => new Date(2025, 5, 15 + i)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n disabled={bookedDates}\n modifiers={{\n booked: bookedDates,\n }}\n modifiersClassNames={{\n booked: \"[&>button]:line-through opacity-100\",\n }}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-15.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-15.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-15",
|
||||
"type": "registry:block",
|
||||
"description": "With Week Numbers",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-15.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar15() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n showWeekNumber\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-16.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-16.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-16",
|
||||
"type": "registry:block",
|
||||
"description": "With time picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-16.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Clock2Icon } from \"lucide-react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\n\nexport default function Calendar16() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n />\n </CardContent>\n <CardFooter className=\"flex flex-col gap-6 border-t px-4 !pt-4\">\n <div className=\"flex w-full flex-col gap-3\">\n <Label htmlFor=\"time-from\">Start Time</Label>\n <div className=\"relative flex w-full items-center gap-2\">\n <Clock2Icon className=\"text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none\" />\n <Input\n id=\"time-from\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n <div className=\"flex w-full flex-col gap-3\">\n <Label htmlFor=\"time-to\">End Time</Label>\n <div className=\"relative flex w-full items-center gap-2\">\n <Clock2Icon className=\"text-muted-foreground pointer-events-none absolute left-2.5 size-4 select-none\" />\n <Input\n id=\"time-to\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"appearance-none pl-8 [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-17.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-17.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-17",
|
||||
"type": "registry:block",
|
||||
"description": "With time picker inline",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-17.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\n\nexport default function Calendar17() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0 [--cell-size:--spacing(10.5)]\"\n />\n </CardContent>\n <CardFooter className=\"flex gap-2 border-t px-4 !pt-4 *:[div]:w-full\">\n <div>\n <Label htmlFor=\"time-from\" className=\"sr-only\">\n Start Time\n </Label>\n <Input\n id=\"time-from\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n <span>-</span>\n <div>\n <Label htmlFor=\"time-to\" className=\"sr-only\">\n End Time\n </Label>\n <Input\n id=\"time-to\"\n type=\"time\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-18.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-18.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-18",
|
||||
"type": "registry:block",
|
||||
"description": "Variable size",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-18.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar18() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border [--cell-size:--spacing(11)] md:[--cell-size:--spacing(12)]\"\n buttonVariant=\"ghost\"\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
31
apps/v4/public/r/styles/new-york-v4/calendar-19.json
Normal file
31
apps/v4/public/r/styles/new-york-v4/calendar-19.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-19",
|
||||
"type": "registry:block",
|
||||
"description": "With presets",
|
||||
"dependencies": [
|
||||
"date-fns"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-19.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { addDays } from \"date-fns\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\n\nexport default function Calendar19() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"max-w-[300px] py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n defaultMonth={date}\n className=\"bg-transparent p-0 [--cell-size:--spacing(9.5)]\"\n />\n </CardContent>\n <CardFooter className=\"flex flex-wrap gap-2 border-t px-4 !pt-4\">\n {[\n { label: \"Today\", value: 0 },\n { label: \"Tomorrow\", value: 1 },\n { label: \"In 3 days\", value: 3 },\n { label: \"In a week\", value: 7 },\n { label: \"In 2 weeks\", value: 14 },\n ].map((preset) => (\n <Button\n key={preset.value}\n variant=\"outline\"\n size=\"sm\"\n className=\"flex-1\"\n onClick={() => {\n const newDate = addDays(new Date(), preset.value)\n setDate(newDate)\n }}\n >\n {preset.label}\n </Button>\n ))}\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-20.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-20.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-20",
|
||||
"type": "registry:block",
|
||||
"description": "With time presets",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-20.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\n\nexport default function Calendar20() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const [selectedTime, setSelectedTime] = React.useState<string | null>(\"10:00\")\n const timeSlots = Array.from({ length: 37 }, (_, i) => {\n const totalMinutes = i * 15\n const hour = Math.floor(totalMinutes / 60) + 9\n const minute = totalMinutes % 60\n return `${hour.toString().padStart(2, \"0\")}:${minute.toString().padStart(2, \"0\")}`\n })\n\n const bookedDates = Array.from(\n { length: 3 },\n (_, i) => new Date(2025, 5, 17 + i)\n )\n\n return (\n <Card className=\"gap-0 p-0\">\n <CardContent className=\"relative p-0 md:pr-48\">\n <div className=\"p-6\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n defaultMonth={date}\n disabled={bookedDates}\n showOutsideDays={false}\n modifiers={{\n booked: bookedDates,\n }}\n modifiersClassNames={{\n booked: \"[&>button]:line-through opacity-100\",\n }}\n className=\"bg-transparent p-0 [--cell-size:--spacing(10)] md:[--cell-size:--spacing(12)]\"\n formatters={{\n formatWeekdayName: (date) => {\n return date.toLocaleString(\"en-US\", { weekday: \"short\" })\n },\n }}\n />\n </div>\n <div className=\"no-scrollbar inset-y-0 right-0 flex max-h-72 w-full scroll-pb-6 flex-col gap-4 overflow-y-auto border-t p-6 md:absolute md:max-h-none md:w-48 md:border-t-0 md:border-l\">\n <div className=\"grid gap-2\">\n {timeSlots.map((time) => (\n <Button\n key={time}\n variant={selectedTime === time ? \"default\" : \"outline\"}\n onClick={() => setSelectedTime(time)}\n className=\"w-full shadow-none\"\n >\n {time}\n </Button>\n ))}\n </div>\n </div>\n </CardContent>\n <CardFooter className=\"flex flex-col gap-4 border-t px-6 !py-5 md:flex-row\">\n <div className=\"text-sm\">\n {date && selectedTime ? (\n <>\n Your meeting is booked for{\" \"}\n <span className=\"font-medium\">\n {\" \"}\n {date?.toLocaleDateString(\"en-US\", {\n weekday: \"long\",\n day: \"numeric\",\n month: \"long\",\n })}{\" \"}\n </span>\n at <span className=\"font-medium\">{selectedTime}</span>.\n </>\n ) : (\n <>Select a date and time for your meeting.</>\n )}\n </div>\n <Button\n disabled={!date || !selectedTime}\n className=\"w-full md:ml-auto md:w-auto\"\n variant=\"outline\"\n >\n Continue\n </Button>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-21.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-21.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-21",
|
||||
"type": "registry:block",
|
||||
"description": "Custom days and formatters",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-21.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { DateRange } from \"react-day-picker\"\n\nimport { Calendar, CalendarDayButton } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function Calendar21() {\n const [range, setRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 5, 17),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={range?.from}\n selected={range}\n onSelect={setRange}\n numberOfMonths={1}\n captionLayout=\"dropdown\"\n className=\"rounded-lg border shadow-sm [--cell-size:--spacing(11)] md:[--cell-size:--spacing(13)]\"\n formatters={{\n formatMonthDropdown: (date) => {\n return date.toLocaleString(\"default\", { month: \"long\" })\n },\n }}\n components={{\n DayButton: ({ children, modifiers, day, ...props }) => {\n const isWeekend = day.date.getDay() === 0 || day.date.getDay() === 6\n\n return (\n <CalendarDayButton day={day} modifiers={modifiers} {...props}>\n {children}\n {!modifiers.outside && <span>{isWeekend ? \"$220\" : \"$100\"}</span>}\n </CalendarDayButton>\n )\n },\n }}\n />\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-22.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-22.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-22",
|
||||
"type": "registry:block",
|
||||
"description": "Date picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-22.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar22() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date of birth\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-48 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-23.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-23.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-23",
|
||||
"type": "registry:block",
|
||||
"description": "Date range picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-23.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar23() {\n const [range, setRange] = React.useState<DateRange | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dates\" className=\"px-1\">\n Select your stay\n </Label>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"dates\"\n className=\"w-56 justify-between font-normal\"\n >\n {range?.from && range?.to\n ? `${range.from.toLocaleDateString()} - ${range.to.toLocaleDateString()}`\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={range}\n captionLayout=\"dropdown\"\n onSelect={(range) => {\n setRange(range)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-24.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-24.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-24",
|
||||
"type": "registry:block",
|
||||
"description": "Date and Time picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-24.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar24() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-32 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time\" className=\"px-1\">\n Time\n </Label>\n <Input\n type=\"time\"\n id=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
28
apps/v4/public/r/styles/new-york-v4/calendar-25.json
Normal file
28
apps/v4/public/r/styles/new-york-v4/calendar-25.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-25",
|
||||
"type": "registry:block",
|
||||
"description": "Date and Time range picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-25.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar25() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-6\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-full justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-from\" className=\"px-1\">\n From\n </Label>\n <Input\n type=\"time\"\n id=\"time-from\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-to\" className=\"px-1\">\n To\n </Label>\n <Input\n type=\"time\"\n id=\"time-to\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/new-york-v4/calendar-26.json
Normal file
29
apps/v4/public/r/styles/new-york-v4/calendar-26.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-26",
|
||||
"type": "registry:block",
|
||||
"description": "Date range picker with time",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"popover",
|
||||
"button",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-26.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar26() {\n const [openFrom, setOpenFrom] = React.useState(false)\n const [openTo, setOpenTo] = React.useState(false)\n const [dateFrom, setDateFrom] = React.useState<Date | undefined>(\n new Date(\"2025-06-01\")\n )\n const [dateTo, setDateTo] = React.useState<Date | undefined>(\n new Date(\"2025-06-03\")\n )\n\n return (\n <div className=\"flex w-full max-w-64 min-w-0 flex-col gap-6\">\n <div className=\"flex gap-4\">\n <div className=\"flex flex-1 flex-col gap-3\">\n <Label htmlFor=\"date-from\" className=\"px-1\">\n Check-in\n </Label>\n <Popover open={openFrom} onOpenChange={setOpenFrom}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date-from\"\n className=\"w-full justify-between font-normal\"\n >\n {dateFrom\n ? dateFrom.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"start\"\n >\n <Calendar\n mode=\"single\"\n selected={dateFrom}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDateFrom(date)\n setOpenFrom(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-from\" className=\"invisible px-1\">\n From\n </Label>\n <Input\n type=\"time\"\n id=\"time-from\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n <div className=\"flex gap-4\">\n <div className=\"flex flex-1 flex-col gap-3\">\n <Label htmlFor=\"date-to\" className=\"px-1\">\n Check-out\n </Label>\n <Popover open={openTo} onOpenChange={setOpenTo}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date-to\"\n className=\"w-full justify-between font-normal\"\n >\n {dateTo\n ? dateTo.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"start\"\n >\n <Calendar\n mode=\"single\"\n selected={dateTo}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDateTo(date)\n setOpenTo(false)\n }}\n disabled={dateFrom && { before: dateFrom }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-to\" className=\"invisible px-1\">\n To\n </Label>\n <Input\n type=\"time\"\n id=\"time-to\"\n step=\"1\"\n defaultValue=\"12:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/new-york-v4/calendar-27.json
Normal file
29
apps/v4/public/r/styles/new-york-v4/calendar-27.json
Normal file
File diff suppressed because one or more lines are too long
29
apps/v4/public/r/styles/new-york-v4/calendar-28.json
Normal file
29
apps/v4/public/r/styles/new-york-v4/calendar-28.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-28",
|
||||
"type": "registry:block",
|
||||
"description": "Input with date picker",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-28.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nfunction formatDate(date: Date | undefined) {\n if (!date) {\n return \"\"\n }\n\n return date.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n })\n}\n\nfunction isValidDate(date: Date | undefined) {\n if (!date) {\n return false\n }\n return !isNaN(date.getTime())\n}\n\nexport default function Calendar28() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(\"2025-06-01\")\n )\n const [month, setMonth] = React.useState<Date | undefined>(date)\n const [value, setValue] = React.useState(formatDate(date))\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Subscription Date\n </Label>\n <div className=\"relative flex gap-2\">\n <Input\n id=\"date\"\n value={value}\n placeholder=\"June 01, 2025\"\n className=\"bg-background pr-10\"\n onChange={(e) => {\n const date = new Date(e.target.value)\n setValue(e.target.value)\n if (isValidDate(date)) {\n setDate(date)\n setMonth(date)\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setOpen(true)\n }\n }}\n />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id=\"date-picker\"\n variant=\"ghost\"\n className=\"absolute top-1/2 right-2 size-6 -translate-y-1/2\"\n >\n <CalendarIcon className=\"size-3.5\" />\n <span className=\"sr-only\">Select date</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-auto overflow-hidden p-0\"\n align=\"end\"\n alignOffset={-8}\n sideOffset={10}\n >\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n onSelect={(date) => {\n setDate(date)\n setValue(formatDate(date))\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
32
apps/v4/public/r/styles/new-york-v4/calendar-29.json
Normal file
32
apps/v4/public/r/styles/new-york-v4/calendar-29.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-29",
|
||||
"type": "registry:block",
|
||||
"description": "Natural language date picker",
|
||||
"dependencies": [
|
||||
"chrono-node"
|
||||
],
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-29.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { parseDate } from \"chrono-node\"\nimport { CalendarIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nfunction formatDate(date: Date | undefined) {\n if (!date) {\n return \"\"\n }\n\n return date.toLocaleDateString(\"en-US\", {\n day: \"2-digit\",\n month: \"long\",\n year: \"numeric\",\n })\n}\n\nexport default function Calendar29() {\n const [open, setOpen] = React.useState(false)\n const [value, setValue] = React.useState(\"In 2 days\")\n const [date, setDate] = React.useState<Date | undefined>(\n parseDate(value) || undefined\n )\n const [month, setMonth] = React.useState<Date | undefined>(date)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Schedule Date\n </Label>\n <div className=\"relative flex gap-2\">\n <Input\n id=\"date\"\n value={value}\n placeholder=\"Tomorrow or next week\"\n className=\"bg-background pr-10\"\n onChange={(e) => {\n setValue(e.target.value)\n const date = parseDate(e.target.value)\n if (date) {\n setDate(date)\n setMonth(date)\n }\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault()\n setOpen(true)\n }\n }}\n />\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n id=\"date-picker\"\n variant=\"ghost\"\n className=\"absolute top-1/2 right-2 size-6 -translate-y-1/2\"\n >\n <CalendarIcon className=\"size-3.5\" />\n <span className=\"sr-only\">Select date</span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"end\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n month={month}\n onMonthChange={setMonth}\n onSelect={(date) => {\n setDate(date)\n setValue(formatDate(date))\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"text-muted-foreground px-1 text-sm\">\n Your post will be published on{\" \"}\n <span className=\"font-medium\">{formatDate(date)}</span>.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/new-york-v4/calendar-30.json
Normal file
29
apps/v4/public/r/styles/new-york-v4/calendar-30.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-30",
|
||||
"type": "registry:block",
|
||||
"description": "With little-date",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"input",
|
||||
"label",
|
||||
"popover",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-30.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { formatDateRange } from \"little-date\"\nimport { ChevronDownIcon } from \"lucide-react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar30() {\n const [range, setRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 4),\n to: new Date(2025, 5, 10),\n })\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"dates\" className=\"px-1\">\n Select your stay\n </Label>\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"dates\"\n className=\"w-56 justify-between font-normal\"\n >\n {range?.from && range?.to\n ? formatDateRange(range.from, range.to, {\n includeTime: false,\n })\n : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"range\"\n selected={range}\n captionLayout=\"dropdown\"\n onSelect={(range) => {\n setRange(range)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-31.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-31.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-31",
|
||||
"type": "registry:block",
|
||||
"description": "With event slots",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-31.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { formatDateRange } from \"little-date\"\nimport { PlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Card, CardContent, CardFooter } from \"@/registry/new-york-v4/ui/card\"\n\nconst events = [\n {\n title: \"Team Sync Meeting\",\n from: \"2025-06-12T09:00:00\",\n to: \"2025-06-12T10:00:00\",\n },\n {\n title: \"Design Review\",\n from: \"2025-06-12T11:30:00\",\n to: \"2025-06-12T12:30:00\",\n },\n {\n title: \"Client Presentation\",\n from: \"2025-06-12T14:00:00\",\n to: \"2025-06-12T15:00:00\",\n },\n]\n\nexport default function Calendar31() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Card className=\"w-fit py-4\">\n <CardContent className=\"px-4\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n required\n />\n </CardContent>\n <CardFooter className=\"flex flex-col items-start gap-3 border-t px-4 !pt-4\">\n <div className=\"flex w-full items-center justify-between px-1\">\n <div className=\"text-sm font-medium\">\n {date?.toLocaleDateString(\"en-US\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n })}\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6\"\n title=\"Add Event\"\n >\n <PlusIcon />\n <span className=\"sr-only\">Add Event</span>\n </Button>\n </div>\n <div className=\"flex w-full flex-col gap-2\">\n {events.map((event) => (\n <div\n key={event.title}\n className=\"bg-muted after:bg-primary/70 relative rounded-md p-2 pl-6 text-sm after:absolute after:inset-y-2 after:left-2 after:w-1 after:rounded-full\"\n >\n <div className=\"font-medium\">{event.title}</div>\n <div className=\"text-muted-foreground text-xs\">\n {formatDateRange(new Date(event.from), new Date(event.to))}\n </div>\n </div>\n ))}\n </div>\n </CardFooter>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "700px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york-v4/calendar-32.json
Normal file
27
apps/v4/public/r/styles/new-york-v4/calendar-32.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-32",
|
||||
"type": "registry:block",
|
||||
"description": "Date picker in a drawer",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"button",
|
||||
"drawer"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/blocks/calendar-32.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { CalendarPlusIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Drawer,\n DrawerContent,\n DrawerDescription,\n DrawerHeader,\n DrawerTitle,\n DrawerTrigger,\n} from \"@/registry/new-york-v4/ui/drawer\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\n\nexport default function Calendar32() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date of birth\n </Label>\n <Drawer open={open} onOpenChange={setOpen}>\n <DrawerTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-48 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <CalendarPlusIcon />\n </Button>\n </DrawerTrigger>\n <DrawerContent className=\"w-auto overflow-hidden p-0\">\n <DrawerHeader className=\"sr-only\">\n <DrawerTitle>Select date</DrawerTitle>\n <DrawerDescription>Set your date of birth</DrawerDescription>\n </DrawerHeader>\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n className=\"mx-auto [--cell-size:clamp(0px,calc(100vw/7.5),52px)]\"\n />\n </DrawerContent>\n </Drawer>\n <div className=\"text-muted-foreground px-1 text-sm\">\n This example works best on mobile.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component"
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/examples/calendar-demo.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function CalendarDemo() {\n const [date, setDate] = React.useState<Date | undefined>(new Date())\n\n return (\n <div className=\"flex flex-col flex-wrap items-start gap-2 @md:flex-row\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"rounded-md border shadow-sm\"\n />\n </div>\n )\n}\n",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\n\nexport default function CalendarDemo() {\n const [date, setDate] = React.useState<Date | undefined>(new Date())\n\n return (\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n className=\"rounded-md border shadow-sm\"\n captionLayout=\"dropdown\"\n />\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/examples/calendar-form.tsx",
|
||||
"content": "\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { useForm } from \"react-hook-form\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from \"@/registry/new-york-v4/ui/form\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nconst FormSchema = z.object({\n dob: z.date({\n required_error: \"A date of birth is required.\",\n }),\n})\n\nexport default function CalendarForm() {\n const form = useForm<z.infer<typeof FormSchema>>({\n resolver: zodResolver(FormSchema),\n })\n\n function onSubmit(data: z.infer<typeof FormSchema>) {\n toast(\"You submitted the following values\", {\n description: (\n <pre className=\"mt-2 w-[320px] rounded-md bg-neutral-950 p-4\">\n <code className=\"text-white\">{JSON.stringify(data, null, 2)}</code>\n </pre>\n ),\n })\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-8\">\n <FormField\n control={form.control}\n name=\"dob\"\n render={({ field }) => (\n <FormItem className=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger asChild>\n <FormControl>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] pl-3 text-left font-normal\",\n !field.value && \"text-muted-foreground\"\n )}\n >\n {field.value ? (\n format(field.value, \"PPP\")\n ) : (\n <span>Pick a date</span>\n )}\n <CalendarIcon className=\"ml-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={field.value}\n onSelect={field.onChange}\n disabled={(date) =>\n date > new Date() || date < new Date(\"1900-01-01\")\n }\n initialFocus\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n <Button type=\"submit\">Submit</Button>\n </form>\n </Form>\n )\n}\n",
|
||||
"content": "\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { useForm } from \"react-hook-form\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from \"@/registry/new-york-v4/ui/form\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nconst FormSchema = z.object({\n dob: z.date({\n required_error: \"A date of birth is required.\",\n }),\n})\n\nexport default function CalendarForm() {\n const form = useForm<z.infer<typeof FormSchema>>({\n resolver: zodResolver(FormSchema),\n })\n\n function onSubmit(data: z.infer<typeof FormSchema>) {\n toast(\"You submitted the following values\", {\n description: (\n <pre className=\"mt-2 w-[320px] rounded-md bg-neutral-950 p-4\">\n <code className=\"text-white\">{JSON.stringify(data, null, 2)}</code>\n </pre>\n ),\n })\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-8\">\n <FormField\n control={form.control}\n name=\"dob\"\n render={({ field }) => (\n <FormItem className=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger asChild>\n <FormControl>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] pl-3 text-left font-normal\",\n !field.value && \"text-muted-foreground\"\n )}\n >\n {field.value ? (\n format(field.value, \"PPP\")\n ) : (\n <span>Pick a date</span>\n )}\n <CalendarIcon className=\"ml-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={field.value}\n onSelect={field.onChange}\n disabled={(date) =>\n date > new Date() || date < new Date(\"1900-01-01\")\n }\n captionLayout=\"dropdown\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n <Button type=\"submit\">Submit</Button>\n </form>\n </Form>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
}
|
||||
]
|
||||
|
||||
25
apps/v4/public/r/styles/new-york-v4/calendar-hijri.json
Normal file
25
apps/v4/public/r/styles/new-york-v4/calendar-hijri.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -14,7 +14,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/examples/date-picker-form.tsx",
|
||||
"content": "\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { useForm } from \"react-hook-form\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from \"@/registry/new-york-v4/ui/form\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nconst FormSchema = z.object({\n dob: z.date({\n required_error: \"A date of birth is required.\",\n }),\n})\n\nexport default function DatePickerForm() {\n const form = useForm<z.infer<typeof FormSchema>>({\n resolver: zodResolver(FormSchema),\n })\n\n function onSubmit(data: z.infer<typeof FormSchema>) {\n toast(\"You submitted the following values\", {\n description: (\n <pre className=\"mt-2 w-[320px] rounded-md bg-neutral-950 p-4\">\n <code className=\"text-white\">{JSON.stringify(data, null, 2)}</code>\n </pre>\n ),\n })\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-8\">\n <FormField\n control={form.control}\n name=\"dob\"\n render={({ field }) => (\n <FormItem className=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger asChild>\n <FormControl>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] pl-3 text-left font-normal\",\n !field.value && \"text-muted-foreground\"\n )}\n >\n {field.value ? (\n format(field.value, \"PPP\")\n ) : (\n <span>Pick a date</span>\n )}\n <CalendarIcon className=\"ml-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={field.value}\n onSelect={field.onChange}\n disabled={(date) =>\n date > new Date() || date < new Date(\"1900-01-01\")\n }\n initialFocus\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n <Button type=\"submit\">Submit</Button>\n </form>\n </Form>\n )\n}\n",
|
||||
"content": "\"use client\"\n\nimport { zodResolver } from \"@hookform/resolvers/zod\"\nimport { format } from \"date-fns\"\nimport { CalendarIcon } from \"lucide-react\"\nimport { useForm } from \"react-hook-form\"\nimport { toast } from \"sonner\"\nimport { z } from \"zod\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from \"@/registry/new-york-v4/ui/form\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nconst FormSchema = z.object({\n dob: z.date({\n required_error: \"A date of birth is required.\",\n }),\n})\n\nexport default function DatePickerForm() {\n const form = useForm<z.infer<typeof FormSchema>>({\n resolver: zodResolver(FormSchema),\n })\n\n function onSubmit(data: z.infer<typeof FormSchema>) {\n toast(\"You submitted the following values\", {\n description: (\n <pre className=\"mt-2 w-[320px] rounded-md bg-neutral-950 p-4\">\n <code className=\"text-white\">{JSON.stringify(data, null, 2)}</code>\n </pre>\n ),\n })\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-8\">\n <FormField\n control={form.control}\n name=\"dob\"\n render={({ field }) => (\n <FormItem className=\"flex flex-col\">\n <FormLabel>Date of birth</FormLabel>\n <Popover>\n <PopoverTrigger asChild>\n <FormControl>\n <Button\n variant={\"outline\"}\n className={cn(\n \"w-[240px] pl-3 text-left font-normal\",\n !field.value && \"text-muted-foreground\"\n )}\n >\n {field.value ? (\n format(field.value, \"PPP\")\n ) : (\n <span>Pick a date</span>\n )}\n <CalendarIcon className=\"ml-auto h-4 w-4 opacity-50\" />\n </Button>\n </FormControl>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={field.value}\n onSelect={field.onChange}\n disabled={(date) =>\n date > new Date() || date < new Date(\"1900-01-01\")\n }\n captionLayout=\"dropdown\"\n />\n </PopoverContent>\n </Popover>\n <FormDescription>\n Your date of birth is used to calculate your age.\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n <Button type=\"submit\">Submit</Button>\n </form>\n </Form>\n )\n}\n",
|
||||
"type": "registry:example"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"files": [
|
||||
{
|
||||
"path": "registry/new-york-v4/ui/drawer.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content bg-background fixed z-50 flex h-auto flex-col\",\n \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b\",\n \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t\",\n \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Drawer({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n return (\n <DrawerPrimitive.Overlay\n data-slot=\"drawer-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n return (\n <DrawerPortal data-slot=\"drawer-portal\">\n <DrawerOverlay />\n <DrawerPrimitive.Content\n data-slot=\"drawer-content\"\n className={cn(\n \"group/drawer-content bg-background fixed z-50 flex h-auto flex-col\",\n \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b\",\n \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t\",\n \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n <div className=\"bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n {children}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(\n \"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n return (\n <DrawerPrimitive.Title\n data-slot=\"drawer-title\"\n className={cn(\"text-foreground font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DrawerDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n return (\n <DrawerPrimitive.Description\n data-slot=\"drawer-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Drawer,\n DrawerPortal,\n DrawerOverlay,\n DrawerTrigger,\n DrawerClose,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n}\n",
|
||||
"type": "registry:ui"
|
||||
}
|
||||
]
|
||||
|
||||
27
apps/v4/public/r/styles/new-york/calendar-01.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-01.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-01",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "A simple calendar.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-01.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar01() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-02.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-02.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-02",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with single selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-02.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar02() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n numberOfMonths={2}\n selected={date}\n onSelect={setDate}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-03.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-03.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-03",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with multiple selection.",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-03.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar03() {\n const [dates, setDates] = React.useState<Date[]>([\n new Date(2025, 5, 12),\n new Date(2025, 6, 24),\n ])\n\n return (\n <Calendar\n mode=\"multiple\"\n numberOfMonths={2}\n defaultMonth={dates[0]}\n required\n selected={dates}\n onSelect={setDates}\n max={5}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-04.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-04.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-04",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Single month with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-04.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar04() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 9),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-4 py-12 items-start md:py-20 justify-center min-w-0 xl:pt-28",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-05.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-05.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-05",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Multiple months with range selection",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-05.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar05() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 6, 15),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-06.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-06.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-06",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Range selection with minimum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-06.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar06() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 12),\n to: new Date(2025, 5, 26),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={1}\n min={5}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n A minimum of 5 days is required\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-07.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-07.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-07",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Range selection with minimum and maximum days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-07.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar07() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 18),\n to: new Date(2025, 6, 7),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n min={2}\n max={20}\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n Your stay must be between 2 and 20 nights\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-08.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-08.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-08",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Calendar with disabled days",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-08.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar08() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n\n return (\n <Calendar\n mode=\"single\"\n defaultMonth={date}\n selected={date}\n onSelect={setDate}\n disabled={{\n before: new Date(2025, 5, 12),\n }}\n className=\"rounded-lg border shadow-sm\"\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-09.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-09.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-09",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Calendar with disabled weekends",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-09.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar09() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <Calendar\n mode=\"range\"\n defaultMonth={dateRange?.from}\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n disabled={{ dayOfWeek: [0, 6] }}\n className=\"rounded-lg border shadow-sm\"\n excludeDisabled\n />\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
29
apps/v4/public/r/styles/new-york/calendar-10.json
Normal file
29
apps/v4/public/r/styles/new-york/calendar-10.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-10",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Today button",
|
||||
"registryDependencies": [
|
||||
"calendar",
|
||||
"card",
|
||||
"button"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-10.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/registry/new-york/ui/card\"\n\nexport default function Calendar10() {\n const [date, setDate] = React.useState<Date | undefined>(\n new Date(2025, 5, 12)\n )\n const [month, setMonth] = React.useState<Date | undefined>(new Date())\n\n return (\n <Card>\n <CardHeader className=\"relative\">\n <CardTitle>Appointment</CardTitle>\n <CardDescription>Find a date</CardDescription>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"absolute right-4 top-4\"\n onClick={() => {\n setMonth(new Date())\n setDate(new Date())\n }}\n >\n Today\n </Button>\n </CardHeader>\n <CardContent>\n <Calendar\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n selected={date}\n onSelect={setDate}\n className=\"bg-transparent p-0\"\n />\n </CardContent>\n </Card>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
27
apps/v4/public/r/styles/new-york/calendar-11.json
Normal file
27
apps/v4/public/r/styles/new-york/calendar-11.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
||||
"name": "calendar-11",
|
||||
"type": "registry:block",
|
||||
"author": "shadcn (https://ui.shadcn.com)",
|
||||
"description": "Start and end of month",
|
||||
"registryDependencies": [
|
||||
"calendar"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"path": "blocks/calendar-11.tsx",
|
||||
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { type DateRange } from \"react-day-picker\"\n\nimport { Calendar } from \"@/registry/new-york/ui/calendar\"\n\nexport default function Calendar11() {\n const [dateRange, setDateRange] = React.useState<DateRange | undefined>({\n from: new Date(2025, 5, 17),\n to: new Date(2025, 5, 20),\n })\n\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Calendar\n mode=\"range\"\n selected={dateRange}\n onSelect={setDateRange}\n numberOfMonths={2}\n startMonth={new Date(2025, 5, 1)}\n endMonth={new Date(2025, 6, 31)}\n disableNavigation\n className=\"rounded-lg border shadow-sm\"\n />\n <div className=\"text-muted-foreground text-center text-xs\">\n We are open in June and July only.\n </div>\n </div>\n )\n}\n",
|
||||
"type": "registry:component",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"iframeHeight": "600px",
|
||||
"container": "w-full bg-surface min-h-svh flex px-6 py-12 items-start md:pt-20 justify-center min-w-0 xl:py-24",
|
||||
"mobile": "component"
|
||||
},
|
||||
"categories": [
|
||||
"calendar",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user