├── lucide-react.d.ts ├── app ├── favicon.ico ├── full-calender │ └── page.tsx ├── layout.tsx ├── not-found.tsx ├── page.tsx └── globals.css ├── next.config.mjs ├── shadcn-fullcalender ├── types │ ├── tabs.tsx │ └── event.tsx ├── utils │ ├── week-render.tsx │ └── day-render.tsx ├── ui │ ├── collapsible.tsx │ ├── label.tsx │ ├── textarea.tsx │ ├── input.tsx │ ├── toaster.tsx │ ├── sonner.tsx │ ├── slider.tsx │ ├── switch.tsx │ ├── date-picker.tsx │ ├── popover.tsx │ ├── scroll-area.tsx │ ├── tabs.tsx │ ├── card.tsx │ ├── drawer.tsx │ ├── credenza.tsx │ ├── dialog.tsx │ ├── sheet.tsx │ ├── form.tsx │ ├── button.tsx │ └── alert-dialog.tsx ├── hooks │ ├── useTabs.tsx │ ├── useToday.tsx │ ├── useAnimationTrigger.tsx │ ├── useYearChange.tsx │ ├── useWeekChange.tsx │ └── useMonthChange.tsx ├── constants.ts ├── calender-components │ ├── yearheader.tsx │ ├── monthview.tsx │ ├── views.tsx │ ├── monthheader.tsx │ ├── combobox.tsx │ ├── yearbox.tsx │ ├── tabs.tsx │ ├── add-event.tsx │ └── yearview.tsx ├── event-components │ ├── yearviewlist.tsx │ ├── eventmodal.tsx │ ├── event-colored-button.tsx │ └── listallevents.tsx ├── validation │ └── event.ts └── full-calender.tsx ├── postcss.config.mjs ├── components ├── typography │ ├── mute.tsx │ ├── p.tsx │ ├── h3.tsx │ ├── h4.tsx │ ├── h1.tsx │ └── h2.tsx ├── ui │ ├── aspect-ratio.tsx │ ├── skeleton.tsx │ ├── collapsible.tsx │ ├── label.tsx │ ├── textarea.tsx │ ├── input.tsx │ ├── separator.tsx │ ├── progress.tsx │ ├── toaster.tsx │ ├── sonner.tsx │ ├── slider.tsx │ ├── checkbox.tsx │ ├── tooltip.tsx │ ├── switch.tsx │ ├── badge.tsx │ ├── hover-card.tsx │ ├── date-picker.tsx │ ├── popover.tsx │ ├── toggle.tsx │ ├── radio-group.tsx │ ├── avatar.tsx │ ├── alert.tsx │ ├── scroll-area.tsx │ ├── resizable.tsx │ ├── toggle-group.tsx │ ├── tabs.tsx │ ├── card.tsx │ ├── accordion.tsx │ ├── input-otp.tsx │ ├── breadcrumb.tsx │ ├── pagination.tsx │ ├── table.tsx │ ├── drawer.tsx │ ├── credenza.tsx │ ├── dialog.tsx │ ├── sheet.tsx │ ├── form.tsx │ ├── button.tsx │ └── alert-dialog.tsx ├── layout │ ├── code-full.tsx │ ├── maxwidthcontainer.tsx │ └── code-block.tsx └── icons │ └── icon.tsx ├── lib └── utils.ts ├── components.json ├── .gitignore ├── hooks ├── use-media-query.tsx └── use-toast.ts ├── full-calender-config.tsx ├── tsconfig.json ├── README.md ├── package.json └── tailwind.config.ts /lucide-react.d.ts: -------------------------------------------------------------------------------- 1 | // src/types/lucide-react.d.ts 2 | declare module "lucide-react"; 3 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deiondz/shadcn-fullcalender/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /shadcn-fullcalender/types/tabs.tsx: -------------------------------------------------------------------------------- 1 | export type TabTypes = "month" | "year" | "week"; // Add more tab types if necessary 2 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /components/typography/mute.tsx: -------------------------------------------------------------------------------- 1 | export function Muted({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return

{children}

; 3 | } 4 | -------------------------------------------------------------------------------- /components/typography/p.tsx: -------------------------------------------------------------------------------- 1 | export function P({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return

{children}

; 3 | } 4 | -------------------------------------------------------------------------------- /components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /components/typography/h3.tsx: -------------------------------------------------------------------------------- 1 | export function H3({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return ( 3 |

4 | {children} 5 |

6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /components/typography/h4.tsx: -------------------------------------------------------------------------------- 1 | export function H4({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return ( 3 |

4 | {children} 5 |

6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /components/typography/h1.tsx: -------------------------------------------------------------------------------- 1 | export function H1({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return ( 3 |

4 | {children} 5 |

6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /components/typography/h2.tsx: -------------------------------------------------------------------------------- 1 | export function H2({ children }: Readonly<{ children: React.ReactNode }>) { 2 | return ( 3 |

4 | {children} 5 |

6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | 8 | export function classNames(...classes: any[]) { 9 | return classes.filter(Boolean).join(" "); 10 | } 11 | -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /shadcn-fullcalender/utils/week-render.tsx: -------------------------------------------------------------------------------- 1 | interface RenderDaysOfWeekProps { 2 | weekDays: string[]; 3 | } 4 | 5 | export const renderDaysOfWeek = ({ 6 | weekDays, 7 | }: RenderDaysOfWeekProps) => { 8 | return weekDays.map((day, i) => ( 9 |
10 | {day} 11 |
12 | )); 13 | }; 14 | -------------------------------------------------------------------------------- /components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /shadcn-fullcalender/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /shadcn-fullcalender/hooks/useTabs.tsx: -------------------------------------------------------------------------------- 1 | // hooks/useTabs.ts 2 | 3 | import { useState } from "react"; 4 | import { TabTypes } from "../types/tabs"; // Adjust path as needed 5 | 6 | export const useTabs = (initialTab: TabTypes) => { 7 | const [activeTab, setActiveTab] = useState(initialTab); 8 | 9 | const toggleTab = (tab: TabTypes) => { 10 | setActiveTab(tab); 11 | }; 12 | 13 | return { activeTab, setActiveTab: toggleTab }; 14 | }; 15 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | } 20 | } -------------------------------------------------------------------------------- /components/layout/code-full.tsx: -------------------------------------------------------------------------------- 1 | export default function FullCalenderCodeSnippet() { 2 | return ( 3 |
4 |

Configuration Snippet

5 |
 6 |                 
 7 |                     {``}
 8 |                 
 9 |             
10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /hooks/use-media-query.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function useMediaQuery(query: string) { 4 | const [value, setValue] = React.useState(false); 5 | 6 | React.useEffect(() => { 7 | function onChange(event: MediaQueryListEvent) { 8 | setValue(event.matches); 9 | } 10 | 11 | const result = matchMedia(query); 12 | result.addEventListener("change", onChange); 13 | setValue(result.matches); 14 | 15 | return () => result.removeEventListener("change", onChange); 16 | }, [query]); 17 | 18 | return value; 19 | } 20 | -------------------------------------------------------------------------------- /app/full-calender/page.tsx: -------------------------------------------------------------------------------- 1 | import MaxWidthContainer from "@components/layout/maxwidthcontainer"; 2 | import { H1 } from "@components/typography/h1"; 3 | import { newevents } from "@data/events"; 4 | import { calendarConfig } from "@full-calender-config"; 5 | import FullCalender from "@shadcn-fullcalender/full-calender"; 6 | 7 | export default function Home() { 8 | return ( 9 | 10 |
11 | 12 |
13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /components/layout/maxwidthcontainer.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | import clsx from "clsx"; // clsx is useful for conditionally merging class names 3 | 4 | interface MaxWidthContainerProps { 5 | children: ReactNode; 6 | className?: string; // Optional className prop for customization 7 | } 8 | 9 | const MaxWidthContainer: React.FC = ({ 10 | children, 11 | className, 12 | }) => { 13 | return ( 14 |
15 | {children} 16 |
17 | ); 18 | }; 19 | 20 | export default MaxWidthContainer; 21 | -------------------------------------------------------------------------------- /shadcn-fullcalender/hooks/useToday.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { format } from "date-fns"; 3 | 4 | interface UseTodayProps { 5 | setCurrentDate: (date: Date) => void; 6 | setValue: (value: string) => void; 7 | triggerAnimation: (updateState: () => void) => void; 8 | } 9 | 10 | export const useToday = ({ 11 | setCurrentDate, 12 | setValue, 13 | triggerAnimation, 14 | }: UseTodayProps) => { 15 | return useCallback(() => { 16 | const today = new Date(); 17 | triggerAnimation(() => { 18 | setCurrentDate(today); 19 | setValue(format(today, "MMMM").toLowerCase()); 20 | }); 21 | }, [setCurrentDate, setValue, triggerAnimation]); 22 | }; 23 | -------------------------------------------------------------------------------- /shadcn-fullcalender/constants.ts: -------------------------------------------------------------------------------- 1 | export const months = [ 2 | { value: "january", label: "January" }, 3 | { value: "february", label: "February" }, 4 | { value: "march", label: "March" }, 5 | { value: "april", label: "April" }, 6 | { value: "may", label: "May" }, 7 | { value: "june", label: "June" }, 8 | { value: "july", label: "July" }, 9 | { value: "august", label: "August" }, 10 | { value: "september", label: "September" }, 11 | { value: "october", label: "October" }, 12 | { value: "november", label: "November" }, 13 | { value: "december", label: "December" }, 14 | ]; 15 | 16 | export const daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; -------------------------------------------------------------------------------- /full-calender-config.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { CalendarProps } from "@shadcn-fullcalender/types/event"; 3 | 4 | 5 | export const calendarConfig: CalendarProps['config'] = { 6 | addEventConfig: { 7 | variant: 'primary', // Default variant (can be 'primary', 'secondary', etc.) 8 | buttonText: 'Add Event', // Default button text 9 | formTitle: 'Create a New Event', // Default form title 10 | formDescription: 'Testing', // Default form description 11 | icon: undefined, // Custom icon for the button, if needed 12 | customForm: undefined, // Custom form component, if needed 13 | }, 14 | animationConfig: { 15 | duration: 300, // Default animation duration in milliseconds 16 | }, 17 | }; 18 | 19 | 20 | -------------------------------------------------------------------------------- /shadcn-fullcalender/hooks/useAnimationTrigger.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useRef, useState } from "react"; 2 | 3 | export const useAnimationTrigger = (animationDuration: number) => { 4 | const [isAnimating, setIsAnimating] = useState(false); 5 | const animationTimeoutRef = useRef(null); 6 | 7 | const triggerAnimation = useCallback((updateState: () => void) => { 8 | setIsAnimating(true); 9 | 10 | if (animationTimeoutRef.current) { 11 | clearTimeout(animationTimeoutRef.current); 12 | } 13 | 14 | animationTimeoutRef.current = setTimeout(() => { 15 | updateState(); 16 | setIsAnimating(false); 17 | }, animationDuration); 18 | }, [animationDuration]); 19 | 20 | return { isAnimating, triggerAnimation }; 21 | }; 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "dom", 5 | "dom.iterable", 6 | "esnext" 7 | ], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "noEmit": true, 12 | "esModuleInterop": true, 13 | "module": "esnext", 14 | "moduleResolution": "bundler", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "jsx": "preserve", 18 | "incremental": true, 19 | "plugins": [ 20 | { 21 | "name": "next" 22 | } 23 | ], 24 | "paths": { 25 | "@*": [ 26 | "./*" 27 | ] 28 | }, 29 | "target": "ES2017" 30 | }, 31 | "include": [ 32 | "next-env.d.ts", 33 | "**/*.ts", 34 | "**/*.tsx", 35 | ".next/types/**/*.ts" 36 | ], 37 | "exclude": [ 38 | "node_modules" 39 | ] 40 | } -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |