mirror of
https://github.com/hanzoai/shadcn.git
synced 2026-11-03 03:18:52 +00:00
Squash merge of shadcn-ui/ui main branch into hanzo/ui, bringing in: - [email protected] through [email protected] releases - New apps/v4 directory structure - Registry system improvements and MCP server - Framework support (Vue, Svelte, React Native) - New templates (vite-app, monorepo-next, laravel) - Zod 4 compatibility (scoped override for zod@>4) - Test fixture corrections for alias resolution All 867 merge conflicts resolved preserving Hanzo customizations. 1020/1020 shadcn tests pass.
29 lines
3.9 KiB
JSON
29 lines
3.9 KiB
JSON
{
|
|
"$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"
|
|
]
|
|
} |